@@ -993,7 +993,7 @@ pub fn (mut t Table) bitsize_to_type(bit_size int) Type {
993993// resolve_generic_to_concrete resolves generics to real types T => int.
994994// Even map[string]map[string]T can be resolved.
995995// This is used for resolving the generic return type of CallExpr white `unwrap_generic` is used to resolve generic usage in FnDecl.
996- pub fn (mut t Table) resolve_generic_to_concrete (generic_type Type, generic_names []string , concrete_types []Type) ? Type {
996+ pub fn (mut t Table) resolve_generic_to_concrete (generic_type Type, generic_names []string , concrete_types []Type, is_inst bool ) ? Type {
997997 mut sym := t.get_type_symbol (generic_type)
998998 if sym.name in generic_names {
999999 index := generic_names.index (sym.name)
@@ -1009,21 +1009,27 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name
10091009 elem_sym = t.get_type_symbol (elem_type)
10101010 dims++
10111011 }
1012- if typ := t.resolve_generic_to_concrete (elem_type, generic_names, concrete_types) {
1012+ if typ := t.resolve_generic_to_concrete (elem_type, generic_names, concrete_types,
1013+ is_inst)
1014+ {
10131015 idx := t.find_or_register_array_with_dims (typ, dims)
10141016 return new_type (idx).derive (generic_type).clear_flag (.generic)
10151017 }
10161018 } else if sym.kind == .chan {
10171019 info := sym.info as Chan
1018- if typ := t.resolve_generic_to_concrete (info.elem_type, generic_names, concrete_types) {
1020+ if typ := t.resolve_generic_to_concrete (info.elem_type, generic_names, concrete_types,
1021+ is_inst)
1022+ {
10191023 idx := t.find_or_register_chan (typ, typ.nr_muls () > 0 )
10201024 return new_type (idx).derive (generic_type).clear_flag (.generic)
10211025 }
10221026 } else if mut sym.info is MultiReturn {
10231027 mut types := []Type{}
10241028 mut type_changed := false
10251029 for ret_type in sym.info.types {
1026- if typ := t.resolve_generic_to_concrete (ret_type, generic_names, concrete_types) {
1030+ if typ := t.resolve_generic_to_concrete (ret_type, generic_names, concrete_types,
1031+ is_inst)
1032+ {
10271033 types << typ
10281034 type_changed = true
10291035 } else {
@@ -1038,18 +1044,39 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name
10381044 mut type_changed := false
10391045 mut unwrapped_key_type := sym.info.key_type
10401046 mut unwrapped_value_type := sym.info.value_type
1041- if typ := t.resolve_generic_to_concrete (sym.info.key_type, generic_names, concrete_types) {
1047+ if typ := t.resolve_generic_to_concrete (sym.info.key_type, generic_names, concrete_types,
1048+ is_inst)
1049+ {
10421050 unwrapped_key_type = typ
10431051 type_changed = true
10441052 }
1045- if typ := t.resolve_generic_to_concrete (sym.info.value_type, generic_names, concrete_types) {
1053+ if typ := t.resolve_generic_to_concrete (sym.info.value_type, generic_names, concrete_types,
1054+ is_inst)
1055+ {
10461056 unwrapped_value_type = typ
10471057 type_changed = true
10481058 }
10491059 if type_changed {
10501060 idx := t.find_or_register_map (unwrapped_key_type, unwrapped_value_type)
10511061 return new_type (idx).derive (generic_type).clear_flag (.generic)
10521062 }
1063+ } else if mut sym.info is Struct {
1064+ if sym.info.is_generic && is_inst {
1065+ mut nrt := '$sym.name <'
1066+ for i in 0 .. concrete_types.len {
1067+ gts := t.get_type_symbol (concrete_types[i])
1068+ nrt + = gts.name
1069+ if i != concrete_types.len - 1 {
1070+ nrt + = ','
1071+ }
1072+ }
1073+ nrt + = '>'
1074+ mut idx := t.type_idxs[nrt]
1075+ if idx == 0 {
1076+ idx = t.add_placeholder_type (nrt, .v)
1077+ }
1078+ return new_type (idx).derive (generic_type).clear_flag (.generic)
1079+ }
10531080 }
10541081 return none
10551082}
@@ -1070,7 +1097,7 @@ pub fn (mut t Table) generic_struct_insts_to_concrete() {
10701097 generic_names := parent_info.generic_types.map (t.get_type_symbol (it ).name)
10711098 for i in 0 .. fields.len {
10721099 if t_typ := t.resolve_generic_to_concrete (fields[i].typ, generic_names,
1073- info.concrete_types)
1100+ info.concrete_types, true )
10741101 {
10751102 fields[i].typ = t_typ
10761103 }
0 commit comments