Skip to content

Commit e6027ee

Browse files
committed
Derive @_implements(Equatable, ==(_:_:)) _DerivedEnumEquals, not func==.
1 parent 3955f5e commit e6027ee

File tree

4 files changed

+24
-13
lines changed

4 files changed

+24
-13
lines changed

include/swift/AST/KnownIdentifiers.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ IDENTIFIER_WITH_NAME(NativeClassLayout, "_NativeClass")
9090
// Operators
9191
IDENTIFIER_WITH_NAME(MatchOperator, "~=")
9292
IDENTIFIER_WITH_NAME(EqualsOperator, "==")
93+
IDENTIFIER_WITH_NAME(derived_enum_equals, "__derived_enum_equals")
9394

9495
// Precedence groups
9596
IDENTIFIER(AssignmentPrecedence)

lib/Sema/DerivedConformanceEquatableHashable.cpp

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,9 @@ deriveEquatable_enum_eq(TypeChecker &tc, Decl *parentDecl, EnumDecl *enumDecl) {
196196
// case A, B, C
197197
//
198198
// @derived
199-
// func ==(a: SomeEnum<T...>, b: SomeEnum<T...>) -> Bool {
199+
// @_implements(Equatable, ==(_:_:))
200+
// func __derived_enum_equals(a: SomeEnum<T...>,
201+
// b: SomeEnum<T...>) -> Bool {
200202
// var index_a: Int
201203
// switch a {
202204
// case .A: index_a = 0
@@ -239,7 +241,7 @@ deriveEquatable_enum_eq(TypeChecker &tc, Decl *parentDecl, EnumDecl *enumDecl) {
239241

240242
auto boolTy = C.getBoolDecl()->getDeclaredType();
241243

242-
DeclName name(C, C.Id_EqualsOperator, params[1]);
244+
DeclName name(C, C.Id_derived_enum_equals, params[1]);
243245
auto eqDecl =
244246
FuncDecl::create(C, /*StaticLoc=*/SourceLoc(),
245247
StaticSpellingKind::KeywordStatic,
@@ -251,19 +253,27 @@ deriveEquatable_enum_eq(TypeChecker &tc, Decl *parentDecl, EnumDecl *enumDecl) {
251253
TypeLoc::withoutLoc(boolTy),
252254
parentDC);
253255
eqDecl->setImplicit();
256+
eqDecl->setUserAccessible(false);
254257
eqDecl->getAttrs().add(new (C) InfixAttr(/*implicit*/false));
255-
auto op = C.getStdlibModule()->lookupInfixOperator(C.Id_EqualsOperator);
256-
if (!op) {
257-
tc.diagnose(parentDecl->getLoc(),
258-
diag::broken_equatable_eq_operator);
259-
return nullptr;
260-
}
258+
259+
// Add the @_implements(Equatable, ==(_:_:)) attribute
260+
auto equatableProto = C.getProtocol(KnownProtocolKind::Equatable);
261+
auto equatableTy = equatableProto->getDeclaredType();
262+
auto equatableTypeLoc = TypeLoc::withoutLoc(equatableTy);
263+
SmallVector<Identifier, 2> argumentLabels = { Identifier(), Identifier() };
264+
auto equalsDeclName = DeclName(C, DeclBaseName(C.Id_EqualsOperator),
265+
argumentLabels);
266+
eqDecl->getAttrs().add(new (C) ImplementsAttr(SourceLoc(),
267+
SourceRange(),
268+
equatableTypeLoc,
269+
equalsDeclName,
270+
DeclNameLoc()));
271+
261272
if (!C.getEqualIntDecl()) {
262273
tc.diagnose(parentDecl->getLoc(), diag::no_equal_overload_for_int);
263274
return nullptr;
264275
}
265276

266-
eqDecl->setOperatorDecl(op);
267277
eqDecl->setBodySynthesizer(&deriveBodyEquatable_enum_eq);
268278

269279
// Compute the type.

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 ==(a: d0200_EscapedIdentifiers.`enum`, b: d0200_EscapedIdentifiers.`enum`) -> Bool
588+
// PASS_COMMON-NEXT: {{^}} {{.*}}static func __derived_enum_equals(_ a: d0200_EscapedIdentifiers.`enum`, _ b: d0200_EscapedIdentifiers.`enum`) -> Bool
589589
// PASS_COMMON-NEXT: {{^}} var hashValue: Int { get }{{$}}
590590
// PASS_COMMON-NEXT: {{^}} }{{$}}
591591

@@ -1010,7 +1010,7 @@ enum d2000_EnumDecl1 {
10101010
// PASS_COMMON: {{^}}enum d2000_EnumDecl1 {{{$}}
10111011
// PASS_COMMON-NEXT: {{^}} case ED1_First{{$}}
10121012
// PASS_COMMON-NEXT: {{^}} case ED1_Second{{$}}
1013-
// PASS_COMMON-NEXT: {{^}} static func ==(a: d2000_EnumDecl1, b: d2000_EnumDecl1) -> Bool
1013+
// PASS_COMMON-NEXT: {{^}} {{.*}}static func __derived_enum_equals(_ a: d2000_EnumDecl1, _ b: d2000_EnumDecl1) -> Bool
10141014
// PASS_COMMON-NEXT: {{^}} var hashValue: Int { get }{{$}}
10151015
// PASS_COMMON-NEXT: {{^}}}{{$}}
10161016

test/IRGen/enum_derived.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ enum E {
1818

1919
// Check if the == comparison can be compiled to a simple icmp instruction.
2020

21-
// CHECK-NORMAL-LABEL:define hidden swiftcc i1 @_T012enum_derived1EO2eeoiSbAC_ACtFZ(i8, i8)
22-
// CHECK-TESTABLE-LABEL:define{{( protected)?}} swiftcc i1 @_T012enum_derived1EO2eeoiSbAC_ACtFZ(i8, i8)
21+
// CHECK-NORMAL-LABEL:define hidden swiftcc i1 @_T012enum_derived1EO02__b1_A7_equalsSbAC_ACtFZ(i8, i8)
22+
// CHECK-TESTABLE-LABEL:define{{( protected)?}} swiftcc i1 @_T012enum_derived1EO02__b1_A7_equalsSbAC_ACtFZ(i8, i8)
2323
// CHECK: %2 = icmp eq i8 %0, %1
2424
// CHECK: ret i1 %2
2525

0 commit comments

Comments
 (0)