mirror of https://github.com/astral-sh/ruff
add with_inferable mdtest function
This commit is contained in:
parent
b033a42ced
commit
e6ec4062d5
|
|
@ -60,29 +60,29 @@ class Sub(Base): ...
|
||||||
class Unrelated: ...
|
class Unrelated: ...
|
||||||
|
|
||||||
def unbounded[T]():
|
def unbounded[T]():
|
||||||
static_assert(ConstraintSet.always().satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(ConstraintSet.always().with_inferable(T).satisfied_by_all_typevars())
|
||||||
static_assert(ConstraintSet.always().satisfied_by_all_typevars())
|
static_assert(ConstraintSet.always().satisfied_by_all_typevars())
|
||||||
|
|
||||||
static_assert(not ConstraintSet.never().satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(not ConstraintSet.never().with_inferable(T).satisfied_by_all_typevars())
|
||||||
static_assert(not ConstraintSet.never().satisfied_by_all_typevars())
|
static_assert(not ConstraintSet.never().satisfied_by_all_typevars())
|
||||||
|
|
||||||
# (T = Never) is a valid specialization, which satisfies (T ≤ Unrelated).
|
# (T = Never) is a valid specialization, which satisfies (T ≤ Unrelated).
|
||||||
static_assert(ConstraintSet.range(Never, T, Unrelated).satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(ConstraintSet.range(Never, T, Unrelated).with_inferable(T).satisfied_by_all_typevars())
|
||||||
# (T = Base) is a valid specialization, which does not satisfy (T ≤ Unrelated).
|
# (T = Base) is a valid specialization, which does not satisfy (T ≤ Unrelated).
|
||||||
static_assert(not ConstraintSet.range(Never, T, Unrelated).satisfied_by_all_typevars())
|
static_assert(not ConstraintSet.range(Never, T, Unrelated).satisfied_by_all_typevars())
|
||||||
|
|
||||||
# (T = Base) is a valid specialization, which satisfies (T ≤ Super).
|
# (T = Base) is a valid specialization, which satisfies (T ≤ Super).
|
||||||
static_assert(ConstraintSet.range(Never, T, Super).satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(ConstraintSet.range(Never, T, Super).with_inferable(T).satisfied_by_all_typevars())
|
||||||
# (T = Unrelated) is a valid specialization, which does not satisfy (T ≤ Super).
|
# (T = Unrelated) is a valid specialization, which does not satisfy (T ≤ Super).
|
||||||
static_assert(not ConstraintSet.range(Never, T, Super).satisfied_by_all_typevars())
|
static_assert(not ConstraintSet.range(Never, T, Super).satisfied_by_all_typevars())
|
||||||
|
|
||||||
# (T = Base) is a valid specialization, which satisfies (T ≤ Base).
|
# (T = Base) is a valid specialization, which satisfies (T ≤ Base).
|
||||||
static_assert(ConstraintSet.range(Never, T, Base).satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(ConstraintSet.range(Never, T, Base).with_inferable(T).satisfied_by_all_typevars())
|
||||||
# (T = Unrelated) is a valid specialization, which does not satisfy (T ≤ Base).
|
# (T = Unrelated) is a valid specialization, which does not satisfy (T ≤ Base).
|
||||||
static_assert(not ConstraintSet.range(Never, T, Base).satisfied_by_all_typevars())
|
static_assert(not ConstraintSet.range(Never, T, Base).satisfied_by_all_typevars())
|
||||||
|
|
||||||
# (T = Sub) is a valid specialization, which satisfies (T ≤ Sub).
|
# (T = Sub) is a valid specialization, which satisfies (T ≤ Sub).
|
||||||
static_assert(ConstraintSet.range(Never, T, Sub).satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(ConstraintSet.range(Never, T, Sub).with_inferable(T).satisfied_by_all_typevars())
|
||||||
# (T = Unrelated) is a valid specialization, which does not satisfy (T ≤ Sub).
|
# (T = Unrelated) is a valid specialization, which does not satisfy (T ≤ Sub).
|
||||||
static_assert(not ConstraintSet.range(Never, T, Sub).satisfied_by_all_typevars())
|
static_assert(not ConstraintSet.range(Never, T, Sub).satisfied_by_all_typevars())
|
||||||
```
|
```
|
||||||
|
|
@ -106,38 +106,38 @@ class Sub(Base): ...
|
||||||
class Unrelated: ...
|
class Unrelated: ...
|
||||||
|
|
||||||
def bounded[T: Base]():
|
def bounded[T: Base]():
|
||||||
static_assert(ConstraintSet.always().satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(ConstraintSet.always().with_inferable(T).satisfied_by_all_typevars())
|
||||||
static_assert(ConstraintSet.always().satisfied_by_all_typevars())
|
static_assert(ConstraintSet.always().satisfied_by_all_typevars())
|
||||||
|
|
||||||
static_assert(not ConstraintSet.never().satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(not ConstraintSet.never().with_inferable(T).satisfied_by_all_typevars())
|
||||||
static_assert(not ConstraintSet.never().satisfied_by_all_typevars())
|
static_assert(not ConstraintSet.never().satisfied_by_all_typevars())
|
||||||
|
|
||||||
# (T = Base) is a valid specialization, which satisfies (T ≤ Super).
|
# (T = Base) is a valid specialization, which satisfies (T ≤ Super).
|
||||||
static_assert(ConstraintSet.range(Never, T, Super).satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(ConstraintSet.range(Never, T, Super).with_inferable(T).satisfied_by_all_typevars())
|
||||||
# Every valid specialization satisfies (T ≤ Base). Since (Base ≤ Super), every valid
|
# Every valid specialization satisfies (T ≤ Base). Since (Base ≤ Super), every valid
|
||||||
# specialization also satisfies (T ≤ Super).
|
# specialization also satisfies (T ≤ Super).
|
||||||
static_assert(ConstraintSet.range(Never, T, Super).satisfied_by_all_typevars())
|
static_assert(ConstraintSet.range(Never, T, Super).satisfied_by_all_typevars())
|
||||||
|
|
||||||
# (T = Base) is a valid specialization, which satisfies (T ≤ Base).
|
# (T = Base) is a valid specialization, which satisfies (T ≤ Base).
|
||||||
static_assert(ConstraintSet.range(Never, T, Base).satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(ConstraintSet.range(Never, T, Base).with_inferable(T).satisfied_by_all_typevars())
|
||||||
# Every valid specialization satisfies (T ≤ Base).
|
# Every valid specialization satisfies (T ≤ Base).
|
||||||
static_assert(ConstraintSet.range(Never, T, Base).satisfied_by_all_typevars())
|
static_assert(ConstraintSet.range(Never, T, Base).satisfied_by_all_typevars())
|
||||||
|
|
||||||
# (T = Sub) is a valid specialization, which satisfies (T ≤ Sub).
|
# (T = Sub) is a valid specialization, which satisfies (T ≤ Sub).
|
||||||
static_assert(ConstraintSet.range(Never, T, Sub).satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(ConstraintSet.range(Never, T, Sub).with_inferable(T).satisfied_by_all_typevars())
|
||||||
# (T = Base) is a valid specialization, which does not satisfy (T ≤ Sub).
|
# (T = Base) is a valid specialization, which does not satisfy (T ≤ Sub).
|
||||||
static_assert(not ConstraintSet.range(Never, T, Sub).satisfied_by_all_typevars())
|
static_assert(not ConstraintSet.range(Never, T, Sub).satisfied_by_all_typevars())
|
||||||
|
|
||||||
# (T = Never) is a valid specialization, which satisfies (T ≤ Unrelated).
|
# (T = Never) is a valid specialization, which satisfies (T ≤ Unrelated).
|
||||||
constraints = ConstraintSet.range(Never, T, Unrelated)
|
constraints = ConstraintSet.range(Never, T, Unrelated)
|
||||||
static_assert(constraints.satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(constraints.with_inferable(T).satisfied_by_all_typevars())
|
||||||
# (T = Base) is a valid specialization, which does not satisfy (T ≤ Unrelated).
|
# (T = Base) is a valid specialization, which does not satisfy (T ≤ Unrelated).
|
||||||
static_assert(not constraints.satisfied_by_all_typevars())
|
static_assert(not constraints.satisfied_by_all_typevars())
|
||||||
|
|
||||||
# Never is the only type that satisfies both (T ≤ Base) and (T ≤ Unrelated). So there is no
|
# Never is the only type that satisfies both (T ≤ Base) and (T ≤ Unrelated). So there is no
|
||||||
# valid specialization that satisfies (T ≤ Unrelated ∧ T ≠ Never).
|
# valid specialization that satisfies (T ≤ Unrelated ∧ T ≠ Never).
|
||||||
constraints = constraints & ~ConstraintSet.range(Never, T, Never)
|
constraints = constraints & ~ConstraintSet.range(Never, T, Never)
|
||||||
static_assert(not constraints.satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(not constraints.with_inferable(T).satisfied_by_all_typevars())
|
||||||
static_assert(not constraints.satisfied_by_all_typevars())
|
static_assert(not constraints.satisfied_by_all_typevars())
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -153,15 +153,15 @@ the constraint set.
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
def bounded_by_gradual[T: Any]():
|
def bounded_by_gradual[T: Any]():
|
||||||
static_assert(ConstraintSet.always().satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(ConstraintSet.always().with_inferable(T).satisfied_by_all_typevars())
|
||||||
static_assert(ConstraintSet.always().satisfied_by_all_typevars())
|
static_assert(ConstraintSet.always().satisfied_by_all_typevars())
|
||||||
|
|
||||||
static_assert(not ConstraintSet.never().satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(not ConstraintSet.never().with_inferable(T).satisfied_by_all_typevars())
|
||||||
static_assert(not ConstraintSet.never().satisfied_by_all_typevars())
|
static_assert(not ConstraintSet.never().satisfied_by_all_typevars())
|
||||||
|
|
||||||
# If we choose Base as the materialization for the upper bound, then (T = Base) is a valid
|
# If we choose Base as the materialization for the upper bound, then (T = Base) is a valid
|
||||||
# specialization, which satisfies (T ≤ Base).
|
# specialization, which satisfies (T ≤ Base).
|
||||||
static_assert(ConstraintSet.range(Never, T, Base).satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(ConstraintSet.range(Never, T, Base).with_inferable(T).satisfied_by_all_typevars())
|
||||||
# We are free to choose any materialization of the upper bound, and only have to show that the
|
# We are free to choose any materialization of the upper bound, and only have to show that the
|
||||||
# constraint set holds for that one materialization. Having chosen one materialization, we then
|
# constraint set holds for that one materialization. Having chosen one materialization, we then
|
||||||
# have to show that the constraint set holds for all valid specializations of that
|
# have to show that the constraint set holds for all valid specializations of that
|
||||||
|
|
@ -173,7 +173,7 @@ def bounded_by_gradual[T: Any]():
|
||||||
# If we choose Unrelated as the materialization, then (T = Unrelated) is a valid specialization,
|
# If we choose Unrelated as the materialization, then (T = Unrelated) is a valid specialization,
|
||||||
# which satisfies (T ≤ Unrelated).
|
# which satisfies (T ≤ Unrelated).
|
||||||
constraints = ConstraintSet.range(Never, T, Unrelated)
|
constraints = ConstraintSet.range(Never, T, Unrelated)
|
||||||
static_assert(constraints.satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(constraints.with_inferable(T).satisfied_by_all_typevars())
|
||||||
# If we choose Never as the materialization, then (T = Never) is the only valid specialization,
|
# If we choose Never as the materialization, then (T = Never) is the only valid specialization,
|
||||||
# which satisfies (T ≤ Unrelated).
|
# which satisfies (T ≤ Unrelated).
|
||||||
static_assert(constraints.satisfied_by_all_typevars())
|
static_assert(constraints.satisfied_by_all_typevars())
|
||||||
|
|
@ -181,7 +181,7 @@ def bounded_by_gradual[T: Any]():
|
||||||
# If we choose Unrelated as the materialization, then (T = Unrelated) is a valid specialization,
|
# If we choose Unrelated as the materialization, then (T = Unrelated) is a valid specialization,
|
||||||
# which satisfies (T ≤ Unrelated ∧ T ≠ Never).
|
# which satisfies (T ≤ Unrelated ∧ T ≠ Never).
|
||||||
constraints = constraints & ~ConstraintSet.range(Never, T, Never)
|
constraints = constraints & ~ConstraintSet.range(Never, T, Never)
|
||||||
static_assert(constraints.satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(constraints.with_inferable(T).satisfied_by_all_typevars())
|
||||||
# There is no upper bound that we can choose to satisfy this constraint set in non-inferable
|
# There is no upper bound that we can choose to satisfy this constraint set in non-inferable
|
||||||
# position. (T = Never) will be a valid assignment no matter what, and that does not satisfy
|
# position. (T = Never) will be a valid assignment no matter what, and that does not satisfy
|
||||||
# (T ≤ Unrelated ∧ T ≠ Never).
|
# (T ≤ Unrelated ∧ T ≠ Never).
|
||||||
|
|
@ -196,15 +196,15 @@ restrictive variance (i.e., invariance), but we get the same results for other v
|
||||||
|
|
||||||
```py
|
```py
|
||||||
def bounded_by_gradual[T: list[Any]]():
|
def bounded_by_gradual[T: list[Any]]():
|
||||||
static_assert(ConstraintSet.always().satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(ConstraintSet.always().with_inferable(T).satisfied_by_all_typevars())
|
||||||
static_assert(ConstraintSet.always().satisfied_by_all_typevars())
|
static_assert(ConstraintSet.always().satisfied_by_all_typevars())
|
||||||
|
|
||||||
static_assert(not ConstraintSet.never().satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(not ConstraintSet.never().with_inferable(T).satisfied_by_all_typevars())
|
||||||
static_assert(not ConstraintSet.never().satisfied_by_all_typevars())
|
static_assert(not ConstraintSet.never().satisfied_by_all_typevars())
|
||||||
|
|
||||||
# If we choose list[Base] as the materialization of the upper bound, then (T = list[Base]) is a
|
# If we choose list[Base] as the materialization of the upper bound, then (T = list[Base]) is a
|
||||||
# valid specialization, which satisfies (T ≤ list[Base]).
|
# valid specialization, which satisfies (T ≤ list[Base]).
|
||||||
static_assert(ConstraintSet.range(Never, T, list[Base]).satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(ConstraintSet.range(Never, T, list[Base]).with_inferable(T).satisfied_by_all_typevars())
|
||||||
# If we choose Base as the materialization, then all valid specializations must satisfy
|
# If we choose Base as the materialization, then all valid specializations must satisfy
|
||||||
# (T ≤ list[Base]).
|
# (T ≤ list[Base]).
|
||||||
# We are free to choose any materialization of the upper bound, and only have to show that the
|
# We are free to choose any materialization of the upper bound, and only have to show that the
|
||||||
|
|
@ -217,7 +217,7 @@ def bounded_by_gradual[T: list[Any]]():
|
||||||
# If we choose Unrelated as the materialization, then (T = list[Unrelated]) is a valid
|
# If we choose Unrelated as the materialization, then (T = list[Unrelated]) is a valid
|
||||||
# specialization, which satisfies (T ≤ list[Unrelated]).
|
# specialization, which satisfies (T ≤ list[Unrelated]).
|
||||||
constraints = ConstraintSet.range(Never, T, list[Unrelated])
|
constraints = ConstraintSet.range(Never, T, list[Unrelated])
|
||||||
static_assert(constraints.satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(constraints.with_inferable(T).satisfied_by_all_typevars())
|
||||||
# If we choose Unrelated as the materialization, then all valid specializations must satisfy
|
# If we choose Unrelated as the materialization, then all valid specializations must satisfy
|
||||||
# (T ≤ list[Unrelated]).
|
# (T ≤ list[Unrelated]).
|
||||||
static_assert(constraints.satisfied_by_all_typevars())
|
static_assert(constraints.satisfied_by_all_typevars())
|
||||||
|
|
@ -225,7 +225,7 @@ def bounded_by_gradual[T: list[Any]]():
|
||||||
# If we choose Unrelated as the materialization, then (T = list[Unrelated]) is a valid
|
# If we choose Unrelated as the materialization, then (T = list[Unrelated]) is a valid
|
||||||
# specialization, which satisfies (T ≤ list[Unrelated] ∧ T ≠ Never).
|
# specialization, which satisfies (T ≤ list[Unrelated] ∧ T ≠ Never).
|
||||||
constraints = constraints & ~ConstraintSet.range(Never, T, Never)
|
constraints = constraints & ~ConstraintSet.range(Never, T, Never)
|
||||||
static_assert(constraints.satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(constraints.with_inferable(T).satisfied_by_all_typevars())
|
||||||
# There is no upper bound that we can choose to satisfy this constraint set in non-inferable
|
# There is no upper bound that we can choose to satisfy this constraint set in non-inferable
|
||||||
# position. (T = Never) will be a valid assignment no matter what, and that does not satisfy
|
# position. (T = Never) will be a valid assignment no matter what, and that does not satisfy
|
||||||
# (T ≤ list[Unrelated] ∧ T ≠ Never).
|
# (T ≤ list[Unrelated] ∧ T ≠ Never).
|
||||||
|
|
@ -251,61 +251,61 @@ class Sub(Base): ...
|
||||||
class Unrelated: ...
|
class Unrelated: ...
|
||||||
|
|
||||||
def constrained[T: (Base, Unrelated)]():
|
def constrained[T: (Base, Unrelated)]():
|
||||||
static_assert(ConstraintSet.always().satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(ConstraintSet.always().with_inferable(T).satisfied_by_all_typevars())
|
||||||
static_assert(ConstraintSet.always().satisfied_by_all_typevars())
|
static_assert(ConstraintSet.always().satisfied_by_all_typevars())
|
||||||
|
|
||||||
static_assert(not ConstraintSet.never().satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(not ConstraintSet.never().with_inferable(T).satisfied_by_all_typevars())
|
||||||
static_assert(not ConstraintSet.never().satisfied_by_all_typevars())
|
static_assert(not ConstraintSet.never().satisfied_by_all_typevars())
|
||||||
|
|
||||||
# (T = Unrelated) is a valid specialization, which satisfies (T ≤ Unrelated).
|
# (T = Unrelated) is a valid specialization, which satisfies (T ≤ Unrelated).
|
||||||
static_assert(ConstraintSet.range(Never, T, Unrelated).satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(ConstraintSet.range(Never, T, Unrelated).with_inferable(T).satisfied_by_all_typevars())
|
||||||
# (T = Base) is a valid specialization, which does not satisfy (T ≤ Unrelated).
|
# (T = Base) is a valid specialization, which does not satisfy (T ≤ Unrelated).
|
||||||
static_assert(not ConstraintSet.range(Never, T, Unrelated).satisfied_by_all_typevars())
|
static_assert(not ConstraintSet.range(Never, T, Unrelated).satisfied_by_all_typevars())
|
||||||
|
|
||||||
# (T = Base) is a valid specialization, which satisfies (T ≤ Super).
|
# (T = Base) is a valid specialization, which satisfies (T ≤ Super).
|
||||||
static_assert(ConstraintSet.range(Never, T, Super).satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(ConstraintSet.range(Never, T, Super).with_inferable(T).satisfied_by_all_typevars())
|
||||||
# (T = Unrelated) is a valid specialization, which does not satisfy (T ≤ Super).
|
# (T = Unrelated) is a valid specialization, which does not satisfy (T ≤ Super).
|
||||||
static_assert(not ConstraintSet.range(Never, T, Super).satisfied_by_all_typevars())
|
static_assert(not ConstraintSet.range(Never, T, Super).satisfied_by_all_typevars())
|
||||||
|
|
||||||
# (T = Base) is a valid specialization, which satisfies (T ≤ Base).
|
# (T = Base) is a valid specialization, which satisfies (T ≤ Base).
|
||||||
static_assert(ConstraintSet.range(Never, T, Base).satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(ConstraintSet.range(Never, T, Base).with_inferable(T).satisfied_by_all_typevars())
|
||||||
# (T = Unrelated) is a valid specialization, which does not satisfy (T ≤ Base).
|
# (T = Unrelated) is a valid specialization, which does not satisfy (T ≤ Base).
|
||||||
static_assert(not ConstraintSet.range(Never, T, Base).satisfied_by_all_typevars())
|
static_assert(not ConstraintSet.range(Never, T, Base).satisfied_by_all_typevars())
|
||||||
|
|
||||||
# Neither (T = Base) nor (T = Unrelated) satisfy (T ≤ Sub).
|
# Neither (T = Base) nor (T = Unrelated) satisfy (T ≤ Sub).
|
||||||
static_assert(not ConstraintSet.range(Never, T, Sub).satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(not ConstraintSet.range(Never, T, Sub).with_inferable(T).satisfied_by_all_typevars())
|
||||||
static_assert(not ConstraintSet.range(Never, T, Sub).satisfied_by_all_typevars())
|
static_assert(not ConstraintSet.range(Never, T, Sub).satisfied_by_all_typevars())
|
||||||
|
|
||||||
# (T = Base) and (T = Unrelated) both satisfy (T ≤ Super ∨ T ≤ Unrelated).
|
# (T = Base) and (T = Unrelated) both satisfy (T ≤ Super ∨ T ≤ Unrelated).
|
||||||
constraints = ConstraintSet.range(Never, T, Super) | ConstraintSet.range(Never, T, Unrelated)
|
constraints = ConstraintSet.range(Never, T, Super) | ConstraintSet.range(Never, T, Unrelated)
|
||||||
static_assert(constraints.satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(constraints.with_inferable(T).satisfied_by_all_typevars())
|
||||||
static_assert(constraints.satisfied_by_all_typevars())
|
static_assert(constraints.satisfied_by_all_typevars())
|
||||||
|
|
||||||
# (T = Base) and (T = Unrelated) both satisfy (T ≤ Base ∨ T ≤ Unrelated).
|
# (T = Base) and (T = Unrelated) both satisfy (T ≤ Base ∨ T ≤ Unrelated).
|
||||||
constraints = ConstraintSet.range(Never, T, Base) | ConstraintSet.range(Never, T, Unrelated)
|
constraints = ConstraintSet.range(Never, T, Base) | ConstraintSet.range(Never, T, Unrelated)
|
||||||
static_assert(constraints.satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(constraints.with_inferable(T).satisfied_by_all_typevars())
|
||||||
static_assert(constraints.satisfied_by_all_typevars())
|
static_assert(constraints.satisfied_by_all_typevars())
|
||||||
|
|
||||||
# (T = Unrelated) is a valid specialization, which satisfies (T ≤ Sub ∨ T ≤ Unrelated).
|
# (T = Unrelated) is a valid specialization, which satisfies (T ≤ Sub ∨ T ≤ Unrelated).
|
||||||
constraints = ConstraintSet.range(Never, T, Sub) | ConstraintSet.range(Never, T, Unrelated)
|
constraints = ConstraintSet.range(Never, T, Sub) | ConstraintSet.range(Never, T, Unrelated)
|
||||||
static_assert(constraints.satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(constraints.with_inferable(T).satisfied_by_all_typevars())
|
||||||
# (T = Base) is a valid specialization, which does not satisfy (T ≤ Sub ∨ T ≤ Unrelated).
|
# (T = Base) is a valid specialization, which does not satisfy (T ≤ Sub ∨ T ≤ Unrelated).
|
||||||
static_assert(not constraints.satisfied_by_all_typevars())
|
static_assert(not constraints.satisfied_by_all_typevars())
|
||||||
|
|
||||||
# (T = Unrelated) is a valid specialization, which satisfies (T = Super ∨ T = Unrelated).
|
# (T = Unrelated) is a valid specialization, which satisfies (T = Super ∨ T = Unrelated).
|
||||||
constraints = ConstraintSet.range(Super, T, Super) | ConstraintSet.range(Unrelated, T, Unrelated)
|
constraints = ConstraintSet.range(Super, T, Super) | ConstraintSet.range(Unrelated, T, Unrelated)
|
||||||
static_assert(constraints.satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(constraints.with_inferable(T).satisfied_by_all_typevars())
|
||||||
# (T = Base) is a valid specialization, which does not satisfy (T = Super ∨ T = Unrelated).
|
# (T = Base) is a valid specialization, which does not satisfy (T = Super ∨ T = Unrelated).
|
||||||
static_assert(not constraints.satisfied_by_all_typevars())
|
static_assert(not constraints.satisfied_by_all_typevars())
|
||||||
|
|
||||||
# (T = Base) and (T = Unrelated) both satisfy (T = Base ∨ T = Unrelated).
|
# (T = Base) and (T = Unrelated) both satisfy (T = Base ∨ T = Unrelated).
|
||||||
constraints = ConstraintSet.range(Base, T, Base) | ConstraintSet.range(Unrelated, T, Unrelated)
|
constraints = ConstraintSet.range(Base, T, Base) | ConstraintSet.range(Unrelated, T, Unrelated)
|
||||||
static_assert(constraints.satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(constraints.with_inferable(T).satisfied_by_all_typevars())
|
||||||
static_assert(constraints.satisfied_by_all_typevars())
|
static_assert(constraints.satisfied_by_all_typevars())
|
||||||
|
|
||||||
# (T = Unrelated) is a valid specialization, which satisfies (T = Sub ∨ T = Unrelated).
|
# (T = Unrelated) is a valid specialization, which satisfies (T = Sub ∨ T = Unrelated).
|
||||||
constraints = ConstraintSet.range(Sub, T, Sub) | ConstraintSet.range(Unrelated, T, Unrelated)
|
constraints = ConstraintSet.range(Sub, T, Sub) | ConstraintSet.range(Unrelated, T, Unrelated)
|
||||||
static_assert(constraints.satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(constraints.with_inferable(T).satisfied_by_all_typevars())
|
||||||
# (T = Base) is a valid specialization, which does not satisfy (T = Sub ∨ T = Unrelated).
|
# (T = Base) is a valid specialization, which does not satisfy (T = Sub ∨ T = Unrelated).
|
||||||
static_assert(not constraints.satisfied_by_all_typevars())
|
static_assert(not constraints.satisfied_by_all_typevars())
|
||||||
```
|
```
|
||||||
|
|
@ -322,50 +322,50 @@ satisfy the constraint set.
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
def constrained_by_gradual[T: (Base, Any)]():
|
def constrained_by_gradual[T: (Base, Any)]():
|
||||||
static_assert(ConstraintSet.always().satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(ConstraintSet.always().with_inferable(T).satisfied_by_all_typevars())
|
||||||
static_assert(ConstraintSet.always().satisfied_by_all_typevars())
|
static_assert(ConstraintSet.always().satisfied_by_all_typevars())
|
||||||
|
|
||||||
static_assert(not ConstraintSet.never().satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(not ConstraintSet.never().with_inferable(T).satisfied_by_all_typevars())
|
||||||
static_assert(not ConstraintSet.never().satisfied_by_all_typevars())
|
static_assert(not ConstraintSet.never().satisfied_by_all_typevars())
|
||||||
|
|
||||||
# If we choose Unrelated as the materialization of the gradual constraint, then (T = Unrelated)
|
# If we choose Unrelated as the materialization of the gradual constraint, then (T = Unrelated)
|
||||||
# is a valid specialization, which satisfies (T ≤ Unrelated).
|
# is a valid specialization, which satisfies (T ≤ Unrelated).
|
||||||
static_assert(ConstraintSet.range(Never, T, Unrelated).satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(ConstraintSet.range(Never, T, Unrelated).with_inferable(T).satisfied_by_all_typevars())
|
||||||
# No matter which materialization we choose, (T = Base) is a valid specialization, which does
|
# No matter which materialization we choose, (T = Base) is a valid specialization, which does
|
||||||
# not satisfy (T ≤ Unrelated).
|
# not satisfy (T ≤ Unrelated).
|
||||||
static_assert(not ConstraintSet.range(Never, T, Unrelated).satisfied_by_all_typevars())
|
static_assert(not ConstraintSet.range(Never, T, Unrelated).satisfied_by_all_typevars())
|
||||||
|
|
||||||
# If we choose Super as the materialization, then (T = Super) is a valid specialization, which
|
# If we choose Super as the materialization, then (T = Super) is a valid specialization, which
|
||||||
# satisfies (T ≤ Super).
|
# satisfies (T ≤ Super).
|
||||||
static_assert(ConstraintSet.range(Never, T, Super).satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(ConstraintSet.range(Never, T, Super).with_inferable(T).satisfied_by_all_typevars())
|
||||||
# If we choose Never as the materialization, then (T = Base) and (T = Never) are the only valid
|
# If we choose Never as the materialization, then (T = Base) and (T = Never) are the only valid
|
||||||
# specializations, both of which satisfy (T ≤ Super).
|
# specializations, both of which satisfy (T ≤ Super).
|
||||||
static_assert(ConstraintSet.range(Never, T, Super).satisfied_by_all_typevars())
|
static_assert(ConstraintSet.range(Never, T, Super).satisfied_by_all_typevars())
|
||||||
|
|
||||||
# If we choose Base as the materialization, then (T = Base) is a valid specialization, which
|
# If we choose Base as the materialization, then (T = Base) is a valid specialization, which
|
||||||
# satisfies (T ≤ Base).
|
# satisfies (T ≤ Base).
|
||||||
static_assert(ConstraintSet.range(Never, T, Base).satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(ConstraintSet.range(Never, T, Base).with_inferable(T).satisfied_by_all_typevars())
|
||||||
# If we choose Never as the materialization, then (T = Base) and (T = Never) are the only valid
|
# If we choose Never as the materialization, then (T = Base) and (T = Never) are the only valid
|
||||||
# specializations, both of which satisfy (T ≤ Base).
|
# specializations, both of which satisfy (T ≤ Base).
|
||||||
static_assert(ConstraintSet.range(Never, T, Base).satisfied_by_all_typevars())
|
static_assert(ConstraintSet.range(Never, T, Base).satisfied_by_all_typevars())
|
||||||
|
|
||||||
def constrained_by_two_gradual[T: (Any, Any)]():
|
def constrained_by_two_gradual[T: (Any, Any)]():
|
||||||
static_assert(ConstraintSet.always().satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(ConstraintSet.always().with_inferable(T).satisfied_by_all_typevars())
|
||||||
static_assert(ConstraintSet.always().satisfied_by_all_typevars())
|
static_assert(ConstraintSet.always().satisfied_by_all_typevars())
|
||||||
|
|
||||||
static_assert(not ConstraintSet.never().satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(not ConstraintSet.never().with_inferable(T).satisfied_by_all_typevars())
|
||||||
static_assert(not ConstraintSet.never().satisfied_by_all_typevars())
|
static_assert(not ConstraintSet.never().satisfied_by_all_typevars())
|
||||||
|
|
||||||
# If we choose Unrelated as the materialization of either constraint, then (T = Unrelated) is a
|
# If we choose Unrelated as the materialization of either constraint, then (T = Unrelated) is a
|
||||||
# valid specialization, which satisfies (T ≤ Unrelated).
|
# valid specialization, which satisfies (T ≤ Unrelated).
|
||||||
static_assert(ConstraintSet.range(Never, T, Unrelated).satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(ConstraintSet.range(Never, T, Unrelated).with_inferable(T).satisfied_by_all_typevars())
|
||||||
# If we choose Unrelated as the materialization of both constraints, then (T = Unrelated) is the
|
# If we choose Unrelated as the materialization of both constraints, then (T = Unrelated) is the
|
||||||
# only valid specialization, which satisfies (T ≤ Unrelated).
|
# only valid specialization, which satisfies (T ≤ Unrelated).
|
||||||
static_assert(ConstraintSet.range(Never, T, Unrelated).satisfied_by_all_typevars())
|
static_assert(ConstraintSet.range(Never, T, Unrelated).satisfied_by_all_typevars())
|
||||||
|
|
||||||
# If we choose Base as the materialization of either constraint, then (T = Base) is a valid
|
# If we choose Base as the materialization of either constraint, then (T = Base) is a valid
|
||||||
# specialization, which satisfies (T ≤ Base).
|
# specialization, which satisfies (T ≤ Base).
|
||||||
static_assert(ConstraintSet.range(Never, T, Base).satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(ConstraintSet.range(Never, T, Base).with_inferable(T).satisfied_by_all_typevars())
|
||||||
# If we choose Never as the materialization of both constraints, then (T = Never) is the only
|
# If we choose Never as the materialization of both constraints, then (T = Never) is the only
|
||||||
# valid specialization, which satisfies (T ≤ Base).
|
# valid specialization, which satisfies (T ≤ Base).
|
||||||
static_assert(ConstraintSet.range(Never, T, Base).satisfied_by_all_typevars())
|
static_assert(ConstraintSet.range(Never, T, Base).satisfied_by_all_typevars())
|
||||||
|
|
@ -379,35 +379,35 @@ restrictive variance (i.e., invariance), but we get the same results for other v
|
||||||
|
|
||||||
```py
|
```py
|
||||||
def constrained_by_gradual[T: (list[Base], list[Any])]():
|
def constrained_by_gradual[T: (list[Base], list[Any])]():
|
||||||
static_assert(ConstraintSet.always().satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(ConstraintSet.always().with_inferable(T).satisfied_by_all_typevars())
|
||||||
static_assert(ConstraintSet.always().satisfied_by_all_typevars())
|
static_assert(ConstraintSet.always().satisfied_by_all_typevars())
|
||||||
|
|
||||||
static_assert(not ConstraintSet.never().satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(not ConstraintSet.never().with_inferable(T).satisfied_by_all_typevars())
|
||||||
static_assert(not ConstraintSet.never().satisfied_by_all_typevars())
|
static_assert(not ConstraintSet.never().satisfied_by_all_typevars())
|
||||||
|
|
||||||
# No matter which materialization we choose, every valid specialization will be of the form
|
# No matter which materialization we choose, every valid specialization will be of the form
|
||||||
# (T = list[X]). Because Unrelated is final, it is disjoint from all lists. There is therefore
|
# (T = list[X]). Because Unrelated is final, it is disjoint from all lists. There is therefore
|
||||||
# no materialization or specialization that satisfies (T ≤ Unrelated).
|
# no materialization or specialization that satisfies (T ≤ Unrelated).
|
||||||
static_assert(not ConstraintSet.range(Never, T, Unrelated).satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(not ConstraintSet.range(Never, T, Unrelated).with_inferable(T).satisfied_by_all_typevars())
|
||||||
static_assert(not ConstraintSet.range(Never, T, Unrelated).satisfied_by_all_typevars())
|
static_assert(not ConstraintSet.range(Never, T, Unrelated).satisfied_by_all_typevars())
|
||||||
|
|
||||||
# If we choose list[Super] as the materialization, then (T = list[Super]) is a valid
|
# If we choose list[Super] as the materialization, then (T = list[Super]) is a valid
|
||||||
# specialization, which satisfies (T ≤ list[Super]).
|
# specialization, which satisfies (T ≤ list[Super]).
|
||||||
static_assert(ConstraintSet.range(Never, T, list[Super]).satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(ConstraintSet.range(Never, T, list[Super]).with_inferable(T).satisfied_by_all_typevars())
|
||||||
# No matter which materialization we choose, (T = list[Base]) is a valid specialization, which
|
# No matter which materialization we choose, (T = list[Base]) is a valid specialization, which
|
||||||
# does not satisfy (T ≤ list[Super]).
|
# does not satisfy (T ≤ list[Super]).
|
||||||
static_assert(not ConstraintSet.range(Never, T, list[Super]).satisfied_by_all_typevars())
|
static_assert(not ConstraintSet.range(Never, T, list[Super]).satisfied_by_all_typevars())
|
||||||
|
|
||||||
# If we choose list[Base] as the materialization, then (T = list[Base]) is a valid
|
# If we choose list[Base] as the materialization, then (T = list[Base]) is a valid
|
||||||
# specialization, which satisfies (T ≤ list[Base]).
|
# specialization, which satisfies (T ≤ list[Base]).
|
||||||
static_assert(ConstraintSet.range(Never, T, list[Base]).satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(ConstraintSet.range(Never, T, list[Base]).with_inferable(T).satisfied_by_all_typevars())
|
||||||
# If we choose list[Base] as the materialization, then all valid specializations must satisfy
|
# If we choose list[Base] as the materialization, then all valid specializations must satisfy
|
||||||
# (T ≤ list[Base]).
|
# (T ≤ list[Base]).
|
||||||
static_assert(ConstraintSet.range(Never, T, list[Base]).satisfied_by_all_typevars())
|
static_assert(ConstraintSet.range(Never, T, list[Base]).satisfied_by_all_typevars())
|
||||||
|
|
||||||
# If we choose list[Sub] as the materialization, then (T = list[Sub]) is a valid specialization,
|
# If we choose list[Sub] as the materialization, then (T = list[Sub]) is a valid specialization,
|
||||||
# which # satisfies (T ≤ list[Sub]).
|
# which # satisfies (T ≤ list[Sub]).
|
||||||
static_assert(ConstraintSet.range(Never, T, list[Sub]).satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(ConstraintSet.range(Never, T, list[Sub]).with_inferable(T).satisfied_by_all_typevars())
|
||||||
# No matter which materialization we choose, (T = list[Base]) is a valid specialization, which
|
# No matter which materialization we choose, (T = list[Base]) is a valid specialization, which
|
||||||
# does not satisfy (T ≤ list[Sub]).
|
# does not satisfy (T ≤ list[Sub]).
|
||||||
static_assert(not ConstraintSet.range(Never, T, list[Sub]).satisfied_by_all_typevars())
|
static_assert(not ConstraintSet.range(Never, T, list[Sub]).satisfied_by_all_typevars())
|
||||||
|
|
@ -415,7 +415,7 @@ def constrained_by_gradual[T: (list[Base], list[Any])]():
|
||||||
# If we choose list[Unrelated] as the materialization, then (T = list[Unrelated]) is a valid
|
# If we choose list[Unrelated] as the materialization, then (T = list[Unrelated]) is a valid
|
||||||
# specialization, which satisfies (T ≤ list[Unrelated]).
|
# specialization, which satisfies (T ≤ list[Unrelated]).
|
||||||
constraints = ConstraintSet.range(Never, T, list[Unrelated])
|
constraints = ConstraintSet.range(Never, T, list[Unrelated])
|
||||||
static_assert(constraints.satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(constraints.with_inferable(T).satisfied_by_all_typevars())
|
||||||
# No matter which materialization we choose, (T = list[Base]) is a valid specialization, which
|
# No matter which materialization we choose, (T = list[Base]) is a valid specialization, which
|
||||||
# does not satisfy (T ≤ list[Unrelated]).
|
# does not satisfy (T ≤ list[Unrelated]).
|
||||||
static_assert(not constraints.satisfied_by_all_typevars())
|
static_assert(not constraints.satisfied_by_all_typevars())
|
||||||
|
|
@ -423,42 +423,42 @@ def constrained_by_gradual[T: (list[Base], list[Any])]():
|
||||||
# If we choose list[Unrelated] as the materialization, then (T = list[Unrelated]) is a valid
|
# If we choose list[Unrelated] as the materialization, then (T = list[Unrelated]) is a valid
|
||||||
# specialization, which satisfies (T ≤ list[Unrelated] ∧ T ≠ Never).
|
# specialization, which satisfies (T ≤ list[Unrelated] ∧ T ≠ Never).
|
||||||
constraints = constraints & ~ConstraintSet.range(Never, T, Never)
|
constraints = constraints & ~ConstraintSet.range(Never, T, Never)
|
||||||
static_assert(constraints.satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(constraints.with_inferable(T).satisfied_by_all_typevars())
|
||||||
# There is no materialization that we can choose to satisfy this constraint set in non-inferable
|
# There is no materialization that we can choose to satisfy this constraint set in non-inferable
|
||||||
# position. (T = Never) will be a valid assignment no matter what, and that does not satisfy
|
# position. (T = Never) will be a valid assignment no matter what, and that does not satisfy
|
||||||
# (T ≤ list[Unrelated] ∧ T ≠ Never).
|
# (T ≤ list[Unrelated] ∧ T ≠ Never).
|
||||||
static_assert(not constraints.satisfied_by_all_typevars())
|
static_assert(not constraints.satisfied_by_all_typevars())
|
||||||
|
|
||||||
def constrained_by_two_gradual[T: (list[Any], list[Any])]():
|
def constrained_by_two_gradual[T: (list[Any], list[Any])]():
|
||||||
static_assert(ConstraintSet.always().satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(ConstraintSet.always().with_inferable(T).satisfied_by_all_typevars())
|
||||||
static_assert(ConstraintSet.always().satisfied_by_all_typevars())
|
static_assert(ConstraintSet.always().satisfied_by_all_typevars())
|
||||||
|
|
||||||
static_assert(not ConstraintSet.never().satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(not ConstraintSet.never().with_inferable(T).satisfied_by_all_typevars())
|
||||||
static_assert(not ConstraintSet.never().satisfied_by_all_typevars())
|
static_assert(not ConstraintSet.never().satisfied_by_all_typevars())
|
||||||
|
|
||||||
# No matter which materialization we choose, every valid specialization will be of the form
|
# No matter which materialization we choose, every valid specialization will be of the form
|
||||||
# (T = list[X]). Because Unrelated is final, it is disjoint from all lists. There is therefore
|
# (T = list[X]). Because Unrelated is final, it is disjoint from all lists. There is therefore
|
||||||
# no materialization or specialization that satisfies (T ≤ Unrelated).
|
# no materialization or specialization that satisfies (T ≤ Unrelated).
|
||||||
static_assert(not ConstraintSet.range(Never, T, Unrelated).satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(not ConstraintSet.range(Never, T, Unrelated).with_inferable(T).satisfied_by_all_typevars())
|
||||||
static_assert(not ConstraintSet.range(Never, T, Unrelated).satisfied_by_all_typevars())
|
static_assert(not ConstraintSet.range(Never, T, Unrelated).satisfied_by_all_typevars())
|
||||||
|
|
||||||
# If we choose list[Super] as the materialization, then (T = list[Super]) is a valid
|
# If we choose list[Super] as the materialization, then (T = list[Super]) is a valid
|
||||||
# specialization, which satisfies (T ≤ list[Super]).
|
# specialization, which satisfies (T ≤ list[Super]).
|
||||||
static_assert(ConstraintSet.range(Never, T, list[Super]).satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(ConstraintSet.range(Never, T, list[Super]).with_inferable(T).satisfied_by_all_typevars())
|
||||||
# No matter which materialization we choose, (T = list[Base]) is a valid specialization, which
|
# No matter which materialization we choose, (T = list[Base]) is a valid specialization, which
|
||||||
# does not satisfy (T ≤ list[Super]).
|
# does not satisfy (T ≤ list[Super]).
|
||||||
static_assert(ConstraintSet.range(Never, T, list[Super]).satisfied_by_all_typevars())
|
static_assert(ConstraintSet.range(Never, T, list[Super]).satisfied_by_all_typevars())
|
||||||
|
|
||||||
# If we choose list[Base] as the materialization, then (T = list[Base]) is a valid
|
# If we choose list[Base] as the materialization, then (T = list[Base]) is a valid
|
||||||
# specialization, which satisfies (T ≤ list[Base]).
|
# specialization, which satisfies (T ≤ list[Base]).
|
||||||
static_assert(ConstraintSet.range(Never, T, list[Base]).satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(ConstraintSet.range(Never, T, list[Base]).with_inferable(T).satisfied_by_all_typevars())
|
||||||
# If we choose Base as the materialization, then all valid specializations must satisfy
|
# If we choose Base as the materialization, then all valid specializations must satisfy
|
||||||
# (T ≤ list[Base]).
|
# (T ≤ list[Base]).
|
||||||
static_assert(ConstraintSet.range(Never, T, list[Base]).satisfied_by_all_typevars())
|
static_assert(ConstraintSet.range(Never, T, list[Base]).satisfied_by_all_typevars())
|
||||||
|
|
||||||
# If we choose list[Sub] as the materialization, then (T = list[Sub]) is a valid specialization,
|
# If we choose list[Sub] as the materialization, then (T = list[Sub]) is a valid specialization,
|
||||||
# which satisfies (T ≤ list[Sub]).
|
# which satisfies (T ≤ list[Sub]).
|
||||||
static_assert(ConstraintSet.range(Never, T, list[Sub]).satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(ConstraintSet.range(Never, T, list[Sub]).with_inferable(T).satisfied_by_all_typevars())
|
||||||
# No matter which materialization we choose, (T = list[Base]) is a valid specialization, which
|
# No matter which materialization we choose, (T = list[Base]) is a valid specialization, which
|
||||||
# does not satisfy (T ≤ list[Sub]).
|
# does not satisfy (T ≤ list[Sub]).
|
||||||
static_assert(ConstraintSet.range(Never, T, list[Sub]).satisfied_by_all_typevars())
|
static_assert(ConstraintSet.range(Never, T, list[Sub]).satisfied_by_all_typevars())
|
||||||
|
|
@ -466,7 +466,7 @@ def constrained_by_two_gradual[T: (list[Any], list[Any])]():
|
||||||
# If we choose list[Unrelated] as the materialization, then (T = list[Unrelated]) is a valid
|
# If we choose list[Unrelated] as the materialization, then (T = list[Unrelated]) is a valid
|
||||||
# specialization, which satisfies (T ≤ list[Unrelated]).
|
# specialization, which satisfies (T ≤ list[Unrelated]).
|
||||||
constraints = ConstraintSet.range(Never, T, list[Unrelated])
|
constraints = ConstraintSet.range(Never, T, list[Unrelated])
|
||||||
static_assert(constraints.satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(constraints.with_inferable(T).satisfied_by_all_typevars())
|
||||||
# No matter which materialization we choose, (T = list[Base]) is a valid specialization, which
|
# No matter which materialization we choose, (T = list[Base]) is a valid specialization, which
|
||||||
# does not satisfy (T ≤ list[Unrelated]).
|
# does not satisfy (T ≤ list[Unrelated]).
|
||||||
static_assert(constraints.satisfied_by_all_typevars())
|
static_assert(constraints.satisfied_by_all_typevars())
|
||||||
|
|
@ -474,7 +474,7 @@ def constrained_by_two_gradual[T: (list[Any], list[Any])]():
|
||||||
# If we choose list[Unrelated] as the materialization, then (T = list[Unrelated]) is a valid
|
# If we choose list[Unrelated] as the materialization, then (T = list[Unrelated]) is a valid
|
||||||
# specialization, which satisfies (T ≤ list[Unrelated] ∧ T ≠ Never).
|
# specialization, which satisfies (T ≤ list[Unrelated] ∧ T ≠ Never).
|
||||||
constraints = constraints & ~ConstraintSet.range(Never, T, Never)
|
constraints = constraints & ~ConstraintSet.range(Never, T, Never)
|
||||||
static_assert(constraints.satisfied_by_all_typevars(inferable=tuple[T]))
|
static_assert(constraints.with_inferable(T).satisfied_by_all_typevars())
|
||||||
# There is no constraint that we can choose to satisfy this constraint set in non-inferable
|
# There is no constraint that we can choose to satisfy this constraint set in non-inferable
|
||||||
# position. (T = Never) will be a valid assignment no matter what, and that does not satisfy
|
# position. (T = Never) will be a valid assignment no matter what, and that does not satisfy
|
||||||
# (T ≤ list[Unrelated] ∧ T ≠ Never).
|
# (T ≤ list[Unrelated] ∧ T ≠ Never).
|
||||||
|
|
|
||||||
|
|
@ -4317,6 +4317,14 @@ impl<'db> Type<'db> {
|
||||||
))
|
))
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
Type::KnownInstance(KnownInstanceType::ConstraintSet(tracked))
|
||||||
|
if name == "with_inferable" =>
|
||||||
|
{
|
||||||
|
Place::bound(Type::KnownBoundMethod(
|
||||||
|
KnownBoundMethodType::ConstraintSetWithInferable(tracked),
|
||||||
|
))
|
||||||
|
.into()
|
||||||
|
}
|
||||||
Type::KnownInstance(KnownInstanceType::ConstraintSet(tracked))
|
Type::KnownInstance(KnownInstanceType::ConstraintSet(tracked))
|
||||||
if name == "implies_subtype_of" =>
|
if name == "implies_subtype_of" =>
|
||||||
{
|
{
|
||||||
|
|
@ -7162,6 +7170,7 @@ impl<'db> Type<'db> {
|
||||||
| KnownBoundMethodType::ConstraintSetRange
|
| KnownBoundMethodType::ConstraintSetRange
|
||||||
| KnownBoundMethodType::ConstraintSetAlways
|
| KnownBoundMethodType::ConstraintSetAlways
|
||||||
| KnownBoundMethodType::ConstraintSetNever
|
| KnownBoundMethodType::ConstraintSetNever
|
||||||
|
| KnownBoundMethodType::ConstraintSetWithInferable(_)
|
||||||
| KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_)
|
| KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_)
|
||||||
| KnownBoundMethodType::ConstraintSetSatisfies(_)
|
| KnownBoundMethodType::ConstraintSetSatisfies(_)
|
||||||
| KnownBoundMethodType::ConstraintSetSatisfiedByAllTypeVars(_)
|
| KnownBoundMethodType::ConstraintSetSatisfiedByAllTypeVars(_)
|
||||||
|
|
@ -7322,6 +7331,7 @@ impl<'db> Type<'db> {
|
||||||
| KnownBoundMethodType::ConstraintSetRange
|
| KnownBoundMethodType::ConstraintSetRange
|
||||||
| KnownBoundMethodType::ConstraintSetAlways
|
| KnownBoundMethodType::ConstraintSetAlways
|
||||||
| KnownBoundMethodType::ConstraintSetNever
|
| KnownBoundMethodType::ConstraintSetNever
|
||||||
|
| KnownBoundMethodType::ConstraintSetWithInferable(_)
|
||||||
| KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_)
|
| KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_)
|
||||||
| KnownBoundMethodType::ConstraintSetSatisfies(_)
|
| KnownBoundMethodType::ConstraintSetSatisfies(_)
|
||||||
| KnownBoundMethodType::ConstraintSetSatisfiedByAllTypeVars(_),
|
| KnownBoundMethodType::ConstraintSetSatisfiedByAllTypeVars(_),
|
||||||
|
|
@ -10780,6 +10790,7 @@ pub enum KnownBoundMethodType<'db> {
|
||||||
ConstraintSetRange,
|
ConstraintSetRange,
|
||||||
ConstraintSetAlways,
|
ConstraintSetAlways,
|
||||||
ConstraintSetNever,
|
ConstraintSetNever,
|
||||||
|
ConstraintSetWithInferable(TrackedConstraintSet<'db>),
|
||||||
ConstraintSetImpliesSubtypeOf(TrackedConstraintSet<'db>),
|
ConstraintSetImpliesSubtypeOf(TrackedConstraintSet<'db>),
|
||||||
ConstraintSetSatisfies(TrackedConstraintSet<'db>),
|
ConstraintSetSatisfies(TrackedConstraintSet<'db>),
|
||||||
ConstraintSetSatisfiedByAllTypeVars(TrackedConstraintSet<'db>),
|
ConstraintSetSatisfiedByAllTypeVars(TrackedConstraintSet<'db>),
|
||||||
|
|
@ -10810,6 +10821,7 @@ pub(super) fn walk_method_wrapper_type<'db, V: visitor::TypeVisitor<'db> + ?Size
|
||||||
| KnownBoundMethodType::ConstraintSetRange
|
| KnownBoundMethodType::ConstraintSetRange
|
||||||
| KnownBoundMethodType::ConstraintSetAlways
|
| KnownBoundMethodType::ConstraintSetAlways
|
||||||
| KnownBoundMethodType::ConstraintSetNever
|
| KnownBoundMethodType::ConstraintSetNever
|
||||||
|
| KnownBoundMethodType::ConstraintSetWithInferable(_)
|
||||||
| KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_)
|
| KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_)
|
||||||
| KnownBoundMethodType::ConstraintSetSatisfies(_)
|
| KnownBoundMethodType::ConstraintSetSatisfies(_)
|
||||||
| KnownBoundMethodType::ConstraintSetSatisfiedByAllTypeVars(_) => {}
|
| KnownBoundMethodType::ConstraintSetSatisfiedByAllTypeVars(_) => {}
|
||||||
|
|
@ -10877,6 +10889,10 @@ impl<'db> KnownBoundMethodType<'db> {
|
||||||
KnownBoundMethodType::ConstraintSetNever,
|
KnownBoundMethodType::ConstraintSetNever,
|
||||||
KnownBoundMethodType::ConstraintSetNever,
|
KnownBoundMethodType::ConstraintSetNever,
|
||||||
)
|
)
|
||||||
|
| (
|
||||||
|
KnownBoundMethodType::ConstraintSetWithInferable(_),
|
||||||
|
KnownBoundMethodType::ConstraintSetWithInferable(_),
|
||||||
|
)
|
||||||
| (
|
| (
|
||||||
KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_),
|
KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_),
|
||||||
KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_),
|
KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_),
|
||||||
|
|
@ -10900,6 +10916,7 @@ impl<'db> KnownBoundMethodType<'db> {
|
||||||
| KnownBoundMethodType::ConstraintSetRange
|
| KnownBoundMethodType::ConstraintSetRange
|
||||||
| KnownBoundMethodType::ConstraintSetAlways
|
| KnownBoundMethodType::ConstraintSetAlways
|
||||||
| KnownBoundMethodType::ConstraintSetNever
|
| KnownBoundMethodType::ConstraintSetNever
|
||||||
|
| KnownBoundMethodType::ConstraintSetWithInferable(_)
|
||||||
| KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_)
|
| KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_)
|
||||||
| KnownBoundMethodType::ConstraintSetSatisfies(_)
|
| KnownBoundMethodType::ConstraintSetSatisfies(_)
|
||||||
| KnownBoundMethodType::ConstraintSetSatisfiedByAllTypeVars(_),
|
| KnownBoundMethodType::ConstraintSetSatisfiedByAllTypeVars(_),
|
||||||
|
|
@ -10912,6 +10929,7 @@ impl<'db> KnownBoundMethodType<'db> {
|
||||||
| KnownBoundMethodType::ConstraintSetRange
|
| KnownBoundMethodType::ConstraintSetRange
|
||||||
| KnownBoundMethodType::ConstraintSetAlways
|
| KnownBoundMethodType::ConstraintSetAlways
|
||||||
| KnownBoundMethodType::ConstraintSetNever
|
| KnownBoundMethodType::ConstraintSetNever
|
||||||
|
| KnownBoundMethodType::ConstraintSetWithInferable(_)
|
||||||
| KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_)
|
| KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_)
|
||||||
| KnownBoundMethodType::ConstraintSetSatisfies(_)
|
| KnownBoundMethodType::ConstraintSetSatisfies(_)
|
||||||
| KnownBoundMethodType::ConstraintSetSatisfiedByAllTypeVars(_),
|
| KnownBoundMethodType::ConstraintSetSatisfiedByAllTypeVars(_),
|
||||||
|
|
@ -10965,6 +10983,10 @@ impl<'db> KnownBoundMethodType<'db> {
|
||||||
) => ConstraintSet::from(true),
|
) => ConstraintSet::from(true),
|
||||||
|
|
||||||
(
|
(
|
||||||
|
KnownBoundMethodType::ConstraintSetWithInferable(left_constraints),
|
||||||
|
KnownBoundMethodType::ConstraintSetWithInferable(right_constraints),
|
||||||
|
)
|
||||||
|
| (
|
||||||
KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(left_constraints),
|
KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(left_constraints),
|
||||||
KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(right_constraints),
|
KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(right_constraints),
|
||||||
)
|
)
|
||||||
|
|
@ -10989,6 +11011,7 @@ impl<'db> KnownBoundMethodType<'db> {
|
||||||
| KnownBoundMethodType::ConstraintSetRange
|
| KnownBoundMethodType::ConstraintSetRange
|
||||||
| KnownBoundMethodType::ConstraintSetAlways
|
| KnownBoundMethodType::ConstraintSetAlways
|
||||||
| KnownBoundMethodType::ConstraintSetNever
|
| KnownBoundMethodType::ConstraintSetNever
|
||||||
|
| KnownBoundMethodType::ConstraintSetWithInferable(_)
|
||||||
| KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_)
|
| KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_)
|
||||||
| KnownBoundMethodType::ConstraintSetSatisfies(_)
|
| KnownBoundMethodType::ConstraintSetSatisfies(_)
|
||||||
| KnownBoundMethodType::ConstraintSetSatisfiedByAllTypeVars(_),
|
| KnownBoundMethodType::ConstraintSetSatisfiedByAllTypeVars(_),
|
||||||
|
|
@ -11001,6 +11024,7 @@ impl<'db> KnownBoundMethodType<'db> {
|
||||||
| KnownBoundMethodType::ConstraintSetRange
|
| KnownBoundMethodType::ConstraintSetRange
|
||||||
| KnownBoundMethodType::ConstraintSetAlways
|
| KnownBoundMethodType::ConstraintSetAlways
|
||||||
| KnownBoundMethodType::ConstraintSetNever
|
| KnownBoundMethodType::ConstraintSetNever
|
||||||
|
| KnownBoundMethodType::ConstraintSetWithInferable(_)
|
||||||
| KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_)
|
| KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_)
|
||||||
| KnownBoundMethodType::ConstraintSetSatisfies(_)
|
| KnownBoundMethodType::ConstraintSetSatisfies(_)
|
||||||
| KnownBoundMethodType::ConstraintSetSatisfiedByAllTypeVars(_),
|
| KnownBoundMethodType::ConstraintSetSatisfiedByAllTypeVars(_),
|
||||||
|
|
@ -11027,6 +11051,7 @@ impl<'db> KnownBoundMethodType<'db> {
|
||||||
| KnownBoundMethodType::ConstraintSetRange
|
| KnownBoundMethodType::ConstraintSetRange
|
||||||
| KnownBoundMethodType::ConstraintSetAlways
|
| KnownBoundMethodType::ConstraintSetAlways
|
||||||
| KnownBoundMethodType::ConstraintSetNever
|
| KnownBoundMethodType::ConstraintSetNever
|
||||||
|
| KnownBoundMethodType::ConstraintSetWithInferable(_)
|
||||||
| KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_)
|
| KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_)
|
||||||
| KnownBoundMethodType::ConstraintSetSatisfies(_)
|
| KnownBoundMethodType::ConstraintSetSatisfies(_)
|
||||||
| KnownBoundMethodType::ConstraintSetSatisfiedByAllTypeVars(_) => self,
|
| KnownBoundMethodType::ConstraintSetSatisfiedByAllTypeVars(_) => self,
|
||||||
|
|
@ -11045,6 +11070,7 @@ impl<'db> KnownBoundMethodType<'db> {
|
||||||
KnownBoundMethodType::ConstraintSetRange
|
KnownBoundMethodType::ConstraintSetRange
|
||||||
| KnownBoundMethodType::ConstraintSetAlways
|
| KnownBoundMethodType::ConstraintSetAlways
|
||||||
| KnownBoundMethodType::ConstraintSetNever
|
| KnownBoundMethodType::ConstraintSetNever
|
||||||
|
| KnownBoundMethodType::ConstraintSetWithInferable(_)
|
||||||
| KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_)
|
| KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_)
|
||||||
| KnownBoundMethodType::ConstraintSetSatisfies(_)
|
| KnownBoundMethodType::ConstraintSetSatisfies(_)
|
||||||
| KnownBoundMethodType::ConstraintSetSatisfiedByAllTypeVars(_) => {
|
| KnownBoundMethodType::ConstraintSetSatisfiedByAllTypeVars(_) => {
|
||||||
|
|
@ -11175,6 +11201,15 @@ impl<'db> KnownBoundMethodType<'db> {
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KnownBoundMethodType::ConstraintSetWithInferable(_) => {
|
||||||
|
Either::Right(std::iter::once(Signature::new(
|
||||||
|
Parameters::new([Parameter::variadic(Name::new_static("inferable"))
|
||||||
|
.type_form()
|
||||||
|
.with_annotated_type(Type::any())]),
|
||||||
|
Some(KnownClass::ConstraintSet.to_instance(db)),
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
|
||||||
KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_) => {
|
KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_) => {
|
||||||
Either::Right(std::iter::once(Signature::new(
|
Either::Right(std::iter::once(Signature::new(
|
||||||
Parameters::new([
|
Parameters::new([
|
||||||
|
|
@ -11199,13 +11234,7 @@ impl<'db> KnownBoundMethodType<'db> {
|
||||||
|
|
||||||
KnownBoundMethodType::ConstraintSetSatisfiedByAllTypeVars(_) => {
|
KnownBoundMethodType::ConstraintSetSatisfiedByAllTypeVars(_) => {
|
||||||
Either::Right(std::iter::once(Signature::new(
|
Either::Right(std::iter::once(Signature::new(
|
||||||
Parameters::new([Parameter::keyword_only(Name::new_static("inferable"))
|
Parameters::empty(),
|
||||||
.type_form()
|
|
||||||
.with_annotated_type(UnionType::from_elements(
|
|
||||||
db,
|
|
||||||
[Type::homogeneous_tuple(db, Type::any()), Type::none(db)],
|
|
||||||
))
|
|
||||||
.with_default_type(Type::none(db))]),
|
|
||||||
Some(KnownClass::Bool.to_instance(db)),
|
Some(KnownClass::Bool.to_instance(db)),
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,9 +36,9 @@ use crate::types::tuple::{TupleLength, TupleType};
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
BoundMethodType, BoundTypeVarIdentity, ClassLiteral, DataclassFlags, DataclassParams,
|
BoundMethodType, BoundTypeVarIdentity, ClassLiteral, DataclassFlags, DataclassParams,
|
||||||
FieldInstance, KnownBoundMethodType, KnownClass, KnownInstanceType, MemberLookupPolicy,
|
FieldInstance, KnownBoundMethodType, KnownClass, KnownInstanceType, MemberLookupPolicy,
|
||||||
NominalInstanceType, PropertyInstanceType, SpecialFormType, TrackedConstraintSet,
|
PropertyInstanceType, SpecialFormType, TrackedConstraintSet, TypeAliasType, TypeContext,
|
||||||
TypeAliasType, TypeContext, UnionBuilder, UnionType, WrapperDescriptorKind, enums, ide_support,
|
UnionBuilder, UnionType, WrapperDescriptorKind, enums, ide_support, infer_isolated_expression,
|
||||||
infer_isolated_expression, todo_type,
|
todo_type,
|
||||||
};
|
};
|
||||||
use ruff_db::diagnostic::{Annotation, Diagnostic, SubDiagnostic, SubDiagnosticSeverity};
|
use ruff_db::diagnostic::{Annotation, Diagnostic, SubDiagnostic, SubDiagnosticSeverity};
|
||||||
use ruff_python_ast::{self as ast, ArgOrKeyword, PythonVersion};
|
use ruff_python_ast::{self as ast, ArgOrKeyword, PythonVersion};
|
||||||
|
|
@ -181,7 +181,7 @@ impl<'db> Bindings<'db> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.evaluate_known_cases(db, dataclass_field_specifiers);
|
self.evaluate_known_cases(db, argument_types, dataclass_field_specifiers);
|
||||||
|
|
||||||
// In order of precedence:
|
// In order of precedence:
|
||||||
//
|
//
|
||||||
|
|
@ -300,7 +300,12 @@ impl<'db> Bindings<'db> {
|
||||||
|
|
||||||
/// Evaluates the return type of certain known callables, where we have special-case logic to
|
/// Evaluates the return type of certain known callables, where we have special-case logic to
|
||||||
/// determine the return type in a way that isn't directly expressible in the type system.
|
/// determine the return type in a way that isn't directly expressible in the type system.
|
||||||
fn evaluate_known_cases(&mut self, db: &'db dyn Db, dataclass_field_specifiers: &[Type<'db>]) {
|
fn evaluate_known_cases(
|
||||||
|
&mut self,
|
||||||
|
db: &'db dyn Db,
|
||||||
|
argument_types: &CallArguments<'_, 'db>,
|
||||||
|
dataclass_field_specifiers: &[Type<'db>],
|
||||||
|
) {
|
||||||
let to_bool = |ty: &Option<Type<'_>>, default: bool| -> bool {
|
let to_bool = |ty: &Option<Type<'_>>, default: bool| -> bool {
|
||||||
if let Some(Type::BooleanLiteral(value)) = ty {
|
if let Some(Type::BooleanLiteral(value)) = ty {
|
||||||
*value
|
*value
|
||||||
|
|
@ -1177,6 +1182,33 @@ impl<'db> Bindings<'db> {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Type::KnownBoundMethod(KnownBoundMethodType::ConstraintSetWithInferable(
|
||||||
|
tracked,
|
||||||
|
)) => {
|
||||||
|
let mut any_invalid = false;
|
||||||
|
let inferable = InferableTypeVars::from_bound_typevars(
|
||||||
|
db,
|
||||||
|
overload
|
||||||
|
.arguments_for_parameter(argument_types, 0)
|
||||||
|
.filter_map(|(_, ty)| {
|
||||||
|
let identity = ty
|
||||||
|
.as_typevar()
|
||||||
|
.map(|bound_typevar| bound_typevar.identity(db));
|
||||||
|
any_invalid |= identity.is_none();
|
||||||
|
identity
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
if any_invalid {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = tracked.constraints(db).with_inferable(inferable);
|
||||||
|
let tracked = TrackedConstraintSet::new(db, result);
|
||||||
|
overload.set_return_type(Type::KnownInstance(
|
||||||
|
KnownInstanceType::ConstraintSet(tracked),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
Type::KnownBoundMethod(
|
Type::KnownBoundMethod(
|
||||||
KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(tracked),
|
KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(tracked),
|
||||||
) => {
|
) => {
|
||||||
|
|
@ -1214,36 +1246,7 @@ impl<'db> Bindings<'db> {
|
||||||
Type::KnownBoundMethod(
|
Type::KnownBoundMethod(
|
||||||
KnownBoundMethodType::ConstraintSetSatisfiedByAllTypeVars(tracked),
|
KnownBoundMethodType::ConstraintSetSatisfiedByAllTypeVars(tracked),
|
||||||
) => {
|
) => {
|
||||||
let extract_inferable = |instance: &NominalInstanceType<'db>| {
|
let result = tracked.constraints(db).satisfied_by_all_typevars(db);
|
||||||
if instance.has_known_class(db, KnownClass::NoneType) {
|
|
||||||
// Caller explicitly passed None, so no typevars are inferable.
|
|
||||||
return Some(InferableTypeVars::none());
|
|
||||||
}
|
|
||||||
Some(InferableTypeVars::from_bound_typevars(
|
|
||||||
db,
|
|
||||||
instance.tuple_spec(db)?.fixed_elements().filter_map(|ty| {
|
|
||||||
ty.as_typevar()
|
|
||||||
.map(|bound_typevar| bound_typevar.identity(db))
|
|
||||||
}),
|
|
||||||
))
|
|
||||||
};
|
|
||||||
|
|
||||||
let inferable = match overload.parameter_types() {
|
|
||||||
// Caller did not provide argument, so no typevars are inferable.
|
|
||||||
[None] => InferableTypeVars::none(),
|
|
||||||
[Some(Type::NominalInstance(instance))] => {
|
|
||||||
match extract_inferable(instance) {
|
|
||||||
Some(inferable) => inferable,
|
|
||||||
None => continue,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => continue,
|
|
||||||
};
|
|
||||||
|
|
||||||
let result = tracked
|
|
||||||
.constraints(db)
|
|
||||||
.with_inferable(inferable)
|
|
||||||
.satisfied_by_all_typevars(db);
|
|
||||||
overload.set_return_type(Type::BooleanLiteral(result));
|
overload.set_return_type(Type::BooleanLiteral(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -532,6 +532,9 @@ impl Display for DisplayRepresentation<'_> {
|
||||||
Type::KnownBoundMethod(KnownBoundMethodType::ConstraintSetNever) => {
|
Type::KnownBoundMethod(KnownBoundMethodType::ConstraintSetNever) => {
|
||||||
f.write_str("bound method `ConstraintSet.never`")
|
f.write_str("bound method `ConstraintSet.never`")
|
||||||
}
|
}
|
||||||
|
Type::KnownBoundMethod(KnownBoundMethodType::ConstraintSetWithInferable(_)) => {
|
||||||
|
f.write_str("bound method `ConstraintSet.with_inferable`")
|
||||||
|
}
|
||||||
Type::KnownBoundMethod(KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_)) => {
|
Type::KnownBoundMethod(KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_)) => {
|
||||||
f.write_str("bound method `ConstraintSet.implies_subtype_of`")
|
f.write_str("bound method `ConstraintSet.implies_subtype_of`")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,12 @@ class ConstraintSet:
|
||||||
def never() -> Self:
|
def never() -> Self:
|
||||||
"""Returns a constraint set that is never satisfied"""
|
"""Returns a constraint set that is never satisfied"""
|
||||||
|
|
||||||
|
def with_inferable(self, *inferable: Any) -> Self:
|
||||||
|
"""
|
||||||
|
Returns a copy of this constraint set with some typevars marked as being
|
||||||
|
in inferable position.
|
||||||
|
"""
|
||||||
|
|
||||||
def implies_subtype_of(self, ty: Any, of: Any) -> Self:
|
def implies_subtype_of(self, ty: Any, of: Any) -> Self:
|
||||||
"""
|
"""
|
||||||
Returns a constraint set that is satisfied when `ty` is a `subtype`_ of
|
Returns a constraint set that is satisfied when `ty` is a `subtype`_ of
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue