Skip to content

Commit a189be3

Browse files
authored
Merge pull request #67981 from DougGregor/extension-macro-fixes-5.9
2 parents 0664218 + fa48076 commit a189be3

12 files changed

+147
-52
lines changed

include/swift/AST/DeclContext.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,6 @@ enum class ConformanceLookupKind : unsigned {
172172
/// All conformances except structurally-derived conformances, of which
173173
/// Sendable is the only one.
174174
NonStructural,
175-
/// Exclude conformances added by a macro that has not been expanded
176-
/// yet.
177-
ExcludeUnexpandedMacros,
178175
};
179176

180177
/// Describes a diagnostic for a conflict between two protocol

include/swift/AST/ProtocolConformance.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,8 @@ class NormalProtocolConformance : public RootProtocolConformance,
552552
assert((sourceKind == ConformanceEntryKind::Implied) ==
553553
(bool)implyingConformance &&
554554
"an implied conformance needs something that implies it");
555+
assert(sourceKind != ConformanceEntryKind::PreMacroExpansion &&
556+
"cannot create conformance pre-macro-expansion");
555557
SourceKindAndImplyingConformance = {implyingConformance, sourceKind};
556558
}
557559

lib/AST/ConformanceLookupTable.cpp

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -889,6 +889,16 @@ ConformanceLookupTable::getConformance(NominalTypeDecl *nominal,
889889
if (!conformingDC)
890890
return nullptr;
891891

892+
// Never produce a conformance for a pre-macro-expansion conformance. They
893+
// are placeholders that will be superseded.
894+
if (entry->getKind() == ConformanceEntryKind::PreMacroExpansion) {
895+
if (auto supersedingEntry = entry->SupersededBy) {
896+
return getConformance(nominal, supersedingEntry);
897+
}
898+
899+
return nullptr;
900+
}
901+
892902
auto *conformingNominal = conformingDC->getSelfNominalTypeDecl();
893903

894904
// Form the conformance.
@@ -926,6 +936,16 @@ ConformanceLookupTable::getConformance(NominalTypeDecl *nominal,
926936
? conformingNominal->getLoc()
927937
: cast<ExtensionDecl>(conformingDC)->getLoc();
928938

939+
NormalProtocolConformance *implyingConf = nullptr;
940+
if (entry->Source.getKind() == ConformanceEntryKind::Implied) {
941+
auto implyingEntry = entry->Source.getImpliedSource();
942+
auto origImplyingConf = getConformance(conformingNominal, implyingEntry);
943+
if (!origImplyingConf)
944+
return nullptr;
945+
946+
implyingConf = origImplyingConf->getRootNormalConformance();
947+
}
948+
929949
// Create or find the normal conformance.
930950
auto normalConf =
931951
ctx.getConformance(conformingType, protocol, conformanceLoc,
@@ -936,12 +956,6 @@ ConformanceLookupTable::getConformance(NominalTypeDecl *nominal,
936956
// early return at the start of this function.
937957
entry->Conformance = normalConf;
938958

939-
NormalProtocolConformance *implyingConf = nullptr;
940-
if (entry->Source.getKind() == ConformanceEntryKind::Implied) {
941-
auto implyingEntry = entry->Source.getImpliedSource();
942-
implyingConf = getConformance(conformingNominal, implyingEntry)
943-
->getRootNormalConformance();
944-
}
945959
normalConf->setSourceKindAndImplyingConformance(entry->Source.getKind(),
946960
implyingConf);
947961

lib/AST/NameLookup.cpp

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1757,6 +1757,17 @@ namespace {
17571757
};
17581758
}
17591759

1760+
/// Given an extension declaration, return the extended nominal type if the
1761+
/// extension was produced by expanding an extension or conformance macro from
1762+
/// the nominal declaration itself.
1763+
static NominalTypeDecl *nominalForExpandedExtensionDecl(ExtensionDecl *ext) {
1764+
if (!ext->isInMacroExpansionInContext())
1765+
return nullptr;
1766+
1767+
1768+
return ext->getSelfNominalTypeDecl();
1769+
}
1770+
17601771
PotentialMacroExpansions PotentialMacroExpansionsInContextRequest::evaluate(
17611772
Evaluator &evaluator, TypeOrExtensionDecl container) const {
17621773
/// The implementation here needs to be kept in sync with
@@ -1767,6 +1778,15 @@ PotentialMacroExpansions PotentialMacroExpansionsInContextRequest::evaluate(
17671778
auto containerDecl = container.getAsDecl();
17681779
forEachPotentialAttachedMacro(containerDecl, MacroRole::Member, nameTracker);
17691780

1781+
// If the container is an extension that was created from an extension macro,
1782+
// look at the nominal declaration to find any extension macros.
1783+
if (auto ext = dyn_cast<ExtensionDecl>(containerDecl)) {
1784+
if (auto nominal = nominalForExpandedExtensionDecl(ext)) {
1785+
forEachPotentialAttachedMacro(
1786+
nominal, MacroRole::Extension, nameTracker);
1787+
}
1788+
}
1789+
17701790
// Peer and freestanding declaration macros.
17711791
auto dc = container.getAsDeclContext();
17721792
auto idc = container.getAsIterableDeclContext();
@@ -1825,13 +1845,15 @@ populateLookupTableEntryFromMacroExpansions(ASTContext &ctx,
18251845
// names match.
18261846
{
18271847
MacroIntroducedNameTracker nameTracker;
1828-
if (auto nominal = dyn_cast<NominalTypeDecl>(container.getAsDecl())) {
1829-
forEachPotentialAttachedMacro(nominal, MacroRole::Extension, nameTracker);
1830-
if (nameTracker.shouldExpandForName(name)) {
1831-
(void)evaluateOrDefault(
1832-
ctx.evaluator,
1833-
ExpandExtensionMacros{nominal},
1834-
false);
1848+
if (auto ext = dyn_cast<ExtensionDecl>(container.getAsDecl())) {
1849+
if (auto nominal = nominalForExpandedExtensionDecl(ext)) {
1850+
forEachPotentialAttachedMacro(nominal, MacroRole::Extension, nameTracker);
1851+
if (nameTracker.shouldExpandForName(name)) {
1852+
(void)evaluateOrDefault(
1853+
ctx.evaluator,
1854+
ExpandExtensionMacros{nominal},
1855+
false);
1856+
}
18351857
}
18361858
}
18371859
}

lib/AST/ProtocolConformance.cpp

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,8 +1302,8 @@ IterableDeclContext::getLocalConformances(ConformanceLookupKind lookupKind)
13021302
switch (conformance->getSourceKind()) {
13031303
case ConformanceEntryKind::Explicit:
13041304
case ConformanceEntryKind::Synthesized:
1305+
return true;
13051306
case ConformanceEntryKind::PreMacroExpansion:
1306-
return true;
13071307
case ConformanceEntryKind::Implied:
13081308
case ConformanceEntryKind::Inherited:
13091309
return false;
@@ -1314,34 +1314,22 @@ IterableDeclContext::getLocalConformances(ConformanceLookupKind lookupKind)
13141314
case ConformanceEntryKind::Explicit:
13151315
case ConformanceEntryKind::Synthesized:
13161316
case ConformanceEntryKind::Implied:
1317-
case ConformanceEntryKind::PreMacroExpansion:
13181317
return true;
13191318
case ConformanceEntryKind::Inherited:
1319+
case ConformanceEntryKind::PreMacroExpansion:
13201320
return false;
13211321
}
13221322

13231323
case ConformanceLookupKind::All:
13241324
case ConformanceLookupKind::NonStructural:
13251325
return true;
1326-
1327-
case ConformanceLookupKind::ExcludeUnexpandedMacros:
1328-
switch (conformance->getSourceKind()) {
1329-
case ConformanceEntryKind::PreMacroExpansion:
1330-
return false;
1331-
case ConformanceEntryKind::Explicit:
1332-
case ConformanceEntryKind::Synthesized:
1333-
case ConformanceEntryKind::Implied:
1334-
case ConformanceEntryKind::Inherited:
1335-
return true;
1336-
}
13371326
}
13381327
});
13391328

13401329
// If we want to add structural conformances, do so now.
13411330
switch (lookupKind) {
13421331
case ConformanceLookupKind::All:
1343-
case ConformanceLookupKind::NonInherited:
1344-
case ConformanceLookupKind::ExcludeUnexpandedMacros: {
1332+
case ConformanceLookupKind::NonInherited: {
13451333
// Look for a Sendable conformance globally. If it is synthesized
13461334
// and matches this declaration context, use it.
13471335
auto dc = getAsGenericContext();

lib/SIL/IR/SILSymbolVisitor.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -238,9 +238,6 @@ class SILSymbolVisitorImpl : public ASTVisitor<SILSymbolVisitorImpl> {
238238
void addConformances(const IterableDeclContext *IDC) {
239239
for (auto conformance :
240240
IDC->getLocalConformances(ConformanceLookupKind::NonInherited)) {
241-
if (conformance->getSourceKind() == ConformanceEntryKind::PreMacroExpansion)
242-
continue;
243-
244241
auto protocol = conformance->getProtocol();
245242
if (Ctx.getOpts().PublicSymbolsOnly &&
246243
getDeclLinkage(protocol) != FormalLinkage::PublicUnique)

lib/SILGen/SILGenType.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,9 +1132,6 @@ class SILGenType : public TypeMemberVisitor<SILGenType> {
11321132
// are existential and do not have witness tables.
11331133
for (auto *conformance : theType->getLocalConformances(
11341134
ConformanceLookupKind::NonInherited)) {
1135-
if (conformance->getSourceKind() == ConformanceEntryKind::PreMacroExpansion)
1136-
continue;
1137-
11381135
assert(conformance->isComplete());
11391136
if (auto *normal = dyn_cast<NormalProtocolConformance>(conformance))
11401137
SGM.getWitnessTable(normal);

lib/Sema/TypeCheckMacros.cpp

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1238,9 +1238,13 @@ static SourceFile *evaluateAttachedMacro(MacroDecl *macro, Decl *attachedTo,
12381238
{
12391239
llvm::raw_string_ostream OS(conformanceList);
12401240
if (role == MacroRole::Extension) {
1241-
for (auto *protocol : conformances) {
1242-
protocol->getDeclaredType()->print(OS);
1243-
}
1241+
llvm::interleave(
1242+
conformances,
1243+
[&](const ProtocolDecl *protocol) {
1244+
protocol->getDeclaredType()->print(OS);
1245+
},
1246+
[&] { OS << ", "; }
1247+
);
12441248
} else {
12451249
OS << "";
12461250
}
@@ -1593,15 +1597,7 @@ llvm::Optional<unsigned> swift::expandExtensions(CustomAttr *attr,
15931597
for (auto protocol : potentialConformances) {
15941598
SmallVector<ProtocolConformance *, 2> existingConformances;
15951599
nominal->lookupConformance(protocol, existingConformances);
1596-
1597-
bool hasExistingConformance = llvm::any_of(
1598-
existingConformances,
1599-
[&](ProtocolConformance *conformance) {
1600-
return conformance->getSourceKind() !=
1601-
ConformanceEntryKind::PreMacroExpansion;
1602-
});
1603-
1604-
if (!hasExistingConformance) {
1600+
if (existingConformances.empty()) {
16051601
introducedConformances.push_back(protocol);
16061602
}
16071603
}

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6443,8 +6443,7 @@ void TypeChecker::checkConformancesInContext(IterableDeclContext *idc) {
64436443
const auto defaultAccess = nominal->getFormalAccess();
64446444

64456445
// Check each of the conformances associated with this context.
6446-
auto conformances = idc->getLocalConformances(
6447-
ConformanceLookupKind::ExcludeUnexpandedMacros);
6446+
auto conformances = idc->getLocalConformances();
64486447

64496448
// The conformance checker bundle that checks all conformances in the context.
64506449
auto &Context = dc->getASTContext();

test/IDE/complete_optionset.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ public macro OptionSet<RawType>() =
2828
// MEMBER_STATIC: Decl[StaticVar]/CurrNominal: secondDay[#ShippingOptions#]; name=secondDay
2929
// MEMBER_STATIC: Decl[StaticVar]/CurrNominal: priority[#ShippingOptions#]; name=priority
3030
// MEMBER_STATIC: Decl[StaticVar]/CurrNominal: standard[#ShippingOptions#]; name=standard
31-
// MEMBER_STATIC: Decl[TypeAlias]/CurrNominal: ArrayLiteralElement[#ShippingOptions#]; name=ArrayLiteralElement
3231
// MEMBER_STATIC: Decl[TypeAlias]/CurrNominal: Element[#ShippingOptions#]; name=Element
3332
// MEMBER_STATIC: Decl[Constructor]/Super/IsSystem: init()[#ShippingOptions#]; name=init()
3433
// MEMBER_STATIC: Decl[Constructor]/Super/IsSystem: init({#(sequence): Sequence#})[#ShippingOptions#]; name=init(:)

0 commit comments

Comments
 (0)