diff --git a/crates/ty_python_semantic/src/types/generics.rs b/crates/ty_python_semantic/src/types/generics.rs index 8ae3f0f434..df9aa8d7f4 100644 --- a/crates/ty_python_semantic/src/types/generics.rs +++ b/crates/ty_python_semantic/src/types/generics.rs @@ -1677,22 +1677,38 @@ impl<'db> SpecializationBuilder<'db> { } (Type::Callable(formal_callable), _) => { - if let Some(actual_callable) = actual + let Some(actual_callable) = actual .try_upcast_to_callable(self.db) .and_then(CallableTypes::exactly_one) - { - for formal_signature in &formal_callable.signatures(self.db).overloads { - for actual_signature in &actual_callable.signatures(self.db).overloads { - if let Some(formal_return_ty) = formal_signature.return_ty - && let Some(actual_return_ty) = actual_signature.return_ty - { - self.infer_map_impl( - formal_return_ty, - actual_return_ty, - polarity, - &mut f, - )?; - } + else { + return Ok(()); + }; + + let [formal_signature] = formal_callable.signatures(self.db).overloads.as_slice() + else { + return Ok(()); + }; + let [actual_signature] = actual_callable.signatures(self.db).overloads.as_slice() + else { + return Ok(()); + }; + + let when = formal_signature.when_constraint_set_assignable_to( + self.db, + actual_signature, + self.inferable, + ); + for formal_signature in &formal_callable.signatures(self.db).overloads { + for actual_signature in &actual_callable.signatures(self.db).overloads { + if let Some(formal_return_ty) = formal_signature.return_ty + && let Some(actual_return_ty) = actual_signature.return_ty + { + self.infer_map_impl( + formal_return_ty, + actual_return_ty, + polarity, + &mut f, + )?; } } } diff --git a/crates/ty_python_semantic/src/types/signatures.rs b/crates/ty_python_semantic/src/types/signatures.rs index ebe2945693..5abc9ebe38 100644 --- a/crates/ty_python_semantic/src/types/signatures.rs +++ b/crates/ty_python_semantic/src/types/signatures.rs @@ -839,6 +839,22 @@ impl<'db> Signature<'db> { result } + pub(crate) fn when_constraint_set_assignable_to( + &self, + db: &'db dyn Db, + other: &Signature<'db>, + inferable: InferableTypeVars<'_, 'db>, + ) -> ConstraintSet<'db> { + self.has_relation_to_impl( + db, + other, + inferable, + TypeRelation::ConstraintSetAssignability, + &HasRelationToVisitor::default(), + &IsDisjointVisitor::default(), + ) + } + /// Implementation of subtyping and assignability for signature. fn has_relation_to_impl( &self, @@ -1175,7 +1191,9 @@ impl<'db> Signature<'db> { break; } - _ => return ConstraintSet::from(false), + _ => { + return ConstraintSet::from(false); + } } } }