Skip to content

Commit d310f37

Browse files
committed
[CSBindings] Infer transitive protocols only for unresolved member base
Nothing besides static member refs on protocols feature is currently using transitive protocols, so instead of trying to infer them on every step let's do that only for base type of a dot-syntax reference when there are no other bindings for it.
1 parent a075459 commit d310f37

File tree

3 files changed

+10
-16
lines changed

3 files changed

+10
-16
lines changed

lib/Sema/CSBindings.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,6 @@ void BindingSet::inferTransitiveBindings(
461461

462462
void BindingSet::finalize(
463463
llvm::SmallDenseMap<TypeVariableType *, BindingSet> &inferredBindings) {
464-
inferTransitiveProtocolRequirements(inferredBindings);
465464
inferTransitiveBindings(inferredBindings);
466465

467466
determineLiteralCoverage();
@@ -478,11 +477,14 @@ void BindingSet::finalize(
478477
// func foo<T: P>(_: T) {}
479478
// foo(.bar) <- `.bar` should be a static member of `P`.
480479
// \endcode
481-
if (!hasViableBindings() && TransitiveProtocols.hasValue()) {
482-
for (auto *constraint : *TransitiveProtocols) {
483-
auto protocolTy = constraint->getSecondType();
484-
addBinding(
485-
{protocolTy, AllowedBindingKind::Exact, constraint});
480+
if (!hasViableBindings()) {
481+
inferTransitiveProtocolRequirements(inferredBindings);
482+
483+
if (TransitiveProtocols.hasValue()) {
484+
for (auto *constraint : *TransitiveProtocols) {
485+
auto protocolTy = constraint->getSecondType();
486+
addBinding({protocolTy, AllowedBindingKind::Exact, constraint});
487+
}
486488
}
487489
}
488490
}

unittests/Sema/BindingInferenceTests.cpp

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -330,16 +330,7 @@ TEST_F(SemaTest, TestTransitiveProtocolInferenceThroughEquivalenceChains) {
330330
cs.addConstraint(ConstraintKind::ConformsTo, typeVar2, protocolTy0, nilLocator);
331331
cs.addConstraint(ConstraintKind::ConformsTo, typeVar3, protocolTy1, nilLocator);
332332

333-
llvm::SmallDenseMap<TypeVariableType *, BindingSet> cache;
334-
for (auto *typeVar : cs.getTypeVariables()) {
335-
cache.insert({typeVar, cs.getBindingsFor(typeVar, /*finalize=*/false)});
336-
}
337-
338-
auto bindingSet = cache.find(typeVar0);
339-
assert(bindingSet != cache.end());
340-
341-
auto &bindings = bindingSet->getSecond();
342-
bindings.inferTransitiveProtocolRequirements(cache);
333+
auto bindings = inferBindings(cs, typeVar0);
343334

344335
ASSERT_TRUE(bool(bindings.TransitiveProtocols));
345336
verifyProtocolInferenceResults(*bindings.TransitiveProtocols,

unittests/Sema/SemaFixture.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ BindingSet SemaTest::inferBindings(ConstraintSystem &cs,
136136
continue;
137137

138138
auto &bindings = cachedBindings->getSecond();
139+
bindings.inferTransitiveProtocolRequirements(cache);
139140
bindings.finalize(cache);
140141
}
141142

0 commit comments

Comments
 (0)