From 3f8821b8d8cbb06724fcf497b237cd2c57588ae7 Mon Sep 17 00:00:00 2001 From: Tim Marston Date: Sat, 4 Mar 2023 09:52:08 +0000 Subject: [PATCH] cgen: unwrap and c-mangle field selectors in or blocks (#17495) --- vlib/v/gen/c/cgen.v | 9 +++++---- vlib/v/tests/struct_selector_or_block_test.v | 13 +++++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 94f3d828e9..dcd7642d35 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -3448,8 +3448,11 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) { g.checker_bug('unexpected SelectorExpr.expr_type = 0', node.pos) } + sym := g.table.sym(g.unwrap_generic(node.expr_type)) + field_name := if sym.language == .v { c_name(node.field_name) } else { node.field_name } + if node.or_block.kind != .absent && !g.is_assign_lhs && g.table.sym(node.typ).kind != .chan { - is_ptr := g.table.sym(g.unwrap_generic(node.expr_type)).kind in [.interface_, .sum_type] + is_ptr := sym.kind in [.interface_, .sum_type] stmt_str := g.go_before_stmt(0).trim_space() styp := g.typ(node.typ) g.empty_line = true @@ -3459,7 +3462,7 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) { g.write('*(') } g.expr(node.expr) - g.write('.${node.field_name}') + g.write('.${field_name}') if is_ptr { g.write(')') } @@ -3472,7 +3475,6 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) { return } - sym := g.table.sym(g.unwrap_generic(node.expr_type)) // if node expr is a root ident and an optional mut is_opt_or_res := node.expr is ast.Ident && (node.expr_type.has_flag(.option) || node.expr_type.has_flag(.result)) @@ -3640,7 +3642,6 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) { if node.expr_type == 0 { verror('cgen: SelectorExpr | expr_type: 0 | it.expr: `${node.expr}` | field: `${node.field_name}` | file: ${g.file.path} | line: ${node.pos.line_nr}') } - field_name := if sym.language == .v { c_name(node.field_name) } else { node.field_name } g.write(field_name) if sum_type_deref_field != '' { g.write('${sum_type_dot}${sum_type_deref_field})') diff --git a/vlib/v/tests/struct_selector_or_block_test.v b/vlib/v/tests/struct_selector_or_block_test.v index e53ce7dddc..2c5f25ec9d 100644 --- a/vlib/v/tests/struct_selector_or_block_test.v +++ b/vlib/v/tests/struct_selector_or_block_test.v @@ -22,3 +22,16 @@ fn test_main() { assert greet(Hello{}) == 'UNKNOWN' assert greet(Hello{'cool', ''}) == 'cool' } + +struct CnameTest { + long ?string + short ?string +} + +fn test_cname_opt_field_selecor() { + x := CnameTest{ + short: 'xyz' + } + assert (x.long or { 'NOPE' }) == 'NOPE' + assert (x.short or { 'NOPE' }) == 'xyz' +}