v.c.gen: fix codegen of auto str methods for structs having &voidptr fields

pull/10597/head
Delyan Angelov 2021-06-28 09:48:58 +03:00
parent b80dcafc24
commit c3b9eaf146
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
5 changed files with 56 additions and 6 deletions

View File

@ -411,8 +411,18 @@ pub const (
error_type = new_type(error_type_idx)
charptr_types = [charptr_type, new_type(char_type_idx).set_nr_muls(1)]
byteptr_types = [byteptr_type, new_type(byte_type_idx).set_nr_muls(1)]
voidptr_types = [voidptr_type, new_type(voidptr_type_idx).set_nr_muls(1)]
cptr_types = merge_types(voidptr_types, byteptr_types, charptr_types)
)
pub fn merge_types(params ...[]Type) []Type {
mut res := []Type{}
for types in params {
res << types
}
return res
}
pub const (
builtin_type_names = ['void', 'voidptr', 'charptr', 'byteptr', 'i8', 'i16', 'int', 'i64', 'u16',
'u32', 'u64', 'int_literal', 'f32', 'f64', 'float_literal', 'string', 'ustring', 'char',

View File

@ -728,12 +728,12 @@ fn (g &Gen) type_to_fmt1(typ ast.Type) StrIntpType {
if typ == ast.char_type_idx {
return .si_c
}
if typ == ast.voidptr_type_idx || typ in ast.byteptr_types {
if typ in ast.voidptr_types || typ in ast.byteptr_types {
return .si_p
}
if typ in ast.charptr_types {
return .si_s
// return '%C\\000' // a C string
return .si_s
}
sym := g.table.get_type_symbol(typ)
if typ.is_ptr() && (typ.is_int_valptr() || typ.is_float_valptr()) {
@ -831,10 +831,10 @@ fn (mut g Gen) gen_str_for_struct(info ast.Struct, styp string, str_fn_name stri
}
mut func := struct_auto_str_func1(sym, field.typ, field_styp_fn_name, field.name)
// manage reference types can be "nil"
if field.typ.is_ptr() && !(field.typ in ast.charptr_types
|| field.typ in ast.byteptr_types || field.typ == ast.voidptr_type_idx) {
if field.typ in ast.cptr_types {
func = '(voidptr) it.$field.name'
} else if field.typ.is_ptr() {
// reference types can be "nil"
fn_builder.write_string('isnil(it.${c_name(field.name)})')
fn_builder.write_string(' ? _SLIT("nil") : ')
// struct, floats and ints have a special case through the _str function

View File

@ -0,0 +1,16 @@
interface IEmpty {}
struct Abc {
x string
}
fn test_empty_interface_string_interpolation() {
a := IEmpty(u64(1))
b := IEmpty(f32(1))
c := IEmpty(Abc{'abc'})
assert '$a' == 'IEmpty(1)'
assert '$b' == 'IEmpty(1.)'
assert '$c'.starts_with('IEmpty(Abc{')
assert '$c'.contains("x: 'abc'")
assert '$c'.ends_with('})')
}

View File

@ -0,0 +1,11 @@
interface IEmpty {
}
struct Abc {
abc int
}
fn test_an_empty_interface_can_be_printed() {
println(IEmpty(Abc{123}))
assert true
}

View File

@ -0,0 +1,13 @@
struct Abc {
mut:
vptr voidptr
vptrptr &voidptr = 0
bptr &byte = 0
cptr &char = c'abcdef'
}
fn test_structs_can_be_printed() {
a := Abc{}
println(a)
assert true
}