Skip to content

Commit da8e84c

Browse files
authored
Merge pull request #66914 from hborla/conformance-macro-in-extension
[Macros] Don't visit macro-generated extensions in `visitAuxiliaryDecls`.
2 parents e99f6f0 + 3ecfb53 commit da8e84c

File tree

10 files changed

+43
-43
lines changed

10 files changed

+43
-43
lines changed

lib/AST/Decl.cpp

-14
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

+1-2
Original file line numberDiff line numberDiff line change
@@ -4113,8 +4113,7 @@ void FileUnit::getTopLevelDeclsWithAuxiliaryDecls(
41134113
getTopLevelDecls(nonExpandedDecls);
41144114
for (auto *decl : nonExpandedDecls) {
41154115
decl->visitAuxiliaryDecls([&](Decl *auxDecl) {
4116-
if (!isa<ExtensionDecl>(auxDecl))
4117-
results.push_back(auxDecl);
4116+
results.push_back(auxDecl);
41184117
});
41194118
results.push_back(decl);
41204119
}

lib/IRGen/GenDecl.cpp

-5
Original file line numberDiff line numberDiff line change
@@ -5578,11 +5578,6 @@ void IRGenModule::emitNestedTypeDecls(DeclRange members) {
55785578
continue;
55795579

55805580
member->visitAuxiliaryDecls([&](Decl *decl) {
5581-
// FIXME: Conformance macros can generate extension decls. These
5582-
// are visited as top-level decls; skip them here.
5583-
if (isa<ExtensionDecl>(decl))
5584-
return;
5585-
55865581
emitNestedTypeDecls({decl, nullptr});
55875582
});
55885583
switch (member->getKind()) {

lib/Index/Index.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -1141,6 +1141,9 @@ void IndexSwiftASTWalker::visitModule(ModuleDecl &Mod) {
11411141
if (!handleSourceOrModuleFile(*SrcFile))
11421142
return;
11431143
walk(*SrcFile);
1144+
if (auto *synthesizedSF = SrcFile->getSynthesizedFile()) {
1145+
walk(synthesizedSF);
1146+
}
11441147
} else {
11451148
IsModuleFile = true;
11461149
isSystemModule = Mod.isNonUserModule();

lib/SILGen/SILGen.cpp

-4
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

-5
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

+7-1
Original file line numberDiff line numberDiff line change
@@ -1442,7 +1442,13 @@ swift::expandConformances(CustomAttr *attr, MacroDecl *macro,
14421442
extension->setExtendedNominal(nominal);
14431443
nominal->addExtension(extension);
14441444

1445-
// Make it accessible to getTopLevelDecls()
1445+
// Most other macro-generated declarations are visited through calling
1446+
// 'visitAuxiliaryDecls' on the original declaration the macro is attached
1447+
// to. We don't do this for macro-generated extensions, because the
1448+
// extension is not a peer of the original declaration. Instead of
1449+
// requiring all callers of 'visitAuxiliaryDecls' to understand the
1450+
// hoisting behavior of macro-generated extensions, we make the
1451+
// extension accessible through 'getTopLevelDecls()'.
14461452
if (auto file = dyn_cast<FileUnit>(
14471453
decl->getDeclContext()->getModuleScopeContext()))
14481454
file->getOrCreateSynthesizedFile().addTopLevelDecl(extension);

lib/Sema/TypeChecker.cpp

+10
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

+16-12
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

+6
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)