diff --git a/crates/ty_python_semantic/resources/mdtest/generics/pep695/functions.md b/crates/ty_python_semantic/resources/mdtest/generics/pep695/functions.md index 777b6c3ec2..6e3434aaae 100644 --- a/crates/ty_python_semantic/resources/mdtest/generics/pep695/functions.md +++ b/crates/ty_python_semantic/resources/mdtest/generics/pep695/functions.md @@ -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]: diff --git a/crates/ty_python_semantic/src/types.rs b/crates/ty_python_semantic/src/types.rs index 210e6a2e4f..8e86c0d51f 100644 --- a/crates/ty_python_semantic/src/types.rs +++ b/crates/ty_python_semantic/src/types.rs @@ -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 } diff --git a/crates/ty_python_semantic/src/types/generics.rs b/crates/ty_python_semantic/src/types/generics.rs index 8b5d472589..bf5893208f 100644 --- a/crates/ty_python_semantic/src/types/generics.rs +++ b/crates/ty_python_semantic/src/types/generics.rs @@ -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 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, + ), + ); + } + } + } - let when = 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);