From 74997fd824e8f73c839d4368c06fa67dd42c49e3 Mon Sep 17 00:00:00 2001 From: yuyi Date: Fri, 29 Sep 2023 16:59:14 +0800 Subject: [PATCH] ast, cgen: fix as cast with call expr (fix #19453) (#19462) --- cmd/tools/vtest-self.v | 3 +- vlib/v/ast/ast.v | 9 ++++++ vlib/v/gen/c/cgen.v | 2 +- ...s_cast_test.v => sumtype_as_cast_1_test.v} | 0 vlib/v/tests/sumtype_as_cast_2_test.v | 31 +++++++++++++++++++ 5 files changed, 43 insertions(+), 2 deletions(-) rename vlib/v/tests/{sumtype_as_cast_test.v => sumtype_as_cast_1_test.v} (100%) create mode 100644 vlib/v/tests/sumtype_as_cast_2_test.v diff --git a/cmd/tools/vtest-self.v b/cmd/tools/vtest-self.v index 4440cdedda..c65bb2eb1b 100644 --- a/cmd/tools/vtest-self.v +++ b/cmd/tools/vtest-self.v @@ -255,7 +255,8 @@ const ( 'do_not_remove', 'vlib/v/tests/const_fixed_array_containing_references_to_itself_test.v', // error C2099: initializer is not a constant 'vlib/v/tests/const_and_global_with_same_name_test.v', // error C2099: initializer is not a constant - 'vlib/v/tests/sumtype_as_cast_test.v', // error: cannot support compound statement expression ({expr; expr; expr;}) + 'vlib/v/tests/sumtype_as_cast_1_test.v', // error: cannot support compound statement expression ({expr; expr; expr;}) + 'vlib/v/tests/sumtype_as_cast_2_test.v', // error: cannot support compound statement expression ({expr; expr; expr;}) 'vlib/v/tests/project_with_cpp_code/compiling_cpp_files_with_a_cplusplus_compiler_test.v', // TODO ] skip_on_windows = [ diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 946f8b9c8c..832bf82bc6 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -2079,6 +2079,15 @@ pub fn (e &Expr) is_lockable() bool { } } +// returns if an expression has call expr` +pub fn (e &Expr) has_fn_call() bool { + return match e { + CallExpr { true } + SelectorExpr { e.expr.has_fn_call() } + else { false } + } +} + // CTempVar is used in cgen only, to hold nodes for temporary variables pub struct CTempVar { pub: diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 13229b0966..f3645d535e 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -6564,7 +6564,7 @@ fn (mut g Gen) as_cast(node ast.AsCast) { mut expr_type_sym := g.table.sym(g.unwrap_generic(node.expr_type)) if mut expr_type_sym.info is ast.SumType { dot := if node.expr_type.is_ptr() { '->' } else { '.' } - if node.expr is ast.CallExpr && !g.is_cc_msvc { + if node.expr.has_fn_call() && !g.is_cc_msvc { tmp_var := g.new_tmp_var() expr_styp := g.typ(node.expr_type) g.write('({ ${expr_styp} ${tmp_var} = ') diff --git a/vlib/v/tests/sumtype_as_cast_test.v b/vlib/v/tests/sumtype_as_cast_1_test.v similarity index 100% rename from vlib/v/tests/sumtype_as_cast_test.v rename to vlib/v/tests/sumtype_as_cast_1_test.v diff --git a/vlib/v/tests/sumtype_as_cast_2_test.v b/vlib/v/tests/sumtype_as_cast_2_test.v new file mode 100644 index 0000000000..de002006d6 --- /dev/null +++ b/vlib/v/tests/sumtype_as_cast_2_test.v @@ -0,0 +1,31 @@ +type Numbers = int | string + +struct Values { + value Numbers +} + +struct Wrapper { + element []Values +mut: + index int +} + +fn (mut instance Wrapper) get() Values { + instance.index++ + return instance.element[0] +} + +fn test_sumtype_as_cast() { + mut wrapper := Wrapper{ + element: [ + Values{ + value: 1 + }, + Values{ + value: '2' + }, + ] + } + println(wrapper.get().value as int) + assert wrapper.index == 1 +}