From 4878077c62536b7837ba5cad496e23ea2fbee9b0 Mon Sep 17 00:00:00 2001 From: yuyi Date: Fri, 19 Feb 2021 00:19:42 +0800 Subject: [PATCH] gen/c: fix gen_str_for_struct with custom ref str (fix #7179) (#8820) --- vlib/v/gen/c/auto_str_methods.v | 7 ++++--- .../string_interpolation_custom_str_test.v | 20 +++++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 vlib/v/tests/string_interpolation_custom_str_test.v diff --git a/vlib/v/gen/c/auto_str_methods.v b/vlib/v/gen/c/auto_str_methods.v index a867e74326..86bf78fea4 100644 --- a/vlib/v/gen/c/auto_str_methods.v +++ b/vlib/v/gen/c/auto_str_methods.v @@ -530,12 +530,12 @@ fn (mut g Gen) gen_str_for_struct(info table.Struct, styp string, str_fn_name st } fn struct_auto_str_func(sym table.TypeSymbol, field_type table.Type, fn_name string, field_name string) string { - has_custom_str := sym.has_method('str') + has_custom_str, expects_ptr, _ := sym.str_method_info() if sym.kind in [.enum_, .interface_] { return '${fn_name}(it.${c_name(field_name)})' } else if sym.kind == .struct_ { mut obj := 'it.${c_name(field_name)}' - if field_type.is_ptr() { + if field_type.is_ptr() && !expects_ptr { obj = '*$obj' } if has_custom_str { @@ -553,7 +553,8 @@ fn struct_auto_str_func(sym table.TypeSymbol, field_type table.Type, fn_name str mut method_str := 'it.${c_name(field_name)}' if sym.kind == .bool { method_str += ' ? _SLIT("true") : _SLIT("false")' - } else if (field_type.is_int() || field_type.is_float()) && field_type.is_ptr() { + } else if (field_type.is_int() || field_type.is_float()) && field_type.is_ptr() + && !expects_ptr { // ptr int can be "nil", so this needs to be castet to a string fmt := if sym.kind in [.f32, .f64] { '%g\\000' diff --git a/vlib/v/tests/string_interpolation_custom_str_test.v b/vlib/v/tests/string_interpolation_custom_str_test.v new file mode 100644 index 0000000000..0fad50e1aa --- /dev/null +++ b/vlib/v/tests/string_interpolation_custom_str_test.v @@ -0,0 +1,20 @@ +struct Foo { + bar int +} + +fn (f &Foo) str() string { + return '${f.bar}' +} + +struct Bar { + foo &Foo +} + +fn test_interpolation_with_custom_ref_str() { + foo := Foo{} + bar := Bar { &foo } + println(bar) + assert '$bar'.contains('Bar{') + assert '$bar'.contains('foo: &0') + assert '$bar'.contains('}') +}