@@ -957,6 +957,11 @@ impl<'db> Type<'db> {
957957 first. is_gradual_equivalent_to ( db, second)
958958 }
959959
960+ (
961+ Type :: Callable ( CallableType :: General ( first) ) ,
962+ Type :: Callable ( CallableType :: General ( second) ) ,
963+ ) => first. is_gradual_equivalent_to ( db, second) ,
964+
960965 _ => false ,
961966 }
962967 }
@@ -4377,6 +4382,53 @@ impl<'db> GeneralCallableType<'db> {
43774382 Signature :: new ( Parameters :: unknown ( ) , Some ( Type :: unknown ( ) ) ) ,
43784383 )
43794384 }
4385+
4386+ /// Return `true` if `self` has exactly the same set of possible static materializations as
4387+ /// `other` (if `self` represents the same set of possible sets of possible runtime objects as
4388+ /// `other`).
4389+ pub ( crate ) fn is_gradual_equivalent_to ( self , db : & ' db dyn Db , other : Self ) -> bool {
4390+ let self_signature = self . signature ( db) ;
4391+ let other_signature = other. signature ( db) ;
4392+
4393+ if self_signature. parameters ( ) . is_gradual ( ) != other_signature. parameters ( ) . is_gradual ( ) {
4394+ return false ;
4395+ }
4396+
4397+ if self_signature. parameters ( ) . len ( ) != other_signature. parameters ( ) . len ( ) {
4398+ return false ;
4399+ }
4400+
4401+ // Check gradual equivalence between the two optional types. They are gradual equivalent
4402+ // if they are both `None` or both the Some types are gradual equivalent.
4403+ let are_optional_types_gradually_equivalent =
4404+ |self_type : Option < Type < ' db > > , other_type : Option < Type < ' db > > | match (
4405+ self_type, other_type,
4406+ ) {
4407+ ( Some ( self_type) , Some ( other_type) ) => {
4408+ self_type. is_gradual_equivalent_to ( db, other_type)
4409+ }
4410+ ( None , None ) => true ,
4411+ _ => false ,
4412+ } ;
4413+
4414+ if !are_optional_types_gradually_equivalent (
4415+ self_signature. return_ty ,
4416+ other_signature. return_ty ,
4417+ ) {
4418+ return false ;
4419+ }
4420+
4421+ self_signature
4422+ . parameters ( )
4423+ . iter ( )
4424+ . zip ( other_signature. parameters ( ) . iter ( ) )
4425+ . all ( |( self_param, other_param) | {
4426+ are_optional_types_gradually_equivalent (
4427+ self_param. annotated_type ( ) ,
4428+ other_param. annotated_type ( ) ,
4429+ )
4430+ } )
4431+ }
43804432}
43814433
43824434/// A type that represents callable objects.
0 commit comments