Repository navigation
feat(lowering): lower match arm guards - #10432
SahilRajputdotexe wants to merge 3 commits into
Conversation
PR SummaryHigh Risk Overview Lowering builds guarded match control flow via Semantics already carry Extensive parser/lowering/semantic/runtime tests cover fall-through, or-patterns, nested enums, and outer-variable side effects in guards. Reviewed by Cursor Bugbot for commit 96c59f8. Bugbot is set up for automated code reviews on this repo. Configure here. |
f87424a to
586b4dd
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Reviewed by Cursor Bugbot for commit 586b4dd. Configure here.
586b4dd to
96c59f8
Compare
orizi
left a comment
There was a problem hiding this comment.
@orizi made 1 comment.
Reviewable status: 0 of 34 files reviewed, 1 unresolved discussion (waiting on SahilRajputdotexe).
-- commits line 6 at r2:
base PR over actual base PR instead of main.
Summary
Stacked on #10431, only the last commit is new.
Lowers guarded arms in the flow control graph.
create_guarded_arms_nodetries the candidate arms in order: bind the pattern variables, evaluate the guard, take the arm if it holds, otherwise move on. Arms after an unguarded one are unreachable, and if every candidate is guarded the match is non-exhaustive.A guard can replace the lowered variable of a pattern variable, for example
x.len()snapshotsx. A newRefreshVarnode reads the current value after a failed guard, so the next arm binds the up to date variable instead of the consumed one. TheUnsupportedreport from the previous PR is removed.Tests: lowering golden cases, a runtime test in
tests/bug_samples, and a docs section on match guards.Type of change
Why is this change needed?
This completes match guards, which #10430 and #10431 only parse and check.
What was the behavior or documentation before?
Lowering reported
Unsupportedon any guard.What is the behavior or documentation after?
Guards compile and run.
Related issue or discussion (if any)
None.
Additional context
Binding the whole non
Copyscrutinee in a later arm fails with "Variable was previously moved", guard or not.match a { None => 0, o => take_opt(o) }on anOption<Array<felt252>>fails on the base branch, because the enum match consumes it, and so does a refutable tuple pattern likeSome((arr, 0))beforeo. SoSome(x) if x.len() > 1 => 2, o => take_opt(o)fails the same way. I left that alone. Binding the payload in a later arm (Some(y) => take(y)) works and is tested.