Skip to content

Commit b3683c1

Browse files
authored
Merge pull request #64020 from DougGregor/conformance-macro-fixes
2 parents ebdeecf + eb06129 commit b3683c1

File tree

5 files changed

+54
-26
lines changed

5 files changed

+54
-26
lines changed

lib/Refactoring/Refactoring.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8549,6 +8549,14 @@ getMacroExpansionBuffers(MacroDecl *macro, const CustomAttr *attr, Decl *decl) {
85498549
allBufferIDs.append(bufferIDs.begin(), bufferIDs.end());
85508550
}
85518551

8552+
if (roles.contains(MacroRole::Conformance)) {
8553+
if (auto nominal = dyn_cast<NominalTypeDecl>(decl)) {
8554+
auto bufferIDs = evaluateOrDefault(
8555+
ctx.evaluator, ExpandConformanceMacros{nominal}, { });
8556+
allBufferIDs.append(bufferIDs.begin(), bufferIDs.end());
8557+
}
8558+
}
8559+
85528560
// Drop any buffers that come from other macros. We could eliminate this
85538561
// step by adding more fine-grained requests above, which only expand for a
85548562
// single custom attribute.

lib/Sema/TypeCheckMacros.cpp

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1276,34 +1276,14 @@ swift::expandConformances(CustomAttr *attr, MacroDecl *macro,
12761276
if (!extension)
12771277
continue;
12781278

1279-
auto &extensionCtx = extension->getASTContext();
1280-
12811279
// Bind the extension to the original nominal type.
12821280
extension->setExtendedNominal(nominal);
1281+
nominal->addExtension(extension);
12831282

1284-
// Resolve the protocol type.
1285-
assert(extension->getInherited().size() == 1);
1286-
auto inheritedType = evaluateOrDefault(
1287-
extensionCtx.evaluator,
1288-
InheritedTypeRequest{extension, 0, TypeResolutionStage::Interface},
1289-
Type());
1290-
1291-
if (!inheritedType || inheritedType->hasError())
1292-
continue;
1293-
1294-
auto protocolType = inheritedType->getAs<ProtocolType>();
1295-
if (!protocolType)
1296-
continue;
1297-
1298-
// Create a synthesized conformance and register it with the nominal type.
1299-
auto conformance = extensionCtx.getConformance(
1300-
nominal->getDeclaredInterfaceType(), protocolType->getDecl(),
1301-
nominal->getLoc(), extension, ProtocolConformanceState::Incomplete,
1302-
/*isUnchecked=*/false);
1303-
conformance->setSourceKindAndImplyingConformance(
1304-
ConformanceEntryKind::Synthesized, nullptr);
1305-
1306-
nominal->registerProtocolConformance(conformance, /*synthesized=*/true);
1283+
// Make it accessible to getTopLevelDecls()
1284+
if (auto file = dyn_cast<FileUnit>(
1285+
decl->getDeclContext()->getModuleScopeContext()))
1286+
file->getOrCreateSynthesizedFile().addTopLevelDecl(extension);
13071287
}
13081288

13091289
return macroSourceFile->getBufferID();

test/Macros/Inputs/syntax_macro_definitions.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,6 +1037,17 @@ public struct EquatableMacro: ConformanceMacro {
10371037
}
10381038
}
10391039

