Skip to content

Commit e29c3a9

Browse files
committed
AST: Lazily populate associated conformances with -enable-experimental-associated-type-inference
1 parent b1ed3c2 commit e29c3a9

File tree

2 files changed

+41
-5
lines changed

2 files changed

+41
-5
lines changed

lib/AST/ProtocolConformance.cpp

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -535,27 +535,48 @@ ProtocolConformance::getAssociatedConformance(Type assocType,
535535
ProtocolConformanceRef
536536
NormalProtocolConformance::getAssociatedConformance(Type assocType,
537537
ProtocolDecl *protocol) const {
538+
if (Loader)
539+
resolveLazyInfo();
540+
538541
assert(assocType->isTypeParameter() &&
539542
"associated type must be a type parameter");
540543

541544
llvm::Optional<ProtocolConformanceRef> result;
542545

546+
auto &ctx = getDeclContext()->getASTContext();
547+
543548
forEachAssociatedConformance(
544549
[&](Type t, ProtocolDecl *p, unsigned index) {
545550
if (t->isEqual(assocType) && p == protocol) {
546-
// Fill in the signature conformances, if we haven't done so yet.
547-
if (!hasComputedAssociatedConformances()) {
548-
const_cast<NormalProtocolConformance *>(this)
549-
->finishSignatureConformances();
551+
if (!ctx.LangOpts.hasFeature(Feature::TypeWitnessSystemInference)) {
552+
// Fill in the signature conformances, if we haven't done so yet.
553+
if (!hasComputedAssociatedConformances()) {
554+
const_cast<NormalProtocolConformance *>(this)
555+
->finishSignatureConformances();
556+
}
557+
}
558+
559+
// Not strictly necessary, but avoids a bit of request evaluator
560+
// overhead in the happy case.
561+
if (hasComputedAssociatedConformances()) {
562+
result = AssociatedConformances[index];
563+
if (result)
564+
return true;
550565
}
551566

552-
result = getAssociatedConformance(index);
567+
result = evaluateOrDefault(ctx.evaluator,
568+
AssociatedConformanceRequest{
569+
const_cast<NormalProtocolConformance *>(this),
570+
t->getCanonicalType(), p, index
571+
}, ProtocolConformanceRef::forInvalid());
553572
return true;
554573
}
555574

556575
return false;
557576
});
558577

578+
assert(result && "Subject type must be exactly equal to left-hand side of a"
579+
"conformance requirement in protocol requirement signature");
559580
return *result;
560581
}
561582

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: not %target-swift-frontend -typecheck %s -enable-experimental-associated-type-inference
2+
3+
struct SyntaxCollectionIterator<E: SyntaxProtocol>: IteratorProtocol {
4+
typealias Element = E
5+
}
6+
7+
protocol SyntaxCollection: BidirectionalCollection {}
8+
9+
extension SyntaxCollection {
10+
typealias Iterator = SyntaxCollectionIterator<Element>
11+
}
12+
13+
struct AccessorListSyntax: SyntaxCollection {
14+
typealias Element = Int
15+
}

0 commit comments

Comments
 (0)