mirror of
https://github.com/astral-sh/ruff.git
synced 2025-11-18 19:41:34 +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")
|
||||
```
|
||||
|
||||
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
|
||||
|
||||
```py
|
||||
|
|
|
|||
|
|
@ -1397,11 +1397,13 @@ impl<'db> SpecializationBuilder<'db> {
|
|||
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`
|
||||
// to `int`.
|
||||
// to `int`, and so ignore the `None`.
|
||||
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) {
|
||||
// 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