cgen: fix auto .str() generation for []&T, and `fn (t &T) str() string{}`
parent
8866773f97
commit
fec7f0f0b9
|
@ -833,6 +833,19 @@ pub fn (mut c Checker) call_fn(call_expr mut ast.CallExpr) table.Type {
|
||||||
if fn_name == 'println' || fn_name == 'print' {
|
if fn_name == 'println' || fn_name == 'print' {
|
||||||
c.expected_type = table.string_type
|
c.expected_type = table.string_type
|
||||||
call_expr.args[0].typ = c.expr(call_expr.args[0].expr)
|
call_expr.args[0].typ = c.expr(call_expr.args[0].expr)
|
||||||
|
/*
|
||||||
|
// TODO: optimize `struct T{} fn (t &T) str() string {return 'abc'} mut a := []&T{} a << &T{} println(a[0])`
|
||||||
|
// It currently generates:
|
||||||
|
// `println(T_str_no_ptr(*(*(T**)array_get(a, 0))));`
|
||||||
|
// ... which works, but could be just:
|
||||||
|
// `println(T_str(*(T**)array_get(a, 0)));`
|
||||||
|
prexpr := call_expr.args[0].expr
|
||||||
|
prtyp := call_expr.args[0].typ
|
||||||
|
prtyp_sym := c.table.get_type_symbol(prtyp)
|
||||||
|
prtyp_is_ptr := prtyp.is_ptr()
|
||||||
|
prhas_str, prexpects_ptr, prnr_args := prtyp_sym.str_method_info()
|
||||||
|
eprintln('>>> println hack typ: ${prtyp} | sym.name: ${prtyp_sym.name} | is_ptr: $prtyp_is_ptr | has_str: $prhas_str | expects_ptr: $prexpects_ptr | nr_args: $prnr_args | expr: ${prexpr.str()} ')
|
||||||
|
*/
|
||||||
return f.return_type
|
return f.return_type
|
||||||
}
|
}
|
||||||
// TODO: typ optimize.. this node can get processed more than once
|
// TODO: typ optimize.. this node can get processed more than once
|
||||||
|
|
|
@ -2578,6 +2578,7 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) {
|
||||||
}
|
}
|
||||||
} else if specs[i] == `s` {
|
} else if specs[i] == `s` {
|
||||||
sym := g.table.get_type_symbol(node.expr_types[i])
|
sym := g.table.get_type_symbol(node.expr_types[i])
|
||||||
|
sym_has_str_method, str_method_expects_ptr, _ := sym.str_method_info()
|
||||||
if node.expr_types[i].flag_is(.variadic) {
|
if node.expr_types[i].flag_is(.variadic) {
|
||||||
str_fn_name := g.gen_str_for_type(node.expr_types[i])
|
str_fn_name := g.gen_str_for_type(node.expr_types[i])
|
||||||
g.write('${str_fn_name}(')
|
g.write('${str_fn_name}(')
|
||||||
|
@ -2599,17 +2600,24 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) {
|
||||||
g.enum_expr(expr)
|
g.enum_expr(expr)
|
||||||
g.write('")')
|
g.write('")')
|
||||||
}
|
}
|
||||||
} else if sym.has_method('str') || sym.kind in [.array, .array_fixed, .map, .struct_] {
|
} else if sym_has_str_method || sym.kind in [.array, .array_fixed, .map, .struct_] {
|
||||||
is_p := node.expr_types[i].is_ptr()
|
is_p := node.expr_types[i].is_ptr()
|
||||||
val_type := if is_p { node.expr_types[i].deref() } else { node.expr_types[i] }
|
val_type := if is_p { node.expr_types[i].deref() } else { node.expr_types[i] }
|
||||||
str_fn_name := g.gen_str_for_type(val_type)
|
str_fn_name := g.gen_str_for_type(val_type)
|
||||||
if is_p {
|
if is_p && str_method_expects_ptr {
|
||||||
g.write('string_add(_SLIT("&"), ${str_fn_name}(*(')
|
g.write('string_add(_SLIT("&"), ${str_fn_name}( (')
|
||||||
} else {
|
}
|
||||||
g.write('${str_fn_name}(')
|
if is_p && !str_method_expects_ptr {
|
||||||
|
g.write('string_add(_SLIT("&"), ${str_fn_name}( *(')
|
||||||
|
}
|
||||||
|
if !is_p && !str_method_expects_ptr {
|
||||||
|
g.write('${str_fn_name}( ')
|
||||||
|
}
|
||||||
|
if !is_p && str_method_expects_ptr {
|
||||||
|
g.write('${str_fn_name}( &')
|
||||||
}
|
}
|
||||||
g.expr(expr)
|
g.expr(expr)
|
||||||
if sym.kind == .struct_ && !sym.has_method('str') {
|
if sym.kind == .struct_ && !sym_has_str_method {
|
||||||
if is_p {
|
if is_p {
|
||||||
g.write('),0))')
|
g.write('),0))')
|
||||||
} else {
|
} else {
|
||||||
|
@ -3179,7 +3187,7 @@ fn (mut g Gen) as_cast(node ast.AsCast) {
|
||||||
expr_type_sym := g.table.get_type_symbol(node.expr_type)
|
expr_type_sym := g.table.get_type_symbol(node.expr_type)
|
||||||
if expr_type_sym.kind == .sum_type {
|
if expr_type_sym.kind == .sum_type {
|
||||||
/*
|
/*
|
||||||
g.write('/* as */ *($styp*)')
|
g.write('*($styp*)')
|
||||||
g.expr(node.expr)
|
g.expr(node.expr)
|
||||||
g.write('.obj')
|
g.write('.obj')
|
||||||
*/
|
*/
|
||||||
|
@ -3220,9 +3228,33 @@ fn (mut g Gen) gen_str_for_type(typ table.Type) string {
|
||||||
fn (mut g Gen) gen_str_for_type_with_styp(typ table.Type, styp string) string {
|
fn (mut g Gen) gen_str_for_type_with_styp(typ table.Type, styp string) string {
|
||||||
sym := g.table.get_type_symbol(typ)
|
sym := g.table.get_type_symbol(typ)
|
||||||
str_fn_name := styp_to_str_fn_name(styp)
|
str_fn_name := styp_to_str_fn_name(styp)
|
||||||
already_generated_key := '${styp}:${str_fn_name}'
|
sym_has_str_method, str_method_expects_ptr, str_nr_args := sym.str_method_info()
|
||||||
// generate for type
|
// generate for type
|
||||||
if !sym.has_method('str') && already_generated_key !in g.str_types {
|
if sym_has_str_method && str_method_expects_ptr && str_nr_args == 1 {
|
||||||
|
// TODO: optimize out this.
|
||||||
|
// It is needed, so that println() can be called with &T and T has `fn (t &T).str() string`
|
||||||
|
/*
|
||||||
|
eprintln('>> gsftws: typ: $typ | typ_is_ptr $typ_is_ptr | styp: $styp ' +
|
||||||
|
'| $str_fn_name | sym.name: $sym.name has_str: $sym_has_str_method ' +
|
||||||
|
'| expects_ptr: $str_method_expects_ptr')
|
||||||
|
*/
|
||||||
|
str_fn_name_no_ptr := '${str_fn_name}_no_ptr'
|
||||||
|
already_generated_key_no_ptr := '${styp}:${str_fn_name_no_ptr}'
|
||||||
|
if already_generated_key_no_ptr !in g.str_types {
|
||||||
|
g.str_types << already_generated_key_no_ptr
|
||||||
|
g.definitions.writeln('string ${str_fn_name_no_ptr}(${styp} it); // auto no_ptr version')
|
||||||
|
g.auto_str_funcs.writeln('string ${str_fn_name_no_ptr}(${styp} it){ return ${str_fn_name}(&it); }')
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
typ_is_ptr := typ.is_ptr()
|
||||||
|
ret_type := if typ_is_ptr { str_fn_name } else { str_fn_name_no_ptr }
|
||||||
|
eprintln(' ret_type: $ret_type')
|
||||||
|
return ret_type
|
||||||
|
*/
|
||||||
|
return str_fn_name_no_ptr
|
||||||
|
}
|
||||||
|
already_generated_key := '${styp}:${str_fn_name}'
|
||||||
|
if !sym_has_str_method && already_generated_key !in g.str_types {
|
||||||
g.str_types << already_generated_key
|
g.str_types << already_generated_key
|
||||||
match sym.info {
|
match sym.info {
|
||||||
table.Alias { g.gen_str_default(sym, styp, str_fn_name) }
|
table.Alias { g.gen_str_default(sym, styp, str_fn_name) }
|
||||||
|
@ -3362,7 +3394,16 @@ fn (mut g Gen) gen_str_for_struct(info table.Struct, styp, str_fn_name string) {
|
||||||
fn (mut g Gen) gen_str_for_array(info table.Array, styp, str_fn_name string) {
|
fn (mut g Gen) gen_str_for_array(info table.Array, styp, str_fn_name string) {
|
||||||
sym := g.table.get_type_symbol(info.elem_type)
|
sym := g.table.get_type_symbol(info.elem_type)
|
||||||
field_styp := g.typ(info.elem_type)
|
field_styp := g.typ(info.elem_type)
|
||||||
if !sym.has_method('str') {
|
is_elem_ptr := info.elem_type.is_ptr()
|
||||||
|
sym_has_str_method, str_method_expects_ptr, _ := sym.str_method_info()
|
||||||
|
mut elem_str_fn_name := ''
|
||||||
|
if sym_has_str_method {
|
||||||
|
elem_str_fn_name = if is_elem_ptr { field_styp.replace('*', '') +'_str' } else { field_styp + '_str' }
|
||||||
|
} else {
|
||||||
|
elem_str_fn_name = styp_to_str_fn_name( field_styp )
|
||||||
|
}
|
||||||
|
if !sym_has_str_method {
|
||||||
|
// eprintln('> sym.name: does not have method `str`')
|
||||||
g.gen_str_for_type_with_styp(info.elem_type, field_styp)
|
g.gen_str_for_type_with_styp(info.elem_type, field_styp)
|
||||||
}
|
}
|
||||||
g.definitions.writeln('string ${str_fn_name}($styp a); // auto')
|
g.definitions.writeln('string ${str_fn_name}($styp a); // auto')
|
||||||
|
@ -3371,12 +3412,25 @@ fn (mut g Gen) gen_str_for_array(info table.Array, styp, str_fn_name string) {
|
||||||
g.auto_str_funcs.writeln('\tstrings__Builder_write(&sb, tos3("["));')
|
g.auto_str_funcs.writeln('\tstrings__Builder_write(&sb, tos3("["));')
|
||||||
g.auto_str_funcs.writeln('\tfor (int i = 0; i < a.len; i++) {')
|
g.auto_str_funcs.writeln('\tfor (int i = 0; i < a.len; i++) {')
|
||||||
g.auto_str_funcs.writeln('\t\t${field_styp} it = (*(${field_styp}*)array_get(a, i));')
|
g.auto_str_funcs.writeln('\t\t${field_styp} it = (*(${field_styp}*)array_get(a, i));')
|
||||||
if sym.kind == .struct_ && !sym.has_method('str') {
|
if sym.kind == .struct_ && !sym_has_str_method {
|
||||||
g.auto_str_funcs.writeln('\t\tstring x = ${field_styp}_str(it,0);')
|
if is_elem_ptr {
|
||||||
|
g.auto_str_funcs.writeln('\t\tstring x = ${elem_str_fn_name}(*it,0);')
|
||||||
|
}else{
|
||||||
|
g.auto_str_funcs.writeln('\t\tstring x = ${elem_str_fn_name}(it,0);')
|
||||||
|
}
|
||||||
} else if sym.kind in [.f32, .f64] {
|
} else if sym.kind in [.f32, .f64] {
|
||||||
g.auto_str_funcs.writeln('\t\tstring x = _STR("%g", 1, it);')
|
g.auto_str_funcs.writeln('\t\tstring x = _STR("%g", 1, it);')
|
||||||
} else {
|
} else {
|
||||||
g.auto_str_funcs.writeln('\t\tstring x = ${field_styp}_str(it);')
|
// There is a custom .str() method, so use it.
|
||||||
|
// NB: we need to take account of whether the user has defined
|
||||||
|
// `fn (x T) str() {` or `fn (x &T) str() {`, and convert accordingly
|
||||||
|
if str_method_expects_ptr && is_elem_ptr || !str_method_expects_ptr && !is_elem_ptr {
|
||||||
|
g.auto_str_funcs.writeln('\t\tstring x = ${elem_str_fn_name}(it);')
|
||||||
|
} else if str_method_expects_ptr && !is_elem_ptr {
|
||||||
|
g.auto_str_funcs.writeln('\t\tstring x = ${elem_str_fn_name}(&it);')
|
||||||
|
} else if !str_method_expects_ptr && is_elem_ptr {
|
||||||
|
g.auto_str_funcs.writeln('\t\tstring x = ${elem_str_fn_name}(*it);')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, x);')
|
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, x);')
|
||||||
if g.pref.autofree && info.elem_type != table.bool_type {
|
if g.pref.autofree && info.elem_type != table.bool_type {
|
||||||
|
@ -3398,6 +3452,14 @@ fn (mut g Gen) gen_str_for_array(info table.Array, styp, str_fn_name string) {
|
||||||
fn (mut g Gen) gen_str_for_array_fixed(info table.ArrayFixed, styp, str_fn_name string) {
|
fn (mut g Gen) gen_str_for_array_fixed(info table.ArrayFixed, styp, str_fn_name string) {
|
||||||
sym := g.table.get_type_symbol(info.elem_type)
|
sym := g.table.get_type_symbol(info.elem_type)
|
||||||
field_styp := g.typ(info.elem_type)
|
field_styp := g.typ(info.elem_type)
|
||||||
|
is_elem_ptr := info.elem_type.is_ptr()
|
||||||
|
sym_has_str_method, str_method_expects_ptr, _ := sym.str_method_info()
|
||||||
|
mut elem_str_fn_name := ''
|
||||||
|
if sym_has_str_method {
|
||||||
|
elem_str_fn_name = if is_elem_ptr { field_styp.replace('*', '') +'_str' } else { field_styp + '_str' }
|
||||||
|
} else {
|
||||||
|
elem_str_fn_name = styp_to_str_fn_name( field_styp )
|
||||||
|
}
|
||||||
if !sym.has_method('str') {
|
if !sym.has_method('str') {
|
||||||
g.gen_str_for_type_with_styp(info.elem_type, field_styp)
|
g.gen_str_for_type_with_styp(info.elem_type, field_styp)
|
||||||
}
|
}
|
||||||
|
@ -3406,14 +3468,20 @@ fn (mut g Gen) gen_str_for_array_fixed(info table.ArrayFixed, styp, str_fn_name
|
||||||
g.auto_str_funcs.writeln('\tstrings__Builder sb = strings__new_builder($info.size * 10);')
|
g.auto_str_funcs.writeln('\tstrings__Builder sb = strings__new_builder($info.size * 10);')
|
||||||
g.auto_str_funcs.writeln('\tstrings__Builder_write(&sb, tos3("["));')
|
g.auto_str_funcs.writeln('\tstrings__Builder_write(&sb, tos3("["));')
|
||||||
g.auto_str_funcs.writeln('\tfor (int i = 0; i < $info.size; i++) {')
|
g.auto_str_funcs.writeln('\tfor (int i = 0; i < $info.size; i++) {')
|
||||||
if sym.kind == .struct_ && !sym.has_method('str') {
|
if sym.kind == .struct_ && !sym_has_str_method {
|
||||||
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, ${field_styp}_str(a[i],0));')
|
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, ${elem_str_fn_name}(a[i],0));')
|
||||||
} else if sym.kind in [.f32, .f64] {
|
} else if sym.kind in [.f32, .f64] {
|
||||||
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, _STR("%g", 1, a[i]));')
|
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, _STR("%g", 1, a[i]));')
|
||||||
} else if sym.kind == .string {
|
} else if sym.kind == .string {
|
||||||
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, _STR("\'%.*s\\000\'", 2, a[i]));')
|
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, _STR("\'%.*s\\000\'", 2, a[i]));')
|
||||||
} else {
|
} else {
|
||||||
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, ${field_styp}_str(a[i]));')
|
if str_method_expects_ptr && is_elem_ptr || !str_method_expects_ptr && !is_elem_ptr {
|
||||||
|
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, ${elem_str_fn_name}(a[i]));')
|
||||||
|
} else if str_method_expects_ptr && !is_elem_ptr {
|
||||||
|
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, ${elem_str_fn_name}(&a[i]));')
|
||||||
|
} else if !str_method_expects_ptr && is_elem_ptr {
|
||||||
|
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, ${elem_str_fn_name}(*a[i]));')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
g.auto_str_funcs.writeln('\t\tif (i < ${info.size-1}) {')
|
g.auto_str_funcs.writeln('\t\tif (i < ${info.size-1}) {')
|
||||||
g.auto_str_funcs.writeln('\t\t\tstrings__Builder_write(&sb, tos3(", "));')
|
g.auto_str_funcs.writeln('\t\t\tstrings__Builder_write(&sb, tos3(", "));')
|
||||||
|
@ -3432,6 +3500,7 @@ fn (mut g Gen) gen_str_for_map(info table.Map, styp, str_fn_name string) {
|
||||||
}
|
}
|
||||||
val_sym := g.table.get_type_symbol(info.value_type)
|
val_sym := g.table.get_type_symbol(info.value_type)
|
||||||
val_styp := g.typ(info.value_type)
|
val_styp := g.typ(info.value_type)
|
||||||
|
elem_str_fn_name := val_styp.replace('*', '') + '_str'
|
||||||
if !val_sym.has_method('str') {
|
if !val_sym.has_method('str') {
|
||||||
g.gen_str_for_type_with_styp(info.value_type, val_styp)
|
g.gen_str_for_type_with_styp(info.value_type, val_styp)
|
||||||
}
|
}
|
||||||
|
@ -3451,11 +3520,11 @@ fn (mut g Gen) gen_str_for_map(info table.Map, styp, str_fn_name string) {
|
||||||
if val_sym.kind == .string {
|
if val_sym.kind == .string {
|
||||||
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, _STR("\'%.*s\\000\'", 2, it));')
|
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, _STR("\'%.*s\\000\'", 2, it));')
|
||||||
} else if val_sym.kind == .struct_ && !val_sym.has_method('str') {
|
} else if val_sym.kind == .struct_ && !val_sym.has_method('str') {
|
||||||
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, ${val_styp}_str(it,0));')
|
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, ${elem_str_fn_name}(it,0));')
|
||||||
} else if val_sym.kind in [.f32, .f64] {
|
} else if val_sym.kind in [.f32, .f64] {
|
||||||
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, _STR("%g", 1, it));')
|
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, _STR("%g", 1, it));')
|
||||||
} else {
|
} else {
|
||||||
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, ${val_styp}_str(it));')
|
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, ${elem_str_fn_name}(it));')
|
||||||
}
|
}
|
||||||
g.auto_str_funcs.writeln('\t\tif (i != m.key_values.size-1) {')
|
g.auto_str_funcs.writeln('\t\tif (i != m.key_values.size-1) {')
|
||||||
g.auto_str_funcs.writeln('\t\t\tstrings__Builder_write(&sb, tos3(", "));')
|
g.auto_str_funcs.writeln('\t\t\tstrings__Builder_write(&sb, tos3(", "));')
|
||||||
|
|
|
@ -677,6 +677,20 @@ pub fn (t &TypeSymbol) find_method(name string) ?Fn {
|
||||||
return none
|
return none
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn (t &TypeSymbol) str_method_info() (bool, bool, int) {
|
||||||
|
mut has_str_method := false
|
||||||
|
mut expects_ptr := false
|
||||||
|
mut nr_args := 0
|
||||||
|
if sym_str_method := t.find_method('str') {
|
||||||
|
has_str_method = true
|
||||||
|
nr_args = sym_str_method.args.len
|
||||||
|
if nr_args > 0 {
|
||||||
|
expects_ptr = sym_str_method.args[0].typ.is_ptr()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return has_str_method, expects_ptr, nr_args
|
||||||
|
}
|
||||||
|
|
||||||
pub fn (s Struct) find_field(name string) ?Field {
|
pub fn (s Struct) find_field(name string) ?Field {
|
||||||
for field in s.fields {
|
for field in s.fields {
|
||||||
if field.name == name {
|
if field.name == name {
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
module main
|
||||||
|
|
||||||
|
struct Anything {
|
||||||
|
mut:
|
||||||
|
name string = ""
|
||||||
|
keepo int = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (a Anything) str() string {
|
||||||
|
return a.name
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_array_of_ptrs_to_structs_can_be_printed() {
|
||||||
|
mut testing := []&Anything{}
|
||||||
|
testing << &Anything{name: "Hehe"}
|
||||||
|
testing << &Anything{name: "other"}
|
||||||
|
testing << &Anything{name: "test"}
|
||||||
|
for test in testing {
|
||||||
|
println(test)
|
||||||
|
assert true
|
||||||
|
}
|
||||||
|
println('testing: $testing')
|
||||||
|
println( testing )
|
||||||
|
assert true
|
||||||
|
}
|
||||||
|
|
||||||
|
// At the same time, this should also work:
|
||||||
|
// (note the str method defined on (a &T), instead on (a T))
|
||||||
|
|
||||||
|
struct PstrAnything {
|
||||||
|
mut:
|
||||||
|
name string = ""
|
||||||
|
keepo int = 0
|
||||||
|
}
|
||||||
|
fn (a &PstrAnything) str() string {
|
||||||
|
return a.name
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_array_of_ptrs_to_structs_can_be_printed_when_structs_have_str_with_ptr() {
|
||||||
|
mut testing := []&PstrAnything{}
|
||||||
|
testing << &PstrAnything{name: "abc"}
|
||||||
|
testing << &PstrAnything{name: "def"}
|
||||||
|
testing << &PstrAnything{name: "ghi"}
|
||||||
|
for test in testing {
|
||||||
|
println(test)
|
||||||
|
assert true
|
||||||
|
}
|
||||||
|
println('testing: $testing')
|
||||||
|
println( testing )
|
||||||
|
assert true
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
fn test_stack_array_of_structs_can_be_printed_when_structs_have_ordinary_str() {
|
||||||
|
mut t := [3]Anything
|
||||||
|
t[0] = Anything{name: "012"}
|
||||||
|
t[1] = Anything{name: "345"}
|
||||||
|
t[2] = Anything{name: "678"}
|
||||||
|
for test in t {
|
||||||
|
println(test)
|
||||||
|
assert true
|
||||||
|
}
|
||||||
|
println('t: $t')
|
||||||
|
println( t )
|
||||||
|
println( 't[0] := ${t[0]}')
|
||||||
|
assert true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_stack_array_of_structs_can_be_printed_when_structs_have_str_with_ptr() {
|
||||||
|
// this generates a C error
|
||||||
|
mut pt := [3]PstrAnything
|
||||||
|
pt[0] = PstrAnything{name: "P012"}
|
||||||
|
pt[1] = PstrAnything{name: "P345"}
|
||||||
|
pt[2] = PstrAnything{name: "P678"}
|
||||||
|
for test in pt {
|
||||||
|
println(test)
|
||||||
|
assert true
|
||||||
|
}
|
||||||
|
println('pt: $pt')
|
||||||
|
println( pt )
|
||||||
|
print( 'pt[0] := ')
|
||||||
|
print( pt[0] )
|
||||||
|
println('')
|
||||||
|
assert true
|
||||||
|
|
||||||
|
$if debug_buggy_println ? {
|
||||||
|
//TODO: fix string interpolation for structs with `fn (t &T) str() string` too:
|
||||||
|
println( 'pt[0] := ${pt[0]}')
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue