use constraint set assignable

This commit is contained in:
Douglas Creager 2025-11-26 15:13:13 -05:00
parent 20ecb561bb
commit fc2f17508b
2 changed files with 49 additions and 15 deletions

View File

@ -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,
)?;
}
}
}

View File

@ -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);
}
}
}
}