Skip to content

Commit c9969a1

Browse files
authored
Merge pull request #65237 from hborla/5.9-nested-conformance-macros
[5.9][Macros] Fix visiting nested conformance macro declarations in SIL and IRGen.
2 parents a9ab4ea + 20f01f8 commit c9969a1

File tree

4 files changed

+48
-0
lines changed

4 files changed

+48
-0
lines changed

lib/IRGen/GenDecl.cpp

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

54955495
member->visitAuxiliaryDecls([&](Decl *decl) {
5496+
// FIXME: Conformance macros can generate extension decls. These
5497+
// are visited as top-level decls; skip them here.
5498+
if (isa<ExtensionDecl>(decl))
5499+
return;
5500+
54965501
emitNestedTypeDecls({decl, nullptr});
54975502
});
54985503
switch (member->getKind()) {

lib/SILGen/SILGen.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2196,6 +2196,10 @@ class SILGenModuleRAII {
21962196
for (auto *D : sf->getTopLevelDecls()) {
21972197
// Emit auxiliary decls.
21982198
D->visitAuxiliaryDecls([&](Decl *auxiliaryDecl) {
2199+
// Skip extensions decls; they are visited below.
2200+
if (isa<ExtensionDecl>(auxiliaryDecl))
2201+
return;
2202+
21992203
FrontendStatsTracer StatsTracer(SGM.getASTContext().Stats,
22002204
"SILgen-decl", auxiliaryDecl);
22012205
SGM.visit(auxiliaryDecl);
@@ -2206,6 +2210,34 @@ class SILGenModuleRAII {
22062210
SGM.visit(D);
22072211
}
22082212

2213+
// FIXME: Visit macro-generated extensions separately.
2214+
//
2215+
// The code below that visits auxiliary decls of the top-level
2216+
// decls in the source file does not work for nested types with
2217+
// attached conformance macros:
2218+
// ```
2219+
// struct Outer {
2220+
// @AddConformance struct Inner {}
2221+
// }
2222+
// ```
2223+
// Because the attached-to decl is not at the top-level. To fix this,
2224+
// visit the macro-generated conformances that are recorded in the
2225+
// synthesized file unit to cover all macro-generated extension decls.
2226+
if (auto *synthesizedFile = sf->getSynthesizedFile()) {
2227+
for (auto *D : synthesizedFile->getTopLevelDecls()) {
2228+
if (!isa<ExtensionDecl>(D))
2229+
continue;
2230+
2231+
auto *sf = D->getInnermostDeclContext()->getParentSourceFile();
2232+
if (sf->getFulfilledMacroRole() != MacroRole::Conformance)
2233+
continue;
2234+
2235+
FrontendStatsTracer StatsTracer(SGM.getASTContext().Stats,
2236+
"SILgen-decl", D);
2237+
SGM.visit(D);
2238+
}
2239+
}
2240+
22092241
for (Decl *D : sf->getHoistedDecls()) {
22102242
FrontendStatsTracer StatsTracer(SGM.getASTContext().Stats,
22112243
"SILgen-decl", D);

lib/SILGen/SILGenType.cpp

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

10881088
forEachMemberToLower(theType, [&](Decl *member) {
1089+
// FIXME: Conformance macros can generate extension decls. These
1090+
// are visited as top-level decls; skip them here.
1091+
if (isa<ExtensionDecl>(member))
1092+
return;
1093+
10891094
visit(member);
10901095
});
10911096

test/Macros/macro_expand_conformances.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ struct S {}
2929
@Hashable
3030
struct S2 {}
3131

32+
enum E {
33+
@Equatable struct Nested {}
34+
}
35+
3236
// CHECK-DUMP: @__swiftmacro_25macro_expand_conformances1S9EquatablefMc_.swift
3337
// CHECK-DUMP: extension S : Equatable {}
3438

@@ -38,6 +42,8 @@ requireEquatable(S())
3842
requireEquatable(S2())
3943
requireHashable(S2())
4044

45+
requireEquatable(E.Nested())
46+
4147
@attached(conformance)
4248
@attached(member, names: named(requirement))
4349
macro DelegatedConformance() = #externalMacro(module: "MacroDefinition", type: "DelegatedConformanceMacro")

0 commit comments

Comments
 (0)