@@ -887,6 +887,11 @@ impl<'db> Type<'db> {
887887 }
888888 }
889889
890+ (
891+ Type :: Callable ( CallableType :: General ( self_callable) ) ,
892+ Type :: Callable ( CallableType :: General ( target_callable) ) ,
893+ ) => self_callable. is_assignable_to ( db, target_callable) ,
894+
890895 // TODO other types containing gradual forms (e.g. generics containing Any/Unknown)
891896 _ => self . is_subtype_of ( db, target) ,
892897 }
@@ -4442,8 +4447,32 @@ impl<'db> GeneralCallableType<'db> {
44424447 } )
44434448 }
44444449
4450+ /// Return `true` if `self` is assignable to `other`.
4451+ pub ( crate ) fn is_assignable_to ( self , db : & ' db dyn Db , other : Self ) -> bool {
4452+ self . is_assignable_to_impl ( db, other, |type1, type2| {
4453+ // In the context of a callable type, the `None` variant represents an `Unknown` type.
4454+ type1
4455+ . unwrap_or ( Type :: unknown ( ) )
4456+ . is_assignable_to ( db, type2. unwrap_or ( Type :: unknown ( ) ) )
4457+ } )
4458+ }
4459+
44454460 /// Return `true` if `self` is a subtype of `other`.
44464461 pub ( crate ) fn is_subtype_of ( self , db : & ' db dyn Db , other : Self ) -> bool {
4462+ self . is_assignable_to_impl ( db, other, |type1, type2| {
4463+ // SAFETY: Subtype relation is only checked for fully static types.
4464+ type1. unwrap ( ) . is_subtype_of ( db, type2. unwrap ( ) )
4465+ } )
4466+ }
4467+
4468+ /// Implementation for the [`is_assignable_to`] and [`is_subtype_of`] for callable types.
4469+ ///
4470+ /// [`is_assignable_to`]: Self::is_assignable_to
4471+ /// [`is_subtype_of`]: Self::is_subtype_of
4472+ fn is_assignable_to_impl < F > ( self , db : & ' db dyn Db , other : Self , check_types : F ) -> bool
4473+ where
4474+ F : Fn ( Option < Type < ' db > > , Option < Type < ' db > > ) -> bool ,
4475+ {
44474476 /// A helper struct to zip two slices of parameters together that provides control over the
44484477 /// two iterators individually. It also keeps track of the current parameter in each
44494478 /// iterator.
@@ -4508,18 +4537,17 @@ impl<'db> GeneralCallableType<'db> {
45084537 let self_signature = self . signature ( db) ;
45094538 let other_signature = other. signature ( db) ;
45104539
4511- // Check if `type1` is a subtype of `type2`. This is mainly to avoid `unwrap` calls
4512- // scattered throughout the function.
4513- let is_subtype = |type1 : Option < Type < ' db > > , type2 : Option < Type < ' db > > | {
4514- // SAFETY: Subtype relation is only checked for fully static types.
4515- type1. unwrap ( ) . is_subtype_of ( db, type2. unwrap ( ) )
4516- } ;
4517-
45184540 // Return types are covariant.
4519- if !is_subtype ( self_signature. return_ty , other_signature. return_ty ) {
4541+ if !check_types ( self_signature. return_ty , other_signature. return_ty ) {
45204542 return false ;
45214543 }
45224544
4545+ if self_signature. parameters ( ) . is_gradual ( ) || other_signature. parameters ( ) . is_gradual ( ) {
4546+ // If either of the parameter lists contains a gradual form (`...`), then it is
4547+ // assignable / subtype to and from any other callable type.
4548+ return true ;
4549+ }
4550+
45234551 let mut parameters = ParametersZip {
45244552 current_self : None ,
45254553 current_other : None ,
@@ -4577,7 +4605,7 @@ impl<'db> GeneralCallableType<'db> {
45774605 if self_default. is_none ( ) && other_default. is_some ( ) {
45784606 return false ;
45794607 }
4580- if !is_subtype (
4608+ if !check_types (
45814609 other_parameter. annotated_type ( ) ,
45824610 self_parameter. annotated_type ( ) ,
45834611 ) {
@@ -4602,7 +4630,7 @@ impl<'db> GeneralCallableType<'db> {
46024630 if self_default. is_none ( ) && other_default. is_some ( ) {
46034631 return false ;
46044632 }
4605- if !is_subtype (
4633+ if !check_types (
46064634 other_parameter. annotated_type ( ) ,
46074635 self_parameter. annotated_type ( ) ,
46084636 ) {
@@ -4611,7 +4639,7 @@ impl<'db> GeneralCallableType<'db> {
46114639 }
46124640
46134641 ( ParameterKind :: Variadic { .. } , ParameterKind :: PositionalOnly { .. } ) => {
4614- if !is_subtype (
4642+ if !check_types (
46154643 other_parameter. annotated_type ( ) ,
46164644 self_parameter. annotated_type ( ) ,
46174645 ) {
@@ -4641,7 +4669,7 @@ impl<'db> GeneralCallableType<'db> {
46414669 // variadic parameter and is deferred to the next iteration.
46424670 break ;
46434671 }
4644- if !is_subtype (
4672+ if !check_types (
46454673 other_parameter. annotated_type ( ) ,
46464674 self_parameter. annotated_type ( ) ,
46474675 ) {
@@ -4652,7 +4680,7 @@ impl<'db> GeneralCallableType<'db> {
46524680 }
46534681
46544682 ( ParameterKind :: Variadic { .. } , ParameterKind :: Variadic { .. } ) => {
4655- if !is_subtype (
4683+ if !check_types (
46564684 other_parameter. annotated_type ( ) ,
46574685 self_parameter. annotated_type ( ) ,
46584686 ) {
@@ -4730,7 +4758,7 @@ impl<'db> GeneralCallableType<'db> {
47304758 if self_default. is_none ( ) && other_default. is_some ( ) {
47314759 return false ;
47324760 }
4733- if !is_subtype (
4761+ if !check_types (
47344762 other_parameter. annotated_type ( ) ,
47354763 self_parameter. annotated_type ( ) ,
47364764 ) {
@@ -4742,8 +4770,10 @@ impl<'db> GeneralCallableType<'db> {
47424770 ) ,
47434771 }
47444772 } else if let Some ( self_keyword_variadic_type) = self_keyword_variadic {
4745- if !is_subtype ( other_parameter. annotated_type ( ) , self_keyword_variadic_type)
4746- {
4773+ if !check_types (
4774+ other_parameter. annotated_type ( ) ,
4775+ self_keyword_variadic_type,
4776+ ) {
47474777 return false ;
47484778 }
47494779 } else {
@@ -4756,7 +4786,7 @@ impl<'db> GeneralCallableType<'db> {
47564786 // parameter, `self` must also have a keyword variadic parameter.
47574787 return false ;
47584788 } ;
4759- if !is_subtype ( other_parameter. annotated_type ( ) , self_keyword_variadic_type) {
4789+ if !check_types ( other_parameter. annotated_type ( ) , self_keyword_variadic_type) {
47604790 return false ;
47614791 }
47624792 }
0 commit comments