forked from swiftlang/swift
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplacement.swift
219 lines (152 loc) · 9.76 KB
/
placement.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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
// RUN: rm -rf %t
// RUN: mkdir -p %t
// RUN: %target-swift-frontend %S/Inputs/placement_module_A.swift -emit-module -parse-as-library -o %t
// RUN: %target-swift-frontend -I %t %S/Inputs/placement_module_B.swift -emit-module -parse-as-library -o %t
// RUN: %target-swift-frontend -typecheck -primary-file %s %S/Inputs/placement_2.swift -I %t -verify
// Tests for the placement of conformances as well as conflicts
// between conformances that come from different sources.
import placement_module_A
import placement_module_B
protocol P1 { }
protocol P2a : P1 { }
protocol P3a : P2a { }
protocol P2b : P1 { }
protocol P3b : P2b { }
protocol P4 : P3a, P3b { }
protocol AnyObjectRefinement : AnyObject { }
// ===========================================================================
// Tests within a single source file
// ===========================================================================
// ---------------------------------------------------------------------------
// Multiple explicit conformances to the same protocol
// ---------------------------------------------------------------------------
struct Explicit1 : P1 { } // expected-note{{'Explicit1' declares conformance to protocol 'P1' here}}
extension Explicit1 : P1 { } // expected-error{{redundant conformance of 'Explicit1' to protocol 'P1'}}
struct Explicit2 { }
extension Explicit2 : P1 { } // expected-note 2{{'Explicit2' declares conformance to protocol 'P1' here}}
extension Explicit2 : P1 { } // expected-error{{redundant conformance of 'Explicit2' to protocol 'P1'}}
extension Explicit2 : P1 { } // expected-error{{redundant conformance of 'Explicit2' to protocol 'P1'}}
// ---------------------------------------------------------------------------
// Multiple implicit conformances, with no ambiguities
// ---------------------------------------------------------------------------
struct MultipleImplicit1 : P2a { }
extension MultipleImplicit1 : P3a { }
struct MultipleImplicit2 : P4 { }
struct MultipleImplicit3 : P4 { }
extension MultipleImplicit3 : P1 { }
// ---------------------------------------------------------------------------
// Multiple implicit conformances, ambiguity resolved because they
// land in the same context.
// ---------------------------------------------------------------------------
struct MultipleImplicit4 : P2a, P2b { }
struct MultipleImplicit5 { }
extension MultipleImplicit5 : P2a, P2b { }
struct MultipleImplicit6 : P4 { }
extension MultipleImplicit6 : P3a { }
struct MultipleImplicit7 : P2a { }
extension MultipleImplicit7 : P2b { }
// ---------------------------------------------------------------------------
// Multiple implicit conformances, ambiguity resolved via explicit conformance
// ---------------------------------------------------------------------------
struct ExplicitMultipleImplicit1 : P2a { }
extension ExplicitMultipleImplicit1 : P2b { }
extension ExplicitMultipleImplicit1 : P1 { } // resolves ambiguity
// ---------------------------------------------------------------------------
// Implicit conformances superseded by inherited conformances
// ---------------------------------------------------------------------------
class ImplicitSuper1 : P3a { }
class ImplicitSub1 : ImplicitSuper1 { }
extension ImplicitSub1 : P4 { } // okay, introduces new conformance to P4; the rest are superseded
// ---------------------------------------------------------------------------
// Synthesized conformances superseded by implicit conformances
// ---------------------------------------------------------------------------
enum SuitA { case Spades, Hearts, Clubs, Diamonds }
func <(lhs: SuitA, rhs: SuitA) -> Bool { return false }
extension SuitA : Comparable {} // okay, implied conformance to Equatable here is preferred.
enum SuitB: Equatable { case Spades, Hearts, Clubs, Diamonds }
func <(lhs: SuitB, rhs: SuitB) -> Bool { return false }
extension SuitB : Comparable {} // okay, explicitly declared earlier.
enum SuitC { case Spades, Hearts, Clubs, Diamonds }
func <(lhs: SuitC, rhs: SuitC) -> Bool { return false }
extension SuitC : Equatable, Comparable {} // okay, explicitly declared here.
// ---------------------------------------------------------------------------
// Explicit conformances conflicting with inherited conformances
// ---------------------------------------------------------------------------
class ExplicitSuper1 : P3a { }
class ExplicitSub1 : ImplicitSuper1 { } // expected-note{{'ExplicitSub1' inherits conformance to protocol 'P1' from superclass here}}
extension ExplicitSub1 : P1 { } // expected-error{{redundant conformance of 'ExplicitSub1' to protocol 'P1'}}
// ---------------------------------------------------------------------------
// Suppression of synthesized conformances
// ---------------------------------------------------------------------------
class SynthesizedClass1 : AnyObject { }
class SynthesizedClass2 { }
extension SynthesizedClass2 : AnyObject { }
class SynthesizedClass3 : AnyObjectRefinement { }
class SynthesizedClass4 { }
extension SynthesizedClass4 : AnyObjectRefinement { }
class SynthesizedSubClass1 : SynthesizedClass1, AnyObject { } // expected-error{{redundant conformance of 'SynthesizedSubClass1' to protocol 'AnyObject'}}
// expected-note@-1{{'SynthesizedSubClass1' inherits conformance to protocol 'AnyObject' from superclass here}}
class SynthesizedSubClass2 : SynthesizedClass2 { } // expected-note{{'SynthesizedSubClass2' inherits conformance to protocol 'AnyObject' from superclass here}}
extension SynthesizedSubClass2 : AnyObject { } // expected-error{{redundant conformance of 'SynthesizedSubClass2' to protocol 'AnyObject'}}
class SynthesizedSubClass3 : SynthesizedClass1, AnyObjectRefinement { }
class SynthesizedSubClass4 : SynthesizedClass2 { }
extension SynthesizedSubClass4 : AnyObjectRefinement { }
enum SynthesizedEnum1 : Int, RawRepresentable { case none = 0 }
enum SynthesizedEnum2 : Int { case none = 0 }
extension SynthesizedEnum2 : RawRepresentable { }
// ===========================================================================
// Tests across different source files
// ===========================================================================
// ---------------------------------------------------------------------------
// Multiple explicit conformances to the same protocol
// ---------------------------------------------------------------------------
struct MFExplicit1 : P1 { }
extension MFExplicit2 : P1 { } // expected-error{{redundant conformance of 'MFExplicit2' to protocol 'P1'}}
// ---------------------------------------------------------------------------
// Multiple implicit conformances, with no ambiguities
// ---------------------------------------------------------------------------
extension MFMultipleImplicit1 : P3a { }
struct MFMultipleImplicit2 : P4 { }
extension MFMultipleImplicit3 : P1 { }
extension MFMultipleImplicit4 : P3a { }
extension MFMultipleImplicit5 : P2b { }
// ---------------------------------------------------------------------------
// Explicit conformances conflicting with inherited conformances
// ---------------------------------------------------------------------------
class MFExplicitSuper1 : P3a { }
extension MFExplicitSub1 : P1 { } // expected-error{{redundant conformance of 'MFExplicitSub1' to protocol 'P1'}}
// ---------------------------------------------------------------------------
// Suppression of synthesized conformances
// ---------------------------------------------------------------------------
class MFSynthesizedClass1 { }
extension MFSynthesizedClass2 : AnyObject { }
class MFSynthesizedClass4 { }
extension MFSynthesizedClass4 : AnyObjectRefinement { }
extension MFSynthesizedSubClass2 : AnyObject { } // expected-error{{redundant conformance of 'MFSynthesizedSubClass2' to protocol 'AnyObject'}}
extension MFSynthesizedSubClass3 : AnyObjectRefinement { }
class MFSynthesizedSubClass4 : MFSynthesizedClass2 { }
extension MFSynthesizedEnum1 : RawRepresentable { }
enum MFSynthesizedEnum2 : Int { case none = 0 }
// ===========================================================================
// Tests with conformances in imported modules
// ===========================================================================
extension MMExplicit1 : MMP1 { } // expected-error{{redundant conformance of 'MMExplicit1' to protocol 'MMP1'}}
extension MMExplicit1 : MMP2a { } // expected-error{{redundant conformance of 'MMExplicit1' to protocol 'MMP2a'}}
extension MMExplicit1 : MMP3a { } // expected-error{{redundant conformance of 'MMExplicit1' to protocol 'MMP3a'}}
extension MMExplicit1 : MMP3b { } // okay
extension MMSuper1 : MMP1 { } // expected-error{{redundant conformance of 'MMSuper1' to protocol 'MMP1'}}
extension MMSuper1 : MMP2a { } // expected-error{{redundant conformance of 'MMSuper1' to protocol 'MMP2a'}}
extension MMSuper1 : MMP3b { } // okay
extension MMSub1 : AnyObject { } // expected-error{{redundant conformance of 'MMSub1' to protocol 'AnyObject'}}
extension MMSub2 : MMP1 { } // expected-error{{redundant conformance of 'MMSub2' to protocol 'MMP1'}}
extension MMSub2 : MMP2a { } // expected-error{{redundant conformance of 'MMSub2' to protocol 'MMP2a'}}
extension MMSub2 : MMP3b { } // okay
extension MMSub2 : MMAnyObjectRefinement { } // okay
extension MMSub3 : MMP1 { } // expected-error{{redundant conformance of 'MMSub3' to protocol 'MMP1'}}
extension MMSub3 : MMP2a { } // expected-error{{redundant conformance of 'MMSub3' to protocol 'MMP2a'}}
extension MMSub3 : MMP3b { } // okay
extension MMSub3 : AnyObject { } // expected-error{{redundant conformance of 'MMSub3' to protocol 'AnyObject'}}
extension MMSub4 : MMP1 { } // expected-error{{redundant conformance of 'MMSub4' to protocol 'MMP1'}}
extension MMSub4 : MMP2a { } // expected-error{{redundant conformance of 'MMSub4' to protocol 'MMP2a'}}
extension MMSub4 : MMP3b { } // okay
extension MMSub4 : AnyObjectRefinement { } // okay