Skip to content

Commit 10f2ee0

Browse files
committed
Executable tests for function type conversions
Also NSHipster is an actual website that exists, so let's use NSBurrito as a placeholder name in the function_conversion_objc test instead. Swift SVN r31550
1 parent 9f7a750 commit 10f2ee0

File tree

2 files changed

+262
-14
lines changed

2 files changed

+262
-14
lines changed

Diff for: test/Interpreter/FunctionConversion.swift

+248
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
//===--- FunctionConversion.swift -----------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
// RUN: %target-run-simple-swift
13+
// REQUIRES: executable_test
14+
//
15+
// XFAIL: interpret
16+
17+
import StdlibUnittest
18+
19+
var FunctionConversionTestSuite = TestSuite("FunctionConversion")
20+
21+
protocol Quilt {
22+
var n: Int8 { get }
23+
}
24+
25+
protocol Patchwork : Quilt {}
26+
27+
struct Trivial : Patchwork {
28+
let n: Int8
29+
}
30+
31+
struct Loadable : Patchwork {
32+
let c: Fabric
33+
34+
var n: Int8 {
35+
return c.n
36+
}
37+
38+
init(n: Int8) {
39+
c = Fabric(n: n)
40+
}
41+
}
42+
43+
struct AddrOnly : Patchwork {
44+
let a: Any
45+
46+
var n: Int8 {
47+
return a as! Int8
48+
}
49+
50+
init(n: Int8) {
51+
a = n
52+
}
53+
}
54+
55+
class Fabric {
56+
let n: Int8
57+
58+
init(n: Int8) {
59+
self.n = n
60+
}
61+
}
62+
63+
class Parent : Patchwork {
64+
let n: Int8
65+
66+
required init(n: Int8) {
67+
self.n = n
68+
}
69+
}
70+
71+
class Child : Parent {}
72+
73+
func t1(s: Trivial?) -> Trivial {
74+
return Trivial(n: s!.n * 2)
75+
}
76+
77+
func l1(s: Loadable?) -> Loadable {
78+
return Loadable(n: s!.n * 2)
79+
}
80+
81+
func a1(s: AddrOnly?) -> AddrOnly {
82+
return AddrOnly(n: s!.n * 2)
83+
}
84+
85+
FunctionConversionTestSuite.test("Optional") {
86+
let g11: Trivial -> Trivial? = t1
87+
let g12: Trivial! -> Trivial? = t1
88+
89+
expectEqual(22, g11(Trivial(n: 11))?.n)
90+
expectEqual(24, g12(Trivial(n: 12))?.n)
91+
92+
let g21: Loadable? -> Loadable? = l1
93+
let g22: Loadable! -> Loadable? = l1
94+
95+
expectEqual(42, g21(Loadable(n: 21))?.n)
96+
expectEqual(44, g22(Loadable(n: 22))?.n)
97+
98+
let g31: AddrOnly? -> AddrOnly? = a1
99+
let g32: AddrOnly! -> AddrOnly? = a1
100+
101+
expectEqual(62, g31(AddrOnly(n: 31))?.n)
102+
expectEqual(64, g32(AddrOnly(n: 32))?.n)
103+
}
104+
105+
func t2(s: Quilt) -> Trivial {
106+
return s as! Trivial
107+
}
108+
109+
func t3(s: Quilt?) -> Trivial {
110+
return s! as! Trivial
111+
}
112+
113+
func l2(s: Quilt) -> Loadable {
114+
return s as! Loadable
115+
}
116+
117+
func l3(s: Quilt?) -> Loadable {
118+
return s! as! Loadable
119+
}
120+
121+
func a2(s: Quilt) -> AddrOnly {
122+
return s as! AddrOnly
123+
}
124+
125+
func a3(s: Quilt?) -> AddrOnly {
126+
return s! as! AddrOnly
127+
}
128+
129+
FunctionConversionTestSuite.test("Existential") {
130+
let g11: Trivial -> Patchwork = t2
131+
let g12: Trivial? -> Patchwork = t3
132+
let g13: Patchwork -> Patchwork = t2
133+
134+
expectEqual(11, g11(Trivial(n: 11)).n)
135+
expectEqual(12, g12(Trivial(n: 12)).n)
136+
expectEqual(13, g13(Trivial(n: 13)).n)
137+
138+
let g21: Loadable -> Patchwork = l2
139+
let g22: Loadable? -> Patchwork = l3
140+
let g23: Patchwork -> Patchwork = l2
141+
142+
expectEqual(21, g21(Loadable(n: 21)).n)
143+
expectEqual(22, g22(Loadable(n: 22)).n)
144+
expectEqual(23, g23(Loadable(n: 23)).n)
145+
146+
let g31: AddrOnly -> Patchwork = a2
147+
let g32: AddrOnly -> Patchwork = a3
148+
let g33: Patchwork -> Patchwork = a2
149+
150+
expectEqual(31, g31(AddrOnly(n: 31)).n)
151+
expectEqual(32, g32(AddrOnly(n: 32)).n)
152+
expectEqual(33, g33(AddrOnly(n: 33)).n)
153+
}
154+
155+
func em(t: Quilt.Type?) -> Trivial.Type {
156+
return t! as! Trivial.Type
157+
}
158+
159+
FunctionConversionTestSuite.test("ExistentialMetatype") {
160+
let g1: Trivial.Type -> Patchwork.Type = em
161+
let g2: Trivial.Type? -> Patchwork.Type = em
162+
let g3: Patchwork.Type -> Patchwork.Type = em
163+
let g4: Patchwork.Type -> Any = em
164+
165+
let result1 = g1(Trivial.self)
166+
let result2 = g2(Trivial.self)
167+
let result3 = g3(Trivial.self)
168+
let result4 = g4(Trivial.self)
169+
170+
expectEqual(true, result1 == Trivial.self)
171+
expectEqual(true, result2 == Trivial.self)
172+
expectEqual(true, result3 == Trivial.self)
173+
expectEqual(true, result4 as! Trivial.Type == Trivial.self)
174+
}
175+
176+
func c1(p: Parent) -> (Child, Trivial) {
177+
return (Child(n: p.n), Trivial(n: p.n))
178+
}
179+
180+
func c2(p: Parent?) -> (Child, Trivial) {
181+
return (Child(n: p!.n), Trivial(n: p!.n))
182+
}
183+
184+
FunctionConversionTestSuite.test("ClassUpcast") {
185+
let g1: Child -> (Parent, Trivial?) = c1
186+
let g2: Child -> (Parent?, Trivial?) = c2
187+
188+
expectEqual(g1(Child(n: 2)).0.n, 2)
189+
expectEqual(g2(Child(n: 4)).0!.n, 4)
190+
}
191+
192+
func cm1(p: Parent.Type) -> (Child.Type, Trivial) {
193+
return (Child.self, Trivial(n: 0))
194+
}
195+
196+
func cm2(p: Parent.Type?) -> (Child.Type, Trivial) {
197+
return (Child.self, Trivial(n: 0))
198+
}
199+
200+
FunctionConversionTestSuite.test("ClassMetatypeUpcast") {
201+
let g1: Child.Type -> (Parent.Type, Trivial?) = cm1
202+
let g2: Child.Type -> (Parent.Type, Trivial?) = cm2
203+
let g3: Child.Type? -> (Parent.Type?, Trivial?) = cm2
204+
205+
let result1 = g1(Child.self)
206+
let result2 = g2(Child.self)
207+
let result3 = g3(Child.self)
208+
209+
expectEqual(true, result1.0 == Child.self)
210+
expectEqual(true, result2.0 == Child.self)
211+
expectEqual(true, result3.0! == Child.self)
212+
}
213+
214+
func sq(i: Int) -> Int {
215+
return i * i
216+
}
217+
218+
func f1(f: Any) -> Int -> Int {
219+
return f as! (Int -> Int)
220+
}
221+
222+
FunctionConversionTestSuite.test("FuncExistential") {
223+
let g11: (Int -> Int) -> Any = f1
224+
225+
expectEqual(100, f1(g11(sq))(10))
226+
}
227+
228+
func generic1<T>(t: Parent) -> (T, Trivial) {
229+
return (t as! T, Trivial(n: 0))
230+
}
231+
232+
func generic2<T : Parent>(f: Parent -> (T, Trivial), t: T) -> Child -> (Parent, Trivial?) {
233+
return f
234+
}
235+
236+
FunctionConversionTestSuite.test("ClassArchetypeUpcast") {
237+
let g11: Child -> (Parent, Trivial?) = generic2(generic1, t: Child(n: 10))
238+
expectEqual(10, g11(Child(n: 10)).0.n)
239+
}
240+
241+
func doesNotThrow() {}
242+
243+
FunctionConversionTestSuite.test("ThrowVariance") {
244+
let g: () throws -> () = doesNotThrow
245+
do { try print(g()) } catch {}
246+
}
247+
248+
runAllTests()

