Skip to content

Commit b668017

Browse files
authored
[ModuleInterface] Explicitly print implied Hashable et al on enums (#25650)
Enums have a handful of conformances that are implied by their structure: Equatable and Hashable if they have no payloads, and RawRepresentable if they have a raw value. In the spirit of making implicit things explicit, these should be printed in the module interface. rdar://problem/50100142
1 parent e676a13 commit b668017

File tree

3 files changed

+49
-2
lines changed

3 files changed

+49
-2
lines changed

lib/Frontend/ParseableInterfaceSupport.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,19 @@ class InheritedProtocolCollector {
225225
// FIXME: This ignores layout constraints, but currently we don't support
226226
// any of those besides 'AnyObject'.
227227
}
228+
229+
// Check for synthesized protocols, like Hashable on enums.
230+
if (auto *nominal = dyn_cast<NominalTypeDecl>(D)) {
231+
SmallVector<ProtocolConformance *, 4> localConformances =
232+
nominal->getLocalConformances(ConformanceLookupKind::NonInherited);
233+
234+
for (auto *conf : localConformances) {
235+
if (conf->getSourceKind() != ConformanceEntryKind::Synthesized)
236+
continue;
237+
ExtraProtocols.push_back({conf->getProtocol(),
238+
getAvailabilityAttrs(D, availableAttrs)});
239+
}
240+
}
228241
}
229242

230243
/// For each type directly inherited by \p extension, record any protocols

test/ParseableInterface/enums-layout.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %empty-directory(%t)
2-
// RUN: %target-swift-frontend -emit-module-interface-path %t/Lib.swiftinterface -typecheck -enable-library-evolution -enable-objc-interop -disable-objc-attr-requires-foundation-module -swift-version 5 %S/Inputs/enums-layout-helper.swift
2+
// RUN: %target-swift-frontend -emit-module-interface-path %t/Lib.swiftinterface -typecheck -enable-library-evolution -enable-objc-interop -disable-objc-attr-requires-foundation-module -swift-version 5 %S/Inputs/enums-layout-helper.swift -module-name Lib
33
// RUN: %FileCheck %S/Inputs/enums-layout-helper.swift < %t/Lib.swiftinterface
44
// RUN: %target-swift-frontend -enable-objc-interop -O -emit-ir -primary-file %s -I %t | %FileCheck %s
55

test/ParseableInterface/synthesized.swift

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
// RUN: %target-swift-frontend -typecheck -emit-parseable-module-interface-path - %s -disable-objc-attr-requires-foundation-module -enable-objc-interop | %FileCheck %s
1+
// RUN: %target-swift-frontend -typecheck -emit-parseable-module-interface-path - %s -disable-objc-attr-requires-foundation-module -enable-objc-interop > %t.swiftinterface
2+
// RUN: %FileCheck %s < %t.swiftinterface
3+
// RUN: %FileCheck -check-prefix=NEGATIVE %s < %t.swiftinterface
24

35
// CHECK-LABEL: public enum HasRawValue : Swift.Int {
46
public enum HasRawValue: Int {
@@ -23,3 +25,35 @@ public enum HasRawValue: Int {
2325
// CHECK-DAG: @inlinable get{{$}}
2426
// CHECK-DAG: }
2527
// CHECK: {{^}$}}
28+
29+
// CHECK-LABEL: public enum NoRawValueWithExplicitEquatable : Swift.Equatable {
30+
public enum NoRawValueWithExplicitEquatable : Equatable {
31+
// CHECK-NEXT: case a, b, c
32+
case a, b, c
33+
} // CHECK: {{^}$}}
34+
35+
// CHECK-LABEL: public enum NoRawValueWithExplicitHashable {
36+
public enum NoRawValueWithExplicitHashable {
37+
// CHECK-NEXT: case a, b, c
38+
case a, b, c
39+
} // CHECK: {{^}$}}
40+
41+
// CHECK-LABEL: extension NoRawValueWithExplicitHashable : Swift.Hashable {
42+
extension NoRawValueWithExplicitHashable : Hashable {
43+
// CHECK-NEXT: public func foo()
44+
public func foo() {}
45+
} // CHECK: {{^}$}}
46+
47+
// CHECK: extension synthesized.HasRawValue : Swift.Equatable {}
48+
// CHECK: extension synthesized.HasRawValue : Swift.Hashable {}
49+
// CHECK: extension synthesized.HasRawValue : Swift.RawRepresentable {}
50+
51+
// CHECK: extension synthesized.ObjCEnum : Swift.Equatable {}
52+
// CHECK: extension synthesized.ObjCEnum : Swift.Hashable {}
53+
// CHECK: extension synthesized.ObjCEnum : Swift.RawRepresentable {}
54+
55+
// CHECK: extension synthesized.NoRawValueWithExplicitEquatable : Swift.Hashable {}
56+
// NEGATIVE-NOT: extension {{.+}}NoRawValueWithExplicitEquatable : Swift.Equatable
57+
58+
// NEGATIVE-NOT: NoRawValueWithExplicitHashable : Swift.Equatable
59+
// NEGATIVE-NOT: NoRawValueWithExplicitHashable : Swift.Hashable {}

0 commit comments

Comments
 (0)