From 7f65d7e7e5c534c4d03382fa858612ba6c84d1c1 Mon Sep 17 00:00:00 2001 From: Joao Matos Date: Wed, 1 Feb 2023 09:45:25 +0000 Subject: [PATCH] Keep track of parents during function application monomorphization. --- sway-core/src/language/ty/ast_node.rs | 4 +++ .../language/ty/declaration/declaration.rs | 18 ++++++++++++ .../ast_node/expression/typed_expression.rs | 29 ++++++++++++++----- .../typed_expression/function_application.rs | 12 ++++++-- 4 files changed, 53 insertions(+), 10 deletions(-) diff --git a/sway-core/src/language/ty/ast_node.rs b/sway-core/src/language/ty/ast_node.rs index 32a99899da5..10a149dfda0 100644 --- a/sway-core/src/language/ty/ast_node.rs +++ b/sway-core/src/language/ty/ast_node.rs @@ -17,6 +17,10 @@ pub trait GetDeclIdent { fn get_decl_ident(&self, decl_engine: &DeclEngine) -> Option; } +pub trait GetDeclId { + fn get_decl_id(&self) -> Option; +} + #[derive(Clone, Debug)] pub struct TyAstNode { pub content: TyAstNodeContent, diff --git a/sway-core/src/language/ty/declaration/declaration.rs b/sway-core/src/language/ty/declaration/declaration.rs index d8d55119748..779839f41c9 100644 --- a/sway-core/src/language/ty/declaration/declaration.rs +++ b/sway-core/src/language/ty/declaration/declaration.rs @@ -309,6 +309,24 @@ impl GetDeclIdent for TyDeclaration { } } +impl GetDeclId for TyDeclaration { + fn get_decl_id(&self) -> Option { + match self { + TyDeclaration::VariableDeclaration(_) => todo!("not a declaration id yet"), + TyDeclaration::ConstantDeclaration(decl) => Some(decl.clone()), + TyDeclaration::FunctionDeclaration(decl) => Some(decl.clone()), + TyDeclaration::TraitDeclaration(decl) => Some(decl.clone()), + TyDeclaration::StructDeclaration(decl) => Some(decl.clone()), + TyDeclaration::EnumDeclaration(decl) => Some(decl.clone()), + TyDeclaration::ImplTrait(decl) => Some(decl.clone()), + TyDeclaration::AbiDeclaration(decl) => Some(decl.clone()), + TyDeclaration::GenericTypeForFunctionScope { .. } => None, + TyDeclaration::ErrorRecovery(_) => None, + TyDeclaration::StorageDeclaration(_decl) => None, + } + } +} + impl TyDeclaration { /// Retrieves the declaration as an enum declaration. /// diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs index b823eb5557e..5ace4caac45 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs @@ -19,7 +19,11 @@ pub(crate) use self::{ use crate::{ asm_lang::{virtual_ops::VirtualOp, virtual_register::VirtualRegister}, error::*, - language::{parsed::*, ty, *}, + language::{ + parsed::*, + ty::{self, GetDeclId}, + *, + }, semantic_analysis::*, transform::to_parsed_lang::type_name_to_type_info_opt, type_system::*, @@ -482,7 +486,7 @@ impl ty::TyExpression { ); // check that the decl is a function decl - let function_decl = check!( + let _ = check!( unknown_decl.expect_function(decl_engine, &span), return err(warnings, errors), warnings, @@ -491,7 +495,7 @@ impl ty::TyExpression { instantiate_function_application( ctx, - function_decl, + unknown_decl.get_decl_id().unwrap(), call_path_binding, Some(arguments), span, @@ -1106,14 +1110,24 @@ impl ty::TyExpression { // Check if this could be a function let mut function_probe_warnings = Vec::new(); let mut function_probe_errors = Vec::new(); - let maybe_function = { + + let maybe_function_decl = { let mut call_path_binding = unknown_call_path_binding.clone(); TypeBinding::type_check_with_ident(&mut call_path_binding, ctx.by_ref()) - .flat_map(|unknown_decl| unknown_decl.expect_function(decl_engine, &span)) .ok(&mut function_probe_warnings, &mut function_probe_errors) .map(|func_decl| (func_decl, call_path_binding)) }; + let maybe_function = { + maybe_function_decl.clone().and_then(|f| { + let (fn_decl, call_path_binding) = f; + fn_decl + .expect_function(decl_engine, &span) + .ok(&mut function_probe_warnings, &mut function_probe_errors) + .map(|func_decl| (func_decl, call_path_binding)) + }) + }; + // Check if this could be an enum let mut enum_probe_warnings = vec![]; let mut enum_probe_errors = vec![]; @@ -1168,11 +1182,12 @@ impl ty::TyExpression { errors ) } - (false, Some((func_decl, call_path_binding)), None, None) => { + (false, Some((_func_decl, call_path_binding)), None, None) => { warnings.append(&mut function_probe_warnings); errors.append(&mut function_probe_errors); + let decl_id = maybe_function_decl.and_then(|d| d.0.get_decl_id()).unwrap(); check!( - instantiate_function_application(ctx, func_decl, call_path_binding, args, span), + instantiate_function_application(ctx, decl_id, call_path_binding, args, span), return err(warnings, errors), warnings, errors diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/function_application.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/function_application.rs index 2a47487cb75..fd00a3fcff4 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/function_application.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/function_application.rs @@ -1,5 +1,5 @@ use crate::{ - decl_engine::ReplaceDecls, + decl_engine::{DeclId, ReplaceDecls}, error::*, language::{ty, *}, semantic_analysis::{ast_node::*, TypeCheckContext}, @@ -11,7 +11,7 @@ use sway_types::Spanned; #[allow(clippy::too_many_arguments)] pub(crate) fn instantiate_function_application( mut ctx: TypeCheckContext, - mut function_decl: ty::TyFunctionDeclaration, + function_decl_id: DeclId, call_path_binding: TypeBinding, arguments: Option>, span: Span, @@ -22,6 +22,10 @@ pub(crate) fn instantiate_function_application( let decl_engine = ctx.decl_engine; let engines = ctx.engines(); + let mut function_decl = decl_engine + .get_function(function_decl_id.clone(), &span) + .unwrap(); + if arguments.is_none() { errors.push(CompileError::MissingParenthesesForFunction { method_name: call_path_binding.inner.suffix.clone(), @@ -86,7 +90,9 @@ pub(crate) fn instantiate_function_application( ); function_decl.replace_decls(&decl_mapping, engines); let return_type = function_decl.return_type; - let new_decl_id = decl_engine.insert(function_decl); + let new_decl_id = decl_engine + .insert(function_decl) + .with_parent(decl_engine, function_decl_id); let exp = ty::TyExpression { expression: ty::TyExpressionVariant::FunctionApplication {