Skip to content

Commit b5a1d4b

Browse files
authored
Merge pull request #14536 from xwu/conditional-hashable-at-implements
[Sema/stdlib] Use @_implements to avoid source breakage in conditional conformances
2 parents d03f0b3 + b0f38e0 commit b5a1d4b

17 files changed

+32
-39
lines changed

include/swift/AST/KnownIdentifiers.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ IDENTIFIER_WITH_NAME(NativeClassLayout, "_NativeClass")
114114
// Operators
115115
IDENTIFIER_WITH_NAME(MatchOperator, "~=")
116116
IDENTIFIER_WITH_NAME(EqualsOperator, "==")
117-
IDENTIFIER_WITH_NAME(derived_enum_equals, "__derived_enum_equals")
118-
IDENTIFIER_WITH_NAME(derived_struct_equals, "__derived_struct_equals")
117+
IDENTIFIER_WITH_NAME(derived_conformance__equals, "__derived_conformance__equals")
118+
IDENTIFIER_WITH_NAME(conditional_conformance__equals, "__conditional_conformance__equals")
119119

120120
// Precedence groups
121121
IDENTIFIER(AssignmentPrecedence)

lib/Sema/DerivedConformanceEquatableHashable.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ static GuardStmt *returnIfNotEqualGuard(ASTContext &C,
326326
/// values. This generates code that converts each value to its integer ordinal
327327
/// and compares them, which produces an optimal single icmp instruction.
328328
static void
329-
deriveBodyEquatable_enum_noAssociatedValues_eq(AbstractFunctionDecl *eqDecl) {
329+
deriveBodyEquatable_enumWithoutAssociatedValues_eq(AbstractFunctionDecl *eqDecl) {
330330
auto parentDC = eqDecl->getDeclContext();
331331
ASTContext &C = parentDC->getASTContext();
332332

@@ -381,7 +381,7 @@ deriveBodyEquatable_enum_noAssociatedValues_eq(AbstractFunctionDecl *eqDecl) {
381381
/// Derive the body for an '==' operator for an enum where at least one of the
382382
/// cases has associated values.
383383
static void
384-
deriveBodyEquatable_enum_hasAssociatedValues_eq(AbstractFunctionDecl *eqDecl) {
384+
deriveBodyEquatable_enumWithAssociatedValues_eq(AbstractFunctionDecl *eqDecl) {
385385
auto parentDC = eqDecl->getDeclContext();
386386
ASTContext &C = parentDC->getASTContext();
387387

@@ -555,8 +555,8 @@ deriveEquatable_eq(TypeChecker &tc, Decl *parentDecl, NominalTypeDecl *typeDecl,
555555
//
556556
// @derived
557557
// @_implements(Equatable, ==(_:_:))
558-
// func __derived_enum_equals(a: SomeEnum<T...>,
559-
// b: SomeEnum<T...>) -> Bool {
558+
// func __derived_conformance__equals(a: SomeEnum<T...>,
559+
// b: SomeEnum<T...>) -> Bool {
560560
// switch (a, b) {
561561
// case (.A, .A):
562562
// return true
@@ -577,8 +577,8 @@ deriveEquatable_eq(TypeChecker &tc, Decl *parentDecl, NominalTypeDecl *typeDecl,
577577
//
578578
// @derived
579579
// @_implements(Equatable, ==(_:_:))
580-
// func __derived_struct_equals(a: SomeStruct<T...>,
581-
// b: SomeStruct<T...>) -> Bool {
580+
// func __derived_conformance__equals(a: SomeStruct<T...>,
581+
// b: SomeStruct<T...>) -> Bool {
582582
// guard a.x == b.x else { return false; }
583583
// guard a.y == b.y else { return false; }
584584
// return true;
@@ -712,15 +712,15 @@ ValueDecl *DerivedConformance::deriveEquatable(TypeChecker &tc,
712712
if (theEnum) {
713713
auto bodySynthesizer =
714714
theEnum->hasOnlyCasesWithoutAssociatedValues()
715-
? &deriveBodyEquatable_enum_noAssociatedValues_eq
716-
: &deriveBodyEquatable_enum_hasAssociatedValues_eq;
715+
? &deriveBodyEquatable_enumWithoutAssociatedValues_eq
716+
: &deriveBodyEquatable_enumWithAssociatedValues_eq;
717717
return deriveEquatable_eq(tc, parentDecl, theEnum,
718-
tc.Context.Id_derived_enum_equals,
718+
tc.Context.Id_derived_conformance__equals,
719719
bodySynthesizer);
720720
}
721721
else if (auto theStruct = dyn_cast<StructDecl>(type))
722722
return deriveEquatable_eq(tc, parentDecl, theStruct,
723-
tc.Context.Id_derived_struct_equals,
723+
tc.Context.Id_derived_conformance__equals,
724724
&deriveBodyEquatable_struct_eq);
725725
else
726726
llvm_unreachable("todo");

lib/Sema/TypeCheckStmt.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,8 +1255,8 @@ void TypeChecker::checkIgnoredExpr(Expr *E) {
12551255
auto &ctx = callee->getASTContext();
12561256
if (callee->isImplicit()) {
12571257
// Translate calls to implicit functions to their user-facing names
1258-
if (callee->getBaseName() == ctx.Id_derived_enum_equals ||
1259-
callee->getBaseName() == ctx.Id_derived_struct_equals) {
1258+
if (callee->getBaseName() == ctx.Id_derived_conformance__equals ||
1259+
callee->getBaseName() == ctx.Id_conditional_conformance__equals) {
12601260
diagnose(fn->getLoc(), diag::expression_unused_result_operator,
12611261
ctx.Id_EqualsOperator)
12621262
.highlight(SR1).highlight(SR2);

stdlib/public/core/Arrays.swift.gyb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2259,7 +2259,6 @@ extension ${Self}: Hashable where Element : Hashable {
22592259
/// Hash values are not guaranteed to be equal across different executions of
22602260
/// your program. Do not save hash values to use during a future execution.
22612261
@_inlineable // FIXME(sil-serialize-all)
2262-
@available(swift, introduced: 4.1)
22632262
public var hashValue: Int {
22642263
// FIXME(ABI)#177: <rdar://problem/18915294> Issue applies to Array too
22652264
var result: Int = 0

stdlib/public/core/ClosedRange.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ extension ClosedRange.Index : Comparable {
170170
@available(swift, introduced: 4.1) // FIXME(conformance-availability)
171171
extension ClosedRange.Index: Hashable
172172
where Bound: Strideable, Bound.Stride: SignedInteger, Bound: Hashable {
173-
@available(swift, introduced: 4.1)
173+
@_inlineable // FIXME(sil-serialize-all)
174174
public var hashValue: Int {
175175
switch self {
176176
case .inRange(let value):
@@ -387,15 +387,14 @@ extension ClosedRange : Hashable where Bound : Hashable {
387387
/// Hash values are not guaranteed to be equal across different executions of
388388
/// your program. Do not save hash values to use during a future execution.
389389
@_inlineable // FIXME(sil-serialize-all)
390-
@available(swift, introduced: 4.1)
391390
public var hashValue: Int {
392391
return _combineHashValues(lowerBound.hashValue, upperBound.hashValue)
393392
}
394393
}
395394

396395
extension ClosedRange : CustomStringConvertible {
397396
/// A textual representation of the range.
398-
@_inlineable // FIXME(sil-serialize-all)...\(
397+
@_inlineable // FIXME(sil-serialize-all)
399398
public var description: String {
400399
return "\(lowerBound)...\(upperBound)"
401400
}

stdlib/public/core/CollectionOfOne.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,10 @@ extension CollectionOfOne: RandomAccessCollection, MutableCollection {
140140
extension CollectionOfOne : Equatable where Element : Equatable {
141141
/// Returns a Boolean value indicating whether two collections are equal.
142142
@_inlineable // FIXME(sil-serialize-all)
143-
@available(swift, introduced: 4.1)
144-
public static func == (lhs: CollectionOfOne, rhs: CollectionOfOne) -> Bool {
143+
@_implements(Equatable, ==(_:_:))
144+
public static func __conditional_conformance__equals(
145+
_ lhs: CollectionOfOne, _ rhs: CollectionOfOne
146+
) -> Bool {
145147
return lhs._element == rhs._element
146148
}
147149
}
@@ -155,7 +157,6 @@ extension CollectionOfOne : Hashable where Element : Hashable {
155157
/// Hash values are not guaranteed to be equal across different executions of
156158
/// your program. Do not save hash values to use during a future execution.
157159
@_inlineable // FIXME(sil-serialize-all)
158-
@available(swift, introduced: 4.1)
159160
public var hashValue: Int {
160161
return _element.hashValue
161162
}

stdlib/public/core/DropWhile.swift.gyb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ public struct LazyDropWhileIndex<Base : Collection> : Comparable {
142142

143143
@available(swift, introduced: 4.1) // FIXME(conformance-availability)
144144
extension LazyDropWhileIndex : Hashable where Base.Index : Hashable {
145-
@available(swift, introduced: 4.1)
145+
@_inlineable // FIXME(sil-serialize-all)
146146
public var hashValue: Int {
147147
return base.hashValue
148148
}

stdlib/public/core/EmptyCollection.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,6 @@ extension EmptyCollection : Equatable {
176176
@available(swift, introduced: 4.1) // FIXME(conformance-availability)
177177
extension EmptyCollection : Hashable {
178178
@_inlineable // FIXME(sil-serialize-all)
179-
@available(swift, introduced: 4.1)
180179
public var hashValue: Int {
181180
return 0
182181
}

stdlib/public/core/ExistentialCollection.swift.gyb

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,9 +1247,9 @@ extension ${Self}: _AnyCollectionProtocol {
12471247
@available(swift, introduced: 4.1) // FIXME(conformance-availability)
12481248
extension AnyCollection : Equatable where Element : Equatable {
12491249
@_inlineable // FIXME(sil-serialize-all)
1250-
@available(swift, introduced: 4.1)
1251-
public static func == (
1252-
lhs: AnyCollection<Element>, rhs: AnyCollection<Element>
1250+
@_implements(Equatable, ==(_:_:))
1251+
public static func __conditional_conformance__equals(
1252+
_ lhs: AnyCollection<Element>, _ rhs: AnyCollection<Element>
12531253
) -> Bool {
12541254
if lhs.count != rhs.count {
12551255
return false
@@ -1268,7 +1268,6 @@ extension AnyCollection : Hashable where Element : Hashable {
12681268
/// Hash values are not guaranteed to be equal across different executions of
12691269
/// your program. Do not save hash values to use during a future execution.
12701270
@_inlineable // FIXME(sil-serialize-all)
1271-
@available(swift, introduced: 4.1)
12721271
public var hashValue: Int {
12731272
// FIXME(ABI)#177: <rdar://problem/18915294> Issue applies to AnyCollection too
12741273
var result: Int = 0

stdlib/public/core/Flatten.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ extension FlattenCollection.Index : Comparable {
233233
@available(swift, introduced: 4.1) // FIXME(conformance-availability)
234234
extension FlattenCollection.Index : Hashable
235235
where Base.Index : Hashable, Base.Element.Index : Hashable {
236-
@available(swift, introduced: 4.1)
236+
@_inlineable // FIXME(sil-serialize-all)
237237
public var hashValue: Int {
238238
return _mixInt(_inner?.hashValue ?? 0) ^ _outer.hashValue
239239
}

stdlib/public/core/HashedCollections.swift.gyb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2795,7 +2795,6 @@ extension Dictionary : Hashable where Value : Hashable {
27952795
/// Hash values are not guaranteed to be equal across different executions of
27962796
/// your program. Do not save hash values to use during a future execution.
27972797
@_inlineable // FIXME(sil-serialize-all)
2798-
@available(swift, introduced: 4.1)
27992798
public var hashValue: Int {
28002799
// FIXME(ABI)#177: <rdar://problem/18915294> Issue applies to Dictionary too
28012800
var result: Int = 0

stdlib/public/core/Mirror.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -908,9 +908,9 @@ extension DictionaryLiteral : RandomAccessCollection {
908908
@available(swift, introduced: 4.1) // FIXME(conformance-availability)
909909
extension DictionaryLiteral: Equatable where Key: Equatable, Value: Equatable {
910910
@_inlineable // FIXME(sil-serialize-all)
911-
@available(swift, introduced: 4.1)
912-
public static func == (
913-
lhs: DictionaryLiteral<Key, Value>, rhs: DictionaryLiteral<Key, Value>
911+
@_implements(Equatable, ==(_:_:))
912+
public static func __conditional_conformance__equals(
913+
_ lhs: DictionaryLiteral<Key, Value>, _ rhs: DictionaryLiteral<Key, Value>
914914
) -> Bool {
915915
if lhs.count != rhs.count {
916916
return false
@@ -929,7 +929,6 @@ extension DictionaryLiteral: Hashable where Key: Hashable, Value: Hashable {
929929
/// Hash values are not guaranteed to be equal across different executions of
930930
/// your program. Do not save hash values to use during a future execution.
931931
@_inlineable // FIXME(sil-serialize-all)
932-
@available(swift, introduced: 4.1)
933932
public var hashValue: Int {
934933
// FIXME(ABI)#177: <rdar://problem/18915294> Issue applies to DictionaryLiteral too
935934
var result: Int = 0

stdlib/public/core/Optional.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,6 @@ extension Optional : Hashable where Wrapped : Hashable {
418418
/// Hash values are not guaranteed to be equal across different executions of
419419
/// your program. Do not save hash values to use during a future execution.
420420
@_inlineable // FIXME(sil-serialize-all)
421-
@available(swift, introduced: 4.1)
422421
public var hashValue: Int {
423422
var result: Int
424423
switch self {

stdlib/public/core/PrefixWhile.swift.gyb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ public struct LazyPrefixWhileIndex<Base : Collection> : Comparable {
164164

165165
@available(swift, introduced: 4.1) // FIXME(conformance-availability)
166166
extension LazyPrefixWhileIndex : Hashable where Base.Index : Hashable {
167-
@available(swift, introduced: 4.1)
167+
@_inlineable // FIXME(sil-serialize-all)
168168
public var hashValue: Int {
169169
switch _value {
170170
case .index(let value):

stdlib/public/core/Range.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,6 @@ extension Range : Hashable where Bound : Hashable {
367367
/// Hash values are not guaranteed to be equal across different executions of
368368
/// your program. Do not save hash values to use during a future execution.
369369
@_inlineable // FIXME(sil-serialize-all)
370-
@available(swift, introduced: 4.1)
371370
public var hashValue: Int {
372371
return _combineHashValues(lowerBound.hashValue, upperBound.hashValue)
373372
}

stdlib/public/core/Reverse.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ extension ReversedCollection.Index: Comparable {
195195

196196
@available(swift, introduced: 4.1) // FIXME(conformance-availability)
197197
extension ReversedCollection.Index: Hashable where Base.Index: Hashable {
198-
@available(swift, introduced: 4.1)
198+
@_inlineable // FIXME(sil-serialize-all)
199199
public var hashValue: Int {
200200
return base.hashValue
201201
}

test/IDE/print_ast_tc_decls.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,7 @@ struct d0200_EscapedIdentifiers {
585585
}
586586
// PASS_COMMON-NEXT: {{^}} enum `enum` {{{$}}
587587
// PASS_COMMON-NEXT: {{^}} case `case`{{$}}
588-
// PASS_COMMON-NEXT: {{^}} {{.*}}static func __derived_enum_equals(_ a: d0200_EscapedIdentifiers.`enum`, _ b: d0200_EscapedIdentifiers.`enum`) -> Bool
588+
// PASS_COMMON-NEXT: {{^}} {{.*}}static func __derived_conformance__equals(_ a: d0200_EscapedIdentifiers.`enum`, _ b: d0200_EscapedIdentifiers.`enum`) -> Bool
589589
// PASS_COMMON-NEXT: {{^}} var hashValue: Int { get }{{$}}
590590
// PASS_COMMON-NEXT: {{^}} }{{$}}
591591

@@ -1013,7 +1013,7 @@ enum d2000_EnumDecl1 {
10131013
// PASS_COMMON: {{^}}enum d2000_EnumDecl1 {{{$}}
10141014
// PASS_COMMON-NEXT: {{^}} case ED1_First{{$}}
10151015
// PASS_COMMON-NEXT: {{^}} case ED1_Second{{$}}
1016-
// PASS_COMMON-NEXT: {{^}} {{.*}}static func __derived_enum_equals(_ a: d2000_EnumDecl1, _ b: d2000_EnumDecl1) -> Bool
1016+
// PASS_COMMON-NEXT: {{^}} {{.*}}static func __derived_conformance__equals(_ a: d2000_EnumDecl1, _ b: d2000_EnumDecl1) -> Bool
10171017
// PASS_COMMON-NEXT: {{^}} var hashValue: Int { get }{{$}}
10181018
// PASS_COMMON-NEXT: {{^}}}{{$}}
10191019

0 commit comments

Comments
 (0)