Skip to content

Commit 052ff42

Browse files
committed
AST: Don't add duplicate synthesized conformances
If an enum has a raw type, and a SynthesizedProtocolAttr, don't add two duplicate conformances, since that triggers an assertion. Instead, make sure to only add each conformance once. We cannot just drop the SynthesizedProtocolAttr in this case, because we need to pull the LazyConformanceLoader out of it.
1 parent 6e21af0 commit 052ff42

File tree

1 file changed

+20
-20
lines changed

1 file changed

+20
-20
lines changed

lib/AST/ProtocolConformance.cpp

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -817,37 +817,37 @@ void NominalTypeDecl::prepareConformanceTable() const {
817817
return;
818818
}
819819

820-
// Add any synthesized conformances.
820+
SmallPtrSet<ProtocolDecl *, 2> protocols;
821+
822+
auto addSynthesized = [&](KnownProtocolKind kind) {
823+
if (auto *proto = getASTContext().getProtocol(kind)) {
824+
if (protocols.count(proto) == 0) {
825+
ConformanceTable->addSynthesizedConformance(mutableThis, proto);
826+
protocols.insert(proto);
827+
}
828+
}
829+
};
830+
831+
// Add protocols for any synthesized protocol attributes.
832+
for (auto attr : getAttrs().getAttributes<SynthesizedProtocolAttr>()) {
833+
addSynthesized(attr->getProtocolKind());
834+
}
835+
836+
// Add any implicit conformances.
821837
if (auto theEnum = dyn_cast<EnumDecl>(mutableThis)) {
822838
if (theEnum->hasCases() && theEnum->hasOnlyCasesWithoutAssociatedValues()) {
823839
// Simple enumerations conform to Equatable.
824-
if (auto equatable = ctx.getProtocol(KnownProtocolKind::Equatable)) {
825-
ConformanceTable->addSynthesizedConformance(mutableThis, equatable);
826-
}
840+
addSynthesized(KnownProtocolKind::Equatable);
827841

828842
// Simple enumerations conform to Hashable.
829-
if (auto hashable = getASTContext().getProtocol(
830-
KnownProtocolKind::Hashable)) {
831-
ConformanceTable->addSynthesizedConformance(mutableThis, hashable);
832-
}
843+
addSynthesized(KnownProtocolKind::Hashable);
833844
}
834845

835846
// Enumerations with a raw type conform to RawRepresentable.
836847
if (resolver)
837848
resolver->resolveRawType(theEnum);
838849
if (theEnum->hasRawType()) {
839-
if (auto rawRepresentable =
840-
ctx.getProtocol(KnownProtocolKind::RawRepresentable)) {
841-
ConformanceTable->addSynthesizedConformance(mutableThis,
842-
rawRepresentable);
843-
}
844-
}
845-
}
846-
847-
// Add protocols for any synthesized protocol attributes.
848-
for (auto attr : getAttrs().getAttributes<SynthesizedProtocolAttr>()) {
849-
if (auto proto = getASTContext().getProtocol(attr->getProtocolKind())) {
850-
ConformanceTable->addSynthesizedConformance(mutableThis, proto);
850+
addSynthesized(KnownProtocolKind::RawRepresentable);
851851
}
852852
}
853853
}

0 commit comments

Comments
 (0)