From da8d854cbb6374dc27f25e023029d27dc06e817c Mon Sep 17 00:00:00 2001 From: xunilrj Date: Tue, 10 Sep 2024 14:10:03 +0100 Subject: [PATCH] fix second pass of method application arguments --- .../ty/expression/expression_variant.rs | 20 ++++++++++++++++++- .../typed_expression/method_application.rs | 13 +----------- .../language/generic_impl_self/Forc.lock | 19 ++++++++++-------- .../language/generic_impl_self/Forc.toml | 1 + .../language/generic_impl_self/src/main.sw | 13 ++++++++++++ 5 files changed, 45 insertions(+), 21 deletions(-) diff --git a/sway-core/src/language/ty/expression/expression_variant.rs b/sway-core/src/language/ty/expression/expression_variant.rs index 8e80a4bc4d0..a71ba25c592 100644 --- a/sway-core/src/language/ty/expression/expression_variant.rs +++ b/sway-core/src/language/ty/expression/expression_variant.rs @@ -1007,7 +1007,9 @@ impl TypeCheckAnalysis for TyExpressionVariant { ) -> Result<(), ErrorEmitted> { match self { TyExpressionVariant::Literal(_) => {} - TyExpressionVariant::FunctionApplication { fn_ref, .. } => { + TyExpressionVariant::FunctionApplication { + fn_ref, arguments, .. + } => { let fn_decl_id = ctx.get_normalized_fn_node_id(fn_ref.id()); let fn_node = ctx.get_node_for_fn_decl(&fn_decl_id); @@ -1021,6 +1023,22 @@ impl TypeCheckAnalysis for TyExpressionVariant { let _ = fn_decl_id.type_check_analyze(handler, ctx); } } + + // Unify arguments that are still not concrete + let decl = ctx.engines.de().get(fn_ref.id()); + + use crate::type_system::unify::unifier::*; + let unifier = Unifier::new(ctx.engines, "", UnifyKind::Default); + + for (decl_param, arg) in decl.parameters.iter().zip(arguments.iter()) { + unifier.unify( + handler, + arg.1.return_type, + decl_param.type_argument.type_id, + &Span::dummy(), + false, + ); + } } TyExpressionVariant::LazyOperator { lhs, rhs, .. } => { lhs.type_check_analyze(handler, ctx)?; diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs index 8dfcd358bfb..68de3f5f79e 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs @@ -52,18 +52,7 @@ pub(crate) fn type_check_method_application( let arg_handler = Handler::default(); let arg_opt = ty::TyExpression::type_check(&arg_handler, ctx, arg).ok(); - // Check this type needs a second pass - let has_errors = arg_handler.has_errors(); - let is_not_concrete = arg_opt - .as_ref() - .map(|x| { - x.return_type - .extract_inner_types(engines, IncludeSelf::Yes) - .iter() - .any(|x| !x.is_concrete(engines, TreatNumericAs::Abstract)) - }) - .unwrap_or_default(); - let needs_second_pass = has_errors || is_not_concrete; + let needs_second_pass = arg_handler.has_errors(); if index == 0 { // We want to emit errors in the self parameter and ignore TraitConstraintNotSatisfied with Placeholder diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_impl_self/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_impl_self/Forc.lock index ec32bff5749..66ff73a2cb8 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_impl_self/Forc.lock +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_impl_self/Forc.lock @@ -1,13 +1,16 @@ [[package]] -name = 'core' -source = 'path+from-root-DA3FEDB2AB26E552' +name = "core" +source = "path+from-root-DA3FEDB2AB26E552" [[package]] -name = 'generic_impl_self' -source = 'member' -dependencies = ['std'] +name = "generic_impl_self" +source = "member" +dependencies = [ + "core", + "std", +] [[package]] -name = 'std' -source = 'path+from-root-DA3FEDB2AB26E552' -dependencies = ['core'] +name = "std" +source = "path+from-root-DA3FEDB2AB26E552" +dependencies = ["core"] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_impl_self/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_impl_self/Forc.toml index 6b5e5c22c7f..41c297ce82a 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_impl_self/Forc.toml +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_impl_self/Forc.toml @@ -5,4 +5,5 @@ name = "generic_impl_self" entry = "main.sw" [dependencies] +core = { path = "../../../../../../../sway-lib-core" } std = { path = "../../../../../../../sway-lib-std" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_impl_self/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_impl_self/src/main.sw index c40a7312e06..7f8a38cf4b8 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_impl_self/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/generic_impl_self/src/main.sw @@ -1,6 +1,7 @@ script; use std::u128::*; +use std::vec::*; struct Data { value: T, @@ -212,9 +213,21 @@ fn generic_impl_self_test() { assert(u.first.value + u.second.value == 7u8); } +impl Vec { + pub fn with(self, with_value: T) -> Self { + let mut inside_vec = self; + inside_vec.push(with_value); + inside_vec + } +} + fn main() -> u32 { generic_impl_self_test(); result_impl_test(); + // data must be Vec + let data = Vec::new().with(0x333u256).with(0x222u256); + assert(data.len() == 2); + 10u32 }