mirror of
https://github.com/astral-sh/ruff.git
synced 2025-11-19 20:24:27 +00:00
[ty] Simplify unions containing multiple type variables during inference (#21275)
## Summary Splitting this one out from https://github.com/astral-sh/ruff/pull/21210. This is also something that should be made obselete by the new constraint solver, but is easy enough to fix now.
This commit is contained in:
parent
7569b09bdd
commit
5c69e00d1c
2 changed files with 14 additions and 2 deletions
|
|
@ -474,6 +474,16 @@ def g(x: str):
|
||||||
f(prefix=x, suffix=".tar.gz")
|
f(prefix=x, suffix=".tar.gz")
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If the type variable is present multiple times in the union, we choose the correct union element to
|
||||||
|
infer against based on the argument type:
|
||||||
|
|
||||||
|
```py
|
||||||
|
def h[T](x: list[T] | dict[T, T]) -> T | None: ...
|
||||||
|
def _(x: list[int], y: dict[int, int]):
|
||||||
|
reveal_type(h(x)) # revealed: int | None
|
||||||
|
reveal_type(h(y)) # revealed: int | None
|
||||||
|
```
|
||||||
|
|
||||||
## Nested functions see typevars bound in outer function
|
## Nested functions see typevars bound in outer function
|
||||||
|
|
||||||
```py
|
```py
|
||||||
|
|
|
||||||
|
|
@ -1397,11 +1397,13 @@ impl<'db> SpecializationBuilder<'db> {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the union elements that are not related to `formal`.
|
// Remove the union elements from `actual` that are not related to `formal`, and vice
|
||||||
|
// versa.
|
||||||
//
|
//
|
||||||
// For example, if `formal` is `list[T]` and `actual` is `list[int] | None`, we want to specialize `T`
|
// For example, if `formal` is `list[T]` and `actual` is `list[int] | None`, we want to specialize `T`
|
||||||
// to `int`.
|
// to `int`, and so ignore the `None`.
|
||||||
let actual = actual.filter_disjoint_elements(self.db, formal, self.inferable);
|
let actual = actual.filter_disjoint_elements(self.db, formal, self.inferable);
|
||||||
|
let formal = formal.filter_disjoint_elements(self.db, actual, self.inferable);
|
||||||
|
|
||||||
match (formal, actual) {
|
match (formal, actual) {
|
||||||
// TODO: We haven't implemented a full unification solver yet. If typevars appear in
|
// TODO: We haven't implemented a full unification solver yet. If typevars appear in
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue