@@ -1525,20 +1525,20 @@ impl<'db> Type<'db> {
15251525 }
15261526 }
15271527
1528- pub(crate) fn try_upcast_to_callable(self, db: &'db dyn Db) -> CallableTypes<'db> {
1528+ pub(crate) fn try_upcast_to_callable(self, db: &'db dyn Db) -> Option< CallableTypes<'db> > {
15291529 match self {
1530- Type::Callable(callable) => CallableTypes::one(callable),
1530+ Type::Callable(callable) => Some( CallableTypes::one(callable) ),
15311531
1532- Type::Dynamic(_) => CallableTypes::one(CallableType::function_like_callable(
1532+ Type::Dynamic(_) => Some( CallableTypes::one(CallableType::function_like_callable(
15331533 db,
15341534 Signature::dynamic(self),
1535- )),
1535+ ))) ,
15361536
15371537 Type::FunctionLiteral(function_literal) => {
1538- CallableTypes::one(function_literal.into_callable_type(db))
1538+ Some( CallableTypes::one(function_literal.into_callable_type(db) ))
15391539 }
15401540 Type::BoundMethod(bound_method) => {
1541- CallableTypes::one(bound_method.into_callable_type(db))
1541+ Some( CallableTypes::one(bound_method.into_callable_type(db) ))
15421542 }
15431543
15441544 Type::NominalInstance(_) | Type::ProtocolInstance(_) => {
@@ -1553,7 +1553,7 @@ impl<'db> Type<'db> {
15531553 if let Place::Defined(ty, _, Definedness::AlwaysDefined) = call_symbol {
15541554 ty.try_upcast_to_callable(db)
15551555 } else {
1556- CallableTypes::none()
1556+ None
15571557 }
15581558 }
15591559 Type::ClassLiteral(class_literal) => {
@@ -1570,23 +1570,20 @@ impl<'db> Type<'db> {
15701570 Type::SubclassOf(subclass_of_ty) => match subclass_of_ty.subclass_of() {
15711571 SubclassOfInner::Class(class) => class.into_callable(db),
15721572 SubclassOfInner::Dynamic(dynamic) => {
1573- CallableTypes::one(CallableType::single_callable(
1573+ Some( CallableTypes::one(CallableType::single_callable(
15741574 db,
15751575 Signature::new(Parameters::unknown(), Some(Type::Dynamic(dynamic))),
1576- ))
1576+ )))
15771577 }
15781578 },
15791579
15801580 Type::Union(union) => {
15811581 let mut callables = SmallVec::new();
15821582 for element in union.elements(db) {
1583- let element_callable = element.try_upcast_to_callable(db);
1584- if element_callable.is_empty() {
1585- return CallableTypes::none();
1586- }
1583+ let element_callable = element.try_upcast_to_callable(db)?;
15871584 callables.extend(element_callable.into_inner());
15881585 }
1589- CallableTypes(callables)
1586+ Some( CallableTypes(callables) )
15901587 }
15911588
15921589 Type::EnumLiteral(enum_literal) => enum_literal
@@ -1595,27 +1592,29 @@ impl<'db> Type<'db> {
15951592
15961593 Type::TypeAlias(alias) => alias.value_type(db).try_upcast_to_callable(db),
15971594
1598- Type::KnownBoundMethod(method) => CallableTypes::one(CallableType::new(
1595+ Type::KnownBoundMethod(method) => Some( CallableTypes::one(CallableType::new(
15991596 db,
16001597 CallableSignature::from_overloads(method.signatures(db)),
16011598 false,
1602- )),
1599+ ))) ,
16031600
1604- Type::WrapperDescriptor(wrapper_descriptor) => CallableTypes::one(CallableType::new(
1605- db,
1606- CallableSignature::from_overloads(wrapper_descriptor.signatures(db)),
1607- false,
1608- )),
1601+ Type::WrapperDescriptor(wrapper_descriptor) => {
1602+ Some(CallableTypes::one(CallableType::new(
1603+ db,
1604+ CallableSignature::from_overloads(wrapper_descriptor.signatures(db)),
1605+ false,
1606+ )))
1607+ }
16091608
16101609 Type::KnownInstance(KnownInstanceType::NewType(newtype)) => {
1611- CallableTypes::one(CallableType::single_callable(
1610+ Some( CallableTypes::one(CallableType::single_callable(
16121611 db,
16131612 Signature::new(
16141613 Parameters::new([Parameter::positional_only(None)
16151614 .with_annotated_type(newtype.base(db).instance_type(db))]),
16161615 Some(Type::NewTypeInstance(newtype)),
16171616 ),
1618- ))
1617+ )))
16191618 }
16201619
16211620 Type::Never
@@ -1628,7 +1627,7 @@ impl<'db> Type<'db> {
16281627 | Type::LiteralString
16291628 | Type::BytesLiteral(_)
16301629 | Type::TypeIs(_)
1631- | Type::TypedDict(_) => CallableTypes::none() ,
1630+ | Type::TypedDict(_) => None ,
16321631
16331632 // TODO
16341633 Type::DataclassDecorator(_)
@@ -1638,7 +1637,7 @@ impl<'db> Type<'db> {
16381637 | Type::PropertyInstance(_)
16391638 | Type::Intersection(_)
16401639 | Type::TypeVar(_)
1641- | Type::BoundSuper(_) => CallableTypes::none() ,
1640+ | Type::BoundSuper(_) => None ,
16421641 }
16431642 }
16441643
@@ -2194,14 +2193,16 @@ impl<'db> Type<'db> {
21942193
21952194 (_, Type::Callable(other_callable)) => {
21962195 relation_visitor.visit((self, target, relation), || {
2197- self.try_upcast_to_callable(db).has_relation_to_impl(
2198- db,
2199- other_callable,
2200- inferable,
2201- relation,
2202- relation_visitor,
2203- disjointness_visitor,
2204- )
2196+ self.try_upcast_to_callable(db).when_some_and(|callables| {
2197+ callables.has_relation_to_impl(
2198+ db,
2199+ other_callable,
2200+ inferable,
2201+ relation,
2202+ relation_visitor,
2203+ disjointness_visitor,
2204+ )
2205+ })
22052206 })
22062207 }
22072208
@@ -11110,20 +11111,21 @@ impl<'db> CallableType<'db> {
1111011111/// when coercing that result to a single type, you'll get a `UnionType`. But this lets you handle
1111111112/// that result as a list of `CallableType`s before merging them into a `UnionType` should that be
1111211113/// helpful.
11114+ ///
11115+ /// Note that this type is guaranteed to contain at least one callable. If you need to support "no
11116+ /// callables" as a possibility, use `Option<CallableTypes>`.
1111311117#[derive(Clone, Debug, Eq, PartialEq, get_size2::GetSize, salsa::Update)]
1111411118pub(crate) struct CallableTypes<'db>(SmallVec<[CallableType<'db>; 1]>);
1111511119
1111611120impl<'db> CallableTypes<'db> {
11117- pub(crate) fn none() -> Self {
11118- CallableTypes(smallvec![])
11119- }
11120-
1112111121 pub(crate) fn one(callable: CallableType<'db>) -> Self {
1112211122 CallableTypes(smallvec![callable])
1112311123 }
1112411124
1112511125 pub(crate) fn from_elements(callables: impl IntoIterator<Item = CallableType<'db>>) -> Self {
11126- CallableTypes(callables.into_iter().collect())
11126+ let callables: SmallVec<_> = callables.into_iter().collect();
11127+ assert!(!callables.is_empty(), "CallableTypes should not be empty");
11128+ CallableTypes(callables)
1112711129 }
1112811130
1112911131 pub(crate) fn exactly_one(self) -> Option<CallableType<'db>> {
@@ -11133,22 +11135,15 @@ impl<'db> CallableTypes<'db> {
1113311135 }
1113411136 }
1113511137
11136- fn is_empty(&self) -> bool {
11137- self.0.is_empty()
11138- }
11139-
1114011138 fn into_inner(self) -> SmallVec<[CallableType<'db>; 1]> {
1114111139 self.0
1114211140 }
1114311141
11144- pub(crate) fn into_type(self, db: &'db dyn Db) -> Option< Type<'db> > {
11142+ pub(crate) fn into_type(self, db: &'db dyn Db) -> Type<'db> {
1114511143 match self.0.as_slice() {
11146- [] => None,
11147- [single] => Some(Type::Callable(*single)),
11148- slice => Some(UnionType::from_elements(
11149- db,
11150- slice.iter().copied().map(Type::Callable),
11151- )),
11144+ [] => unreachable!("CallableTypes should not be empty"),
11145+ [single] => Type::Callable(*single),
11146+ slice => UnionType::from_elements(db, slice.iter().copied().map(Type::Callable)),
1115211147 }
1115311148 }
1115411149
@@ -11165,9 +11160,6 @@ impl<'db> CallableTypes<'db> {
1116511160 relation_visitor: &HasRelationToVisitor<'db>,
1116611161 disjointness_visitor: &IsDisjointVisitor<'db>,
1116711162 ) -> ConstraintSet<'db> {
11168- if self.is_empty() {
11169- return ConstraintSet::from(false);
11170- }
1117111163 self.0.iter().when_all(db, |element| {
1117211164 element.has_relation_to_impl(
1117311165 db,
0 commit comments