Skip to content

Commit c3e214c

Browse files
committed
[Macros] Expand conformance macros as extension macros.
ConformanceMacro now refines ExtensionMacro, so these roles can share the same expansion request.
1 parent a9df3e2 commit c3e214c

File tree

7 files changed

+35
-28
lines changed

7 files changed

+35
-28
lines changed

lib/AST/ConformanceLookupTable.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -282,12 +282,8 @@ void ConformanceLookupTable::updateLookupTable(NominalTypeDecl *nominal,
282282
addInheritedProtocols(nominal,
283283
ConformanceSource::forExplicit(nominal));
284284

285-
// Expand conformance macros.
286-
ASTContext &ctx = nominal->getASTContext();
287-
(void)evaluateOrDefault(
288-
ctx.evaluator, ExpandConformanceMacros{nominal}, { });
289-
290285
// Expand extension macros.
286+
ASTContext &ctx = nominal->getASTContext();
291287
(void)evaluateOrDefault(
292288
ctx.evaluator, ExpandExtensionMacros{nominal}, { });
293289
},

lib/Refactoring/Refactoring.cpp

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8673,15 +8673,8 @@ getMacroExpansionBuffers(MacroDecl *macro, const CustomAttr *attr, Decl *decl) {
86738673
allBufferIDs.append(bufferIDs.begin(), bufferIDs.end());
86748674
}
86758675

8676-
if (roles.contains(MacroRole::Conformance)) {
8677-
if (auto nominal = dyn_cast<NominalTypeDecl>(decl)) {
8678-
auto bufferIDs = evaluateOrDefault(
8679-
ctx.evaluator, ExpandConformanceMacros{nominal}, { });
8680-
allBufferIDs.append(bufferIDs.begin(), bufferIDs.end());
8681-
}
8682-
}
8683-
8684-
if (roles.contains(MacroRole::Extension)) {
8676+
if (roles.contains(MacroRole::Conformance) ||
8677+
roles.contains(MacroRole::Extension)) {
86858678
if (auto nominal = dyn_cast<NominalTypeDecl>(decl)) {
86868679
auto bufferIDs = evaluateOrDefault(
86878680
ctx.evaluator, ExpandExtensionMacros{nominal}, { });

lib/Sema/TypeCheckMacros.cpp

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -867,8 +867,10 @@ static uint8_t getRawMacroRole(MacroRole role) {
867867
case MacroRole::MemberAttribute: return 3;
868868
case MacroRole::Member: return 4;
869869
case MacroRole::Peer: return 5;
870-
case MacroRole::Conformance: return 6;
871870
case MacroRole::CodeItem: return 7;
871+
// Use the same raw macro role for conformance and extension
872+
// in ASTGen.
873+
case MacroRole::Conformance:
872874
case MacroRole::Extension: return 8;
873875
}
874876
}
@@ -1156,7 +1158,7 @@ static SourceFile *evaluateAttachedMacro(MacroDecl *macro, Decl *attachedTo,
11561158
std::string extendedType;
11571159
{
11581160
llvm::raw_string_ostream OS(extendedType);
1159-
if (role == MacroRole::Extension) {
1161+
if (role == MacroRole::Extension || role == MacroRole::Conformance) {
11601162
auto *nominal = dyn_cast<NominalTypeDecl>(attachedTo);
11611163
PrintOptions options;
11621164
options.FullyQualifiedExtendedTypesIfAmbiguous = true;
@@ -1473,13 +1475,27 @@ ArrayRef<unsigned>
14731475
ExpandExtensionMacros::evaluate(Evaluator &evaluator,
14741476
NominalTypeDecl *nominal) const {
14751477
SmallVector<unsigned, 2> bufferIDs;
1476-
nominal->forEachAttachedMacro(MacroRole::Extension,
1477-
[&](CustomAttr *attr, MacroDecl *macro) {
1478-
if (auto bufferID = expandExtensions(attr, macro,
1479-
MacroRole::Extension,
1480-
nominal))
1481-
bufferIDs.push_back(*bufferID);
1482-
});
1478+
for (auto customAttrConst : nominal->getSemanticAttrs().getAttributes<CustomAttr>()) {
1479+
auto customAttr = const_cast<CustomAttr *>(customAttrConst);
1480+
auto *macro = nominal->getResolvedMacro(customAttr);
1481+
1482+
if (!macro)
1483+
continue;
1484+
1485+
// Prefer the extension role
1486+
MacroRole role;
1487+
if (macro->getMacroRoles().contains(MacroRole::Extension)) {
1488+
role = MacroRole::Extension;
1489+
} else if (macro->getMacroRoles().contains(MacroRole::Conformance)) {
1490+
role = MacroRole::Conformance;
1491+
} else {
1492+
continue;
1493+
}
1494+
1495+
if (auto bufferID = expandExtensions(customAttr, macro,
1496+
role, nominal))
1497+
bufferIDs.push_back(*bufferID);
1498+
}
14831499

14841500
return nominal->getASTContext().AllocateCopy(bufferIDs);
14851501
}

test/Macros/Inputs/syntax_macro_definitions.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1299,7 +1299,7 @@ public struct DelegatedConformanceMacro: ConformanceMacro, MemberMacro {
12991299
}
13001300
}
13011301

1302-
extension DelegatedConformanceMacro: ExtensionMacro {
1302+
public struct DelegatedConformanceViaExtensionMacro: ExtensionMacro {
13031303
public static func expansion(
13041304
of node: AttributeSyntax,
13051305
attachedTo decl: some DeclGroupSyntax,

test/Macros/extension_macro_plugin.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
// RUN: %FileCheck %s < %t/macro-expansions.txt
2525

2626
@attached(extension, conformances: P, names: named(requirement))
27-
macro DelegatedConformance() = #externalMacro(module: "MacroDefinition", type: "DelegatedConformanceMacro")
27+
macro DelegatedConformance() = #externalMacro(module: "MacroDefinition", type: "DelegatedConformanceViaExtensionMacro")
2828

2929
protocol P {
3030
static func requirement()

test/Macros/macro_expand_conformances.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ enum E {
5353
}
5454

5555
// CHECK-DUMP: @__swiftmacro_25macro_expand_conformances1S9EquatablefMc_.swift
56-
// CHECK-DUMP: extension S : Equatable {}
56+
// CHECK-DUMP: extension S: Equatable {
57+
// CHECK-DUMP: }
5758

5859
// CHECK: true
5960
requireEquatable(S())
@@ -94,7 +95,8 @@ struct Wrapped: P {
9495
struct Generic<Element> {}
9596

9697
// CHECK-DUMP: @__swiftmacro_25macro_expand_conformances7Generic20DelegatedConformancefMc_.swift
97-
// CHECK-DUMP: extension Generic : P where Element: P {}
98+
// CHECK-DUMP: extension Generic: P where Element: P {
99+
// CHECK-DUMP: }
98100

99101
func requiresP(_ value: (some P).Type) {
100102
value.requirement()

test/Macros/macro_expand_extensions.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
// RUN: %target-run %t/main | %FileCheck %s
1212

1313
@attached(extension, conformances: P, names: named(requirement))
14-
macro DelegatedConformance() = #externalMacro(module: "MacroDefinition", type: "DelegatedConformanceMacro")
14+
macro DelegatedConformance() = #externalMacro(module: "MacroDefinition", type: "DelegatedConformanceViaExtensionMacro")
1515

1616
protocol P {
1717
static func requirement()

0 commit comments

Comments
 (0)