1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

ast,cgen: support a := Abc{unsafe{nil}}, for struct Abc { next &Abc }

This commit is contained in:
Delyan Angelov 2022-07-20 10:46:55 +03:00
parent 1ccb4c3ac0
commit 50075d5a79
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
2 changed files with 41 additions and 53 deletions

View File

@ -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]
)

View File

@ -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
}
}