allow multiple overloads/callables when inferring

This commit is contained in:
Douglas Creager 2025-12-03 11:20:30 -05:00
parent db5834dfd7
commit 77ce24a5bf
3 changed files with 28 additions and 27 deletions

View File

@ -624,8 +624,7 @@ class ClassWithNewAndInit:
def __init__(self, x: int) -> None: ...
# TODO: revealed: ClassWithNewAndInit
# revealed: Unknown
# revealed: ClassWithNewAndInit
reveal_type(accepts_callable(ClassWithNewAndInit)())
class Meta(type):
@ -660,10 +659,10 @@ class ClassWithOverloadedInit[T]:
def __init__(self, x: int | str) -> None: ...
# TODO: revealed: ClassWithOverloadedInit[int]
# revealed: Unknown
# revealed: Top[ClassWithOverloadedInit[Unknown]]
reveal_type(accepts_callable(ClassWithOverloadedInit)(0))
# TODO: revealed: ClassWithOverloadedInit[str]
# revealed: Unknown
# revealed: Top[ClassWithOverloadedInit[Unknown]]
reveal_type(accepts_callable(ClassWithOverloadedInit)(""))
class GenericClass[T]:

View File

@ -11966,6 +11966,10 @@ impl<'db> CallableTypes<'db> {
}
}
fn as_slice(&self) -> &SmallVec<[CallableType<'db>; 1]> {
&self.0
}
fn into_inner(self) -> SmallVec<[CallableType<'db>; 1]> {
self.0
}

View File

@ -17,12 +17,11 @@ use crate::types::signatures::Parameters;
use crate::types::tuple::{TupleSpec, TupleType, walk_tuple_type};
use crate::types::visitor::{TypeCollector, TypeVisitor, walk_type_with_recursion_guard};
use crate::types::{
ApplyTypeMappingVisitor, BoundTypeVarIdentity, BoundTypeVarInstance, CallableTypes,
ClassLiteral, FindLegacyTypeVarsVisitor, HasRelationToVisitor, IsDisjointVisitor,
IsEquivalentVisitor, KnownClass, KnownInstanceType, MaterializationKind, NormalizedVisitor,
Type, TypeContext, TypeMapping, TypeRelation, TypeVarBoundOrConstraints, TypeVarIdentity,
TypeVarInstance, TypeVarKind, TypeVarVariance, UnionType, declaration_type,
walk_bound_type_var_type,
ApplyTypeMappingVisitor, BoundTypeVarIdentity, BoundTypeVarInstance, ClassLiteral,
FindLegacyTypeVarsVisitor, HasRelationToVisitor, IsDisjointVisitor, IsEquivalentVisitor,
KnownClass, KnownInstanceType, MaterializationKind, NormalizedVisitor, Type, TypeContext,
TypeMapping, TypeRelation, TypeVarBoundOrConstraints, TypeVarIdentity, TypeVarInstance,
TypeVarKind, TypeVarVariance, UnionType, declaration_type, walk_bound_type_var_type,
};
use crate::{Db, FxOrderMap, FxOrderSet};
@ -1650,27 +1649,26 @@ impl<'db> SpecializationBuilder<'db> {
}
(Type::Callable(formal_callable), _) => {
let Some(actual_callable) = actual
.try_upcast_to_callable(self.db)
.and_then(CallableTypes::exactly_one)
else {
let Some(actual_callables) = actual.try_upcast_to_callable(self.db) 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(
let mut when = ConstraintSet::from(false);
for formal_signature in &formal_callable.signatures(self.db).overloads {
for actual_callable in actual_callables.as_slice() {
for actual_signature in &actual_callable.signatures(self.db).overloads {
when.union(
self.db,
formal_signature.when_constraint_set_assignable_to(
self.db,
actual_signature,
self.inferable,
),
);
}
}
}
when.for_each_path(self.db, |path| {
for constraint in path.positive_constraints() {
let typevar = constraint.typevar(self.db);