@@ -657,25 +657,26 @@ impl<'db> Type<'db> {
657657 }
658658 }
659659
660- pub fn contains_todo ( & self , db : & ' db dyn Db ) -> bool {
661- match self {
662- Self :: Dynamic ( DynamicType :: Todo ( _) | DynamicType :: TodoPEP695ParamSpec ) => true ,
660+ /// Return `true` if `self`, or any of the types contained in `self`, match the closure passed in.
661+ pub fn any_over_type ( self , db : & ' db dyn Db , type_fn : & dyn Fn ( Type < ' db > ) -> bool ) -> bool {
662+ if type_fn ( self ) {
663+ return true ;
664+ }
663665
666+ match self {
664667 Self :: AlwaysFalsy
665668 | Self :: AlwaysTruthy
666669 | Self :: Never
667670 | Self :: BooleanLiteral ( _)
668671 | Self :: BytesLiteral ( _)
669- | Self :: FunctionLiteral ( _)
670- | Self :: NominalInstance ( _)
671672 | Self :: ModuleLiteral ( _)
673+ | Self :: FunctionLiteral ( _)
672674 | Self :: ClassLiteral ( _)
673675 | Self :: KnownInstance ( _)
674- | Self :: PropertyInstance ( _)
675676 | Self :: StringLiteral ( _)
676677 | Self :: IntLiteral ( _)
677678 | Self :: LiteralString
678- | Self :: Dynamic ( DynamicType :: Unknown | DynamicType :: Any )
679+ | Self :: Dynamic ( _ )
679680 | Self :: BoundMethod ( _)
680681 | Self :: WrapperDescriptor ( _)
681682 | Self :: MethodWrapper ( _)
@@ -686,62 +687,82 @@ impl<'db> Type<'db> {
686687 . specialization ( db)
687688 . types ( db)
688689 . iter ( )
689- . any ( |ty| ty. contains_todo ( db) ) ,
690+ . copied ( )
691+ . any ( |ty| ty. any_over_type ( db, type_fn) ) ,
690692
691693 Self :: Callable ( callable) => {
692694 let signatures = callable. signatures ( db) ;
693695 signatures. iter ( ) . any ( |signature| {
694696 signature. parameters ( ) . iter ( ) . any ( |param| {
695697 param
696698 . annotated_type ( )
697- . is_some_and ( |ty| ty. contains_todo ( db) )
698- } ) || signature. return_ty . is_some_and ( |ty| ty. contains_todo ( db) )
699+ . is_some_and ( |ty| ty. any_over_type ( db, type_fn) )
700+ } ) || signature
701+ . return_ty
702+ . is_some_and ( |ty| ty. any_over_type ( db, type_fn) )
699703 } )
700704 }
701705
702- Self :: SubclassOf ( subclass_of) => match subclass_of. subclass_of ( ) {
703- SubclassOfInner :: Dynamic (
704- DynamicType :: Todo ( _) | DynamicType :: TodoPEP695ParamSpec ,
705- ) => true ,
706- SubclassOfInner :: Dynamic ( DynamicType :: Unknown | DynamicType :: Any ) => false ,
707- SubclassOfInner :: Class ( _) => false ,
708- } ,
706+ Self :: SubclassOf ( subclass_of) => {
707+ Type :: from ( subclass_of. subclass_of ( ) ) . any_over_type ( db, type_fn)
708+ }
709709
710710 Self :: TypeVar ( typevar) => match typevar. bound_or_constraints ( db) {
711711 None => false ,
712- Some ( TypeVarBoundOrConstraints :: UpperBound ( bound) ) => bound. contains_todo ( db) ,
712+ Some ( TypeVarBoundOrConstraints :: UpperBound ( bound) ) => {
713+ bound. any_over_type ( db, type_fn)
714+ }
713715 Some ( TypeVarBoundOrConstraints :: Constraints ( constraints) ) => constraints
714716 . elements ( db)
715717 . iter ( )
716- . any ( |constraint| constraint. contains_todo ( db) ) ,
718+ . any ( |constraint| constraint. any_over_type ( db, type_fn ) ) ,
717719 } ,
718720
719721 Self :: BoundSuper ( bound_super) => {
720- matches ! (
721- bound_super. pivot_class( db) ,
722- ClassBase :: Dynamic ( DynamicType :: Todo ( _) )
723- ) || matches ! (
724- bound_super. owner( db) ,
725- SuperOwnerKind :: Dynamic ( DynamicType :: Todo ( _) )
726- )
722+ Type :: from ( bound_super. pivot_class ( db) ) . any_over_type ( db, type_fn)
723+ || Type :: from ( bound_super. owner ( db) ) . any_over_type ( db, type_fn)
727724 }
728725
729- Self :: Tuple ( tuple) => tuple. elements ( db) . iter ( ) . any ( |ty| ty. contains_todo ( db) ) ,
726+ Self :: Tuple ( tuple) => tuple
727+ . elements ( db)
728+ . iter ( )
729+ . any ( |ty| ty. any_over_type ( db, type_fn) ) ,
730730
731- Self :: Union ( union) => union. elements ( db) . iter ( ) . any ( |ty| ty. contains_todo ( db) ) ,
731+ Self :: Union ( union) => union
732+ . elements ( db)
733+ . iter ( )
734+ . any ( |ty| ty. any_over_type ( db, type_fn) ) ,
732735
733736 Self :: Intersection ( intersection) => {
734737 intersection
735738 . positive ( db)
736739 . iter ( )
737- . any ( |ty| ty. contains_todo ( db) )
740+ . any ( |ty| ty. any_over_type ( db, type_fn ) )
738741 || intersection
739742 . negative ( db)
740743 . iter ( )
741- . any ( |ty| ty. contains_todo ( db) )
744+ . any ( |ty| ty. any_over_type ( db, type_fn) )
745+ }
746+
747+ Self :: ProtocolInstance ( protocol) => protocol. any_over_type ( db, type_fn) ,
748+
749+ Self :: PropertyInstance ( property) => {
750+ property
751+ . getter ( db)
752+ . is_some_and ( |ty| ty. any_over_type ( db, type_fn) )
753+ || property
754+ . setter ( db)
755+ . is_some_and ( |ty| ty. any_over_type ( db, type_fn) )
742756 }
743757
744- Self :: ProtocolInstance ( protocol) => protocol. contains_todo ( db) ,
758+ Self :: NominalInstance ( instance) => match instance. class {
759+ ClassType :: NonGeneric ( _) => false ,
760+ ClassType :: Generic ( generic) => generic
761+ . specialization ( db)
762+ . types ( db)
763+ . iter ( )
764+ . any ( |ty| ty. any_over_type ( db, type_fn) ) ,
765+ } ,
745766 }
746767 }
747768
@@ -8172,6 +8193,16 @@ impl<'db> SuperOwnerKind<'db> {
81728193 }
81738194}
81748195
8196+ impl < ' db > From < SuperOwnerKind < ' db > > for Type < ' db > {
8197+ fn from ( owner : SuperOwnerKind < ' db > ) -> Self {
8198+ match owner {
8199+ SuperOwnerKind :: Dynamic ( dynamic) => Type :: Dynamic ( dynamic) ,
8200+ SuperOwnerKind :: Class ( class) => class. into ( ) ,
8201+ SuperOwnerKind :: Instance ( instance) => instance. into ( ) ,
8202+ }
8203+ }
8204+ }
8205+
81758206/// Represent a bound super object like `super(PivotClass, owner)`
81768207#[ salsa:: interned( debug) ]
81778208pub struct BoundSuperType < ' db > {
0 commit comments