example implementation of `is_disjoint_from`

This commit is contained in:
Alex Waygood 2025-08-26 09:57:16 +01:00
parent 1c7f3cd2b8
commit 446a1ba2e1
2 changed files with 42 additions and 1 deletions

View File

@ -2287,6 +2287,15 @@ impl<'db> Type<'db> {
C::from_bool(db, !known_instance.is_instance_of(db, instance.class(db)))
}
(Type::NewTypeInstance(left), Type::NewTypeInstance(right)) => {
left.is_disjoint_from(db, right)
}
(Type::NewTypeInstance(new_type_instance), other)
| (other, Type::NewTypeInstance(new_type_instance)) => new_type_instance
.supertype(db)
.is_disjoint_from_impl(db, other, visitor),
(Type::BooleanLiteral(..) | Type::TypeIs(_), Type::NominalInstance(instance))
| (Type::NominalInstance(instance), Type::BooleanLiteral(..) | Type::TypeIs(_)) => {
// A `Type::BooleanLiteral()` must be an instance of exactly `bool`

View File

@ -5,7 +5,7 @@ use ruff_python_ast::name::Name;
use crate::{
Db,
semantic_index::definition::Definition,
types::{ClassType, Type, tuple::TupleSpec},
types::{ClassType, Type, constraints::Constraints, tuple::TupleSpec},
};
#[derive(
@ -64,6 +64,38 @@ impl<'db> NewTypeInstance<'db> {
}
}
pub(crate) fn supertype(self, db: &'db dyn Db) -> Type<'db> {
match self.0.supertype(db) {
NewTypeBase::Class(class) => Type::instance(db, class),
NewTypeBase::NewType(newtype) => Type::NewTypeInstance(NewTypeInstance(newtype)),
}
}
pub(crate) fn has_relation_to<C: Constraints<'db>>(
self,
db: &'db dyn Db,
other: NewTypeInstance<'db>,
) -> C {
if self == other {
return C::from_bool(db, true);
}
match self.0.supertype(db) {
NewTypeBase::Class(_) => C::from_bool(db, false),
NewTypeBase::NewType(newtype) => NewTypeInstance(newtype).has_relation_to(db, other),
}
}
pub(crate) fn is_disjoint_from<C: Constraints<'db>>(
self,
db: &'db dyn Db,
other: NewTypeInstance<'db>,
) -> C {
C::from_bool(
db,
!(self.has_relation_to(db, other) || other.has_relation_to(db, self)),
)
}
pub(crate) fn name(&self, db: &'db dyn Db) -> &'db str {
self.0.name(db)
}