rust-lang / rust-lang/reference
Figure out how to better define let chain grammar
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 1.6k
- Forks
- 607
- PR merge metrics
- PR metrics pending
Description
The let chain grammar has some issues, and could use some improvement.
The let chain grammar doesn't handle the minimum precedence of chains of associative operators (see prec_let_scrutinee_needs_par). The ExcludedConditions doesn't explain how "deep" the exclusion goes in terms of the AST. For example, naively:
#[cfg(false)]
fn f() -> Range<i32> {
let mut z = 0;
if let r = 1+z=1 {}
todo!()
}
// Contrast this with `if 1+z=1 {}` which is OK since it doesn't have the
// minimum precedence restriction.
The Scrutinee here could be parsed as arithmetic plus of 1 and z=1 (assignment expression, whose value is unit). The ExcludedConditions doesn't explain that the minimum precedence applies to the RHS of the add expression. Similar to https://github.com/rust-lang/reference/issues/1808, the parser keeps track of a minimum precedence for some period of time (while parsing a chain of associative operators I believe), but there are many places where sub-expressions ignore this minimum precedence (I think all sub-expressions except for associative operators?).
I don't know how to specify that. One option is to define a variant of Expression that excludes the relevant expressions, and has a new set of associative operator expressions that have the appropriate exclusions. Like IfCondArithmeticOrLogicalExpression -> IfCondExpression + IfCondExpression | ... and IfCondExpression is the set of restricted expressions. However, I'm concerned this will result in a very large duplication of the Expression sub-grammar.
In https://hackmd.io/@ehuss/S1juwZuyxl I also sketched out a grammar that made LetExpression an actual expression, but only in a ConditionExpression. I don't know if that would help with anything. I think the current Restrictions::ALLOW_LET restriction is correctly captured in the grammar, but it could use more scrutiny.
The range expression exclusion is a little odd since it allows ranges that don't have a LHS. I think it is fine as it is, but it seemed quite unusual and could use some more inspection.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading the let-chain grammar in the Rust Reference alongside compiler/rustc_ast/src/util/parser.rs, especially prec_let_scrutinee_needs_par and ExcludedConditions. Compare the grammar with the examples in this issue and the linked Reference issue and HackMD sketch. Done means the precedence and exclusion rules are specified precisely, including associative operators, ranges, and ALLOW_LET.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers, documentation
- Issue type
- Documentation
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100