Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 48 additions & 4 deletions crates/ty_python_semantic/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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,
Expand Down
5 changes: 3 additions & 2 deletions crates/ty_python_semantic/src/types/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion crates/ty_python_semantic/src/types/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,7 @@ impl<'db> ProtocolInstanceType<'db> {
_value: ProtocolInstanceType<'db>,
_: (),
) -> bool {
true
false
}

is_equivalent_to_object_inner(db, self, ())
Expand Down
Loading