diff --git a/vlib/v/gen/c/if.v b/vlib/v/gen/c/if.v index dba1885169..683e9f6de6 100644 --- a/vlib/v/gen/c/if.v +++ b/vlib/v/gen/c/if.v @@ -31,42 +31,91 @@ fn (mut g Gen) need_tmp_var_in_expr(expr ast.Expr) bool { if is_noreturn_callexpr(expr) { return true } - if expr is ast.MatchExpr { - return true - } - if expr is ast.CallExpr { - if expr.is_method { - left_sym := g.table.sym(expr.receiver_type) - if left_sym.kind in [.array, .array_fixed, .map] { + match expr { + ast.IfExpr { + if g.need_tmp_var_in_if(expr) { return true } } - if expr.or_block.kind != .absent { + ast.MatchExpr { return true } - } - if expr is ast.CastExpr { - return g.need_tmp_var_in_expr(expr.expr) - } - if expr is ast.ParExpr { - return g.need_tmp_var_in_expr(expr.expr) - } - if expr is ast.ConcatExpr { - for val in expr.vals { - if val is ast.CallExpr { - if val.return_type.has_flag(.optional) { + ast.CallExpr { + if expr.is_method { + left_sym := g.table.sym(expr.receiver_type) + if left_sym.kind in [.array, .array_fixed, .map] { + return true + } + } + if expr.or_block.kind != .absent { + return true + } + } + ast.CastExpr { + return g.need_tmp_var_in_expr(expr.expr) + } + ast.ParExpr { + return g.need_tmp_var_in_expr(expr.expr) + } + ast.ConcatExpr { + for val in expr.vals { + if val is ast.CallExpr { + if val.return_type.has_flag(.optional) { + return true + } + } + } + } + ast.IndexExpr { + if expr.or_expr.kind != .absent { + return true + } + if g.need_tmp_var_in_expr(expr.index) { + return true + } + } + ast.ArrayInit { + if g.need_tmp_var_in_expr(expr.len_expr) { + return true + } + if g.need_tmp_var_in_expr(expr.cap_expr) { + return true + } + if g.need_tmp_var_in_expr(expr.default_expr) { + return true + } + for elem_expr in expr.exprs { + if g.need_tmp_var_in_expr(elem_expr) { return true } } } - } - if expr is ast.IndexExpr { - if expr.or_expr.kind != .absent { - return true + ast.MapInit { + for key in expr.keys { + if g.need_tmp_var_in_expr(key) { + return true + } + } + for val in expr.vals { + if g.need_tmp_var_in_expr(val) { + return true + } + } } - if g.need_tmp_var_in_expr(expr.index) { - return true + ast.StructInit { + if g.need_tmp_var_in_expr(expr.update_expr) { + return true + } + for field in expr.fields { + if g.need_tmp_var_in_expr(field.expr) { + return true + } + } } + ast.SelectorExpr { + return g.need_tmp_var_in_expr(expr.expr) + } + else {} } return false } diff --git a/vlib/v/gen/c/match.v b/vlib/v/gen/c/match.v index f93b9aa19a..e611b95098 100644 --- a/vlib/v/gen/c/match.v +++ b/vlib/v/gen/c/match.v @@ -28,9 +28,7 @@ fn (mut g Gen) need_tmp_var_in_match(node ast.MatchExpr) bool { if branch.stmts.len == 1 { if branch.stmts[0] is ast.ExprStmt { stmt := branch.stmts[0] as ast.ExprStmt - if stmt.expr in [ast.CallExpr, ast.IfExpr, ast.MatchExpr, ast.StructInit] - || (stmt.expr is ast.IndexExpr - && (stmt.expr as ast.IndexExpr).or_expr.kind != .absent) { + if g.need_tmp_var_in_expr(stmt.expr) { return true } } diff --git a/vlib/v/tests/if_expr_with_index_expr_test.v b/vlib/v/tests/if_expr_with_index_expr_test.v index 2d1f452635..a5fb562937 100644 --- a/vlib/v/tests/if_expr_with_index_expr_test.v +++ b/vlib/v/tests/if_expr_with_index_expr_test.v @@ -7,3 +7,15 @@ fn test_if_expr_with_index_expr() { println(b) assert true } + +struct Foo { + name string +} + +fn test_if_expr_with_selector_expr() { + a := [Foo{'abc1'}, Foo{'abc2'}, Foo{'abc3'}] + + b := if true { a[rand.intn(a.len) or { 0 }].name } else { 'not found' } + println(b) + assert true +}