Skip to content

Commit 3e74a44

Browse files
committed
[CSBindings] Infer transitive protocol requirements through all conversions
1 parent 4568e6e commit 3e74a44

File tree

1 file changed

+26
-18
lines changed

1 file changed

+26
-18
lines changed

lib/Sema/CSBindings.cpp

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,26 @@ void ConstraintSystem::PotentialBindings::inferTransitiveBindings(
2828
&inferredBindings) {
2929
using BindingKind = ConstraintSystem::AllowedBindingKind;
3030

31-
llvm::SmallVector<Constraint *, 4> subtypeOf;
32-
// First, let's collect all of the `subtype` constraints associated
31+
llvm::SmallVector<Constraint *, 4> conversions;
32+
// First, let's collect all of the conversions associated
3333
// with this type variable.
34-
llvm::copy_if(Sources, std::back_inserter(subtypeOf),
35-
[&](const Constraint *constraint) -> bool {
36-
if (constraint->getKind() != ConstraintKind::Subtype)
37-
return false;
38-
39-
auto rhs = cs.simplifyType(constraint->getSecondType());
40-
return rhs->getAs<TypeVariableType>() == TypeVar;
41-
});
42-
43-
if (subtypeOf.empty())
34+
llvm::copy_if(
35+
Sources, std::back_inserter(conversions),
36+
[&](const Constraint *constraint) -> bool {
37+
if (constraint->getKind() != ConstraintKind::Subtype &&
38+
constraint->getKind() != ConstraintKind::Conversion &&
39+
constraint->getKind() != ConstraintKind::ArgumentConversion &&
40+
constraint->getKind() != ConstraintKind::OperatorArgumentConversion)
41+
return false;
42+
43+
auto rhs = cs.simplifyType(constraint->getSecondType());
44+
return rhs->getAs<TypeVariableType>() == TypeVar;
45+
});
46+
47+
if (conversions.empty())
4448
return;
4549

46-
for (auto *constraint : subtypeOf) {
50+
for (auto *constraint : conversions) {
4751
auto *tv =
4852
cs.simplifyType(constraint->getFirstType())->getAs<TypeVariableType>();
4953
if (!tv)
@@ -53,6 +57,15 @@ void ConstraintSystem::PotentialBindings::inferTransitiveBindings(
5357
if (relatedBindings == inferredBindings.end())
5458
continue;
5559

60+
// Infer transitive protocol requirements.
61+
for (auto *protocol : relatedBindings->getSecond().Protocols) {
62+
Protocols.push_back(protocol);
63+
}
64+
65+
// TODO: We shouldn't need this in the future.
66+
if (constraint->getKind() != ConstraintKind::Subtype)
67+
continue;
68+
5669
for (auto &binding : relatedBindings->getSecond().Bindings) {
5770
// We need the binding kind for the potential binding to
5871
// either be Exact or Supertypes in order for it to make sense
@@ -76,11 +89,6 @@ void ConstraintSystem::PotentialBindings::inferTransitiveBindings(
7689
addPotentialBinding(
7790
binding.withSameSource(type, BindingKind::Supertypes));
7891
}
79-
80-
// Infer transitive protocol requirements.
81-
for (auto *protocol : relatedBindings->getSecond().Protocols) {
82-
Protocols.push_back(protocol);
83-
}
8492
}
8593
}
8694

0 commit comments

Comments
 (0)