parser: fix match-arm !/? propagation when a match is used as a block value (fix #28000) - #28002
Open
medvednikov wants to merge 1 commit into
Open
parser: fix match-arm !/? propagation when a match is used as a block value (fix #28000)#28002medvednikov wants to merge 1 commit into
!/? propagation when a match is used as a block value (fix #28000)#28002medvednikov wants to merge 1 commit into
Conversation
…alue (fix #28000) A `match` whose arms use `!`/`?` error-propagation, when the match is used as the value of an if-expression (or directly as a block value), emitted invalid C: the if-expression result temp was assigned an empty expression (`_t4 = ;`), giving "expected expression". `mark_last_call_return_as_used` recursively descended into `if` branches to flag the last call's return value as used, but had no case for `match`, so calls in match arms kept `is_return_used == false`. cgen then skipped emitting the unwrapped propagated value. Add a `MatchExpr` case symmetric to the existing `IfExpr` one, marking the last statement of each match branch. The v3 backend already handled this case; a regression test is added there too.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Member
Author
|
@codex review |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fix #28000
A
matchwhose arms use!/?error-propagation, when thematchis used as the value of anif-expression (e.g. anif value := opt { … } else { … }option-guard assigned to a variable), emitted invalid C:The if-expression's result temp was never assigned the propagated value.
Root cause
Parser.mark_last_call_return_as_used(vlib/v/parser/parser.v) is called for the last statement of an assignment-RHS block and recursively descends intoifbranches to flag the last call's return value as used (is_return_used = true). It had a case forIfExprbut no case forMatchExpr, so calls in match arms keptis_return_used == false.In cgen (
vlib/v/gen/c/fn.v), the branch that emits the unwrapped value of a propagated call (_t4 = (*(int*)_t5.data);) is guarded bynode.is_return_used || is_gen_or_and_assign_rhs. With neither set, cgen wrote only_t4 =followed by nothing.Fix
Add a
MatchExprcase symmetric to the existingIfExprone, marking the last statement of each match branch.Reproduction (from the issue)
Now compiles and runs correctly.
Tests
vlib/v/tests/match_as_if_expr_value_with_propagation_test.v— covers!and?propagation for a match inside an if-guard, as a direct return value, and assigned to a variable.vlib/v3/tests/match_as_if_expr_value_propagation_codegen_test.v— the v3 backend already handled this case correctly; a regression test is added to keep it covered.Existing
vlib/v/compiler_errors_test.v(1617 checker snapshots) and the related match/option/result/or-block test suites pass unchanged.