ENH: Support slack variables (lower bound emulation)
- Dominant language
- Rust
- Stars
- 7k
- Forks
- 516
- PR merge metrics
- No merged PRs in 30d
Description
### Describe the Bug
Context: https://github.com/python/typing/issues/674
[Slack variables](https://en.wikipedia.org/wiki/Slack_variable) would allow us to emulate lower bounds on type variables, which is relevant for methods like `dict.__or__` or sequence concatenation, when an outer context is present.
```python
from typing import Never, assert_type, reveal_type
class Vec[T]: # invariant in T
def _items(self) -> list[T]: ...
def _append(self, item: T) -> None: ...
def concat_vecs[T1, T2, _T_slack=Never](
left: Vec[T1],
right: Vec[T2],
) -> Vec[T1 | T2 | _T_slack]: # <-- Slack variable makes return a supertype of T1 | T2
return Vec()
class A: ...
class B: ...
class C: ...
def test_vec_concat(left: Vec[A], right: Vec[B]) -> None:
# without outer context, the type is precise
assert_type(concat_vecs(left, right), Vec[A | B]) # ✅️
# outer context allows widening due to slack variables
_0: Vec[A | B] = concat_vecs(left, right) # ❌️
_1: Vec[A | B | C] = concat_vecs(left, right) # ❌️
_2: Vec[object] = concat_vecs(left, right) # ❌️
```
`pyrefly` fails to find existing solutions to these function calls:
- `_0`: (`T1=A`, `T2=B`, `_T_slack=Never`)
- `_1`: (`T1=A`, `T2=B`, `_T_slack=C`)
- `_2`: (`T1=A`, `T2=B`, `_T_slack=object`)
```
ERROR sandbox.py:21:38-42: Argument `Vec[A]` is not assignable to parameter `left` with type `Vec[A | B]` in function `concat_vecs`
ERROR sandbox.py:21:44-49: Argument `Vec[B]` is not assignable to parameter `right` with type `Vec[A | B]` in function `concat_vecs`
ERROR sandbox.py:22:38-42: Argument `Vec[A]` is not assignable to parameter `left` with type `Vec[A | B | C]` in function `concat_vecs`
ERROR sandbox.py:22:44-49: Argument `Vec[B]` is not assignable to parameter `right` with type `Vec[A | B | C]` in function `concat_vecs`
ERROR sandbox.py:23:38-42: Argument `Vec[A]` is not assignable to parameter `left` with type `Vec[object]` in function `concat_vecs`
```
### Sandbox Link
https://pyrefly.org/sandbox/?project=N4IgZglgNgpgziAXKOBDAdgEwEYHsAeAdAA4CeS4ATrgLYAEALqcROgOZ0Q3G6UN0A5GADcYlADR1UcOGIYB9JsRiTKImKiiLmMADrp9AYyjS4dAGoxDAbQAqAXUR06AYk7phqShAz9WdW31nZ0wYMDp5CAYYGjgAClkoMABKOgBaAD46KAg4BjtHOkJioODQ8PlUYmUsBJgkySiYp1tUzMFcdBgnYsJ9fXK6Q07DVAVRQzg7AEZJWwAmSXlbeTgTQwBrAF4hUUp7ONLnWDAGJ0sbW2n7cSO6bzYACzOLKzt5m-02rIuZugAfALzAERFZrVCbQquOgAHjSaToAGV1hs6J5vKhsLA6DRUBt4PcYAwAK6UdBSOhwYnKPg6Oi4cJXEELO5qElk16GOLJfroYymOgAQR6JT5JhkdAAQiK%2BmKBQBhGW8wbRPLyCbyYZ8sZxE4vX6Cm73CBPfVvSX2b4dLqIO5uADuUUeuGJ-Bd0UoQ060XwDEkDEeMEYdNydGIakMuT05OCpjk2mUcS1o3GVnietUJueyUkBpBFtS0MAoOSAeD%2B7fTXWIvegffxNFBcPazI7QuhWBxMMSgwxcJSUWivD4sfA7vIAAznN6C-P2YLOLbVlPqtO6sJ%2B42m1JuQAy5GWY855NNJzZp4DJSD5bOF8mxsvJqvTpnN9Dd6P5sfrLhsAArKwMWfBNeIy3hM6Zrk%2B2YvnuIDiCArrQHAJDkIgIBuAAqgw0BRKQdBgMSfKYZ0cDKmEuG8LiCjoMSNDYGIcT4E4rAMFaeSULa%2B6Euy5JgLoIACNRtFsXQwD4AAvrx%2BgwSAZBqGAUCkIQPY0FAFBuAACqQsnyZSGA4AQ1aQGwpJjBAnSym4iIwEGzwMMQcCIAA9A5MlhPJhC8GwDkwOgDmYLgkwOVqhnGYRPlkZ6qCeNAmLYkFJohaZ5K4MQoWIfoZABp0aR7HAiV0AuvEAMyENMhUSegICibBEKYaIABi0AwBQaBYHgRBkJVQA
### (Only applicable for extension issues) IDE Information
_No response_
Contributor guide
Assessment
This issue has not been assessed yet.