@@ -654,14 +654,20 @@ impl<'db> Type<'db> {
654654 } ,
655655 )
656656 }
657- ( Type :: ClassLiteral ( self_class) , Type :: SubclassOf ( target_class) ) => {
658- self_class. class . is_subclass_of_base ( db, target_class. base )
659- }
657+ (
658+ Type :: ClassLiteral ( ClassLiteralType { class : self_class } ) ,
659+ Type :: SubclassOf ( SubclassOfType {
660+ base : ClassBase :: Class ( target_class) ,
661+ } ) ,
662+ ) => self_class. is_subclass_of ( db, target_class) ,
660663 (
661664 Type :: Instance ( InstanceType { class : self_class } ) ,
662- Type :: SubclassOf ( target_class) ,
663- ) if self_class. is_known ( db, KnownClass :: Type ) => {
664- self_class. is_subclass_of_base ( db, target_class. base )
665+ Type :: SubclassOf ( SubclassOfType {
666+ base : ClassBase :: Class ( target_class) ,
667+ } ) ,
668+ ) => {
669+ self_class. is_known ( db, KnownClass :: Type )
670+ && target_class. is_known ( db, KnownClass :: Type )
665671 }
666672 (
667673 Type :: SubclassOf ( SubclassOfType {
@@ -928,10 +934,18 @@ impl<'db> Type<'db> {
928934 | Type :: ClassLiteral ( ..) ) ,
929935 ) => left != right,
930936
931- ( Type :: SubclassOf ( type_class) , Type :: ClassLiteral ( class_literal) )
932- | ( Type :: ClassLiteral ( class_literal) , Type :: SubclassOf ( type_class) ) => {
933- !class_literal. class . is_subclass_of_base ( db, type_class. base )
934- }
937+ (
938+ Type :: SubclassOf ( SubclassOfType {
939+ base : ClassBase :: Class ( class_a) ,
940+ } ) ,
941+ Type :: ClassLiteral ( ClassLiteralType { class : class_b } ) ,
942+ )
943+ | (
944+ Type :: ClassLiteral ( ClassLiteralType { class : class_b } ) ,
945+ Type :: SubclassOf ( SubclassOfType {
946+ base : ClassBase :: Class ( class_a) ,
947+ } ) ,
948+ ) => !class_b. is_subclass_of ( db, class_a) ,
935949 ( Type :: SubclassOf ( _) , Type :: SubclassOf ( _) ) => false ,
936950 ( Type :: SubclassOf ( _) , Type :: Instance ( _) ) | ( Type :: Instance ( _) , Type :: SubclassOf ( _) ) => {
937951 false
@@ -2593,11 +2607,7 @@ impl<'db> Class<'db> {
25932607 pub fn is_subclass_of ( self , db : & ' db dyn Db , other : Class ) -> bool {
25942608 // `is_subclass_of` is checking the subtype relation, in which gradual types do not
25952609 // participate, so we should not return `True` if we find `Any/Unknown` in the MRO.
2596- self . is_subclass_of_base ( db, other)
2597- }
2598-
2599- fn is_subclass_of_base ( self , db : & ' db dyn Db , other : impl Into < ClassBase < ' db > > ) -> bool {
2600- self . iter_mro ( db) . contains ( & other. into ( ) )
2610+ self . iter_mro ( db) . contains ( & ClassBase :: Class ( other) )
26012611 }
26022612
26032613 /// Return the explicit `metaclass` of this class, if one is defined.
@@ -3146,6 +3156,7 @@ pub(crate) mod tests {
31463156 #[ test_case( Ty :: BuiltinInstance ( "type" ) , Ty :: SubclassOfAny ) ]
31473157 #[ test_case( Ty :: BuiltinInstance ( "type" ) , Ty :: SubclassOfBuiltinClass ( "object" ) ) ]
31483158 #[ test_case( Ty :: BuiltinInstance ( "type" ) , Ty :: BuiltinInstance ( "type" ) ) ]
3159+ #[ test_case( Ty :: BuiltinClassLiteral ( "str" ) , Ty :: SubclassOfAny ) ]
31493160 fn is_assignable_to ( from : Ty , to : Ty ) {
31503161 let db = setup_db ( ) ;
31513162 assert ! ( from. into_type( & db) . is_assignable_to( & db, to. into_type( & db) ) ) ;
@@ -3242,6 +3253,8 @@ pub(crate) mod tests {
32423253 #[ test_case( Ty :: BuiltinClassLiteral ( "int" ) , Ty :: BuiltinClassLiteral ( "object" ) ) ]
32433254 #[ test_case( Ty :: BuiltinInstance ( "int" ) , Ty :: BuiltinClassLiteral ( "int" ) ) ]
32443255 #[ test_case( Ty :: TypingInstance ( "_SpecialForm" ) , Ty :: TypingLiteral ) ]
3256+ #[ test_case( Ty :: BuiltinInstance ( "type" ) , Ty :: SubclassOfBuiltinClass ( "str" ) ) ]
3257+ #[ test_case( Ty :: BuiltinClassLiteral ( "str" ) , Ty :: SubclassOfAny ) ]
32453258 fn is_not_subtype_of ( from : Ty , to : Ty ) {
32463259 let db = setup_db ( ) ;
32473260 assert ! ( !from. into_type( & db) . is_subtype_of( & db, to. into_type( & db) ) ) ;
@@ -3401,6 +3414,7 @@ pub(crate) mod tests {
34013414 #[ test_case( Ty :: Intersection { pos: vec![ Ty :: BuiltinInstance ( "int" ) , Ty :: IntLiteral ( 2 ) ] , neg: vec![ ] } , Ty :: IntLiteral ( 2 ) ) ]
34023415 #[ test_case( Ty :: Tuple ( vec![ Ty :: IntLiteral ( 1 ) , Ty :: IntLiteral ( 2 ) ] ) , Ty :: Tuple ( vec![ Ty :: IntLiteral ( 1 ) , Ty :: BuiltinInstance ( "int" ) ] ) ) ]
34033416 #[ test_case( Ty :: BuiltinClassLiteral ( "str" ) , Ty :: BuiltinInstance ( "type" ) ) ]
3417+ #[ test_case( Ty :: BuiltinClassLiteral ( "str" ) , Ty :: SubclassOfAny ) ]
34043418 fn is_not_disjoint_from ( a : Ty , b : Ty ) {
34053419 let db = setup_db ( ) ;
34063420 let a = a. into_type ( & db) ;
0 commit comments