mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-29 13:24:57 +00:00
[ty] don't mark entire type-alias scopes as Deferred (#20086)
## Summary This has been here for awhile (since our initial PEP 695 type alias support) but isn't really correct. The right-hand-side of a PEP 695 type alias is a distinct scope, and we don't mark it as an "eager" nested scope, so it automatically gets "deferred" resolution of names from outer scopes (just like a nested function). Thus it's redundant/unnecessary for us to use `DeferredExpressionState::Deferred` for resolving that RHS expression -- that's for deferring resolution of individual names within a scope. Using it here causes us to wrongly ignore applicable outer-scope narrowing. ## Test Plan Added mdtest that failed before this PR (the second snippet -- the first snippet always passed.)
This commit is contained in:
parent
ba47010150
commit
33c5f6f4f8
2 changed files with 27 additions and 1 deletions
|
@ -75,6 +75,32 @@ def f(x: T):
|
||||||
reveal_type(b) # revealed: str
|
reveal_type(b) # revealed: str
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Scoping
|
||||||
|
|
||||||
|
PEP 695 type aliases delay runtime evaluation of their right-hand side, so they are a lazy (not
|
||||||
|
eager) nested scope.
|
||||||
|
|
||||||
|
```py
|
||||||
|
type Alias = Foo | str
|
||||||
|
|
||||||
|
def f(x: Alias):
|
||||||
|
reveal_type(x) # revealed: Foo | str
|
||||||
|
|
||||||
|
class Foo:
|
||||||
|
pass
|
||||||
|
```
|
||||||
|
|
||||||
|
But narrowing of names used in the type alias is still respected:
|
||||||
|
|
||||||
|
```py
|
||||||
|
def _(flag: bool):
|
||||||
|
t = int if flag else None
|
||||||
|
if t is not None:
|
||||||
|
type Alias = t | str
|
||||||
|
def f(x: Alias):
|
||||||
|
reveal_type(x) # revealed: int | str
|
||||||
|
```
|
||||||
|
|
||||||
## Generic type aliases
|
## Generic type aliases
|
||||||
|
|
||||||
```py
|
```py
|
||||||
|
|
|
@ -2344,7 +2344,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn infer_type_alias(&mut self, type_alias: &ast::StmtTypeAlias) {
|
fn infer_type_alias(&mut self, type_alias: &ast::StmtTypeAlias) {
|
||||||
self.infer_annotation_expression(&type_alias.value, DeferredExpressionState::Deferred);
|
self.infer_annotation_expression(&type_alias.value, DeferredExpressionState::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If the current scope is a method inside an enclosing class,
|
/// If the current scope is a method inside an enclosing class,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue