Add more fast-paths
This commit is contained in:
@@ -823,23 +823,47 @@ impl<'db> Type<'db> {
|
||||
})
|
||||
}),
|
||||
|
||||
// Fast path for pure negations (~X): these are semantically `object & ~X`, so they're
|
||||
// only assignable to types that `object` is assignable to. Since `object` is only
|
||||
// assignable to `object`, dynamic types, unions/protocols/intersections that might
|
||||
// contain `object`, we can short-circuit most cases directly.
|
||||
(Type::Intersection(intersection), _) if intersection.positive(db).is_empty() => {
|
||||
match target {
|
||||
// `object` is a subtype of `object`
|
||||
_ if target.is_object() => ConstraintSet::from(true),
|
||||
// `object` is a subtype of dynamic types
|
||||
Type::Dynamic(_) => ConstraintSet::from(true),
|
||||
// These cases need more complex checking - delegate to full machinery
|
||||
// (TypeVar needs special handling for inference)
|
||||
Type::Union(_)
|
||||
| Type::ProtocolInstance(_)
|
||||
| Type::Intersection(_)
|
||||
| Type::TypeVar(_) => Type::object().has_relation_to_impl(
|
||||
db,
|
||||
target,
|
||||
inferable,
|
||||
relation,
|
||||
relation_visitor,
|
||||
disjointness_visitor,
|
||||
),
|
||||
// `object` is not a subtype of any other type
|
||||
_ => ConstraintSet::from(false),
|
||||
}
|
||||
}
|
||||
|
||||
(Type::Intersection(intersection), _) => {
|
||||
// An intersection type is a subtype of another type if at least one of its
|
||||
// positive elements is a subtype of that type. If there are no positive elements,
|
||||
// we treat `object` as the implicit positive element (e.g., `~str` is semantically
|
||||
// `object & ~str`).
|
||||
intersection
|
||||
.positive_elements_or_object(db)
|
||||
.when_any(db, |elem_ty| {
|
||||
elem_ty.has_relation_to_impl(
|
||||
db,
|
||||
target,
|
||||
inferable,
|
||||
relation,
|
||||
relation_visitor,
|
||||
disjointness_visitor,
|
||||
)
|
||||
})
|
||||
// positive elements is a subtype of that type.
|
||||
intersection.positive(db).iter().when_any(db, |&elem_ty| {
|
||||
elem_ty.has_relation_to_impl(
|
||||
db,
|
||||
target,
|
||||
inferable,
|
||||
relation,
|
||||
relation_visitor,
|
||||
disjointness_visitor,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
// Other than the special cases checked above, no other types are a subtype of a
|
||||
|
||||
Reference in New Issue
Block a user