From e8754af0ce63a4b47680a7732b09b0372c2d4a3e Mon Sep 17 00:00:00 2001 From: kbkpbot Date: Fri, 14 Nov 2025 22:36:04 +0800 Subject: [PATCH] parser: fix last stmt is fn call in or_expr (fix #25732) (#25739) --- vlib/v/parser/parser.v | 38 +++++++++++++++---- vlib/v/tests/last_stmt_fn_call_or_expr_test.v | 22 +++++++++++ 2 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 vlib/v/tests/last_stmt_fn_call_or_expr_test.v diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 54ad6b0aa..61a50cdee 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -530,14 +530,9 @@ fn (mut p Parser) mark_last_call_return_as_used(mut last_stmt ast.Stmt) { ast.CallExpr { // last stmt on block is CallExpr last_stmt.expr.is_return_used = true - } - ast.IfExpr { - // last stmt on block is: if .. { foo() } else { bar() } - for mut branch in last_stmt.expr.branches { - if branch.stmts.len > 0 { - mut last_if_stmt := branch.stmts.last() - p.mark_last_call_return_as_used(mut last_if_stmt) - } + if last_stmt.expr.or_block.stmts.len > 0 { + mut or_block_last_stmt := last_stmt.expr.or_block.stmts.last() + p.mark_last_call_return_as_used(mut or_block_last_stmt) } } ast.ConcatExpr { @@ -548,20 +543,47 @@ fn (mut p Parser) mark_last_call_return_as_used(mut last_stmt ast.Stmt) { } } } + ast.IfExpr { + // last stmt on block is: if .. { foo() } else { bar() } + for mut branch in last_stmt.expr.branches { + if branch.stmts.len > 0 { + mut last_if_stmt := branch.stmts.last() + p.mark_last_call_return_as_used(mut last_if_stmt) + } + } + } ast.InfixExpr { + if last_stmt.expr.or_block.stmts.len > 0 { + mut or_block_last_stmt := last_stmt.expr.or_block.stmts.last() + p.mark_last_call_return_as_used(mut or_block_last_stmt) + } // last stmt has infix expr with CallExpr: foo()? + 'a' mut left_expr := last_stmt.expr.left for { if mut left_expr is ast.InfixExpr { + if left_expr.or_block.stmts.len > 0 { + mut or_block_last_stmt := left_expr.or_block.stmts.last() + p.mark_last_call_return_as_used(mut or_block_last_stmt) + } left_expr = left_expr.left continue } if mut left_expr is ast.CallExpr { left_expr.is_return_used = true + if left_expr.or_block.stmts.len > 0 { + mut or_block_last_stmt := left_expr.or_block.stmts.last() + p.mark_last_call_return_as_used(mut or_block_last_stmt) + } } break } } + ast.ComptimeCall, ast.ComptimeSelector, ast.PrefixExpr, ast.SelectorExpr { + if last_stmt.expr.or_block.stmts.len > 0 { + mut or_block_last_stmt := last_stmt.expr.or_block.stmts.last() + p.mark_last_call_return_as_used(mut or_block_last_stmt) + } + } else {} } } diff --git a/vlib/v/tests/last_stmt_fn_call_or_expr_test.v b/vlib/v/tests/last_stmt_fn_call_or_expr_test.v new file mode 100644 index 000000000..0e0001639 --- /dev/null +++ b/vlib/v/tests/last_stmt_fn_call_or_expr_test.v @@ -0,0 +1,22 @@ +module main + +fn x1() ?int { + return none +} + +fn x2() ?int { + return none +} + +fn x3() ?int { + return none +} + +fn def() int { + return 123 +} + +fn test_last_stmt_fn_call_or_expr() { + y := x1() or { x2() or { x3() or { def() } } } + assert y == 123 +} -- 2.39.5