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: ...
|
||||
|
||||
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(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())
|
||||
|
||||
# (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).
|
||||
static_assert(not ConstraintSet.range(Never, T, Unrelated).satisfied_by_all_typevars())
|
||||
|
||||
# (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).
|
||||
static_assert(not ConstraintSet.range(Never, T, Super).satisfied_by_all_typevars())
|
||||
|
||||
# (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).
|
||||
static_assert(not ConstraintSet.range(Never, T, Base).satisfied_by_all_typevars())
|
||||
|
||||
# (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).
|
||||
static_assert(not ConstraintSet.range(Never, T, Sub).satisfied_by_all_typevars())
|
||||
```
|
||||
|
|
@ -106,38 +106,38 @@ class Sub(Base): ...
|
|||
class Unrelated: ...
|
||||
|
||||
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(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())
|
||||
|
||||
# (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
|
||||
# specialization also satisfies (T ≤ Super).
|
||||
static_assert(ConstraintSet.range(Never, T, Super).satisfied_by_all_typevars())
|
||||
|
||||
# (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).
|
||||
static_assert(ConstraintSet.range(Never, T, Base).satisfied_by_all_typevars())
|
||||
|
||||
# (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).
|
||||
static_assert(not ConstraintSet.range(Never, T, Sub).satisfied_by_all_typevars())
|
||||
|
||||
# (T = Never) is a valid specialization, which satisfies (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).
|
||||
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
|
||||
# valid specialization that satisfies (T ≤ Unrelated ∧ 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())
|
||||
```
|
||||
|
||||
|
|
@ -153,15 +153,15 @@ the constraint set.
|
|||
from typing import 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(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())
|
||||
|
||||
# If we choose Base as the materialization for the upper bound, then (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())
|
||||
# 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
|
||||
# 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,
|
||||
# which satisfies (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,
|
||||
# which satisfies (T ≤ Unrelated).
|
||||
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,
|
||||
# which satisfies (T ≤ Unrelated ∧ 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
|
||||
# position. (T = Never) will be a valid assignment no matter what, and that does not satisfy
|
||||
# (T ≤ Unrelated ∧ T ≠ Never).
|
||||
|
|
@ -196,15 +196,15 @@ restrictive variance (i.e., invariance), but we get the same results for other v
|
|||
|
||||
```py
|
||||
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(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())
|
||||
|
||||
# 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]).
|
||||
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
|
||||
# (T ≤ list[Base]).
|
||||
# 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
|
||||
# specialization, which satisfies (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
|
||||
# (T ≤ list[Unrelated]).
|
||||
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
|
||||
# specialization, which satisfies (T ≤ list[Unrelated] ∧ 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
|
||||
# position. (T = Never) will be a valid assignment no matter what, and that does not satisfy
|
||||
# (T ≤ list[Unrelated] ∧ T ≠ Never).
|
||||
|
|
@ -251,61 +251,61 @@ class Sub(Base): ...
|
|||
class 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(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())
|
||||
|
||||
# (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).
|
||||
static_assert(not ConstraintSet.range(Never, T, Unrelated).satisfied_by_all_typevars())
|
||||
|
||||
# (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).
|
||||
static_assert(not ConstraintSet.range(Never, T, Super).satisfied_by_all_typevars())
|
||||
|
||||
# (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).
|
||||
static_assert(not ConstraintSet.range(Never, T, Base).satisfied_by_all_typevars())
|
||||
|
||||
# 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())
|
||||
|
||||
# (T = Base) and (T = Unrelated) both satisfy (T ≤ Super ∨ 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())
|
||||
|
||||
# (T = Base) and (T = Unrelated) both satisfy (T ≤ Base ∨ 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())
|
||||
|
||||
# (T = Unrelated) is a valid specialization, which satisfies (T ≤ Sub ∨ 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).
|
||||
static_assert(not constraints.satisfied_by_all_typevars())
|
||||
|
||||
# (T = Unrelated) is a valid specialization, which satisfies (T = Super ∨ 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).
|
||||
static_assert(not constraints.satisfied_by_all_typevars())
|
||||
|
||||
# (T = Base) and (T = Unrelated) both satisfy (T = Base ∨ 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())
|
||||
|
||||
# (T = Unrelated) is a valid specialization, which satisfies (T = Sub ∨ 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).
|
||||
static_assert(not constraints.satisfied_by_all_typevars())
|
||||
```
|
||||
|
|
@ -322,50 +322,50 @@ satisfy the constraint set.
|
|||
from typing import 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(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())
|
||||
|
||||
# If we choose Unrelated as the materialization of the gradual constraint, then (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
|
||||
# not satisfy (T ≤ Unrelated).
|
||||
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
|
||||
# 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
|
||||
# specializations, both of which satisfy (T ≤ Super).
|
||||
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
|
||||
# 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
|
||||
# specializations, both of which satisfy (T ≤ Base).
|
||||
static_assert(ConstraintSet.range(Never, T, Base).satisfied_by_all_typevars())
|
||||
|
||||
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(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())
|
||||
|
||||
# If we choose Unrelated as the materialization of either constraint, then (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())
|
||||
# If we choose Unrelated as the materialization of both constraints, then (T = Unrelated) is the
|
||||
# only valid specialization, which satisfies (T ≤ Unrelated).
|
||||
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
|
||||
# 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
|
||||
# valid specialization, which satisfies (T ≤ Base).
|
||||
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
|
||||
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(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())
|
||||
|
||||
# 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
|
||||
# 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())
|
||||
|
||||
# If we choose list[Super] as the materialization, then (T = list[Super]) is a valid
|
||||
# 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
|
||||
# does not satisfy (T ≤ list[Super]).
|
||||
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
|
||||
# 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
|
||||
# (T ≤ list[Base]).
|
||||
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,
|
||||
# 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
|
||||
# does not satisfy (T ≤ list[Sub]).
|
||||
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
|
||||
# specialization, which satisfies (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
|
||||
# does not satisfy (T ≤ list[Unrelated]).
|
||||
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
|
||||
# specialization, which satisfies (T ≤ list[Unrelated] ∧ 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
|
||||
# position. (T = Never) will be a valid assignment no matter what, and that does not satisfy
|
||||
# (T ≤ list[Unrelated] ∧ T ≠ Never).
|
||||
static_assert(not constraints.satisfied_by_all_typevars())
|
||||
|
||||
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(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())
|
||||
|
||||
# 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
|
||||
# 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())
|
||||
|
||||
# If we choose list[Super] as the materialization, then (T = list[Super]) is a valid
|
||||
# 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
|
||||
# does not satisfy (T ≤ list[Super]).
|
||||
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
|
||||
# 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
|
||||
# (T ≤ list[Base]).
|
||||
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,
|
||||
# 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
|
||||
# does not satisfy (T ≤ list[Sub]).
|
||||
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
|
||||
# specialization, which satisfies (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
|
||||
# does not satisfy (T ≤ list[Unrelated]).
|
||||
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
|
||||
# specialization, which satisfies (T ≤ list[Unrelated] ∧ 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
|
||||
# position. (T = Never) will be a valid assignment no matter what, and that does not satisfy
|
||||
# (T ≤ list[Unrelated] ∧ T ≠ Never).
|
||||
|
|
|
|||
|
|
@ -4317,6 +4317,14 @@ impl<'db> Type<'db> {
|
|||
))
|
||||
.into()
|
||||
}
|
||||
Type::KnownInstance(KnownInstanceType::ConstraintSet(tracked))
|
||||
if name == "with_inferable" =>
|
||||
{
|
||||
Place::bound(Type::KnownBoundMethod(
|
||||
KnownBoundMethodType::ConstraintSetWithInferable(tracked),
|
||||
))
|
||||
.into()
|
||||
}
|
||||
Type::KnownInstance(KnownInstanceType::ConstraintSet(tracked))
|
||||
if name == "implies_subtype_of" =>
|
||||
{
|
||||
|
|
@ -7162,6 +7170,7 @@ impl<'db> Type<'db> {
|
|||
| KnownBoundMethodType::ConstraintSetRange
|
||||
| KnownBoundMethodType::ConstraintSetAlways
|
||||
| KnownBoundMethodType::ConstraintSetNever
|
||||
| KnownBoundMethodType::ConstraintSetWithInferable(_)
|
||||
| KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_)
|
||||
| KnownBoundMethodType::ConstraintSetSatisfies(_)
|
||||
| KnownBoundMethodType::ConstraintSetSatisfiedByAllTypeVars(_)
|
||||
|
|
@ -7322,6 +7331,7 @@ impl<'db> Type<'db> {
|
|||
| KnownBoundMethodType::ConstraintSetRange
|
||||
| KnownBoundMethodType::ConstraintSetAlways
|
||||
| KnownBoundMethodType::ConstraintSetNever
|
||||
| KnownBoundMethodType::ConstraintSetWithInferable(_)
|
||||
| KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_)
|
||||
| KnownBoundMethodType::ConstraintSetSatisfies(_)
|
||||
| KnownBoundMethodType::ConstraintSetSatisfiedByAllTypeVars(_),
|
||||
|
|
@ -10780,6 +10790,7 @@ pub enum KnownBoundMethodType<'db> {
|
|||
ConstraintSetRange,
|
||||
ConstraintSetAlways,
|
||||
ConstraintSetNever,
|
||||
ConstraintSetWithInferable(TrackedConstraintSet<'db>),
|
||||
ConstraintSetImpliesSubtypeOf(TrackedConstraintSet<'db>),
|
||||
ConstraintSetSatisfies(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::ConstraintSetAlways
|
||||
| KnownBoundMethodType::ConstraintSetNever
|
||||
| KnownBoundMethodType::ConstraintSetWithInferable(_)
|
||||
| KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_)
|
||||
| KnownBoundMethodType::ConstraintSetSatisfies(_)
|
||||
| KnownBoundMethodType::ConstraintSetSatisfiedByAllTypeVars(_) => {}
|
||||
|
|
@ -10877,6 +10889,10 @@ impl<'db> KnownBoundMethodType<'db> {
|
|||
KnownBoundMethodType::ConstraintSetNever,
|
||||
KnownBoundMethodType::ConstraintSetNever,
|
||||
)
|
||||
| (
|
||||
KnownBoundMethodType::ConstraintSetWithInferable(_),
|
||||
KnownBoundMethodType::ConstraintSetWithInferable(_),
|
||||
)
|
||||
| (
|
||||
KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_),
|
||||
KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_),
|
||||
|
|
@ -10900,6 +10916,7 @@ impl<'db> KnownBoundMethodType<'db> {
|
|||
| KnownBoundMethodType::ConstraintSetRange
|
||||
| KnownBoundMethodType::ConstraintSetAlways
|
||||
| KnownBoundMethodType::ConstraintSetNever
|
||||
| KnownBoundMethodType::ConstraintSetWithInferable(_)
|
||||
| KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_)
|
||||
| KnownBoundMethodType::ConstraintSetSatisfies(_)
|
||||
| KnownBoundMethodType::ConstraintSetSatisfiedByAllTypeVars(_),
|
||||
|
|
@ -10912,6 +10929,7 @@ impl<'db> KnownBoundMethodType<'db> {
|
|||
| KnownBoundMethodType::ConstraintSetRange
|
||||
| KnownBoundMethodType::ConstraintSetAlways
|
||||
| KnownBoundMethodType::ConstraintSetNever
|
||||
| KnownBoundMethodType::ConstraintSetWithInferable(_)
|
||||
| KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_)
|
||||
| KnownBoundMethodType::ConstraintSetSatisfies(_)
|
||||
| KnownBoundMethodType::ConstraintSetSatisfiedByAllTypeVars(_),
|
||||
|
|
@ -10965,6 +10983,10 @@ impl<'db> KnownBoundMethodType<'db> {
|
|||
) => ConstraintSet::from(true),
|
||||
|
||||
(
|
||||
KnownBoundMethodType::ConstraintSetWithInferable(left_constraints),
|
||||
KnownBoundMethodType::ConstraintSetWithInferable(right_constraints),
|
||||
)
|
||||
| (
|
||||
KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(left_constraints),
|
||||
KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(right_constraints),
|
||||
)
|
||||
|
|
@ -10989,6 +11011,7 @@ impl<'db> KnownBoundMethodType<'db> {
|
|||
| KnownBoundMethodType::ConstraintSetRange
|
||||
| KnownBoundMethodType::ConstraintSetAlways
|
||||
| KnownBoundMethodType::ConstraintSetNever
|
||||
| KnownBoundMethodType::ConstraintSetWithInferable(_)
|
||||
| KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_)
|
||||
| KnownBoundMethodType::ConstraintSetSatisfies(_)
|
||||
| KnownBoundMethodType::ConstraintSetSatisfiedByAllTypeVars(_),
|
||||
|
|
@ -11001,6 +11024,7 @@ impl<'db> KnownBoundMethodType<'db> {
|
|||
| KnownBoundMethodType::ConstraintSetRange
|
||||
| KnownBoundMethodType::ConstraintSetAlways
|
||||
| KnownBoundMethodType::ConstraintSetNever
|
||||
| KnownBoundMethodType::ConstraintSetWithInferable(_)
|
||||
| KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_)
|
||||
| KnownBoundMethodType::ConstraintSetSatisfies(_)
|
||||
| KnownBoundMethodType::ConstraintSetSatisfiedByAllTypeVars(_),
|
||||
|
|
@ -11027,6 +11051,7 @@ impl<'db> KnownBoundMethodType<'db> {
|
|||
| KnownBoundMethodType::ConstraintSetRange
|
||||
| KnownBoundMethodType::ConstraintSetAlways
|
||||
| KnownBoundMethodType::ConstraintSetNever
|
||||
| KnownBoundMethodType::ConstraintSetWithInferable(_)
|
||||
| KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_)
|
||||
| KnownBoundMethodType::ConstraintSetSatisfies(_)
|
||||
| KnownBoundMethodType::ConstraintSetSatisfiedByAllTypeVars(_) => self,
|
||||
|
|
@ -11045,6 +11070,7 @@ impl<'db> KnownBoundMethodType<'db> {
|
|||
KnownBoundMethodType::ConstraintSetRange
|
||||
| KnownBoundMethodType::ConstraintSetAlways
|
||||
| KnownBoundMethodType::ConstraintSetNever
|
||||
| KnownBoundMethodType::ConstraintSetWithInferable(_)
|
||||
| KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_)
|
||||
| KnownBoundMethodType::ConstraintSetSatisfies(_)
|
||||
| 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(_) => {
|
||||
Either::Right(std::iter::once(Signature::new(
|
||||
Parameters::new([
|
||||
|
|
@ -11199,13 +11234,7 @@ impl<'db> KnownBoundMethodType<'db> {
|
|||
|
||||
KnownBoundMethodType::ConstraintSetSatisfiedByAllTypeVars(_) => {
|
||||
Either::Right(std::iter::once(Signature::new(
|
||||
Parameters::new([Parameter::keyword_only(Name::new_static("inferable"))
|
||||
.type_form()
|
||||
.with_annotated_type(UnionType::from_elements(
|
||||
db,
|
||||
[Type::homogeneous_tuple(db, Type::any()), Type::none(db)],
|
||||
))
|
||||
.with_default_type(Type::none(db))]),
|
||||
Parameters::empty(),
|
||||
Some(KnownClass::Bool.to_instance(db)),
|
||||
)))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,9 +36,9 @@ use crate::types::tuple::{TupleLength, TupleType};
|
|||
use crate::types::{
|
||||
BoundMethodType, BoundTypeVarIdentity, ClassLiteral, DataclassFlags, DataclassParams,
|
||||
FieldInstance, KnownBoundMethodType, KnownClass, KnownInstanceType, MemberLookupPolicy,
|
||||
NominalInstanceType, PropertyInstanceType, SpecialFormType, TrackedConstraintSet,
|
||||
TypeAliasType, TypeContext, UnionBuilder, UnionType, WrapperDescriptorKind, enums, ide_support,
|
||||
infer_isolated_expression, todo_type,
|
||||
PropertyInstanceType, SpecialFormType, TrackedConstraintSet, TypeAliasType, TypeContext,
|
||||
UnionBuilder, UnionType, WrapperDescriptorKind, enums, ide_support, infer_isolated_expression,
|
||||
todo_type,
|
||||
};
|
||||
use ruff_db::diagnostic::{Annotation, Diagnostic, SubDiagnostic, SubDiagnosticSeverity};
|
||||
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:
|
||||
//
|
||||
|
|
@ -300,7 +300,12 @@ impl<'db> Bindings<'db> {
|
|||
|
||||
/// 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.
|
||||
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 {
|
||||
if let Some(Type::BooleanLiteral(value)) = ty {
|
||||
*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(
|
||||
KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(tracked),
|
||||
) => {
|
||||
|
|
@ -1214,36 +1246,7 @@ impl<'db> Bindings<'db> {
|
|||
Type::KnownBoundMethod(
|
||||
KnownBoundMethodType::ConstraintSetSatisfiedByAllTypeVars(tracked),
|
||||
) => {
|
||||
let extract_inferable = |instance: &NominalInstanceType<'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);
|
||||
let result = tracked.constraints(db).satisfied_by_all_typevars(db);
|
||||
overload.set_return_type(Type::BooleanLiteral(result));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -532,6 +532,9 @@ impl Display for DisplayRepresentation<'_> {
|
|||
Type::KnownBoundMethod(KnownBoundMethodType::ConstraintSetNever) => {
|
||||
f.write_str("bound method `ConstraintSet.never`")
|
||||
}
|
||||
Type::KnownBoundMethod(KnownBoundMethodType::ConstraintSetWithInferable(_)) => {
|
||||
f.write_str("bound method `ConstraintSet.with_inferable`")
|
||||
}
|
||||
Type::KnownBoundMethod(KnownBoundMethodType::ConstraintSetImpliesSubtypeOf(_)) => {
|
||||
f.write_str("bound method `ConstraintSet.implies_subtype_of`")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,12 @@ class ConstraintSet:
|
|||
def never() -> Self:
|
||||
"""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:
|
||||
"""
|
||||
Returns a constraint set that is satisfied when `ty` is a `subtype`_ of
|
||||
|
|
|
|||
Loading…
Reference in New Issue