diff --git a/vlib/v/ast/types.v b/vlib/v/ast/types.v index 1e05d7272b..944738318d 100644 --- a/vlib/v/ast/types.v +++ b/vlib/v/ast/types.v @@ -471,7 +471,7 @@ pub const ( number_type_idxs = [i8_type_idx, i16_type_idx, int_type_idx, i64_type_idx, u8_type_idx, char_type_idx, u16_type_idx, u32_type_idx, u64_type_idx, isize_type_idx, usize_type_idx, f32_type_idx, f64_type_idx, int_literal_type_idx, float_literal_type_idx, rune_type_idx] - pointer_type_idxs = [voidptr_type_idx, byteptr_type_idx, charptr_type_idx] + pointer_type_idxs = [voidptr_type_idx, byteptr_type_idx, charptr_type_idx, nil_type_idx] string_type_idxs = [string_type_idx] ) diff --git a/vlib/v/gen/c/struct.v b/vlib/v/gen/c/struct.v index 171835c371..40c9be0be0 100644 --- a/vlib/v/gen/c/struct.v +++ b/vlib/v/gen/c/struct.v @@ -70,26 +70,10 @@ fn (mut g Gen) struct_init(node ast.StructInit) { } inited_fields[field.name] = i if sym.kind != .struct_ { - field_name := if sym.language == .v { c_name(field.name) } else { field.name } - g.write('.$field_name = ') if field.typ == 0 { g.checker_bug('struct init, field.typ is 0', field.pos) } - field_type_sym := g.table.sym(field.typ) - mut cloned := false - if g.is_autofree && !field.typ.is_ptr() && field_type_sym.kind in [.array, .string] { - g.write('/*clone1*/') - if g.gen_clone_assignment(field.expr, field.typ, false) { - cloned = true - } - } - if !cloned { - if (field.expected_type.is_ptr() && !field.expected_type.has_flag(.shared_f)) - && !(field.typ.is_ptr() || field.typ.is_pointer()) && !field.typ.is_number() { - g.write('/* autoref */&') - } - g.expr_with_cast(field.expr, field.typ, field.expected_type) - } + g.struct_init_field(field, sym.language) if i != node.fields.len - 1 { if is_multiline { g.writeln(',') @@ -167,44 +151,10 @@ fn (mut g Gen) struct_init(node ast.StructInit) { } if field.name in inited_fields { sfield := node.fields[inited_fields[field.name]] - field_name := if sym.language == .v { c_name(field.name) } else { field.name } if sfield.typ == 0 { continue } - g.write('.$field_name = ') - field_type_sym := g.table.sym(sfield.typ) - mut cloned := false - if g.is_autofree && !sfield.typ.is_ptr() && field_type_sym.kind in [.array, .string] { - g.write('/*clone1*/') - if g.gen_clone_assignment(sfield.expr, sfield.typ, false) { - cloned = true - } - } - if !cloned { - inside_cast_in_heap := g.inside_cast_in_heap - g.inside_cast_in_heap = 0 // prevent use of pointers in child structs - - if field_type_sym.kind == .array_fixed && sfield.expr is ast.Ident { - fixed_array_info := field_type_sym.info as ast.ArrayFixed - g.write('{') - for i in 0 .. fixed_array_info.size { - g.expr(sfield.expr) - g.write('[$i]') - if i != fixed_array_info.size - 1 { - g.write(', ') - } - } - g.write('}') - } else { - if (sfield.expected_type.is_ptr() - && !sfield.expected_type.has_flag(.shared_f)) && !(sfield.typ.is_ptr() - || sfield.typ.is_pointer()) && !sfield.typ.is_number() { - g.write('/* autoref */&') - } - g.expr_with_cast(sfield.expr, sfield.typ, sfield.expected_type) - } - g.inside_cast_in_heap = inside_cast_in_heap // restore value for further struct inits - } + g.struct_init_field(sfield, sym.language) if is_multiline { g.writeln(',') } else { @@ -434,3 +384,41 @@ fn (mut g Gen) struct_decl(s ast.Struct, name string, is_anon bool) { g.type_definitions.writeln('\n') g.type_definitions.writeln(post_pragma) } + +fn (mut g Gen) struct_init_field(sfield ast.StructInitField, language ast.Language) { + field_name := if language == .v { c_name(sfield.name) } else { sfield.name } + g.write('.$field_name = ') + field_type_sym := g.table.sym(sfield.typ) + mut cloned := false + if g.is_autofree && !sfield.typ.is_ptr() && field_type_sym.kind in [.array, .string] { + g.write('/*clone1*/') + if g.gen_clone_assignment(sfield.expr, sfield.typ, false) { + cloned = true + } + } + if !cloned { + inside_cast_in_heap := g.inside_cast_in_heap + g.inside_cast_in_heap = 0 // prevent use of pointers in child structs + + if field_type_sym.kind == .array_fixed && sfield.expr is ast.Ident { + fixed_array_info := field_type_sym.info as ast.ArrayFixed + g.write('{') + for i in 0 .. fixed_array_info.size { + g.expr(sfield.expr) + g.write('[$i]') + if i != fixed_array_info.size - 1 { + g.write(', ') + } + } + g.write('}') + } else { + if sfield.typ != ast.nil_type + && (sfield.expected_type.is_ptr() && !sfield.expected_type.has_flag(.shared_f)) + && !(sfield.typ.is_ptr() || sfield.typ.is_pointer()) && !sfield.typ.is_number() { + g.write('/* autoref */&') + } + g.expr_with_cast(sfield.expr, sfield.typ, sfield.expected_type) + } + g.inside_cast_in_heap = inside_cast_in_heap // restore value for further struct inits + } +}