gen: fix infinite loop when struct's ref field is pointing to self (#8632) (#8641)

pull/8768/head
Peter Badida 2021-02-15 14:43:10 +01:00 committed by GitHub
parent 325aef6d41
commit 6781f732f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 2 deletions

View File

@ -447,7 +447,7 @@ fn (mut g Gen) gen_str_for_struct(info table.Struct, styp string, str_fn_name st
// generates all definitions of substructs
mut fnames2strfunc := map{
'': ''
} // map[string]string // TODO vfmt bug
}
for field in info.fields {
sym := g.table.get_type_symbol(field.typ)
if !sym.has_method('str') {
@ -510,7 +510,13 @@ fn (mut g Gen) gen_str_for_struct(info table.Struct, styp string, str_fn_name st
g.auto_str_funcs.write('*')
}
}
g.auto_str_funcs.write(func)
// handle circular ref type of struct to the struct itself
if styp == field_styp {
g.auto_str_funcs.write('_SLIT("<circular>")')
} else {
g.auto_str_funcs.write(func)
}
if i < info.fields.len - 1 {
g.auto_str_funcs.write(',\n\t\t')
}

View File

@ -50,3 +50,22 @@ fn test_struct_map_field_string_interpolation() {
assert s.contains("dict: {'a': 1, 'b': 2}")
assert s.ends_with('}')
}
struct Circular {
mut:
next &Circular
}
fn test_stack_circular_elem_auto_str() {
mut elem := Circular{0}
elem.next = &elem
s := '$elem'.replace('\n', '|')
assert s == 'Circular{| next: &<circular>|}'
}
fn test_heap_circular_elem_auto_str() {
mut elem := &Circular{0}
elem.next = elem
s := '$elem'.replace('\n', '|')
assert s == '&Circular{| next: &<circular>|}'
}