Diff for: test/SILGen/function_conversion_objc.swift

+14-14
Original file line numberDiff line numberDiff line change
@@ -17,30 +17,30 @@ func convMetatypeToObject(f: NSObject -> NSObject.Type) {
1717
// CHECK: objc_metatype_to_object {{.*}} : $@objc_metatype NSObject.Type to $AnyObject
1818
// CHECK: return
1919

20-
@objc protocol NSHipster {}
20+
@objc protocol NSBurrito {}
2121

22-
// CHECK-LABEL: sil hidden @_TF24function_conversion_objc31convExistentialMetatypeToObjectFFPS_9NSHipster_PMPS0__T_
23-
func convExistentialMetatypeToObject(f: NSHipster -> NSHipster.Type) {
24-
// CHECK: function_ref @_TTRXFo_oP24function_conversion_objc9NSHipster__dXPMTPS0___XFo_oPS0___oPSs9AnyObject__
22+
// CHECK-LABEL: sil hidden @_TF24function_conversion_objc31convExistentialMetatypeToObjectFFPS_9NSBurrito_PMPS0__T_
23+
func convExistentialMetatypeToObject(f: NSBurrito -> NSBurrito.Type) {
24+
// CHECK: function_ref @_TTRXFo_oP24function_conversion_objc9NSBurrito__dXPMTPS0___XFo_oPS0___oPSs9AnyObject__
2525
// CHECK: partial_apply
26-
let _: NSHipster -> AnyObject = f
26+
let _: NSBurrito -> AnyObject = f
2727
}
2828

29-
// CHECK-LABEL: sil shared [transparent] [reabstraction_thunk] @_TTRXFo_oP24function_conversion_objc9NSHipster__dXPMTPS0___XFo_oPS0___oPSs9AnyObject__ : $@convention(thin) (@owned NSHipster, @owned @callee_owned (@owned NSHipster) -> @thick NSHipster.Type) -> @owned AnyObject
29+
// CHECK-LABEL: sil shared [transparent] [reabstraction_thunk] @_TTRXFo_oP24function_conversion_objc9NSBurrito__dXPMTPS0___XFo_oPS0___oPSs9AnyObject__ : $@convention(thin) (@owned NSBurrito, @owned @callee_owned (@owned NSBurrito) -> @thick NSBurrito.Type) -> @owned AnyObject
3030
// CHECK: apply %1(%0)
31-
// CHECK: thick_to_objc_metatype {{.*}} : $@thick NSHipster.Type to $@objc_metatype NSHipster.Type
32-
// CHECK: objc_existential_metatype_to_object {{.*}} : $@objc_metatype NSHipster.Type to $AnyObject
31+
// CHECK: thick_to_objc_metatype {{.*}} : $@thick NSBurrito.Type to $@objc_metatype NSBurrito.Type
32+
// CHECK: objc_existential_metatype_to_object {{.*}} : $@objc_metatype NSBurrito.Type to $AnyObject
3333
// CHECK: return
3434

35-
// CHECK-LABEL: sil hidden @_TF24function_conversion_objc28convProtocolMetatypeToObjectFFT_MPS_9NSHipster_T_
36-
func convProtocolMetatypeToObject(f: () -> NSHipster.Protocol) {
37-
// CHECK: function_ref @_TTRXFo__dXMtP24function_conversion_objc9NSHipster__XFo__oCSo8Protocol_
35+
// CHECK-LABEL: sil hidden @_TF24function_conversion_objc28convProtocolMetatypeToObjectFFT_MPS_9NSBurrito_T_
36+
func convProtocolMetatypeToObject(f: () -> NSBurrito.Protocol) {
37+
// CHECK: function_ref @_TTRXFo__dXMtP24function_conversion_objc9NSBurrito__XFo__oCSo8Protocol_
3838
// CHECK: partial_apply
3939
let _: () -> Protocol = f
4040
}
4141

42-
// CHECK-LABEL: sil shared [transparent] [reabstraction_thunk] @_TTRXFo__dXMtP24function_conversion_objc9NSHipster__XFo__oCSo8Protocol_ : $@convention(thin) (@owned @callee_owned () -> @thin NSHipster.Protocol) -> @owned Protocol
43-
// CHECK: apply %0() : $@callee_owned () -> @thin NSHipster.Protocol
44-
// CHECK: objc_protocol #NSHipster : $Protocol
42+
// CHECK-LABEL: sil shared [transparent] [reabstraction_thunk] @_TTRXFo__dXMtP24function_conversion_objc9NSBurrito__XFo__oCSo8Protocol_ : $@convention(thin) (@owned @callee_owned () -> @thin NSBurrito.Protocol) -> @owned Protocol
43+
// CHECK: apply %0() : $@callee_owned () -> @thin NSBurrito.Protocol
44+
// CHECK: objc_protocol #NSBurrito : $Protocol
4545
// CHECK: strong_retain
4646
// CHECK: return

0 commit comments

Comments
 (0)