use subtyping
This commit is contained in:
@@ -747,12 +747,16 @@ impl<'db> ConstrainedTypeVar<'db> {
|
||||
if !self.typevar(db).is_same_typevar_as(db, other.typevar(db)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Note that we check that the bounds are _subtypes_ of each other, because we do not want
|
||||
// dynamic types like `Any` to be pivots that we can use to compute transitive sequent map
|
||||
// relationships.
|
||||
other
|
||||
.lower(db)
|
||||
.is_constraint_set_assignable_to(db, self.lower(db))
|
||||
.is_constraint_set_subtype_of(db, self.lower(db))
|
||||
&& self
|
||||
.upper(db)
|
||||
.is_constraint_set_assignable_to(db, other.upper(db))
|
||||
.is_constraint_set_subtype_of(db, other.upper(db))
|
||||
}
|
||||
|
||||
/// Returns the intersection of two range constraints, or `None` if the intersection is empty.
|
||||
@@ -763,7 +767,7 @@ impl<'db> ConstrainedTypeVar<'db> {
|
||||
|
||||
// If `lower ≰ upper`, then the intersection is empty, since there is no type that is both
|
||||
// greater than `lower`, and less than `upper`.
|
||||
if !lower.is_constraint_set_assignable_to(db, upper) {
|
||||
if !lower.is_constraint_set_subtype_of(db, upper) {
|
||||
return IntersectionResult::Disjoint;
|
||||
}
|
||||
|
||||
|
||||
@@ -260,15 +260,17 @@ impl<'db> Type<'db> {
|
||||
}
|
||||
|
||||
/// Return true if this type is assignable to type `target` using constraint-set assignability.
|
||||
///
|
||||
/// This uses `TypeRelation::ConstraintSetAssignability`, which encodes typevar relations into
|
||||
/// a constraint set and lets `satisfied_by_all_typevars` perform existential vs universal
|
||||
/// reasoning depending on inferable typevars.
|
||||
pub fn is_constraint_set_assignable_to(self, db: &'db dyn Db, target: Type<'db>) -> bool {
|
||||
self.when_constraint_set_assignable_to(db, target, InferableTypeVars::None)
|
||||
.is_always_satisfied(db)
|
||||
}
|
||||
|
||||
/// Return true if this type is assignable to type `target` using constraint-set assignability.
|
||||
pub fn is_constraint_set_subtype_of(self, db: &'db dyn Db, target: Type<'db>) -> bool {
|
||||
self.when_constraint_set_subtype_of(db, target, InferableTypeVars::None)
|
||||
.is_always_satisfied(db)
|
||||
}
|
||||
|
||||
pub(super) fn when_assignable_to(
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
@@ -297,6 +299,20 @@ impl<'db> Type<'db> {
|
||||
)
|
||||
}
|
||||
|
||||
pub(super) fn when_constraint_set_subtype_of(
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
target: Type<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
self.has_relation_to(
|
||||
db,
|
||||
target,
|
||||
inferable,
|
||||
TypeRelation::Subtyping(UseConstraintSets::Yes),
|
||||
)
|
||||
}
|
||||
|
||||
/// Return `true` if it would be redundant to add `self` to a union that already contains `other`.
|
||||
///
|
||||
/// See [`TypeRelation::Redundancy`] for more details.
|
||||
|
||||
Reference in New Issue
Block a user