forked from swiftlang/swift
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathenum_equatable_hashable.swift
125 lines (97 loc) · 2.96 KB
/
enum_equatable_hashable.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// RUN: rm -rf %t && mkdir -p %t
// RUN: cp %s %t/main.swift
// RUN: %target-swift-frontend -parse -verify -primary-file %t/main.swift %S/Inputs/enum_equatable_hashable_other.swift
enum Foo {
case A, B
}
if Foo.A == .B { }
var aHash: Int = Foo.A.hashValue
enum Generic<T> {
case A, B
func method() -> Int {
if A == B { }
return A.hashValue
}
}
if Generic<Foo>.A == .B { }
var gaHash: Int = Generic<Foo>.A.hashValue
func localEnum() -> Bool {
enum Local {
case A, B
}
return Local.A == .B
}
enum CustomHashable {
case A, B
var hashValue: Int { return 0 }
}
func ==(x: CustomHashable, y: CustomHashable) -> Bool { // expected-note{{non-matching type}}
return true
}
if CustomHashable.A == .B { }
var custHash: Int = CustomHashable.A.hashValue
// We still synthesize conforming overloads of '==' and 'hashValue' if
// explicit definitions don't satisfy the protocol requirements. Probably
// not what we actually want.
enum InvalidCustomHashable {
case A, B
var hashValue: String { return "" } // expected-note{{previously declared here}}
}
func ==(x: InvalidCustomHashable, y: InvalidCustomHashable) -> String { // expected-note{{non-matching type}}
return ""
}
if InvalidCustomHashable.A == .B { }
var s: String = InvalidCustomHashable.A == .B
s = InvalidCustomHashable.A.hashValue
var i: Int = InvalidCustomHashable.A.hashValue
// Check use of an enum's synthesized members before the enum is actually declared.
struct UseEnumBeforeDeclaration {
let eqValue = EnumToUseBeforeDeclaration.A == .A
let hashValue = EnumToUseBeforeDeclaration.A.hashValue
}
enum EnumToUseBeforeDeclaration {
case A
}
// Check enums from another file in the same module.
if FromOtherFile.A == .A {}
let _: Int = FromOtherFile.A.hashValue
func getFromOtherFile() -> AlsoFromOtherFile { return .A }
if .A == getFromOtherFile() {}
// FIXME: This should work.
func overloadFromOtherFile() -> YetAnotherFromOtherFile { return .A }
func overloadFromOtherFile() -> Bool { return false }
if .A == overloadFromOtherFile() {}
// Complex enums are not implicitly Equatable or Hashable.
enum Complex {
case A(Int)
case B
}
if Complex.A(1) == .B { } // expected-error{{type of expression is ambiguous without more context}}
// rdar://19773050
private enum Bar<T> {
case E(Unknown<T>) // expected-error {{use of undeclared type 'Unknown'}}
mutating func value() -> T {
switch self {
case E(let x): // expected-error{{invalid pattern}}
return x.value
}
}
}
// Equatable extension -- rdar://20981254
enum Instrument {
case Piano
case Violin
case Guitar
}
extension Instrument : Equatable {}
// Explicit conformance should work too
public enum Medicine {
case Antibiotic
case Antihistamine
}
extension Medicine : Equatable {}
public func ==(lhs: Medicine, rhs: Medicine) -> Bool { // expected-note{{non-matching type}}
return true
}
// No explicit conformance and cannot be derived
extension Complex : Hashable {} // expected-error 2 {{does not conform}}