Expand semantic syntax errors for invalid walruses#25415
Conversation
Typing conformance resultsNo changes detected ✅Current numbersThe percentage of diagnostics emitted that were expected errors held steady at 91.94%. The percentage of expected errors that received a diagnostic held steady at 87.09%. The number of fully passing files held steady at 92/134. |
Memory usage reportMemory usage unchanged ✅ |
|
|
|
Tagging @ntBre on this one. (Not super urgent.) |
59f3a4e to
d5e10cc
Compare
| /// Searches for the first named expression (`x := y`) rebinding one of the `iteration_variables` in | ||
| /// a comprehension or generator expression. | ||
| struct ReboundComprehensionVisitor<'a> { |
There was a problem hiding this comment.
Should we preserve this doc comment?
| // TODO(brent) with multiple diagnostic ranges, we could mark both the named expr (current) | ||
| // and the name expr being rebound | ||
| for range in rebound_variables { |
There was a problem hiding this comment.
Should we preserve this TODO somewhere too? Unless it doesn't seem useful to do it anymore.
| struct ComprehensionTargetNameVisitor { | ||
| names: FxHashSet<ast::name::Name>, | ||
| } |
There was a problem hiding this comment.
I think you could probably reuse the StoredNameFinder from the AST crate here, but the API is a little different.
ruff/crates/ruff_python_ast/src/helpers.rs
Lines 1143 to 1159 in d5e10cc
46d25ae to
209dd25
Compare
209dd25 to
09158b7
Compare
## Summary
Python rejects assignment expressions in several comprehension contexts,
but we previously only reported the case in which a walrus rebound a
comprehension variable.
As a result, we accepted invalid walruses in the iterable and class-body
portions clause of a comprehension, and missed some rebinding cases in
filter clauses and nested comprehensions. It turns out the rules are
really complicated!
For example, we now report the two newly modeled syntax errors:
```py
# error: [invalid-syntax] "assignment expression cannot be used in a comprehension iterable expression"
[x for x in (values := [1])]
class C:
# error: [invalid-syntax] "assignment expression within a comprehension cannot be used in a class body"
[(value := item) for item in [1]]
```
We also catch previously missed instances of the existing rebinding
error:
```py
# error: [invalid-syntax] "assignment expression cannot rebind comprehension variable"
[x for x in [1] if (x := 0)]
```
In general, I decided not to worry about emitting multiple diagnostics
for a single error. These are rare, they're fatal, and it added a lot of
complexity (so in some cases we may emit two errors for a walrus that is
invalid for two reasons).
Summary
Python rejects assignment expressions in several comprehension contexts, but we previously only reported the case in which a walrus rebound a comprehension variable.
As a result, we accepted invalid walruses in the iterable and class-body portions clause of a comprehension, and missed some rebinding cases in filter clauses and nested comprehensions. It turns out the rules are really complicated!
For example, we now report the two newly modeled syntax errors:
We also catch previously missed instances of the existing rebinding error:
In general, I decided not to worry about emitting multiple diagnostics for a single error. These are rare, they're fatal, and it added a lot of complexity (so in some cases we may emit two errors for a walrus that is invalid for two reasons).