Skip to content

Commit df2e2ee

Browse files
authored
Merge pull request #68028 from DougGregor/supersede-pre-macro-expansion-implied-conformances
Always supersede conformances implied by pre-macro-expansion conformances
2 parents 924785f + ab576b3 commit df2e2ee

File tree

4 files changed

+52
-10
lines changed

4 files changed

+52
-10
lines changed

Diff for: include/swift/AST/DeclContext.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -153,15 +153,15 @@ enum class ConformanceEntryKind : unsigned {
153153
/// Explicitly specified.
154154
Explicit,
155155

156+
/// The conformance is generated by a macro that has not been
157+
/// expanded yet.
158+
PreMacroExpansion,
159+
156160
/// Implicitly synthesized.
157161
Synthesized,
158162

159163
/// Implied by an explicitly-specified conformance.
160164
Implied,
161-
162-
/// The conformance is generated by a macro that has not been
163-
/// expanded yet.
164-
PreMacroExpansion,
165165
};
166166

167167
/// Describes the kind of conformance lookup desired.

Diff for: lib/AST/ConformanceLookupTable.h

+17-6
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ class ConformanceLookupTable : public ASTAllocated<ConformanceLookupTable> {
147147
///
148148
/// The only difference between the ranking kind and the kind is
149149
/// that implied conformances originating from a synthesized
150-
/// conformance are considered to be synthesized (which has a
150+
/// or pre-macro-expansion conformance are considered to be synthesized (which has a
151151
/// lower ranking).
152152
ConformanceEntryKind getRankingKind() const {
153153
switch (auto kind = getKind()) {
@@ -157,11 +157,22 @@ class ConformanceLookupTable : public ASTAllocated<ConformanceLookupTable> {
157157
case ConformanceEntryKind::PreMacroExpansion:
158158
return kind;
159159

160-
case ConformanceEntryKind::Implied:
161-
return (getImpliedSource()->getDeclaredConformance()->getKind()
162-
== ConformanceEntryKind::Synthesized)
163-
? ConformanceEntryKind::Synthesized
164-
: ConformanceEntryKind::Implied;
160+
case ConformanceEntryKind::Implied: {
161+
auto impliedSourceKind =
162+
getImpliedSource()->getDeclaredConformance()->getKind();
163+
switch (impliedSourceKind) {
164+
case ConformanceEntryKind::Synthesized:
165+
case ConformanceEntryKind::PreMacroExpansion:
166+
return impliedSourceKind;
167+
168+
case ConformanceEntryKind::Explicit:
169+
case ConformanceEntryKind::Inherited:
170+
return ConformanceEntryKind::Implied;
171+
172+
case ConformanceEntryKind::Implied:
173+
return getImpliedSource()->getRankingKind();
174+
}
175+
}
165176
}
166177

167178
llvm_unreachable("Unhandled ConformanceEntryKind in switch.");

Diff for: test/Macros/Inputs/syntax_macro_definitions.swift

+13
Original file line numberDiff line numberDiff line change
@@ -1380,6 +1380,19 @@ public struct HashableMacro: ExtensionMacro {
13801380
}
13811381
}
13821382

1383+
public struct ImpliesHashableMacro: ExtensionMacro {
1384+
public static func expansion(
1385+
of node: AttributeSyntax,
1386+
attachedTo: some DeclGroupSyntax,
1387+
providingExtensionsOf type: some TypeSyntaxProtocol,
1388+
conformingTo protocols: [TypeSyntax],
1389+
in context: some MacroExpansionContext
1390+
) throws -> [ExtensionDeclSyntax] {
1391+
let ext: DeclSyntax = "extension \(type.trimmed): ImpliesHashable {}"
1392+
return [ext.cast(ExtensionDeclSyntax.self)]
1393+
}
1394+
}
1395+
13831396
public struct DelegatedConformanceMacro: ExtensionMacro, MemberMacro {
13841397
public static func expansion(
13851398
of node: AttributeSyntax,

Diff for: test/Macros/macro_expand_extensions.swift

+18
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
// RUN: not %target-swift-frontend -enable-experimental-feature ExtensionMacros -swift-version 5 -typecheck -load-plugin-library %t/%target-library-name(MacroDefinition) -module-name MacroUser -DTEST_DIAGNOSTICS -serialize-diagnostics-path %t/macro_expand.dia %s -emit-macro-expansion-files no-diagnostics
1111
// RUN: c-index-test -read-diagnostics %t/macro_expand.dia 2>&1 | %FileCheck -check-prefix CHECK-DIAGS %s
1212

13+
// Ensure that we can serialize this file as a module.
14+
// RUN: %target-swift-frontend -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) %s -I %t -disable-availability-checking -emit-module -o %t/MyModule.swiftmodule -enable-testing
15+
1316
// RUN: %target-build-swift -enable-experimental-feature ExtensionMacros -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) %s -o %t/main -module-name MacroUser -swift-version 5 -emit-tbd -emit-tbd-path %t/MacroUser.tbd -I %t
1417
// RUN: %target-codesign %t/main
1518
// RUN: %target-run %t/main | %FileCheck %s
@@ -198,3 +201,18 @@ func requiresEquatable<T: Equatable>(_: T) { }
198201
func testHasPropertyWrappers(hpw: HasPropertyWrappers) {
199202
requiresEquatable(hpw)
200203
}
204+
205+
// Check that conformances implied by a macro-defined conformance are serialized
206+
// without issue.
207+
public protocol ImpliesHashable: Hashable { }
208+
209+
@attached(extension, conformances: ImpliesHashable)
210+
macro ImpliesHashable() = #externalMacro(module: "MacroDefinition", type: "ImpliesHashableMacro")
211+
212+
func requiresHashable<T: Hashable>(_: T) { }
213+
func testMakeMeHashable(mmh: MakeMeHashable, dict: [MakeMeHashable: Int]) {
214+
requiresHashable(mmh)
215+
}
216+
217+
@ImpliesHashable
218+
public struct MakeMeHashable { }

0 commit comments

Comments
 (0)