From f2387ab16e38c88515dc6173c1bdd7bca6cb659e Mon Sep 17 00:00:00 2001 From: Swastik Baranwal Date: Tue, 26 Nov 2024 14:20:08 +0530 Subject: [PATCH] cgen: allow unwrapping of `foo.bar as string`, where `foo.bar` is `?string` (fix #22960) (#22973) --- vlib/v/gen/c/cgen.v | 10 +++++++++- .../option_unwrap_as_cast_test.v | 0 ...option_unwrap_selector_expr_as_cast_test.v | 20 +++++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) rename vlib/v/tests/{ => options}/option_unwrap_as_cast_test.v (100%) create mode 100644 vlib/v/tests/options/option_unwrap_selector_expr_as_cast_test.v diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 043bed1d0..dfd87bf45 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -7797,10 +7797,18 @@ fn (mut g Gen) as_cast(node ast.AsCast) { } else { mut is_optional_ident_var := false if node.expr is ast.Ident { - if node.expr.info is ast.IdentVar && node.expr.info.is_option { + if node.expr.info is ast.IdentVar && node.expr.info.is_option + && !unwrapped_node_typ.has_flag(.option) { g.unwrap_option_type(unwrapped_node_typ, node.expr.name, node.expr.is_auto_heap()) is_optional_ident_var = true } + } else if node.expr is ast.SelectorExpr { + if node.expr.expr is ast.Ident && node.expr.typ.has_flag(.option) + && !unwrapped_node_typ.has_flag(.option) { + g.unwrap_option_type(node.expr.typ, '${node.expr.expr.name}.${node.expr.field_name}', + node.expr.expr.is_auto_heap()) + is_optional_ident_var = true + } } if !is_optional_ident_var { g.expr(node.expr) diff --git a/vlib/v/tests/option_unwrap_as_cast_test.v b/vlib/v/tests/options/option_unwrap_as_cast_test.v similarity index 100% rename from vlib/v/tests/option_unwrap_as_cast_test.v rename to vlib/v/tests/options/option_unwrap_as_cast_test.v diff --git a/vlib/v/tests/options/option_unwrap_selector_expr_as_cast_test.v b/vlib/v/tests/options/option_unwrap_selector_expr_as_cast_test.v new file mode 100644 index 000000000..9fb5064bc --- /dev/null +++ b/vlib/v/tests/options/option_unwrap_selector_expr_as_cast_test.v @@ -0,0 +1,20 @@ +struct Foo { + foo string + bar ?string +} + +fn (f Foo) str() string { + mut ret := f.foo + bar_value := f.bar as string + if bar_value == '' { + return ret + } + return ret + '%' + bar_value +} + +fn test_selector_expr_as_cast() { + ff := Foo{ + foo: 'Fooooo' + } + assert '${ff}' == 'Fooooo' +} -- 2.39.5