Skip to content

Commit 472ea7f

Browse files
committed
AST: Propagate the LazyConformanceLoader from SynthesizedProtocolAttr to the conformance
1 parent 6d3ea57 commit 472ea7f

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

lib/AST/ConformanceLookupTable.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -827,6 +827,33 @@ ProtocolConformance *ConformanceLookupTable::getConformance(
827827
conformance = ctx.getConformance(conformingType, protocol, conformanceLoc,
828828
conformingDC,
829829
ProtocolConformanceState::Incomplete);
830+
831+
// If the conformance was synthesized by the ClangImporter, give it a
832+
// lazy loader that will be used to populate the conformance.
833+
834+
// First, if this is a conformance to a base protocol of a derived
835+
// protocol, find the most derived protocol.
836+
auto *impliedEntry = entry;
837+
while (impliedEntry->getKind() == ConformanceEntryKind::Implied)
838+
impliedEntry = impliedEntry->Source.getImpliedSource();
839+
840+
// Check if this was a synthesized conformance.
841+
if (impliedEntry->getKind() == ConformanceEntryKind::Synthesized) {
842+
auto *impliedProto = impliedEntry->getProtocol();
843+
844+
// Find a SynthesizedProtocolAttr corresponding to the protocol.
845+
for (auto attr : conformingNominal->getAttrs()
846+
.getAttributes<SynthesizedProtocolAttr>()) {
847+
auto otherProto = ctx.getProtocol(attr->getProtocolKind());
848+
if (otherProto == impliedProto) {
849+
// Set the conformance loader to the loader stashed inside
850+
// the attribute.
851+
cast<NormalProtocolConformance>(conformance)
852+
->setLazyLoader(attr->getLazyLoader(), /*context=*/0);
853+
break;
854+
}
855+
}
856+
}
830857
}
831858

832859
// Record the conformance.

0 commit comments

Comments
 (0)