Skip to content

Commit 224c843

Browse files
authored
[red-knot] Minor simplifications to types.rs (#14962)
1 parent 90a5439 commit 224c843

File tree

3 files changed

+25
-33
lines changed

3 files changed

+25
-33
lines changed

crates/red_knot_python_semantic/src/types.rs

Lines changed: 23 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -769,34 +769,10 @@ impl<'db> Type<'db> {
769769
Type::subclass_of(class).is_subtype_of(db, target)
770770
}
771771

772-
// As the `unreachable!()` message says, non-fully-static `SubclassOf` types such as
773-
// `type[Any]`,` type[Unknown]` and `type[Todo]` should all be handled right at the top of this function.
774-
(
775-
Type::SubclassOf(SubclassOfType {
776-
base: ClassBase::Any | ClassBase::Unknown | ClassBase::Todo(_),
777-
}),
778-
_,
779-
)
780-
| (
781-
_,
782-
Type::SubclassOf(SubclassOfType {
783-
base: ClassBase::Any | ClassBase::Unknown | ClassBase::Todo(_),
784-
}),
785-
) => unreachable!(
786-
"Non-fully-static types should be handled at the top of this function!"
787-
),
788-
789-
// For example, `type[bool]` describes all possible runtime subclasses of the class `bool`,
790-
// and `type[int]` describes all possible runtime subclasses of the class `int`.
791-
// The first set is a subset of the second set, because `bool` is itself a subclass of `int`.
792-
(
793-
Type::SubclassOf(SubclassOfType {
794-
base: ClassBase::Class(self_class),
795-
}),
796-
Type::SubclassOf(SubclassOfType {
797-
base: ClassBase::Class(target_class),
798-
}),
799-
) => self_class.is_subclass_of(db, target_class),
772+
// This branch asks: given two types `type[T]` and `type[S]`, is `type[T]` a subtype of `type[S]`?
773+
(Type::SubclassOf(self_subclass_ty), Type::SubclassOf(target_subclass_ty)) => {
774+
self_subclass_ty.is_subtype_of(db, target_subclass_ty)
775+
}
800776

801777
// `type[str]` (== `SubclassOf("str")` in red-knot) describes all possible runtime subclasses
802778
// of the class object `str`. It is a subtype of `type` (== `Instance("type")`) because `str`
@@ -1046,9 +1022,8 @@ impl<'db> Type<'db> {
10461022
| Type::SliceLiteral(..)
10471023
| Type::StringLiteral(..)
10481024
| Type::LiteralString,
1049-
) => true,
1050-
1051-
(
1025+
)
1026+
| (
10521027
Type::ClassLiteral(..)
10531028
| Type::ModuleLiteral(..)
10541029
| Type::BooleanLiteral(..)
@@ -3128,6 +3103,22 @@ impl<'db> SubclassOfType<'db> {
31283103
fn member(self, db: &'db dyn Db, name: &str) -> Symbol<'db> {
31293104
Type::from(self.base).member(db, name)
31303105
}
3106+
3107+
fn is_subtype_of(self, db: &'db dyn Db, other: SubclassOfType<'db>) -> bool {
3108+
match (self.base, other.base) {
3109+
// Non-fully-static types do not participate in subtyping
3110+
(ClassBase::Any | ClassBase::Unknown | ClassBase::Todo(_), _)
3111+
| (_, ClassBase::Any | ClassBase::Unknown | ClassBase::Todo(_)) => false,
3112+
3113+
// For example, `type[bool]` describes all possible runtime subclasses of the class `bool`,
3114+
// and `type[int]` describes all possible runtime subclasses of the class `int`.
3115+
// The first set is a subset of the second set, because `bool` is itself a subclass of `int`.
3116+
(ClassBase::Class(self_class), ClassBase::Class(other_class)) => {
3117+
// N.B. The subclass relation is fully static
3118+
self_class.is_subclass_of(db, other_class)
3119+
}
3120+
}
3121+
}
31313122
}
31323123

31333124
/// A type representing the set of runtime objects which are instances of a certain class.
@@ -3138,6 +3129,7 @@ pub struct InstanceType<'db> {
31383129

31393130
impl<'db> InstanceType<'db> {
31403131
fn is_subtype_of(self, db: &'db dyn Db, other: InstanceType<'db>) -> bool {
3132+
// N.B. The subclass relation is fully static
31413133
self.class.is_subclass_of(db, other.class)
31423134
}
31433135
}

crates/red_knot_python_semantic/src/types/class_base.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ impl<'db> ClassBase<'db> {
125125
}
126126
}
127127

128-
pub(super) fn into_class_literal_type(self) -> Option<Class<'db>> {
128+
pub(super) fn into_class(self) -> Option<Class<'db>> {
129129
match self {
130130
Self::Class(class) => Some(class),
131131
_ => None,

crates/red_knot_python_semantic/src/types/mro.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ impl<'db> Mro<'db> {
117117
for (index, base) in valid_bases
118118
.iter()
119119
.enumerate()
120-
.filter_map(|(index, base)| Some((index, base.into_class_literal_type()?)))
120+
.filter_map(|(index, base)| Some((index, base.into_class()?)))
121121
{
122122
if !seen_bases.insert(base) {
123123
duplicate_bases.push((index, base));

0 commit comments

Comments
 (0)