Skip to content

Commit 72401ca

Browse files
authored
Merge pull request #82129 from slavapestov/bind-extensions-macro
Sema: Don't expand macros when binding extensions
2 parents c24bae7 + 63a5731 commit 72401ca

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
@@ -2061,7 +2061,8 @@ class ExtensionDecl final : public GenericContext, public Decl,
20612061
NominalTypeDecl *getExtendedNominal() const;
20622062

20632063
/// Compute the nominal type declaration that is being extended.
2064-
NominalTypeDecl *computeExtendedNominal() const;
2064+
NominalTypeDecl *computeExtendedNominal(
2065+
bool excludeMacroExpansions=false) const;
20652066

20662067
/// \c hasBeenBound means nothing if this extension can never been bound
20672068
/// 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
@@ -2079,11 +2079,14 @@ NominalTypeDecl *ExtensionDecl::getExtendedNominal() const {
20792079
"Extension must have already been bound (by bindExtensions)");
20802080
}
20812081

2082-
NominalTypeDecl *ExtensionDecl::computeExtendedNominal() const {
2082+
NominalTypeDecl *ExtensionDecl::computeExtendedNominal(
2083+
bool excludeMacroExpansions) const {
20832084
ASTContext &ctx = getASTContext();
2084-
return evaluateOrDefault(
2085-
ctx.evaluator, ExtendedNominalRequest{const_cast<ExtensionDecl *>(this)},
2086-
nullptr);
2085+
return evaluateOrDefault(ctx.evaluator,
2086+
ExtendedNominalRequest{
2087+
const_cast<ExtensionDecl *>(this),
2088+
excludeMacroExpansions},
2089+
nullptr);
20872090
}
20882091

20892092
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
@@ -5474,8 +5474,7 @@ namespace {
54745474
{ }, dc, nullptr, decl);
54755475
Impl.SwiftContext.evaluator.cacheOutput(ExtendedTypeRequest{result},
54765476
objcClass->getDeclaredType());
5477-
Impl.SwiftContext.evaluator.cacheOutput(ExtendedNominalRequest{result},
5478-
std::move(objcClass));
5477+
result->setExtendedNominal(objcClass);
54795478

54805479
Identifier categoryName;
54815480
if (!decl->getName().empty())
@@ -10256,8 +10255,7 @@ ClangImporter::Implementation::importDeclContextOf(
1025610255
getClangModuleForDecl(decl), nullptr);
1025710256
SwiftContext.evaluator.cacheOutput(ExtendedTypeRequest{ext},
1025810257
nominal->getDeclaredType());
10259-
SwiftContext.evaluator.cacheOutput(ExtendedNominalRequest{ext},
10260-
std::move(nominal));
10258+
ext->setExtendedNominal(nominal);
1026110259

1026210260
// Record this extension so we can find it later. We do this early because
1026310261
// 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
@@ -800,8 +800,7 @@ class InheritedProtocolCollector {
800800

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

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

lib/Sema/TypeCheckConcurrency.cpp

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

71597159
ctx.evaluator.cacheOutput(ExtendedTypeRequest{extension},
71607160
nominal->getDeclaredType());
7161-
ctx.evaluator.cacheOutput(ExtendedNominalRequest{extension},
7162-
std::move(nominal));
7161+
extension->setExtendedNominal(nominal);
71637162
nominal->addExtension(extension);
71647163

71657164
// 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
@@ -5465,8 +5465,7 @@ class DeclDeserializer {
54655465
ctx.evaluator.cacheOutput(ExtendedTypeRequest{extension},
54665466
std::move(extendedType));
54675467
auto nominal = dyn_cast_or_null<NominalTypeDecl>(MF.getDecl(extendedNominalID));
5468-
ctx.evaluator.cacheOutput(ExtendedNominalRequest{extension},
5469-
std::move(nominal));
5468+
extension->setExtendedNominal(nominal);
54705469

54715470
if (isImplicit)
54725471
extension->setImplicit();

0 commit comments

Comments
 (0)