[ty] Unpack variadic argument type in specialization (#20130)
## Summary This PR fixes various TODOs around overload call when a variadic argument is used. The reason this bug existed is because the specialization wouldn't account for unpacking the type of the variadic argument. This is fixed by expanding `MatchedArgument` to contain the type of that argument _only_ when it is a variadic argument. The reason is that there's a split for when the argument type is inferred -- the non-variadic arguments are inferred using `infer_argument_types` _after_ parameter matching while the variadic argument type is inferred _during_ the parameter matching. And, the `MatchedArgument` is populated _during_ parameter matching which means the unpacking would need to happen during parameter matching. This split seems a bit inconsistent but I don't want to spend a lot of time on trying to merge them such that all argument type inference happens in a single place. I might look into it while adding support for `**kwargs`. ## Test Plan Update existing tests by resolving the todos. The ecosystem changes looks correct to me except for the `slice` call but it seems that it's unrelated to this PR as we infer `slice[Any, Any, Any]` for a `slice(1, 2, 3)` call on `main` as well ([playground](https://play.ty.dev/9eacce00-c7d5-4dd5-a932-4265cb2bb4f6)).
This commit is contained in:
@@ -290,16 +290,10 @@ from overloaded import A, f
|
||||
|
||||
def _(x: int, y: A | int):
|
||||
reveal_type(f(x)) # revealed: int
|
||||
# TODO: revealed: int
|
||||
# TODO: no error
|
||||
# error: [no-matching-overload]
|
||||
reveal_type(f(*(x,))) # revealed: Unknown
|
||||
reveal_type(f(*(x,))) # revealed: int
|
||||
|
||||
reveal_type(f(y)) # revealed: A | int
|
||||
# TODO: revealed: A | int
|
||||
# TODO: no error
|
||||
# error: [no-matching-overload]
|
||||
reveal_type(f(*(y,))) # revealed: Unknown
|
||||
reveal_type(f(*(y,))) # revealed: A | int
|
||||
```
|
||||
|
||||
### Generics (PEP 695)
|
||||
@@ -328,16 +322,10 @@ from overloaded import B, f
|
||||
|
||||
def _(x: int, y: B | int):
|
||||
reveal_type(f(x)) # revealed: int
|
||||
# TODO: revealed: int
|
||||
# TODO: no error
|
||||
# error: [no-matching-overload]
|
||||
reveal_type(f(*(x,))) # revealed: Unknown
|
||||
reveal_type(f(*(x,))) # revealed: int
|
||||
|
||||
reveal_type(f(y)) # revealed: B | int
|
||||
# TODO: revealed: B | int
|
||||
# TODO: no error
|
||||
# error: [no-matching-overload]
|
||||
reveal_type(f(*(y,))) # revealed: Unknown
|
||||
reveal_type(f(*(y,))) # revealed: B | int
|
||||
```
|
||||
|
||||
### Expanding `bool`
|
||||
@@ -1236,21 +1224,14 @@ def _(integer: int, string: str, any: Any, list_any: list[Any]):
|
||||
reveal_type(f(*(integer, string))) # revealed: int
|
||||
|
||||
reveal_type(f(string, integer)) # revealed: int
|
||||
# TODO: revealed: int
|
||||
# TODO: no error
|
||||
# error: [no-matching-overload]
|
||||
reveal_type(f(*(string, integer))) # revealed: Unknown
|
||||
reveal_type(f(*(string, integer))) # revealed: int
|
||||
|
||||
# This matches the second overload and is _not_ the case of ambiguous overload matching.
|
||||
reveal_type(f(string, any)) # revealed: Any
|
||||
# TODO: Any
|
||||
reveal_type(f(*(string, any))) # revealed: tuple[str, Any]
|
||||
reveal_type(f(*(string, any))) # revealed: Any
|
||||
|
||||
reveal_type(f(string, list_any)) # revealed: list[Any]
|
||||
# TODO: revealed: list[Any]
|
||||
# TODO: no error
|
||||
# error: [no-matching-overload]
|
||||
reveal_type(f(*(string, list_any))) # revealed: Unknown
|
||||
reveal_type(f(*(string, list_any))) # revealed: list[Any]
|
||||
```
|
||||
|
||||
### Generic `self`
|
||||
|
||||
Reference in New Issue
Block a user