diff --git a/sway-core/src/semantic_analysis/namespace/trait_map.rs b/sway-core/src/semantic_analysis/namespace/trait_map.rs index 6551432e7b0..92dc42dfcc3 100644 --- a/sway-core/src/semantic_analysis/namespace/trait_map.rs +++ b/sway-core/src/semantic_analysis/namespace/trait_map.rs @@ -933,11 +933,6 @@ impl TraitMap { *map_type_id, *type_id, ); - type_id.subst(&SubstTypesContext::new( - engines, - &type_mapping, - matches!(code_block_first_pass, CodeBlockFirstPass::No), - )); let trait_items: TraitItems = map_trait_items .clone() .into_iter() diff --git a/sway-core/src/type_system/unify/unify_check.rs b/sway-core/src/type_system/unify/unify_check.rs index f1242e94f64..04e3473d5b1 100644 --- a/sway-core/src/type_system/unify/unify_check.rs +++ b/sway-core/src/type_system/unify/unify_check.rs @@ -510,7 +510,8 @@ impl<'a> UnifyCheck<'a> { // any type can be coerced into a generic, // except if the type already contains the generic (_e, _g @ UnknownGeneric { .. }) => { - !OccursCheck::new(self.engines).check(right, left) + matches!(self.mode, ConstraintSubset) + || !OccursCheck::new(self.engines).check(right, left) } (Alias { ty: l_ty, .. }, Alias { ty: r_ty, .. }) => { diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/nested_generics/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/nested_generics/Forc.lock new file mode 100644 index 00000000000..c3615fcc0e6 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/nested_generics/Forc.lock @@ -0,0 +1,13 @@ +[[package]] +name = "core" +source = "path+from-root-9C31758901D851EE" + +[[package]] +name = "nested_generics" +source = "member" +dependencies = ["std"] + +[[package]] +name = "std" +source = "path+from-root-9C31758901D851EE" +dependencies = ["core"] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/nested_generics/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/nested_generics/Forc.toml new file mode 100644 index 00000000000..bf41a0eb817 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/nested_generics/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "nested_generics" + +[dependencies] +std = { path = "../../../../reduced_std_libs/sway-lib-std-assert" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/nested_generics/json_abi_oracle.json b/test/src/e2e_vm_tests/test_programs/should_pass/language/nested_generics/json_abi_oracle.json new file mode 100644 index 00000000000..03b2f150939 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/nested_generics/json_abi_oracle.json @@ -0,0 +1,25 @@ +{ + "configurables": [], + "functions": [ + { + "attributes": null, + "inputs": [], + "name": "main", + "output": { + "name": "", + "type": 0, + "typeArguments": null + } + } + ], + "loggedTypes": [], + "messagesTypes": [], + "types": [ + { + "components": null, + "type": "bool", + "typeId": 0, + "typeParameters": null + } + ] +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/nested_generics/json_abi_oracle_new_encoding.json b/test/src/e2e_vm_tests/test_programs/should_pass/language/nested_generics/json_abi_oracle_new_encoding.json new file mode 100644 index 00000000000..668a88f2e07 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/nested_generics/json_abi_oracle_new_encoding.json @@ -0,0 +1,23 @@ +{ + "concreteTypes": [ + { + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "type": "bool" + } + ], + "configurables": [], + "encodingVersion": "1", + "functions": [ + { + "attributes": null, + "inputs": [], + "name": "main", + "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + ], + "loggedTypes": [], + "messagesTypes": [], + "metadataTypes": [], + "programType": "script", + "specVersion": "1" +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/nested_generics/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/nested_generics/src/main.sw new file mode 100644 index 00000000000..90af63e4401 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/nested_generics/src/main.sw @@ -0,0 +1,74 @@ +script; + +enum MyOption { + Some: T, + None: (), +} + +impl MyOption { + fn new() -> Self { + Self::None + } + + fn is_none(self) -> bool { + true + } +} + +fn generic_arg_in_function_method_call() { + let o: MyOption = MyOption::None; + let _ = o.is_none(); + + let o: MyOption> = MyOption::None; + let _ = o.is_none(); + + let o: MyOption = MyOption::None; + let _ = o.is_none(); + + let o: MyOption> = MyOption::None; + let _ = o.is_none(); + + let _ = MyOption::is_none(o); +} + +fn generic_arg_in_function_associated_function_call() { + let _ = MyOption::::new(); + let o: MyOption = MyOption::new(); + + let _ = MyOption::>::new(); + let o: MyOption> = MyOption::new(); + + let _ = MyOption::::new(); + let o: MyOption = MyOption::new(); + + let _ = MyOption::>::new(); +} + +struct S { } + +impl S { + fn generic_arg_in_type() { + let o: MyOption = MyOption::None; + let _ = o.is_none(); + + let o: MyOption> = MyOption::None; + let _ = o.is_none(); + + let o: MyOption = MyOption::None; + let _ = o.is_none(); + + let o: MyOption> = MyOption::None; + let _ = o.is_none(); + + let _ = MyOption::is_none(o); + } +} + +pub fn main() -> bool { + generic_arg_in_function_method_call::<(())>(); + S::<()>::generic_arg_in_type(); + + generic_arg_in_function_associated_function_call::<()>(); + + true +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/nested_generics/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/nested_generics/test.toml new file mode 100644 index 00000000000..4458095bab6 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/nested_generics/test.toml @@ -0,0 +1,5 @@ +category = "run" +expected_result = { action = "return", value = 1 } +expected_result_new_encoding = { action = "return_data", value = "01" } +validate_abi = true +expected_warnings = 30