@@ -131,6 +131,11 @@ fn is_anonymous_struct_type_name(name string) bool {
131131}
132132
133133fn (mut g FlatGen) struct_init_effective_type_name(id flat.NodeId, node flat.Node) string {
134+ if node.typ == node.value && node.typ.contains('[') && node.typ.contains('.') {
135+ // A specialized clone's explicit type annotation is newer than the
136+ // checker's expression cache and can retain nested main-module locks.
137+ return node.typ
138+ }
134139 if node.value.starts_with('main.') && !node.value['main.'.len..].contains('.') {
135140 // Monomorphization pins a caller-owned program type with `main.` when the
136141 // generic declaration's module has a same-named type. The expression type
@@ -447,7 +452,12 @@ fn (mut g FlatGen) gen_struct_init(id flat.NodeId) {
447452 }
448453 if is_optional_init && !has_expected_optional
449454 && (g.cur_fn_is_specialized || g.name_uses_specialized_generic_abi(g.cur_fn_name)) {
450- name = g.fn_return_type_name (g.cur_fn_ret)
455+ concrete_type := if node_type is types.OptionType || node_type is types.ResultType {
456+ node_type
457+ } else {
458+ g.cur_fn_ret
459+ }
460+ name = g.concrete_optional_type_name(concrete_type)
451461 }
452462 // A bare generic literal stores its fields under the concrete instance key (`Box[int]`);
453463 // the bare `node.value` (`Box`) entry is removed by monomorphization, so resolve the
@@ -800,6 +810,15 @@ fn (mut g FlatGen) struct_init_has_fixed_array_field(node flat.Node, type_name s
800810 }
801811 }
802812 }
813+ if fields := g.struct_fields_for_type(type_name) {
814+ for field in fields {
815+ if fixed := array_fixed_type(field.typ) {
816+ if g.field_needs_default_init(fixed.elem_type) {
817+ return true
818+ }
819+ }
820+ }
821+ }
803822 return false
804823}
805824
@@ -957,6 +976,23 @@ fn (mut g FlatGen) gen_struct_init_with_fixed_array_fields_impl(node flat.Node,
957976 g.gen_fixed_array_copy_source(fixed_values[i], fixed_field_types[i])
958977 g.write(', sizeof(${tmp}.${cfield}));')
959978 }
979+ if fields := g.struct_fields_for_type(lookup_name) {
980+ for field in fields {
981+ if field.name in set_fields {
982+ continue
983+ }
984+ if fixed := array_fixed_type(field.typ) {
985+ if g.field_needs_default_init(fixed.elem_type) {
986+ cfield := c_field_name(field.name)
987+ for idx in 0 .. fixed.len {
988+ g.write(' ${tmp}.${cfield}[${idx}] = ')
989+ g.gen_default_value_for_type(fixed.elem_type)
990+ g.write(';')
991+ }
992+ }
993+ }
994+ }
995+ }
960996 if heap {
961997 if align := g.struct_decl_alignment_for_init_names(node.value, name) {
962998 align_arg := struct_decl_alignment_memdup_arg(align, name)
@@ -3842,6 +3878,37 @@ fn struct_decl_alignment_memdup_arg(align StructDeclAlignment, c_type string) st
38423878 return '__alignof__(${c_type})'
38433879}
38443880
3881+ fn (g &FlatGen) struct_decl_alignment_c_type(type_name string, fallback string) string {
3882+ resolved_name := g.struct_init_resolved_decl_name(type_name)
3883+ if resolved_name.len == 0 {
3884+ return fallback
3885+ }
3886+ ct := g.tc.c_type(g.tc.parse_type(resolved_name))
3887+ if ct.len == 0 || ct == 'void' {
3888+ return fallback
3889+ }
3890+ if fallback != ct && fallback.ends_with('__${ct}') {
3891+ return fallback
3892+ }
3893+ if qualified_ct := g.unique_qualified_struct_c_type(ct) {
3894+ return qualified_ct
3895+ }
3896+ // Main-module declarations are bare-keyed in the semantic tables, while C
3897+ // emits their typedefs with the `main__` namespace.
3898+ if !resolved_name.contains('.') && resolved_name in g.tc.structs {
3899+ decl_module := g.tc.struct_modules[resolved_name] or { '' }
3900+ if decl_module in ['', 'main'] {
3901+ return 'main__${g.cname(resolved_name)}'
3902+ }
3903+ }
3904+ if info := g.find_struct_decl(resolved_name) {
3905+ if !resolved_name.contains('.') && info.module in ['', 'main'] {
3906+ return 'main__${g.cname(resolved_name)}'
3907+ }
3908+ }
3909+ return ct
3910+ }
3911+
38453912fn (g &FlatGen) struct_type_alias_target(type_name string) ?string {
38463913 qname := g.tc.qualify_name(type_name)
38473914 if target := g.tc.type_aliases[qname] {
@@ -4386,7 +4453,8 @@ fn (mut g FlatGen) gen_heap_assoc_expr(node flat.Node) {
43864453 }
43874454 }
43884455 if align := g.heap_assoc_struct_alignment(node, target_type, target_name, ct) {
4389- align_arg := struct_decl_alignment_memdup_arg (align, ct)
4456+ align_ct := g.struct_decl_alignment_c_type(target_name, ct)
4457+ align_arg := struct_decl_alignment_memdup_arg(align, align_ct)
43904458 g.write(' (${ct}*)v3_aligned_memdup(&${tmp}, sizeof(${ct}), ${align_arg});})')
43914459 } else {
43924460 g.write(' (${ct}*)memdup(&${tmp}, sizeof(${ct}));})')
0 commit comments