@@ -14,14 +14,14 @@ const option_name = ast.option_name
1414pub struct Generics {
1515 pref & pref.Preferences
1616pub mut :
17- table & ast.Table = unsafe { nil }
18- file & ast.File = unsafe { nil }
19- styp_cache map [ast.Type]string
20- cur_fn & ast.FnDecl = unsafe { nil }
21- cur_concrete_types []ast.Type
22- inside_struct_init bool
23- cur_struct_init_typ ast.Type
24- forin_types map [string ]ast.Type // maps the name of the elem variable (`for elem in my_array`) to the solved type
17+ table & ast.Table = unsafe { nil }
18+ file & ast.File = unsafe { nil }
19+ styp_cache map [ast.Type]string
20+ cur_fn & ast.FnDecl = unsafe { nil }
21+ cur_concrete_types []ast.Type
22+ inside_struct_init bool
23+ cur_struct_init_node & ast.StructInit = unsafe { nil }
24+ forin_types map [string ]ast.Type // maps the name of the elem variable (`for elem in my_array`) to the solved type
2525}
2626
2727pub fn new_generics (pref_ & pref.Preferences) & Generics {
@@ -377,10 +377,6 @@ fn (mut g Generics) register_result(t ast.Type) string {
377377 return styp
378378}
379379
380- // TODO: this really shouldn't be separate from typ
381- // but I(emily) would rather have this generation
382- // all unified in one place so that it doesn't break
383- // if one location changes
384380fn (mut g Generics) option_type_name (t ast.Type) (string , string ) {
385381 mut base := g.base_type (t)
386382 mut styp := ''
@@ -452,12 +448,12 @@ fn (mut g Generics) cc_type(typ ast.Type, is_prefix_struct bool) string {
452448 return styp
453449}
454450
455- pub fn (mut g Generics) method_concrete_name (old_name string , concrete_types []ast.Type, _receiver_type ast.Type) string {
451+ pub fn (mut g Generics) method_concrete_name (old_name string , concrete_types []ast.Type, receiver_type ast.Type) string {
456452 mut name := old_name
457- if _receiver_type != 0 {
458- mut info := g.table.sym (g.unwrap_generic (_receiver_type )).info
453+ if receiver_type != 0 {
454+ mut info := g.table.sym (g.unwrap_generic (receiver_type )).info
459455 if mut info is ast.Alias {
460- info = g.table.sym (g.table.unaliased_type (g.unwrap_generic (_receiver_type ))).info
456+ info = g.table.sym (g.table.unaliased_type (g.unwrap_generic (receiver_type ))).info
461457 }
462458 if mut info is ast.Struct {
463459 fn_conc_types := concrete_types#[info.generic_types.len..] // concrete types without the generic types of the struct
@@ -1171,33 +1167,40 @@ pub fn (mut g Generics) expr(mut node ast.Expr) ast.Expr {
11711167 }
11721168 ast.StructInit {
11731169 if g.cur_concrete_types.len > 0 {
1170+ old_inside_struct_init := g.inside_struct_init
11741171 g.inside_struct_init = true
1175- g.cur_struct_init_typ = node.typ
1172+ old_cur_struct_init_node := g.cur_struct_init_node
1173+ g.cur_struct_init_node = unsafe { & node }
1174+
11761175 mut init_fields := node.init_fields.clone ()
11771176 for mut init_field in init_fields {
11781177 init_field.expr = g.expr (mut init_field.expr)
1178+ init_field.typ = g.unwrap_generic (init_field.typ)
1179+ init_field.expected_type = g.unwrap_generic (init_field.expected_type)
1180+ init_field.parent_type = g.unwrap_generic (init_field.parent_type)
11791181 }
1182+
11801183 out := ast.Expr (ast.StructInit{
11811184 ...node
11821185 typ: g.unwrap_generic (node.typ)
11831186 typ_str: g.table.type_str (g.unwrap_generic (node.typ))
1184- generic_types: []
1187+ generic_types: node.generic_types. map (g. unwrap_generic ( it ))
11851188 update_expr: g.expr (mut node.update_expr)
11861189 update_expr_type: g.unwrap_generic (node.update_expr_type)
11871190 init_fields: init_fields
11881191 })
1189- g.cur_struct_init_typ = 0
1190- g.inside_struct_init = false
1192+
1193+ g.cur_struct_init_node = old_cur_struct_init_node
1194+ g.inside_struct_init = old_inside_struct_init
11911195 return out
11921196 }
1197+ old_inside_struct_init := g.inside_struct_init
11931198 g.inside_struct_init = true
1194- g.cur_struct_init_typ = node.typ
11951199 node.update_expr = g.expr (mut node.update_expr)
11961200 for mut init_field in node.init_fields {
11971201 init_field.expr = g.expr (mut init_field.expr)
11981202 }
1199- g.cur_struct_init_typ = 0
1200- g.inside_struct_init = false
1203+ g.inside_struct_init = old_inside_struct_init
12011204 }
12021205 ast.TypeNode {
12031206 if g.cur_concrete_types.len > 0 {
@@ -1239,13 +1242,14 @@ fn (mut g Generics) unwrap_generic(typ ast.Type) ast.Type {
12391242 if t_typ := g.table.convert_generic_type (typ, g.cur_fn.generic_names, g.cur_concrete_types) {
12401243 return t_typ
12411244 }
1242- } else if g.inside_struct_init {
1243- if g.cur_struct_init_typ != 0 {
1244- sym := g.table.sym (g.cur_struct_init_typ)
1245+ }
1246+ if g.inside_struct_init && g.cur_struct_init_node != unsafe { nil } {
1247+ if g.cur_struct_init_node.typ != 0 {
1248+ sym := g.table.sym (g.cur_struct_init_node.typ)
12451249 if sym.info is ast.Struct {
12461250 if sym.info.generic_types.len > 0 {
12471251 generic_names := sym.info.generic_types.map (g.table.sym (it ).name)
1248- if t_typ := g.table.convert_generic_type (typ, generic_names, sym.info.concrete_types ) {
1252+ if t_typ := g.table.convert_generic_type (typ, generic_names, g.cur_struct_init_node.generic_types. map (g. unwrap_generic ( it )) ) {
12491253 return t_typ
12501254 }
12511255 }
0 commit comments