1040+
public struct HashableMacro: ConformanceMacro {
1041+
public static func expansion(
1042+
of node: AttributeSyntax,
1043+
providingConformancesOf decl: some DeclGroupSyntax,
1044+
in context: some MacroExpansionContext
1045+
) throws -> [(TypeSyntax, GenericWhereClauseSyntax?)] {
1046+
let protocolName: TypeSyntax = "Hashable"
1047+
return [(protocolName, nil)]
1048+
}
1049+
}
1050+
10401051
public struct DelegatedConformanceMacro: ConformanceMacro, MemberMacro {
10411052
public static func expansion(
10421053
of node: AttributeSyntax,

test/Macros/macro_expand_conformances.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,32 @@
1313
@attached(conformance)
1414
macro Equatable() = #externalMacro(module: "MacroDefinition", type: "EquatableMacro")
1515

16+
@attached(conformance)
17+
macro Hashable() = #externalMacro(module: "MacroDefinition", type: "HashableMacro")
18+
1619
func requireEquatable(_ value: some Equatable) {
1720
print(value == value)
1821
}
1922

23+
func requireHashable(_ value: some Hashable) {
24+
print(value.hashValue)
25+
}
26+
2027
@Equatable
2128
struct S {}
2229

30+
@Hashable
31+
struct S2 {}
32+
2333
// CHECK-DUMP: @__swiftmacro_25macro_expand_conformances1SV9EquatablefMc_.swift
2434
// CHECK-DUMP: extension S : Equatable {}
2535

2636
// CHECK: true
2737
requireEquatable(S())
2838

39+
requireEquatable(S2())
40+
requireHashable(S2())
41+
2942
@attached(conformance)
3043
@attached(member)
3144
macro DelegatedConformance() = #externalMacro(module: "MacroDefinition", type: "DelegatedConformanceMacro")

test/SourceKit/Macros/macro_basic.swift

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ struct S3 {
4545
}
4646
}
4747

48+
@attached(conformance)
49+
macro Hashable() = #externalMacro(module: "MacroDefinition", type: "HashableMacro")
50+
51+
@Hashable
52+
struct S4 { }
53+
4854
// FIXME: Swift parser is not enabled on Linux CI yet.
4955
// REQUIRES: OS=macosx
5056

@@ -162,7 +168,7 @@ struct S3 {
162168
// ACCESSOR2_EXPAND-NEXT: source.edit.kind.active:
163169
// ACCESSOR2_EXPAND-NEXT: 33:3-33:20 ""
164170

165-
//##-- Refactoring expanding the second accessor macro
171+
//##-- Refactoring expanding the addCompletionHandler macro.
166172
// RUN: %sourcekitd-test -req=refactoring.expand.macro -pos=42:5 %s -- ${COMPILER_ARGS[@]} | %FileCheck -check-prefix=PEER_EXPAND %s
167173
// PEER_EXPAND: source.edit.kind.active:
168174
// PEER_EXPAND-NEXT: 45:4-45:4 (@__swiftmacro_9MacroUser2S3V1f1a3for_SSSi_SSSdtYaF20addCompletionHandlerfMp_.swift) "
@@ -176,6 +182,16 @@ struct S3 {
176182
// PEER_EXPAND-NEXT: source.edit.kind.active:
177183
// PEER_EXPAND-NEXT: 42:3-42:24 ""
178184

185+
//##-- Refactoring expanding a conformance macro.
186+
// RUN: %sourcekitd-test -req=refactoring.expand.macro -pos=51:5 %s -- ${COMPILER_ARGS[@]} | %FileCheck -check-prefix=CONFORMANCE_EXPAND %s
187+
// CONFORMANCE_EXPAND: source.edit.kind.active:
188+
// CONFORMANCE_EXPAND-NEXT: 52:14-52:14 (@__swiftmacro_9MacroUser2S4V8HashablefMc_.swift) "
189+
// CONFORMANCE_EXPAND-EMPTY:
190+
// CONFORMANCE_EXPAND-NEXT: extension S4 : Hashable {}
191+
// CONFORMANCE_EXPAND-NEXT: "
192+
// CONFORMANCE_EXPAND-NEXT: source.edit.kind.active:
193+
// CONFORMANCE_EXPAND-NEXT: 51:1-51:10 ""
194+
179195
//##-- Doc info, mostly just checking we don't crash because of the separate buffers
180196
// RUN: %sourcekitd-test -req=doc-info %s -- ${COMPILER_ARGS_WITHOUT_SOURCE[@]} | %FileCheck -check-prefix=DOCINFO %s
181197
// DOCINFO: key.name: "myTypeWrapper()"

0 commit comments

Comments
 (0)