Conversation
|
Maybe we could remove tree sitter parser.c from the repo and generate it on the fly? Then we won't have 35k line diffs every time we make a syntax change. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 11593f2b51
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
|
Codex Review: Didn't find any major issues. Hooray! ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
There was a problem hiding this comment.
Pull request overview
Adds support for Rust-2024-style if let / while let condition expressions (including && let-chains) across parsing → HIR lowering/typecheck/CTFE → MIR lowering → codegen, and fixes a Yul loop-lowering/control-flow emission bug.
Changes:
- Extend the parser and tree-sitter grammar to recognize condition-only
letexpressions inif/while, including&&chains and a grammar-level restriction against mixing unparenthesized||withletconditions. - Introduce a dedicated HIR
Condtree (separate fromExpr) and update visitors, type checking, const checks, and CTFE to evaluate/validate condition chains and their bindings correctly. - Update MIR lowering and Yul emission to handle condition decision trees (not just a single branch terminator) and fix loop/control-flow lowering issues; refresh snapshots and formatting fixtures accordingly.
Reviewed changes
Copilot reviewed 74 out of 75 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| crates/uitest/fixtures/ty_check/if_let_chain_scope.snap | New snapshot asserting let-chain bindings don’t leak outside condition/body scopes. |
| crates/uitest/fixtures/ty_check/if_let_chain_scope.fe | New typecheck fixture for if let / while let chains and scoping. |
| crates/uitest/fixtures/ty_check/const_eval/if_let_condition.snap | New snapshot for const-eval + if let condition behavior. |
| crates/uitest/fixtures/ty_check/const_eval/if_let_condition.fe | New CTFE fixture using if let in a const fn context. |
| crates/uitest/fixtures/parser/if_let_or_chain.snap | New parser diagnostic snapshot for ` |
| crates/uitest/fixtures/parser/if_let_or_chain.fe | New parser fixture exercising `if let ... |
| crates/tree-sitter-fe/src/node-types.json | Adds node types for condition-specific binary expressions and let_condition. |
| crates/tree-sitter-fe/src/grammar.json | Adds condition sub-grammars to model let conditions and restrict ` |
| crates/tree-sitter-fe/grammar.js | Implements condition-only let_condition + condition grammar variants and conflicts. |
| crates/parser/test_files/syntax_node/stmts/while.snap | Updates syntax-node snapshot to include while let parsing. |
| crates/parser/test_files/syntax_node/stmts/while.fe | Adds while let examples to parser test input. |
| crates/parser/test_files/syntax_node/exprs/if.snap | Updates syntax-node snapshot to include if let parsing. |
| crates/parser/test_files/syntax_node/exprs/if.fe | Adds if let examples (incl. else if let) to parser test input. |
| crates/parser/src/syntax_kind.rs | Introduces SyntaxKind::LetExpr for condition-only let expressions. |
| crates/parser/src/parser/stmt.rs | Switches while condition parsing to parse_condition_expr. |
| crates/parser/src/parser/expr_atom.rs | Switches if condition parsing to parse_condition_expr. |
| crates/parser/src/parser/expr.rs | Implements condition parsing with let expressions and ` |
| crates/parser/src/ast/stmt.rs | Adds AST tests for while let condition parsing and ` |
| crates/parser/src/ast/expr.rs | Adds AST support/tests for LetExpr and let-chains in if conditions. |
| crates/mir/tests/fixtures/trait_assoc_fn_call.mir.snap | Snapshot update due to control-flow lowering changes. |
| crates/mir/tests/fixtures/if_let_while_let.mir.snap | New MIR snapshot validating if let / while let lowering. |
| crates/mir/tests/fixtures/if_let_while_let.fe | New MIR fixture covering if let and while let. |
| crates/mir/tests/fixtures/for_continue.mir.snap | Snapshot update due to branch lowering changes. |
| crates/mir/tests/fixtures/echo.mir.snap | Snapshot update due to branch lowering changes. |
| crates/mir/tests/fixtures/contract_field_layout_slots_const_hole.mir.snap | Snapshot update due to branch lowering changes. |
| crates/mir/tests/fixtures/const_hole_storage_map_contract_defaults.mir.snap | Snapshot update due to branch lowering changes. |
| crates/mir/tests/fixtures/abi_decode.mir.snap | Snapshot update due to branch lowering changes. |
| crates/mir/src/lower/mod.rs | Updates MIR builder to traverse the new Cond structure for return-param collection. |
| crates/mir/src/lower/match_lowering.rs | Adds lowering for let conditions into match/decision-tree branching. |
| crates/mir/src/lower/expr.rs | Lowers if/while using CondId via lower_condition_branch (supports decision trees). |
| crates/language-server/test_files/completion.snap | Snapshot update (completion list shifted by unrelated symbol set changes). |
| crates/hir/tests/ty_check.rs | Skips unresolved spans when collecting typed-property snapshots (stability fix). |
| crates/hir/test_files/ty_check/if_.snap | Snapshot update reflecting if let typing and new test cases. |
| crates/hir/test_files/ty_check/if_.fe | Adds if let typing test (no-else behavior) and updates file layout. |
| crates/hir/test_files/ty_check/contract_effects.snap | Snapshot update due to condition typing/printing changes. |
| crates/hir/src/core/visitor.rs | Updates visitor traversal to walk Cond trees (and bind patterns/exprs inside). |
| crates/hir/src/core/print.rs | Adds pretty-printing for Cond nodes. |
| crates/hir/src/core/lower/stmt.rs | Lowers while condition into Cond instead of Expr. |
| crates/hir/src/core/lower/expr.rs | Lowers if condition into Cond and rejects direct lowering of let as normal Expr. |
| crates/hir/src/core/lower/event.rs | Threads conds store into body creation for event lowering. |
| crates/hir/src/core/lower/body.rs | Adds conds NodeStore to Body lowering context and final body assembly. |
| crates/hir/src/core/hir_def/stmt.rs | Changes While to store CondId instead of ExprId. |
| crates/hir/src/core/hir_def/expr.rs | Introduces Cond / CondId and changes Expr::If to store CondId. |
| crates/hir/src/core/hir_def/body.rs | Adds conds NodeStore to Body. |
| crates/hir/src/analysis/ty/ty_check/stmt.rs | Typechecks while via check_cond with correct scoping/pending-binding handling. |
| crates/hir/src/analysis/ty/ty_check/expr.rs | Implements check_cond + check_let_condition; updates if typing/scoping for let-chains. |
| crates/hir/src/analysis/ty/ty_check/env.rs | Adds enter_lexical_scope and clear_pending_bindings utilities for let-chain handling. |
| crates/hir/src/analysis/ty/ctfe.rs | Adds eval_cond so CTFE can evaluate let-conditions and logical condition chains. |
| crates/hir/src/analysis/ty/const_check.rs | Adds check_cond so const checking visits let-conditions and condition trees. |
| crates/fmt/tests/fixtures/loops.snap | Snapshot update for formatted while let. |
| crates/fmt/tests/fixtures/loops.fe | Adds unformatted while let case to formatter fixtures. |
| crates/fmt/tests/fixtures/if_else_width.snap | Snapshot update to include if let width behavior. |
| crates/fmt/tests/fixtures/if_else_width.fe | Adds unformatted if let single-line case to formatter fixtures. |
| crates/fmt/src/ast/types.rs | Adds formatting dispatch for ExprKind::Let. |
| crates/fmt/src/ast/stmt.rs | Adjusts while formatting node handling (robustness with new AST shape). |
| crates/fmt/src/ast/expr.rs | Adds LetExpr formatter and adjusts if formatting node handling (robustness). |
| crates/fe/tests/fixtures/fe_test/if_let_while_let.fe | End-to-end test fixture for if let / while let (incl. let-chains). |
| crates/codegen/tests/fixtures/sonatina_ir/range_bounds.snap | Snapshot update from changed branching lowering patterns. |
| crates/codegen/tests/fixtures/sonatina_ir/if_else.snap | Snapshot update from changed branching lowering patterns. |
| crates/codegen/tests/fixtures/sonatina_ir/high_level_contract.snap | Snapshot update from changed branching lowering patterns. |
| crates/codegen/tests/fixtures/sonatina_ir/for_range.snap | Snapshot update from changed branching lowering patterns. |
| crates/codegen/tests/fixtures/sonatina_ir/erc20.snap | Snapshot update from changed branching lowering patterns. |
| crates/codegen/tests/fixtures/sonatina_ir/create_contract.snap | Snapshot update from changed branching lowering patterns. |
| crates/codegen/tests/fixtures/sonatina_ir/const_fn_packed_config.snap | Snapshot update from changed branching lowering patterns. |
| crates/codegen/tests/fixtures/sonatina_ir/const_array_branch.snap | Snapshot update from changed branching lowering patterns. |
| crates/codegen/tests/fixtures/range_bounds.snap | Snapshot update of Yul output due to branch emission changes. |
| crates/codegen/tests/fixtures/if_else.snap | Snapshot update of Yul output due to branch emission changes. |
| crates/codegen/tests/fixtures/high_level_contract.snap | Snapshot update of Yul output due to branch emission changes. |
| crates/codegen/tests/fixtures/for_range.snap | Snapshot update of Yul output due to branch emission changes. |
| crates/codegen/tests/fixtures/erc20.snap | Snapshot update of Yul output due to branch emission changes. |
| crates/codegen/tests/fixtures/create_contract.snap | Snapshot update of Yul output due to branch emission changes. |
| crates/codegen/tests/fixtures/const_fn_packed_config.snap | Snapshot update of Yul output due to branch emission changes. |
| crates/codegen/tests/fixtures/const_array_branch.snap | Snapshot update of Yul output due to branch emission changes. |
| crates/codegen/src/yul/emitter/control_flow.rs | Fixes loop/control-flow emission to handle complex loop headers and avoid incorrect join detection. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| parser.set_newline_as_trivia(false); | ||
| let is_or = parser.current_kind() == Some(SyntaxKind::Pipe2); | ||
| let msg = "`||` cannot be mixed with `let` conditions in this position"; | ||
| let (_, rbp) = infix_binding_power(parser).unwrap(); | ||
| let saw_let_before = self | ||
| .condition_state | ||
| .as_ref() | ||
| .is_some_and(|state| state.borrow().saw_let); | ||
| let mut reported = false; | ||
| if self.allow_let_expr && is_or && saw_let_before { | ||
| parser.error_msg_on_current_token(msg); | ||
| reported = true; | ||
| } | ||
| bump_bin_op(parser); | ||
| parse_expr_with_min_bp(parser, rbp, false) | ||
| parse_expr_with_min_bp( | ||
| parser, | ||
| rbp, | ||
| false, | ||
| self.allow_let_expr, | ||
| self.condition_state.clone(), | ||
| )?; | ||
|
|
||
| if self.allow_let_expr | ||
| && is_or | ||
| && !reported | ||
| && self | ||
| .condition_state | ||
| .as_ref() | ||
| .is_some_and(|state| state.borrow().saw_let) | ||
| { | ||
| parser.error(msg); | ||
| } |
There was a problem hiding this comment.
In BinExprScope::parse, when || is followed by a let condition on the RHS (e.g. ready || let Some(x) = ...), the diagnostic is currently emitted via parser.error(msg) after parsing the RHS. That attaches a zero-length range at the next token (often {), rather than highlighting the || operator. Consider detecting let on the RHS upfront (e.g. via lookahead to the next non-trivia token) and using error_msg_on_current_token on the || token so the error location is consistent and points at the operator.
fixes #1249
fixes #1250
We don't support rust-2024-style if-let in compound conditions yet (eg
if let .. = y && let ... && foo {This also fixes a loop-lowering bug in yul codegen.