Skip to content

Commit acb53d2

Browse files
authored
Merge pull request #82132 from slavapestov/bind-extensions-macro-6.2
[6.2] Sema: Don't expand macros when binding extensions
2 parents c1db12a + a10cc92 commit acb53d2

File tree

9 files changed

+60
-33
lines changed

9 files changed

+60
-33
lines changed

include/swift/AST/Decl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2064,7 +2064,8 @@ class ExtensionDecl final : public GenericContext, public Decl,
20642064
NominalTypeDecl *getExtendedNominal() const;
20652065

20662066
/// Compute the nominal type declaration that is being extended.
2067-
NominalTypeDecl *computeExtendedNominal() const;
2067+
NominalTypeDecl *computeExtendedNominal(
2068+
bool excludeMacroExpansions=false) const;
20682069

20692070
/// \c hasBeenBound means nothing if this extension can never been bound
20702071
/// because it is not at the top level.

include/swift/AST/NameLookupRequests.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ class HasMissingDesignatedInitializersRequest :
267267
/// Request the nominal declaration extended by a given extension declaration.
268268
class ExtendedNominalRequest
269269
: public SimpleRequest<
270-
ExtendedNominalRequest, NominalTypeDecl *(ExtensionDecl *),
270+
ExtendedNominalRequest, NominalTypeDecl *(ExtensionDecl *, bool),
271271
RequestFlags::SeparatelyCached | RequestFlags::DependencySink> {
272272
public:
273273
using SimpleRequest::SimpleRequest;
@@ -276,8 +276,8 @@ class ExtendedNominalRequest
276276
friend SimpleRequest;
277277

278278
// Evaluation.
279-
NominalTypeDecl *
280-
evaluate(Evaluator &evaluator, ExtensionDecl *ext) const;
279+
NominalTypeDecl * evaluate(Evaluator &evaluator, ExtensionDecl *ext,
280+
bool excludeMacroExpansions) const;
281281

282282
public:
283283
// Separate caching.

lib/AST/Decl.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2075,11 +2075,14 @@ NominalTypeDecl *ExtensionDecl::getExtendedNominal() const {
20752075
"Extension must have already been bound (by bindExtensions)");
20762076
}
20772077

2078-
NominalTypeDecl *ExtensionDecl::computeExtendedNominal() const {
2078+
NominalTypeDecl *ExtensionDecl::computeExtendedNominal(
2079+
bool excludeMacroExpansions) const {
20792080
ASTContext &ctx = getASTContext();
2080-
return evaluateOrDefault(
2081-
ctx.evaluator, ExtendedNominalRequest{const_cast<ExtensionDecl *>(this)},
2082-
nullptr);
2081+
return evaluateOrDefault(ctx.evaluator,
2082+
ExtendedNominalRequest{
2083+
const_cast<ExtensionDecl *>(this),
2084+
excludeMacroExpansions},
2085+
nullptr);
20832086
}
20842087

20852088
bool ExtensionDecl::canNeverBeBound() const {

lib/AST/NameLookup.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1125,6 +1125,9 @@ enum class DirectlyReferencedTypeLookupFlags {
11251125
/// Include members that would normally be excluded because they come from
11261126
/// modules that have not been imported directly.
11271127
IgnoreMissingImports = 1 << 3,
1128+
1129+
/// Whenther we should exclude macro expansions.
1130+
ExcludeMacroExpansions = 1 << 4,
11281131
};
11291132

11301133
using DirectlyReferencedTypeLookupOptions =
@@ -3065,6 +3068,10 @@ static DirectlyReferencedTypeDecls directReferencesForUnqualifiedTypeLookup(
30653068
DirectlyReferencedTypeLookupFlags::IgnoreMissingImports))
30663069
options |= UnqualifiedLookupFlags::IgnoreMissingImports;
30673070

3071+
if (typeLookupOptions.contains(
3072+
DirectlyReferencedTypeLookupFlags::ExcludeMacroExpansions))
3073+
options |= UnqualifiedLookupFlags::ExcludeMacroExpansions;
3074+
30683075
// Manually exclude macro expansions here since the source location
30693076
// is overridden below.
30703077
if (namelookup::isInMacroArgument(dc->getParentSourceFile(), loc))
@@ -3147,6 +3154,10 @@ static llvm::TinyPtrVector<TypeDecl *> directReferencesForQualifiedTypeLookup(
31473154
DirectlyReferencedTypeLookupFlags::IgnoreMissingImports))
31483155
options |= NL_IgnoreMissingImports;
31493156

