Compare commits

...

5 Commits

Author SHA1 Message Date
Zanie Blue
6c2d87ed80 Invert case 2025-12-20 22:31:37 -06:00
Zanie Blue
7d4831597b Lint 2025-12-20 22:31:37 -06:00
Zanie Blue
81f39680d2 [ty] Cache Type::is_disjoint_from 2025-12-20 22:31:37 -06:00
Zanie Blue
3c2f534480 [ty] Cache Type::is_subtype_of 2025-12-20 22:31:37 -06:00
Zanie Blue
592a674447 [ty] Cache ClassType::nearest_disjoint_base 2025-12-20 22:31:37 -06:00
3 changed files with 52 additions and 7 deletions

View File

@@ -1952,8 +1952,18 @@ impl<'db> Type<'db> {
///
/// See [`TypeRelation::Subtyping`] for more details.
pub(crate) fn is_subtype_of(self, db: &'db dyn Db, target: Type<'db>) -> bool {
self.when_subtype_of(db, target, InferableTypeVars::None)
.is_always_satisfied(db)
#[salsa::tracked(cycle_initial=is_subtype_of_cycle_initial, heap_size=ruff_memory_usage::heap_size)]
fn is_subtype_of_impl<'db>(db: &'db dyn Db, self_ty: Type<'db>, target: Type<'db>) -> bool {
self_ty
.when_subtype_of(db, target, InferableTypeVars::None)
.is_always_satisfied(db)
}
if self == target {
return true;
}
is_subtype_of_impl(db, self, target)
}
fn when_subtype_of(
@@ -3224,8 +3234,22 @@ impl<'db> Type<'db> {
/// This function aims to have no false positives, but might return wrong
/// `false` answers in some cases.
pub(crate) fn is_disjoint_from(self, db: &'db dyn Db, other: Type<'db>) -> bool {
self.when_disjoint_from(db, other, InferableTypeVars::None)
.is_always_satisfied(db)
#[salsa::tracked(cycle_initial=is_disjoint_from_cycle_initial, heap_size=ruff_memory_usage::heap_size)]
fn is_disjoint_from_cached<'db>(
db: &'db dyn Db,
self_ty: Type<'db>,
other: Type<'db>,
) -> bool {
self_ty
.when_disjoint_from(db, other, InferableTypeVars::None)
.is_always_satisfied(db)
}
if self == other {
return false;
}
is_disjoint_from_cached(db, self, other)
}
fn when_disjoint_from(
@@ -8689,6 +8713,26 @@ impl<'db> VarianceInferable<'db> for Type<'db> {
}
}
#[allow(clippy::trivially_copy_pass_by_ref)]
fn is_subtype_of_cycle_initial<'db>(
_db: &'db dyn Db,
_id: salsa::Id,
_self_ty: Type<'db>,
_target: Type<'db>,
) -> bool {
false
}
#[allow(clippy::trivially_copy_pass_by_ref)]
fn is_disjoint_from_cycle_initial<'db>(
_db: &'db dyn Db,
_id: salsa::Id,
_self_ty: Type<'db>,
_other: Type<'db>,
) -> bool {
false
}
#[allow(clippy::trivially_copy_pass_by_ref)]
fn is_redundant_with_cycle_initial<'db>(
_db: &'db dyn Db,

View File

@@ -716,6 +716,7 @@ impl<'db> ClassType<'db> {
/// Return the [`DisjointBase`] that appears first in the MRO of this class.
///
/// Returns `None` if this class does not have any disjoint bases in its MRO.
#[salsa::tracked(heap_size=ruff_memory_usage::heap_size)]
pub(super) fn nearest_disjoint_base(self, db: &'db dyn Db) -> Option<DisjointBase<'db>> {
self.iter_mro(db)
.filter_map(ClassBase::into_class)
@@ -4124,7 +4125,7 @@ impl InheritanceCycle {
/// `TypeError`s resulting from class definitions.
///
/// [PEP 800]: https://peps.python.org/pep-0800/
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, get_size2::GetSize, salsa::Update)]
pub(super) struct DisjointBase<'db> {
pub(super) class: ClassLiteral<'db>,
pub(super) kind: DisjointBaseKind,
@@ -4161,7 +4162,7 @@ impl<'db> DisjointBase<'db> {
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, get_size2::GetSize, salsa::Update)]
pub(super) enum DisjointBaseKind {
/// We know the class is a disjoint base because it's either hardcoded in ty
/// or has the `@disjoint_base` decorator.

View File

@@ -720,7 +720,7 @@ impl<'db> ProtocolInstanceType<'db> {
_value: ProtocolInstanceType<'db>,
_: (),
) -> bool {
true
false
}
is_equivalent_to_object_inner(db, self, ())