Support all cases of contextual typing for overloads
- Dominant language
- Rust
- Stars
- 7k
- Forks
- 516
- PR merge metrics
- No merged PRs in 30d
Description
### Describe the Bug
We turned off contextual typing altogether in 09eee7f79b0f9478c27e44b7065bfff7aefc2ef6 to avoid quadratic behavior. We then loosened this in b3d99be2471f0587bc922f9c0d141fb754a7332c to continue contextually typing containers like lists, so in many cases we will succeed with contextual typing.
We should support contextual typing for _all_ contextually sensitive expressions in an overloaded call, including nested function calls, comprehensions, walrus, if/else expressions, etc. But we need to be careful to enable this without introducing unacceptable worst-case performance.
Suggestions:
* Identify contextually-insensitive expressions before calls, infer types for them just once
* Optimize overload selection to filter out overloads based on signature mismatch, before trying types
* Limit contextual typing to some fixed depth, to avoid worst case time when the above strategies don't apply
```
from typing import overload
class A: ...
class B(A): ...
@overload
def foo[T](xs: list[T]) -> list[T]: ...
@overload
def foo[T](xs: set[T]) -> set[T]: ...
def foo[T](xs: list[T] | set[T]) -> list[T] | set[T]:
return xs
x1: list[A] = foo([B()]) # should suceed
x2: list[A] = foo(foo([B()])) # should succeed
```
### Sandbox Link
_No response_
### (Only applicable for extension issues) IDE Information
_No response_
Contributor guide
Assessment
This issue has not been assessed yet.