Skip to content

Commit f93ca42

Browse files
committed
Add a basic execution tests for method overrides and overloads
1 parent 5d439bd commit f93ca42

File tree

1 file changed

+337
-0
lines changed

1 file changed

+337
-0
lines changed
Lines changed: 337 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,337 @@
1+
// RUN: %target-parse-verify-swift -D ERRORS
2+
// RUN: %target-run-simple-swift
3+
// REQUIRES: executable_test
4+
5+
import StdlibUnittest
6+
7+
struct Token1 {}
8+
struct Token2 {}
9+
struct Token3 {}
10+
11+
class C1 {}
12+
class C1x : C1 {}
13+
class C1xx : C1x {}
14+
15+
protocol P1 {}
16+
protocol P1x : P1 {}
17+
18+
struct P1ImplS1 : P1 {}
19+
struct P1xImplS1 : P1x {}
20+
21+
class P1ImplC1x : C1, P1 {}
22+
class P1ImplC1xx {}
23+
class P1xImplC1x : C1, P1x {}
24+
25+
var which = ""
26+
27+
var Overrides = TestSuite("Overrides")
28+
29+
Overrides.test("covariant argument override, non-optional to optional") {
30+
class Base {
31+
func foo(_: C1) { which = "Base.foo(C1)" }
32+
}
33+
class Derived : Base {
34+
override func foo(_: C1?) { which = "Derived.foo(C1?)" }
35+
}
36+
37+
Derived().foo(C1())
38+
expectEqual("Derived.foo(C1?)", which)
39+
40+
Derived().foo(nil as C1?)
41+
expectEqual("Derived.foo(C1?)", which)
42+
}
43+
44+
Overrides.test("covariant argument override, derived class to base class") {
45+
class Base {
46+
func foo(_: C1x) { which = "Base.foo(C1x)" }
47+
}
48+
class Derived : Base {
49+
override func foo(_: C1) { which = "Derived.foo(C1)" }
50+
}
51+
52+
Derived().foo(C1())
53+
expectEqual("Derived.foo(C1)", which)
54+
55+
Derived().foo(C1x())
56+
expectEqual("Derived.foo(C1)", which)
57+
}
58+
59+
Overrides.test("covariant argument override, optional derived class to non-optional base class") {
60+
class Base {
61+
func foo(_: C1x) { which = "Base.foo(C1x)" }
62+
}
63+
class Derived : Base {
64+
override func foo(_: C1?) { which = "Derived.foo(C1?)" }
65+
}
66+
67+
Derived().foo(C1())
68+
expectEqual("Derived.foo(C1?)", which)
69+
70+
Derived().foo(C1x())
71+
expectEqual("Derived.foo(C1?)", which)
72+
73+
Derived().foo(nil)
74+
expectEqual("Derived.foo(C1?)", which)
75+
}
76+
77+
Overrides.test("covariant argument override, protocol to protocol") {
78+
// FIXME: https://bugs.swift.org/browse/SR-731
79+
// Covariant overrides don't work with protocols
80+
class Base {
81+
func foo(_: P1x) { which = "Base.foo(P1x)" }
82+
}
83+
class Derived : Base {
84+
/*FIXME: override */ func foo(_: P1) { which = "Derived.foo(P1)" }
85+
}
86+
87+
Derived().foo(P1ImplS1())
88+
expectEqual("Derived.foo(P1)", which)
89+
90+
Derived().foo(P1xImplS1())
91+
expectEqual("Base.foo(P1x)", which)
92+
}
93+
94+
Overrides.test("covariant argument override, struct to protocol") {
95+
// FIXME: https://bugs.swift.org/browse/SR-731
96+
// Covariant overrides don't work with protocols
97+
class Base {
98+
func foo(_: P1ImplS1) { which = "Base.foo(P1ImplS1)" }
99+
}
100+
class Derived : Base {
101+
/*FIXME: override */ func foo(_: P1) { which = "Derived.foo(P1)" }
102+
}
103+
104+
// FIXME: https://bugs.swift.org/browse/SR-731
105+
expectFailure {
106+
Derived().foo(P1ImplS1())
107+
expectEqual("Derived.foo(P1)", which)
108+
}
109+
110+
Derived().foo(P1xImplS1())
111+
expectEqual("Derived.foo(P1)", which)
112+
}
113+
114+
Overrides.test("contravariant return type override, optional to non-optional") {
115+
class Base {
116+
func foo() -> C1? { which = "Base.foo() -> C1?"; return C1() }
117+
}
118+
class Derived : Base {
119+
override func foo() -> C1 {
120+
which = "Derived.foo() -> C1"; return C1()
121+
}
122+
}
123+
124+
Derived().foo() as C1
125+
expectEqual("Derived.foo() -> C1", which)
126+
127+
Derived().foo() as C1?
128+
expectEqual("Derived.foo() -> C1", which)
129+
}
130+
131+
Overrides.test("contravariant return type override, base class to derived class") {
132+
class Base {
133+
func foo() -> C1 { which = "Base.foo() -> C1"; return C1() }
134+
}
135+
class Derived : Base {
136+
override func foo() -> C1x {
137+
which = "Derived.foo() -> C1x"; return C1x()
138+
}
139+
}
140+
141+
Derived().foo() as C1
142+
expectEqual("Derived.foo() -> C1x", which)
143+
144+
Derived().foo() as C1x
145+
expectEqual("Derived.foo() -> C1x", which)
146+
}
147+
148+
Overrides.test("contravariant return type override, optional base class to non-optional derived class") {
149+
class Base {
150+
func foo() -> C1? { which = "Base.foo() -> C1?"; return C1() }
151+
}
152+
class Derived : Base {
153+
override func foo() -> C1x {
154+
which = "Derived.foo() -> C1x"; return C1x()
155+
}
156+
}
157+
158+
Derived().foo() as C1
159+
expectEqual("Derived.foo() -> C1x", which)
160+
161+
Derived().foo() as C1x
162+
expectEqual("Derived.foo() -> C1x", which)
163+
}
164+
165+
Overrides.test("contravariant return type override, protocol to protocol") {
166+
// FIXME: https://bugs.swift.org/browse/SR-733
167+
// Contravariant overrides on return type don't work with protocols
168+
class Base {
169+
func foo() -> P1 { which = "Base.foo() -> P1"; return P1ImplS1() }
170+
}
171+
class Derived : Base {
172+
/*FIXME: override */ func foo() -> P1x {
173+
which = "Derived.foo() -> P1x"; return P1xImplS1()
174+
}
175+
}
176+
177+
// https://bugs.swift.org/browse/SR-733
178+
// FIXME: uncomment when the bug is fixed.
179+
// Derived().foo() as P1 // error: ambiguous use of 'foo()'
180+
// expectEqual("Derived.foo() -> P1x", which)
181+
182+
Derived().foo() as P1x
183+
expectEqual("Derived.foo() -> P1x", which)
184+
}
185+
186+
Overrides.test("contravariant return type override, protocol to struct") {
187+
// FIXME: https://bugs.swift.org/browse/SR-733
188+
// Contravariant overrides on return type don't work with protocols
189+
class Base {
190+
func foo() -> P1 { which = "Base.foo() -> P1"; return P1ImplS1() }
191+
}
192+
class Derived : Base {
193+
/*FIXME: override */ func foo() -> P1ImplS1 {
194+
which = "Derived.foo() -> P1ImplS1"; return P1ImplS1()
195+
}
196+
}
197+
198+
// https://bugs.swift.org/browse/SR-733
199+
// FIXME: uncomment when the bug is fixed.
200+
// Derived().foo() as P1 // error: ambiguous use of 'foo()'
201+
// expectEqual("Derived.foo() -> P1ImplS1", which)
202+
203+
Derived().foo() as P1ImplS1
204+
expectEqual("Derived.foo() -> P1ImplS1", which)
205+
}
206+
207+
Overrides.test("overrides don't affect overload resolution") {
208+
class Base {
209+
func foo(_: P1) { which = "Base.foo(P1)" }
210+
}
211+
class Derived : Base {
212+
func foo(_: P1x) { which = "Derived.foo(P1x)" }
213+
}
214+
class MoreDerived : Derived {
215+
override func foo(_: P1) { which = "MoreDerived.foo(P1)" }
216+
}
217+
218+
Base().foo(P1ImplS1())
219+
expectEqual("Base.foo(P1)", which)
220+
221+
Derived().foo(P1ImplS1())
222+
expectEqual("Base.foo(P1)", which)
223+
224+
Derived().foo(P1xImplS1())
225+
expectEqual("Derived.foo(P1x)", which)
226+
227+
MoreDerived().foo(P1ImplS1())
228+
expectEqual("MoreDerived.foo(P1)", which)
229+
230+
MoreDerived().foo(P1xImplS1())
231+
expectEqual("Derived.foo(P1x)", which)
232+
}
233+
234+
var Overloads = TestSuite("Overloads")
235+
236+
Overloads.test("perfect match") {
237+
class Base {
238+
func foo(_: C1, _: C1, _: C1) { which = "C1, C1, C1" }
239+
func foo(_: C1, _: C1, _: C1x) { which = "C1, C1, C1x" }
240+
func foo(_: C1, _: C1x, _: C1) { which = "C1, C1x, C1" }
241+
func foo(_: C1, _: C1x, _: C1x) { which = "C1, C1x, C1x" }
242+
func foo(_: C1x, _: C1, _: C1) { which = "C1x, C1, C1" }
243+
func foo(_: C1x, _: C1, _: C1x) { which = "C1x, C1, C1x" }
244+
func foo(_: C1x, _: C1x, _: C1) { which = "C1x, C1x, C1" }
245+
func foo(_: C1x, _: C1x, _: C1x) { which = "C1x, C1x, C1x" }
246+
}
247+
248+
Base().foo(C1(), C1(), C1()); expectEqual("C1, C1, C1", which)
249+
Base().foo(C1(), C1(), C1x()); expectEqual("C1, C1, C1x", which)
250+
Base().foo(C1(), C1x(), C1()); expectEqual("C1, C1x, C1", which)
251+
Base().foo(C1(), C1x(), C1x()); expectEqual("C1, C1x, C1x", which)
252+
Base().foo(C1x(), C1(), C1()); expectEqual("C1x, C1, C1", which)
253+
Base().foo(C1x(), C1(), C1x()); expectEqual("C1x, C1, C1x", which)
254+
Base().foo(C1x(), C1x(), C1()); expectEqual("C1x, C1x, C1", which)
255+
Base().foo(C1x(), C1x(), C1x()); expectEqual("C1x, C1x, C1x", which)
256+
}
257+
258+
Overloads.test("implicit conversion to superclass") {
259+
class Base {
260+
func foo(_: C1) { which = "foo(C1)" }
261+
}
262+
263+
Base().foo(C1()); expectEqual("foo(C1)", which)
264+
Base().foo(C1x()); expectEqual("foo(C1)", which)
265+
Base().foo(C1xx()); expectEqual("foo(C1)", which)
266+
}
267+
268+
Overloads.test("implicit conversion to protocol existential") {
269+
class Base {
270+
func foo(_: P1) { which = "foo(P1)" }
271+
}
272+
273+
Base().foo(P1ImplS1()); expectEqual("foo(P1)", which)
274+
Base().foo(P1xImplS1()); expectEqual("foo(P1)", which)
275+
}
276+
277+
Overloads.test("implicit conversion to a superclass is better than conversion to an optional") {
278+
class Base {
279+
func foo(_: C1) { which = "foo(C1)" }
280+
func foo(_: C1x?) { which = "foo(C1x?)" }
281+
}
282+
283+
Base().foo(C1()); expectEqual("foo(C1)", which)
284+
Base().foo(C1x()); expectEqual("foo(C1)", which)
285+
Base().foo(C1xx()); expectEqual("foo(C1)", which)
286+
287+
Base().foo(C1x() as C1x?); expectEqual("foo(C1x?)", which)
288+
Base().foo(C1xx() as C1xx?); expectEqual("foo(C1x?)", which)
289+
}
290+
291+
Overloads.test("implicit conversion to a protocol existential is better than conversion to an optional") {
292+
class Base {
293+
func foo(_: P1) { which = "foo(P1)" }
294+
func foo(_: P1x?) { which = "foo(P1x?)" }
295+
}
296+
297+
Base().foo(P1ImplS1()); expectEqual("foo(P1)", which)
298+
Base().foo(P1xImplS1()); expectEqual("foo(P1)", which)
299+
300+
Base().foo(P1xImplS1() as P1x?); expectEqual("foo(P1x?)", which)
301+
}
302+
303+
Overloads.test("implicit conversion to a superclass is ambiguous with conversion to a protocol existential") {
304+
class Base {
305+
func foo(_: C1) { which = "foo(C1)" } // expected-note {{found this candidate}}
306+
func foo(_: P1) { which = "foo(P1)" } // expected-note {{found this candidate}}
307+
}
308+
309+
Base().foo(C1()); expectEqual("foo(C1)", which)
310+
Base().foo(P1ImplS1()); expectEqual("foo(P1)", which)
311+
312+
#if ERRORS
313+
Base().foo(P1ImplC1x())
314+
// expected-error @-1 {{ambiguous use of 'foo'}}
315+
#endif
316+
}
317+
318+
Overloads.test("generic methods are worse than non-generic") {
319+
class Base {
320+
func foo(_: C1) { which = "foo(C1)" }
321+
func foo(_: Any) { which = "foo(Any)" }
322+
func foo<T>(_: T) { which = "foo(T)" }
323+
// It is not possible to call foo<T>(T). foo(Any) always wins.
324+
325+
func bar(_: C1) { which = "bar(C1)" }
326+
func bar<T>(_: T) { which = "bar(T)" }
327+
}
328+
329+
Base().foo(C1()); expectEqual("foo(C1)", which)
330+
Base().foo(Token1()); expectEqual("foo(Any)", which)
331+
332+
Base().bar(C1()); expectEqual("bar(C1)", which)
333+
Base().bar(Token1()); expectEqual("bar(T)", which)
334+
}
335+
336+
runAllTests()
337+

0 commit comments

Comments
 (0)