@@ -766,12 +766,12 @@ fn (mut g Gen) collect_module_type_names() {
766766 }
767767 fields[field.name] = true
768768 }
769- cloned_fields := fields.clone ()
770- g.enum_type_fields[enum_name] = cloned_fields
769+ mut cloned_fields := fields.clone ()
770+ g.enum_type_fields[enum_name] = cloned_fields. move ()
771771 if enum_name.contains ('__' ) {
772772 short_name := enum_name.all_after_last ('__' )
773- short_cloned_fields := fields.clone ()
774- g.enum_type_fields[short_name] = short_cloned_fields
773+ mut short_cloned_fields := fields.clone ()
774+ g.enum_type_fields[short_name] = short_cloned_fields. move ()
775775 }
776776 }
777777 ast.TypeDecl {
@@ -952,8 +952,9 @@ fn (mut g Gen) collect_aliases_from_type(t types.Type) {
952952 g.register_alias_type ('_result_${base }' )
953953 }
954954 types.Alias {
955- g.collect_aliases_from_type (t.base_type)
956- g.register_alias_type (t.name)
955+ // Alias payloads from self-host env caches can be malformed.
956+ // Decls are collected from AST, so skip runtime alias recursion here.
957+ return
957958 }
958959 types.Pointer {
959960 g.collect_aliases_from_type (t.base_type)
@@ -2384,7 +2385,7 @@ fn (mut g Gen) gen_assign_stmt(node ast.AssignStmt) {
23842385 }
23852386 }
23862387 }
2387- if typ == '' {
2388+ if typ == '' || typ == 'void' {
23882389 typ = 'int'
23892390 }
23902391 g.sb.write_string ('${typ } ${name } = ' )
@@ -3233,7 +3234,7 @@ fn (mut g Gen) gen_interface_cast(type_name string, value_expr ast.Expr) bool {
32333234 return false
32343235 }
32353236 mut is_iface := false
3236- if scope := g.env_scope (g.cur_module) {
3237+ if mut scope := g.env_scope (g.cur_module) {
32373238 if obj := scope.lookup_parent (type_name, 0 ) {
32383239 if obj is types.Type && obj is types.Interface {
32393240 is_iface = true
@@ -3304,7 +3305,7 @@ fn (g &Gen) is_enum_type(name string) bool {
33043305 // Also check the types.Environment
33053306 if g.env != unsafe { nil } {
33063307 mut found := false
3307- if scope := g.env_scope (g.cur_module) {
3308+ if mut scope := g.env_scope (g.cur_module) {
33083309 if obj := scope.lookup_parent (name, 0 ) {
33093310 if obj is types.Type && obj is types.Enum {
33103311 found = true
@@ -3396,7 +3397,7 @@ fn (mut g Gen) is_module_ident(name string) bool {
33963397 }
33973398 if g.env != unsafe { nil } {
33983399 mut found := false
3399- if scope := g.env_scope (g.cur_module) {
3400+ if mut scope := g.env_scope (g.cur_module) {
34003401 if obj := scope.lookup_parent (name, 0 ) {
34013402 found = obj is types.Module
34023403 }
@@ -3719,17 +3720,17 @@ fn (mut g Gen) gen_expr(node ast.Expr) {
37193720 if node.name in g.global_var_modules
37203721 && g.global_var_modules[node.name] == g.cur_module {
37213722 g.sb.write_string ('${g .cur_module }__${node .name }' )
3722- } else {
3723- is_local_var := g.get_local_var_c_type (node.name) != none
3724- const_key := 'const_${g .cur_module }__${node .name }'
3725- global_key := 'global_${g .cur_module }__${node .name }'
3726- if g.cur_module != '' && g.cur_module != 'main' && g.cur_module != 'builtin'
3727- && ! node.name.contains ('__' ) && ! is_local_var
3728- && ((const_key in g.emitted_types || global_key in g.emitted_types)
3729- || g.is_module_local_const_or_global (node.name)) {
3730- g.sb.write_string ('${g .cur_module }__${node .name }' )
3731- } else if g.cur_module != '' && g.cur_module != 'main'
3732- && g.cur_module != 'builtin' && ! node.name.contains ('__' ) && ! is_local_var
3723+ } else {
3724+ is_local_var := g.get_local_var_c_type (node.name) != none
3725+ const_key := 'const_${g .cur_module }__${node .name }'
3726+ global_key := 'global_${g .cur_module }__${node .name }'
3727+ if g.cur_module != '' && g.cur_module != 'main' && g.cur_module != 'builtin'
3728+ && ! node.name.contains ('__' ) && ! is_local_var
3729+ && ((const_key in g.emitted_types || global_key in g.emitted_types)
3730+ || g.is_module_local_const_or_global (node.name)) {
3731+ g.sb.write_string ('${g .cur_module }__${node .name }' )
3732+ } else if g.cur_module != '' && g.cur_module != 'main'
3733+ && g.cur_module != 'builtin' && ! node.name.contains ('__' ) && ! is_local_var
37333734 && ! g.is_module_ident (node.name) && g.is_module_local_fn (node.name)
37343735 && ! g.is_type_name (node.name) {
37353736 g.sb.write_string ('${g .cur_module }__${sanitize_fn_ident (node .name )}' )
@@ -4505,15 +4506,15 @@ fn (mut g Gen) gen_expr(node ast.Expr) {
45054506 return
45064507 }
45074508 }
4508- // Fixed-size array `.len` becomes compile-time length.
4509- if node.rhs.name == 'len' {
4510- if node.lhs is ast.Ident {
4511- mut fixed_name := node.lhs.name
4512- module_const_key := 'const_${g .cur_module }__${node .lhs .name }'
4513- if g.cur_module != '' && g.cur_module != 'main' && g.cur_module != 'builtin'
4514- && module_const_key in g.emitted_types {
4515- fixed_name = '${g .cur_module }__${node .lhs .name }'
4516- }
4509+ // Fixed-size array `.len` becomes compile-time length.
4510+ if node.rhs.name == 'len' {
4511+ if node.lhs is ast.Ident {
4512+ mut fixed_name := node.lhs.name
4513+ module_const_key := 'const_${g .cur_module }__${node .lhs .name }'
4514+ if g.cur_module != '' && g.cur_module != 'main' && g.cur_module != 'builtin'
4515+ && module_const_key in g.emitted_types {
4516+ fixed_name = '${g .cur_module }__${node .lhs .name }'
4517+ }
45174518 if fixed_name in g.fixed_array_globals {
45184519 g.sb.write_string ('((int)(sizeof(${fixed_name }) / sizeof(${fixed_name }[0])))' )
45194520 return
@@ -5940,23 +5941,85 @@ struct SumVariantMatch {
59405941}
59415942
59425943fn (mut g Gen) infer_sum_variant_from_expr (type_name string , variants []string , expr ast.Expr) SumVariantMatch {
5944+ // Handle module constants used as sum variants in selfhosted checker code
5945+ // (e.g. char_, string_, void_, nil_, none_).
5946+ if expr is ast.Ident {
5947+ variant_hint := match expr.name {
5948+ 'char_' {
5949+ 'Char'
5950+ }
5951+ 'string_' {
5952+ 'String'
5953+ }
5954+ 'void_' {
5955+ 'Void'
5956+ }
5957+ 'nil_' {
5958+ 'Nil'
5959+ }
5960+ 'none_' {
5961+ 'None'
5962+ }
5963+ 'rune_' {
5964+ 'Rune'
5965+ }
5966+ 'usize_' {
5967+ 'USize'
5968+ }
5969+ 'isize_' {
5970+ 'ISize'
5971+ }
5972+ 'thread_' {
5973+ 'Thread'
5974+ }
5975+ 'chan_' {
5976+ 'Channel'
5977+ }
5978+ 'bool_' , 'i8_' , 'i16_' , 'i32_' , 'int_' , 'i64_' , 'u8_' , 'u16_' , 'u32_' , 'u64_' , 'f32_' ,
5979+ 'f64_' , 'int_literal_' , 'float_literal_' {
5980+ 'Primitive'
5981+ }
5982+ else {
5983+ ''
5984+ }
5985+ }
5986+ if variant_hint != '' {
5987+ for i, v in variants {
5988+ v_short := if v.contains ('__' ) { v.all_after_last ('__' ) } else { v }
5989+ if v_short == variant_hint || v == variant_hint || v.ends_with ('__${variant_hint }' ) {
5990+ return SumVariantMatch{
5991+ tag: i
5992+ field_name: v
5993+ is_primitive: variant_hint == 'Primitive'
5994+ inner_type: ''
5995+ }
5996+ }
5997+ }
5998+ }
5999+ }
6000+
59436001 // For InitExpr, infer from the struct type name
59446002 if expr is ast.InitExpr {
59456003 init_type := g.expr_type_to_c (expr.typ)
5946- if init_type != '' {
5947- init_short := if init_type.contains ('__' ) {
5948- init_type.all_after_last ('__' )
6004+ mut resolved_init_type := init_type
6005+ if (resolved_init_type == '' || resolved_init_type == 'int' ) && expr.typ is ast.Ident {
6006+ resolved_init_type = expr.typ.name.replace ('.' , '__' )
6007+ }
6008+ if resolved_init_type != '' {
6009+ init_short := if resolved_init_type.contains ('__' ) {
6010+ resolved_init_type.all_after_last ('__' )
59496011 } else {
5950- init_type
6012+ resolved_init_type
59516013 }
59526014 for i, v in variants {
5953- if v == init_short || v == init_type || init_type.ends_with ('__${v }' )
5954- || v.ends_with ('__${init_type }' ) {
6015+ if v == init_short || v == resolved_init_type
6016+ || resolved_init_type.ends_with ('__${v }' )
6017+ || v.ends_with ('__${resolved_init_type }' ) {
59556018 return SumVariantMatch{
59566019 tag: i
59576020 field_name: v
59586021 is_primitive: false
5959- inner_type: init_type
6022+ inner_type: resolved_init_type
59606023 }
59616024 }
59626025 }
@@ -7665,7 +7728,7 @@ fn (g &Gen) lookup_module_scope_object(name string) ?types.Object {
76657728 if g.cur_module == '' {
76667729 return none
76677730 }
7668- if module_scope := g.env_scope (g.cur_module) {
7731+ if mut module_scope := g.env_scope (g.cur_module) {
76697732 if obj := module_scope.lookup (name) {
76707733 return obj
76717734 }
@@ -7736,7 +7799,7 @@ fn (mut g Gen) get_raw_type(node ast.Expr) ?types.Type {
77367799 }
77377800 // Fallback to module scopes when function scope chain misses the symbol.
77387801 if g.cur_module != '' {
7739- if mod_scope := g.env_scope (g.cur_module) {
7802+ if mut mod_scope := g.env_scope (g.cur_module) {
77407803 if obj := mod_scope.lookup_parent (node.name, 0 ) {
77417804 if obj ! is types.Module {
77427805 return obj.typ ()
@@ -7745,7 +7808,7 @@ fn (mut g Gen) get_raw_type(node ast.Expr) ?types.Type {
77457808 }
77467809 }
77477810 if g.cur_module != 'builtin' {
7748- if builtin_scope := g.env_scope ('builtin' ) {
7811+ if mut builtin_scope := g.env_scope ('builtin' ) {
77497812 if obj := builtin_scope.lookup_parent (node.name, 0 ) {
77507813 if obj ! is types.Module {
77517814 return obj.typ ()
@@ -7778,7 +7841,7 @@ fn (mut g Gen) get_raw_type(node ast.Expr) ?types.Type {
77787841 }
77797842 }
77807843 if g.cur_module != '' {
7781- if mod_scope := g.env_scope (g.cur_module) {
7844+ if mut mod_scope := g.env_scope (g.cur_module) {
77827845 if obj := mod_scope.lookup_parent (node.lhs.name, 0 ) {
77837846 if obj is types.Module {
77847847 if rhs_obj := obj.lookup (node.rhs.name) {
0 commit comments