From d3862db10cf57d43d81c923e8c6920169abe7716 Mon Sep 17 00:00:00 2001 From: Dnreikronos Date: Tue, 26 May 2026 15:05:43 -0300 Subject: [PATCH 1/2] Fix ICE when type aliases for arrays hit const generic traits extract_type_parameters ignored array lengths when matching concrete arrays against generic impls like [T; N], so N was never mapped to its literal value. Additionally, MaterializeConstGenerics did not recurse through TypeInfo::Alias, stopping materialization at the alias boundary. Closes #7616 --- sway-core/src/type_system/id.rs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/sway-core/src/type_system/id.rs b/sway-core/src/type_system/id.rs index de6cbd9e75a..29b2fad3a21 100644 --- a/sway-core/src/type_system/id.rs +++ b/sway-core/src/type_system/id.rs @@ -244,6 +244,17 @@ impl MaterializeConstGenerics for TypeId { .te() .insert_ref(engines, *to_mutable_value, referenced_type); } + TypeInfo::Alias { + name: alias_name, + ty, + } => { + let alias_name = alias_name.clone(); + let mut ty = ty.clone(); + ty.type_id + .materialize_const_generics(engines, handler, name, value)?; + + *self = engines.te().new_alias(engines, alias_name, ty); + } _ => {} } @@ -596,7 +607,7 @@ impl TypeId { } } // Primitive types have "implicit" type parameters - (TypeInfo::Array(ty, _), TypeInfo::Array(orig_ty, _)) => { + (TypeInfo::Array(ty, len), TypeInfo::Array(orig_ty, orig_len)) => { type_parameters.push((ty.type_id, orig_ty.type_id)); ty.type_id.extract_type_parameters( handler, @@ -606,6 +617,15 @@ impl TypeId { const_generic_parameters, orig_ty.type_id, ); + + if let ConstGenericExpr::AmbiguousVariableExpression { ident, .. } = &orig_len.0 { + if let ConstGenericExpr::Literal { .. } = &len.0 { + const_generic_parameters.insert( + ident.as_str().to_string(), + len.0.to_ty_expression(engines), + ); + } + } } (TypeInfo::Alias { name: _, ty }, _) => { ty.type_id.extract_type_parameters( From b4c4d0ca3e381fab44f0dd8fbe10a757a696a64e Mon Sep 17 00:00:00 2001 From: Dnreikronos Date: Tue, 26 May 2026 15:05:54 -0300 Subject: [PATCH 2/2] Add e2e test for type alias array const generics Covers struct fields typed as array aliases, nested aliases, equality via the Eq trait, and Vec::get().unwrap() return type resolution. --- .../type_alias_array_const_generics/Forc.lock | 8 +++++ .../type_alias_array_const_generics/Forc.toml | 8 +++++ .../src/main.sw | 31 +++++++++++++++++++ .../type_alias_array_const_generics/test.toml | 5 +++ 4 files changed, 52 insertions(+) create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_array_const_generics/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_array_const_generics/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_array_const_generics/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_array_const_generics/test.toml diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_array_const_generics/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_array_const_generics/Forc.lock new file mode 100644 index 00000000000..0a8df9d35fd --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_array_const_generics/Forc.lock @@ -0,0 +1,8 @@ +[[package]] +name = "std" +source = "path+from-root-BCE5F39600308AA6" + +[[package]] +name = "type_alias_array_const_generics" +source = "member" +dependencies = ["std"] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_array_const_generics/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_array_const_generics/Forc.toml new file mode 100644 index 00000000000..5d5ce8128a7 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_array_const_generics/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "type_alias_array_const_generics" + +[dependencies] +std = { path = "../../../../../../../sway-lib-std" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_array_const_generics/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_array_const_generics/src/main.sw new file mode 100644 index 00000000000..fff36e92b12 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_array_const_generics/src/main.sw @@ -0,0 +1,31 @@ +script; + +type ArrayU8Len2 = [u8; 2]; +type ArrayNestedLen3 = [ArrayU8Len2; 3]; + +struct MyStruct { + f_array: ArrayU8Len2, + f_nested: ArrayNestedLen3, +} + +fn main() -> u64 { + let a = MyStruct { + f_array: [1u8, 2u8], + f_nested: [[1u8, 2u8], [3u8, 4u8], [5u8, 6u8]], + }; + let b = MyStruct { + f_array: [1u8, 2u8], + f_nested: [[1u8, 2u8], [3u8, 4u8], [5u8, 6u8]], + }; + + assert(a.f_array == b.f_array); + assert(a.f_nested == b.f_nested); + + let mut v: Vec = Vec::new(); + v.push([10u8, 20u8]); + let got: ArrayU8Len2 = v.get(0).unwrap(); + assert(got[0] == 10u8); + assert(got[1] == 20u8); + + 1 +} diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_array_const_generics/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_array_const_generics/test.toml new file mode 100644 index 00000000000..c4978579b04 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_array_const_generics/test.toml @@ -0,0 +1,5 @@ +category = "run" +expected_result = { action = "return", value = 1 } +expected_result_new_encoding = { action = "return_data", value = "0000000000000001" } +validate_abi = false +expected_warnings = 1