Skip to content

Commit

Permalink
cgen: fix auto str for interface struct member which implements str m…
Browse files Browse the repository at this point in the history
…ethod (#19970)
  • Loading branch information
felipensp committed Nov 23, 2023
1 parent bb77707 commit 9ca4c22
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 1 deletion.
5 changes: 5 additions & 0 deletions vlib/v/gen/c/auto_str_methods.v
Expand Up @@ -1068,6 +1068,11 @@ fn struct_auto_str_func(sym &ast.TypeSymbol, lang ast.Language, _field_type ast.
} else if _field_type.has_flag(.option) || should_use_indent_func(sym.kind) {
obj := '${deref}it.${final_field_name}${sufix}'
if has_custom_str {
if sym.kind == .interface_ && (sym.info as ast.Interface).defines_method('str') {
iface_obj := 'it.${final_field_name}${sufix}'
dot := if field_type.is_ptr() { '->' } else { '.' }
return '${fn_name.trim_string_right('_str')}_name_table[${iface_obj}${dot}_typ]._method_str(${iface_obj}${dot}_object)', true
}
return '${fn_name}(${obj})', true
}
return 'indent_${fn_name}(${obj}, indent_count + 1)', true
Expand Down
10 changes: 9 additions & 1 deletion vlib/v/gen/c/str.v
Expand Up @@ -108,6 +108,7 @@ fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype ast.Type) {
unwrap_option := expr is ast.Ident && expr.or_expr.kind == .propagate_option
exp_typ := if unwrap_option { typ.clear_flag(.option) } else { typ }
is_ptr := exp_typ.is_ptr()
is_dump_expr := expr is ast.DumpExpr
is_var_mut := expr.is_auto_deref_var()
str_fn_name := g.get_str_fn(exp_typ)
if is_ptr && !is_var_mut {
Expand All @@ -130,7 +131,14 @@ fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype ast.Type) {
}
g.write('${str_fn_name}(')
if str_method_expects_ptr && !is_ptr {
g.write('&')
if is_dump_expr {
g.write('ADDR(${g.typ(typ)}, ')
defer {
g.write(')')
}
} else {
g.write('&')
}
} else if is_ptr && typ.has_flag(.option) {
g.write('*(${g.typ(typ)}*)&')
} else if !str_method_expects_ptr && !is_shared && (is_ptr || is_var_mut) {
Expand Down
31 changes: 31 additions & 0 deletions vlib/v/tests/interface_auto_str_test.v
@@ -0,0 +1,31 @@
interface Context {
str() string
}

struct OtherContext {
a string
}

pub fn (o &OtherContext) str() string {
return 'OtherContext'
}

struct WithContext {
pub mut:
ctx Context
}

fn with_function(ctx Context) {
println(ctx)
}

fn test_main() {
mut s := WithContext{
ctx: OtherContext{}
}
assert dump(s) == WithContext{
ctx: OtherContext{}
}

assert dump(OtherContext{}) == OtherContext{}
}

0 comments on commit 9ca4c22

Please sign in to comment.