Skip to content

Conversation

@dcreager
Copy link
Member

This reworks the assignability/subtyping relations a bit to handle typevars better:

  1. For the most part, types are not assignable to typevars, since there's no guarantee what type the typevar will be specialized to.

  2. An intersection is an exception, if it contains the typevar itself as one of the positive elements. This should fall out from the other clauses automatically, since a typevar is assignable to itself, and an intersection is assignable to something if any positive element is assignable to that something.

  3. Constrained typevars are an exception, since they must be specialized to exactly one of the constraints, not to a subtype of a constraint. If a type is assignable to every constraint, then the type is also assignable to the constrained typevar.

We already had a special case for (3), but the ordering of it relative to the intersection clauses meant we weren't catching (2) correctly. To fix this, we keep the special case for (3), but fall through to the other match arms for non-constrained typevars and if the special case isn't true for a constrained typevar.

Closes #17364

@dcreager dcreager added the ty Multi-file analysis & type inference label Apr 15, 2025
@github-actions
Copy link
Contributor

mypy_primer results

No ecosystem changes detected ✅

Copy link
Contributor

@carljm carljm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent, thank you!

@dcreager dcreager merged commit 807a8a7 into main Apr 15, 2025
23 checks passed
@dcreager dcreager deleted the dcreager/typevar-minus branch April 15, 2025 20:34
sharkdp pushed a commit that referenced this pull request Apr 16, 2025
This reworks the assignability/subtyping relations a bit to handle
typevars better:

1. For the most part, types are not assignable to typevars, since
there's no guarantee what type the typevar will be specialized to.

2. An intersection is an exception, if it contains the typevar itself as
one of the positive elements. This should fall out from the other
clauses automatically, since a typevar is assignable to itself, and an
intersection is assignable to something if any positive element is
assignable to that something.

3. Constrained typevars are an exception, since they must be specialized
to _exactly_ one of the constraints, not to a _subtype_ of a constraint.
If a type is assignable to every constraint, then the type is also
assignable to the constrained typevar.

We already had a special case for (3), but the ordering of it relative
to the intersection clauses meant we weren't catching (2) correctly. To
fix this, we keep the special case for (3), but fall through to the
other match arms for non-constrained typevars and if the special case
isn't true for a constrained typevar.

Closes #17364
dcreager added a commit that referenced this pull request Apr 16, 2025
* main: (44 commits)
  [`airflow`] Extend `AIR311` rules (#17422)
  [red-knot] simplify union size limit handling (#17429)
  [`airflow`] Extract `AIR311` from `AIR301` rules (`AIR301`, `AIR311`) (#17310)
  [red-knot] set a size limit on unions of literals (#17419)
  [red-knot] make large-union benchmark slow again (#17418)
  [red-knot] optimize building large unions of literals (#17403)
  [red-knot] Fix comments in type_api.md (#17425)
  [red-knot] Do not assume that `x != 0` if `x` inhabits `~Literal[0]` (#17370)
  [red-knot] make large-union benchmark more challenging (#17416)
  [red-knot] Acknowledge that `T & anything` is assignable to `T` (#17413)
  Update Rust crate clap to v4.5.36 (#17381)
  Raise syntax error when `\` is at end of file (#17409)
  [red-knot] Add regression tests for narrowing constraints cycles (#17408)
  [red-knot] Add some knowledge of `__all__` to `*`-import machinery (#17373)
  Update taiki-e/install-action digest to be7c31b (#17379)
  Update Rust crate mimalloc to v0.1.46 (#17382)
  Update PyO3/maturin-action action to v1.49.1 (#17384)
  Update Rust crate anyhow to v1.0.98 (#17380)
  dependencies: switch from `chrono` to `jiff`
  Update Rust crate bstr to v1.12.0 (#17385)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[red-knot] T & ~X should be assignable to T

3 participants