diff --git a/vlib/v/ast/table.v b/vlib/v/ast/table.v index 1d13cd276373b1..e6943a9c1d9c6a 100644 --- a/vlib/v/ast/table.v +++ b/vlib/v/ast/table.v @@ -1945,7 +1945,9 @@ pub fn (mut t Table) unwrap_generic_type_ex(typ Type, generic_names []string, co return new_type(idx).derive_add_muls(typ).clear_flag(.generic) } Struct, Interface, SumType { - if !ts.info.is_generic { + // alias to generic type needs to be rechecked + // e.g. type Vec4 = vec.Vec4[f64] + if !ts.info.is_generic && !(generic_names.len > 0 && recheck_concrete_types) { return typ } mut t_generic_names := generic_names.clone() @@ -2054,7 +2056,7 @@ pub fn (mut t Table) unwrap_generic_type_ex(typ Type, generic_names []string, co } } if final_concrete_types.len > 0 { - for method in ts.methods { + for method in ts.get_methods() { for i in 1 .. method.params.len { if method.params[i].typ.has_flag(.generic) && method.params[i].typ != method.params[0].typ { diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 965cee2bf2e44a..c6346419667e2d 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -599,6 +599,12 @@ fn (mut c Checker) alias_type_decl(node ast.AliasTypeDecl) { } } } + + // Recheck generic type with its supplied concrete type + if parent_typ_sym.info.generic_types.len > 0 { + c.table.unwrap_generic_type_ex(node.parent_type, parent_typ_sym.info.generic_types.map(c.table.type_to_str(it)), + parent_typ_sym.info.concrete_types, true) + } } } .array { diff --git a/vlib/v/tests/aliases/alias_generic_struct_test.v b/vlib/v/tests/aliases/alias_generic_struct_test.v new file mode 100644 index 00000000000000..b195949815cbce --- /dev/null +++ b/vlib/v/tests/aliases/alias_generic_struct_test.v @@ -0,0 +1,25 @@ +module main + +import math.vec + +type Vec4 = vec.Vec4[f32] +type Vec4x = vec.Vec4[f32] + +fn test_main() { + mut v := Vec4{0, 0, 0, 1} + v.one() + assert v.x == 1 + assert v.y == 1 + assert v.z == 1 + assert v.w == 1 + v.from(vec.Vec4[f32]{2, 2, 2, 2}) + assert v.x == 2 + assert v.y == 2 + assert v.z == 2 + assert v.w == 2 + v.from(Vec4x{3, 3, 3, 3}) + assert v.x == 3 + assert v.y == 3 + assert v.z == 3 + assert v.w == 3 +}