Skip to content

Commit 5c69e00

Browse files
authored
[ty] Simplify unions containing multiple type variables during inference (#21275)
## Summary Splitting this one out from #21210. This is also something that should be made obselete by the new constraint solver, but is easy enough to fix now.
1 parent 7569b09 commit 5c69e00

File tree

2 files changed

+14
-2
lines changed

2 files changed

+14
-2
lines changed

crates/ty_python_semantic/resources/mdtest/generics/pep695/functions.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,16 @@ def g(x: str):
474474
f(prefix=x, suffix=".tar.gz")
475475
```
476476

477+
If the type variable is present multiple times in the union, we choose the correct union element to
478+
infer against based on the argument type:
479+
480+
```py
481+
def h[T](x: list[T] | dict[T, T]) -> T | None: ...
482+
def _(x: list[int], y: dict[int, int]):
483+
reveal_type(h(x)) # revealed: int | None
484+
reveal_type(h(y)) # revealed: int | None
485+
```
486+
477487
## Nested functions see typevars bound in outer function
478488

479489
```py

crates/ty_python_semantic/src/types/generics.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1397,11 +1397,13 @@ impl<'db> SpecializationBuilder<'db> {
13971397
return Ok(());
13981398
}
13991399

1400-
// Remove the union elements that are not related to `formal`.
1400+
// Remove the union elements from `actual` that are not related to `formal`, and vice
1401+
// versa.
14011402
//
14021403
// For example, if `formal` is `list[T]` and `actual` is `list[int] | None`, we want to specialize `T`
1403-
// to `int`.
1404+
// to `int`, and so ignore the `None`.
14041405
let actual = actual.filter_disjoint_elements(self.db, formal, self.inferable);
1406+
let formal = formal.filter_disjoint_elements(self.db, actual, self.inferable);
14051407

14061408
match (formal, actual) {
14071409
// TODO: We haven't implemented a full unification solver yet. If typevars appear in

0 commit comments

Comments
 (0)