Skip to content

Commit 094dda6

Browse files
authored
Merge pull request #66956 from hborla/5.9-conformance-macro-in-extension
[5.9][Macros] Don't visit macro-generated extensions in `visitAuxiliaryDecls`.
2 parents 5a28850 + d073c21 commit 094dda6

File tree

10 files changed

+43
-43
lines changed

10 files changed

+43
-43
lines changed

lib/AST/Decl.cpp

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -407,20 +407,6 @@ void Decl::visitAuxiliaryDecls(
407407
}
408408
}
409409

410-
if (auto *nominal = dyn_cast<NominalTypeDecl>(mutableThis)) {
411-
auto conformanceBuffers =
412-
evaluateOrDefault(ctx.evaluator,
413-
ExpandConformanceMacros{nominal},
414-
{});
415-
for (auto bufferID : conformanceBuffers) {
416-
auto startLoc = sourceMgr.getLocForBufferStart(bufferID);
417-
auto *sourceFile = moduleDecl->getSourceFileContainingLocation(startLoc);
418-
for (auto *extension : sourceFile->getTopLevelDecls()) {
419-
callback(extension);
420-
}
421-
}
422-
}
423-
424410
if (visitFreestandingExpanded) {
425411
if (auto *med = dyn_cast<MacroExpansionDecl>(mutableThis)) {
426412
if (auto bufferID = evaluateOrDefault(

lib/AST/Module.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4101,8 +4101,7 @@ void FileUnit::getTopLevelDeclsWithAuxiliaryDecls(
41014101
getTopLevelDecls(nonExpandedDecls);
41024102
for (auto *decl : nonExpandedDecls) {
41034103
decl->visitAuxiliaryDecls([&](Decl *auxDecl) {
4104-
if (!isa<ExtensionDecl>(auxDecl))
4105-
results.push_back(auxDecl);
4104+
results.push_back(auxDecl);
41064105
});
41074106
results.push_back(decl);
41084107
}

lib/IRGen/GenDecl.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5510,11 +5510,6 @@ void IRGenModule::emitNestedTypeDecls(DeclRange members) {
55105510
continue;
55115511

55125512
member->visitAuxiliaryDecls([&](Decl *decl) {
5513-
// FIXME: Conformance macros can generate extension decls. These
5514-
// are visited as top-level decls; skip them here.
5515-
if (isa<ExtensionDecl>(decl))
5516-
return;
5517-
55185513
emitNestedTypeDecls({decl, nullptr});
55195514
});
55205515
switch (member->getKind()) {

lib/Index/Index.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,6 +1142,9 @@ void IndexSwiftASTWalker::visitModule(ModuleDecl &Mod) {
11421142
if (!handleSourceOrModuleFile(*SrcFile))
11431143
return;
11441144
walk(*SrcFile);
1145+
if (auto *synthesizedSF = SrcFile->getSynthesizedFile()) {
1146+
walk(synthesizedSF);
1147+
}
11451148
} else {
11461149
IsModuleFile = true;
11471150
isSystemModule = Mod.isNonUserModule();

lib/SILGen/SILGen.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2201,10 +2201,6 @@ class SILGenModuleRAII {
22012201
for (auto *D : sf->getTopLevelDecls()) {
22022202
// Emit auxiliary decls.
22032203
D->visitAuxiliaryDecls([&](Decl *auxiliaryDecl) {
2204-
// Skip extensions decls; they are visited below.
2205-
if (isa<ExtensionDecl>(auxiliaryDecl))
2206-
return;
2207-
22082204
FrontendStatsTracer StatsTracer(SGM.getASTContext().Stats,
22092205
"SILgen-decl", auxiliaryDecl);
22102206
SGM.visit(auxiliaryDecl);

lib/SILGen/SILGenType.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,11 +1101,6 @@ class SILGenType : public TypeMemberVisitor<SILGenType> {
11011101
SGM.emitLazyConformancesForType(theType);
11021102

11031103
forEachMemberToLower(theType, [&](Decl *member) {
1104-
// FIXME: Conformance macros can generate extension decls. These
1105-
// are visited as top-level decls; skip them here.
1106-
if (isa<ExtensionDecl>(member))
1107-
return;
1108-
11091104
visit(member);
11101105
});
11111106

lib/Sema/TypeCheckMacros.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1452,7 +1452,13 @@ swift::expandConformances(CustomAttr *attr, MacroDecl *macro,
14521452
extension->setExtendedNominal(nominal);
14531453
nominal->addExtension(extension);
14541454

1455-
// Make it accessible to getTopLevelDecls()
1455+
// Most other macro-generated declarations are visited through calling
1456+
// 'visitAuxiliaryDecls' on the original declaration the macro is attached
1457+
// to. We don't do this for macro-generated extensions, because the
1458+
// extension is not a peer of the original declaration. Instead of
1459+
// requiring all callers of 'visitAuxiliaryDecls' to understand the
1460+
// hoisting behavior of macro-generated extensions, we make the
1461+
// extension accessible through 'getTopLevelDecls()'.
14561462
if (auto file = dyn_cast<FileUnit>(
14571463
decl->getDeclContext()->getModuleScopeContext()))
14581464
file->getOrCreateSynthesizedFile().addTopLevelDecl(extension);

lib/Sema/TypeChecker.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,16 @@ TypeCheckSourceFileRequest::evaluate(Evaluator &eval, SourceFile *SF) const {
297297
}
298298
}
299299

300+
// Type-check macro-generated extensions.
301+
if (auto *synthesizedSF = SF->getSynthesizedFile()) {
302+
for (auto *decl : synthesizedSF->getTopLevelDecls()) {
303+
if (!decl->isImplicit()) {
304+
assert(isa<ExtensionDecl>(decl));
305+
TypeChecker::typeCheckDecl(decl);
306+
}
307+
}
308+
}
309+
300310
typeCheckDelayedFunctions(*SF);
301311
}
302312

test/Index/index_macros.swift

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,12 @@ struct AddOne {
8181
// CHECK: [[@LINE-5]]:1 | function/Swift | freeLog() | [[FREE_LOG_USR]] | Ref,Call,Impl,RelCall,RelCont
8282
// CHECK-NEXT: RelCall,RelCont | instance-method/Swift | freeFunc() | [[FREE_FUNC_USR]]
8383

84+
func testExpr() {
85+
#freestandingExpr
86+
// CHECK: [[@LINE-1]]:3 | function/Swift | exprLog() | [[EXPR_LOG_USR]] | Ref,Call,Impl,RelCall,RelCont
87+
// CHECK-NEXT: RelCall,RelCont | function/Swift | testExpr()
88+
}
89+
8490
// CHECK: [[@LINE+4]]:40 | macro/Swift | Peer() | [[PEER_USR]] | Ref
8591
// CHECK: [[@LINE+3]]:23 | macro/Swift | MemberAttribute() | [[MEMBER_ATTRIBUTE_USR]] | Ref
8692
// CHECK: [[@LINE+2]]:15 | macro/Swift | Member() | [[MEMBER_USR]] | Ref
@@ -112,11 +118,6 @@ struct TestAttached {
112118
// CHECK: [[@LINE-24]]:39 | function/Swift | peerLog() | [[PEER_LOG_USR]] | Ref,Call,Impl,RelCall,RelCont
113119
// CHECK-NEXT: RelCall,RelCont | instance-method/Swift | peerFunc() | [[PEER_FUNC_USR]]
114120

115-
// `Conformance` adds `TestProto` as a conformance on an extension of `TestAttached`
116-
// CHECK: [[@LINE-28]]:1 | extension/ext-struct/Swift | TestAttached | {{.*}} | Def,Impl
117-
// CHECK: [[@LINE-29]]:1 | protocol/Swift | TestProto | [[PROTO_USR]] | Ref,Impl,RelBase
118-
// CHECK-NEXT: RelBase | extension/ext-struct/Swift | TestAttached
119-
120121
// CHECK: [[@LINE+1]]:8 | struct/Swift | Outer | [[OUTER_USR:.*]] | Def
121122
struct Outer {
122123
// CHECK: [[@LINE+1]]:4 | macro/Swift | PeerMember() | [[PEER_MEMBER_USR]] | Ref
@@ -137,16 +138,19 @@ struct Outer {
137138
// CHECK: [[@LINE-6]]:16 | function/Swift | memberLog() | [[MEMBER_LOG_USR]] | Ref,Call,Impl,RelCall,RelCont
138139
// CHECK-NEXT: RelCall,RelCont | instance-method/Swift | memberFunc() | [[INNER_FUNC_USR]]
139140

141+
142+
// Expanded extensions are visited last
143+
144+
// `Conformance` adds `TestProto` as a conformance on an extension of `TestAttached`
145+
// CHECK: [[@LINE-51]]:1 | extension/ext-struct/Swift | TestAttached | {{.*}} | Def,Impl
146+
// CHECK: [[@LINE-52]]:1 | protocol/Swift | TestProto | [[PROTO_USR]] | Ref,Impl,RelBase
147+
// CHECK-NEXT: RelBase | extension/ext-struct/Swift | TestAttached
148+
140149
// `Conformance` adds `TestProto` as a conformance on an extension of `TestInner`
141-
// CHECK: [[@LINE-10]]:3 | extension/ext-struct/Swift | TestInner | {{.*}} | Def,Impl
142-
// CHECK: [[@LINE-11]]:3 | protocol/Swift | TestProto | [[PROTO_USR]] | Ref,Impl,RelBase
150+
// CHECK: [[@LINE-18]]:3 | extension/ext-struct/Swift | TestInner | {{.*}} | Def,Impl
151+
// CHECK: [[@LINE-19]]:3 | protocol/Swift | TestProto | [[PROTO_USR]] | Ref,Impl,RelBase
143152
// CHECK-NEXT: RelBase | extension/ext-struct/Swift | TestInner
144153

145-
func testExpr() {
146-
#freestandingExpr
147-
// CHECK: [[@LINE-1]]:3 | function/Swift | exprLog() | [[EXPR_LOG_USR]] | Ref,Call,Impl,RelCall,RelCont
148-
// CHECK-NEXT: RelCall,RelCont | function/Swift | testExpr()
149-
}
150154

151155
//--- IndexMacros.swift
152156
import SwiftSyntax

test/Macros/macro_expand_conformances.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ requireHashable(S2())
6363

6464
requireEquatable(E.Nested())
6565

66+
extension E {
67+
@Equatable struct NestedInExtension {}
68+
}
69+
70+
requireEquatable(E.NestedInExtension())
71+
6672
#if TEST_DIAGNOSTICS
6773
requireEquatable(PublicEquatable())
6874

0 commit comments

Comments
 (0)