3157+
if (typeLookupOptions.contains(
3158+
DirectlyReferencedTypeLookupFlags::ExcludeMacroExpansions))
3159+
options |= NL_ExcludeMacroExpansions;
3160+
31503161
// Look through the type declarations we were given, resolving them down
31513162
// to nominal type declarations, module declarations, and
31523163
SmallVector<ModuleDecl *, 2> moduleDecls;
@@ -3574,7 +3585,8 @@ ProtocolRequirementsRequest::evaluate(Evaluator &evaluator,
35743585

35753586
NominalTypeDecl *
35763587
ExtendedNominalRequest::evaluate(Evaluator &evaluator,
3577-
ExtensionDecl *ext) const {
3588+
ExtensionDecl *ext,
3589+
bool excludeMacroExpansions) const {
35783590
auto typeRepr = ext->getExtendedTypeRepr();
35793591
if (!typeRepr) {
35803592
// We must've seen 'extension { ... }' during parsing.
@@ -3583,9 +3595,15 @@ ExtendedNominalRequest::evaluate(Evaluator &evaluator,
35833595

35843596
ASTContext &ctx = ext->getASTContext();
35853597
auto options = defaultDirectlyReferencedTypeLookupOptions;
3598+
35863599
if (ext->isInSpecializeExtensionContext()) {
35873600
options |= DirectlyReferencedTypeLookupFlags::AllowUsableFromInline;
35883601
}
3602+
3603+
if (excludeMacroExpansions) {
3604+
options |= DirectlyReferencedTypeLookupFlags::ExcludeMacroExpansions;
3605+
}
3606+
35893607
DirectlyReferencedTypeDecls referenced = directReferencesForTypeRepr(
35903608
evaluator, ctx, typeRepr, ext->getParent(), options);
35913609

lib/ClangImporter/ImportDecl.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5453,8 +5453,7 @@ namespace {
54535453
{ }, dc, nullptr, decl);
54545454
Impl.SwiftContext.evaluator.cacheOutput(ExtendedTypeRequest{result},
54555455
objcClass->getDeclaredType());
5456-
Impl.SwiftContext.evaluator.cacheOutput(ExtendedNominalRequest{result},
5457-
std::move(objcClass));
5456+
result->setExtendedNominal(objcClass);
54585457

54595458
Identifier categoryName;
54605459
if (!decl->getName().empty())
@@ -10230,8 +10229,7 @@ ClangImporter::Implementation::importDeclContextOf(
1023010229
getClangModuleForDecl(decl), nullptr);
1023110230
SwiftContext.evaluator.cacheOutput(ExtendedTypeRequest{ext},
1023210231
nominal->getDeclaredType());
10233-
SwiftContext.evaluator.cacheOutput(ExtendedNominalRequest{ext},
10234-
std::move(nominal));
10232+
ext->setExtendedNominal(nominal);
1023510233

1023610234
// Record this extension so we can find it later. We do this early because
1023710235
// once we've set the member loader, we don't know when the compiler will use

lib/Frontend/ModuleInterfaceSupport.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -799,8 +799,7 @@ class InheritedProtocolCollector {
799799

800800
ctx.evaluator.cacheOutput(ExtendedTypeRequest{extension},
801801
nominal->getDeclaredType());
802-
ctx.evaluator.cacheOutput(ExtendedNominalRequest{extension},
803-
const_cast<NominalTypeDecl *>(nominal));
802+
extension->setExtendedNominal(const_cast<NominalTypeDecl *>(nominal));
804803

805804
extension->print(printer, printOptions);
806805
printer << "\n";

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7175,8 +7175,7 @@ ProtocolConformance *swift::deriveImplicitSendableConformance(
71757175

71767176
ctx.evaluator.cacheOutput(ExtendedTypeRequest{extension},
71777177
nominal->getDeclaredType());
7178-
ctx.evaluator.cacheOutput(ExtendedNominalRequest{extension},
7179-
std::move(nominal));
7178+
extension->setExtendedNominal(nominal);
71807179
nominal->addExtension(extension);
71817180

71827181
// Make it accessible to getTopLevelDecls()

lib/Sema/TypeChecker.cpp

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -191,12 +191,14 @@ ModuleDecl *TypeChecker::getStdlibModule(const DeclContext *dc) {
191191
}
192192

193193
void swift::bindExtensions(ModuleDecl &mod) {
194+
bool excludeMacroExpansions = true;
195+
194196
// Utility function to try and resolve the extended type without diagnosing.
195197
// If we succeed, we go ahead and bind the extension. Otherwise, return false.
196198
auto tryBindExtension = [&](ExtensionDecl *ext) -> bool {
197199
assert(!ext->canNeverBeBound() &&
198200
"Only extensions that can ever be bound get here.");
199-
if (auto nominal = ext->computeExtendedNominal()) {
201+
if (auto nominal = ext->computeExtendedNominal(excludeMacroExpansions)) {
200202
nominal->addExtension(ext);
201203
return true;
202204
}
@@ -228,20 +230,28 @@ void swift::bindExtensions(ModuleDecl &mod) {
228230
visitTopLevelDecl(D);
229231
}
230232

231-
// Phase 2 - repeatedly go through the worklist and attempt to bind each
232-
// extension there, removing it from the worklist if we succeed.
233-
bool changed;
234-
do {
235-
changed = false;
236-
237-
auto last = std::remove_if(worklist.begin(), worklist.end(),
238-
tryBindExtension);
239-
if (last != worklist.end()) {
240-
worklist.erase(last, worklist.end());
241-
changed = true;
242-
}
243-
} while(changed);
233+
auto tryBindExtensions = [&]() {
234+
// Phase 2 - repeatedly go through the worklist and attempt to bind each
235+
// extension there, removing it from the worklist if we succeed.
236+
bool changed;
237+
do {
238+
changed = false;
239+
240+
auto last = std::remove_if(worklist.begin(), worklist.end(),
241+
tryBindExtension);
242+
if (last != worklist.end()) {
243+
worklist.erase(last, worklist.end());
244+
changed = true;
245+
}
246+
} while(changed);
247+
};
248+
249+
tryBindExtensions();
244250

251+
// If that fails, try again, but this time expand macros.
252+
excludeMacroExpansions = false;
253+
tryBindExtensions();
254+
245255
// Any remaining extensions are invalid. They will be diagnosed later by
246256
// typeCheckDecl().
247257
}

lib/Serialization/Deserialization.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5420,8 +5420,7 @@ class DeclDeserializer {
54205420
ctx.evaluator.cacheOutput(ExtendedTypeRequest{extension},
54215421
std::move(extendedType));
54225422
auto nominal = dyn_cast_or_null<NominalTypeDecl>(MF.getDecl(extendedNominalID));
5423-
ctx.evaluator.cacheOutput(ExtendedNominalRequest{extension},
5424-
std::move(nominal));
5423+
extension->setExtendedNominal(nominal);
54255424

54265425
if (isImplicit)
54275426
extension->setImplicit();

0 commit comments

Comments
 (0)