1
- // RUN: %target-run-simple-swift | %FileCheck %s
1
+ // RUN: %target-run-simple-swift
2
2
// RUN: %target-build-swift -O %s -o %t/a.out.optimized
3
- // RUN: %target-run %t/a.out.optimized | %FileCheck %s
3
+ // RUN: %target-run %t/a.out.optimized
4
4
// REQUIRES: executable_test
5
5
6
+ import StdlibUnittest
7
+
8
+ let tupleCastTests = TestSuite ( " Tuple casting " )
9
+
6
10
func anyToIntPoint( _ x: Any ) -> ( x: Int , y: Int ) {
7
11
return x as! ( x: Int , y: Int )
8
12
}
@@ -19,17 +23,122 @@ func anyToPartlyLabeled(_ x: Any) -> (first: Int, Int, third: Int) {
19
23
return x as! ( first: Int , Int , third: Int )
20
24
}
21
25
22
- // Labels can be added/removed.
23
- print ( " Label add/remove " ) // CHECK: Label add/remove
24
- print ( anyToIntPoint ( ( x: 1 , y: 2 ) ) ) // CHECK-NEXT: (x: 1, y: 2)
25
- print ( anyToIntPoint ( ( 3 , 4 ) ) ) // CHECK-NEXT: (x: 3, y: 4)
26
- print ( anyToIntPoint ( ( x: 5 , 6 ) ) ) // CHECK-NEXT: (x: 5, y: 6)
27
- print ( anyToInt2 ( ( 1 , 2 ) ) ) // CHECK-NEXT: (1, 2)
28
- print ( anyToInt2 ( ( x: 3 , y: 4 ) ) ) // CHECK-NEXT: (3, 4)
29
- print ( anyToInt2 ( ( x: 5 , 6 ) ) ) // CHECK-NEXT: (5, 6)
30
- print ( anyToPartlyLabeled ( ( 1 , 2 , 3 ) ) ) // CHECK-NEXT: (first: 1, 2, third: 3)
31
-
32
- // Labels cannot be wrong.
33
- print ( " Wrong labels " ) // CHECK: Wrong labels
34
- print ( anyToIntPointOpt ( ( x: 1 , z: 2 ) ) ) // CHECK-NEXT: nil
35
- print ( anyToIntPointOpt ( ( x: 1 , y: 2 ) ) ) // CHECK-NEXT: Optional((x: 1, y: 2))
26
+ tupleCastTests. test ( " Adding/removing labels " ) {
27
+ expectEqual ( " (x: 1, y: 2) " ,
28
+ String ( describing: anyToIntPoint ( ( x: 1 , y: 2 ) ) ) )
29
+ expectEqual ( " (x: 3, y: 4) " ,
30
+ String ( describing: anyToIntPoint ( ( 3 , 4 ) ) ) )
31
+ expectEqual ( " (x: 5, y: 6) " ,
32
+ String ( describing: anyToIntPoint ( ( x: 5 , 6 ) ) ) )
33
+
34
+ expectEqual ( " (1, 2) " , String ( describing: anyToInt2 ( ( 1 , 2 ) ) ) )
35
+ expectEqual ( " (3, 4) " , String ( describing: anyToInt2 ( ( x: 3 , y: 4 ) ) ) )
36
+ expectEqual ( " (5, 6) " , String ( describing: anyToInt2 ( ( x: 5 , 6 ) ) ) )
37
+
38
+ expectEqual ( " (first: 1, 2, third: 3) " ,
39
+ String ( describing: anyToPartlyLabeled ( ( 1 , 2 , 3 ) ) ) )
40
+ }
41
+
42
+ tupleCastTests. test ( " Incorrect labels conditional cast " ) {
43
+ expectNil ( anyToIntPointOpt ( ( x: 1 , z: 2 ) ) )
44
+ expectEqual ( " Optional((x: 1, y: 2)) " ,
45
+ String ( describing: anyToIntPointOpt ( ( x: 1 , y: 2 ) ) ) )
46
+ }
47
+
48
+ tupleCastTests
49
+ . test ( " Incorrect labels forced cast " )
50
+ . crashOutputMatches ( " Could not cast value of type '(x: Swift.Int, z: Swift.Int)' " )
51
+ . code {
52
+ expectCrashLater ( )
53
+ _ = anyToIntPoint ( ( x: 1 , z: 2 ) )
54
+ }
55
+
56
+ func castToThree< T, U, V> ( _ x: Any , _: T . Type , _: U . Type , _: V . Type )
57
+ -> ( t: T , u: U , v: V ) {
58
+ return x as! ( t: T , u: U , v: V )
59
+ }
60
+
61
+ func castToThreeOpt< T, U, V> ( _ x: Any , _: T . Type , _: U . Type , _: V . Type )
62
+ -> ( t: T , u: U , v: V ) ? {
63
+ return x as? ( t: T , u: U , v: V )
64
+ }
65
+
66
+ class LifetimeA {
67
+ var tracked : LifetimeTracked
68
+
69
+ init ( value: Int ) {
70
+ tracked = LifetimeTracked ( value)
71
+ }
72
+ }
73
+
74
+ class LifetimeB : LifetimeA {
75
+ }
76
+
77
+ class LifetimeC : LifetimeA {
78
+ }
79
+
80
+ protocol P { }
81
+ extension LifetimeA : P { }
82
+
83
+ tupleCastTests. test ( " Elementwise tuple casts that succeed " ) {
84
+ let abc : ( P , Any , P ) = ( LifetimeA ( value: 1 ) ,
85
+ LifetimeB ( value: 2 ) ,
86
+ LifetimeC ( value: 3 ) )
87
+
88
+ expectEqual (
89
+ " (t: main.LifetimeA, u: main.LifetimeB, v: main.LifetimeC) " ,
90
+ String ( describing: castToThree ( abc, LifetimeA . self, LifetimeA . self,
91
+ LifetimeA . self) ) )
92
+
93
+ expectEqual (
94
+ " (t: main.LifetimeA, u: main.LifetimeB, v: main.LifetimeC) " ,
95
+ String ( describing: castToThree ( ( LifetimeA ( value: 1 ) ,
96
+ LifetimeB ( value: 2 ) ,
97
+ LifetimeC ( value: 3 ) ) as ( P , Any , P ) ,
98
+ LifetimeA . self, LifetimeA . self,
99
+ LifetimeA . self) ) )
100
+ }
101
+
102
+ tupleCastTests. test ( " Elementwise tuple casts that conditionally fail " ) {
103
+ let abc : ( P , Any , P ) = ( LifetimeA ( value: 1 ) ,
104
+ LifetimeB ( value: 2 ) ,
105
+ LifetimeC ( value: 3 ) )
106
+ expectNil ( castToThreeOpt ( abc, LifetimeA . self, LifetimeB . self, LifetimeB . self) )
107
+ expectNil ( castToThreeOpt ( abc, LifetimeA . self, LifetimeC . self, LifetimeC . self) )
108
+ expectNil ( castToThreeOpt ( abc, LifetimeC . self, LifetimeB . self, LifetimeC . self) )
109
+ }
110
+
111
+ tupleCastTests
112
+ . test ( " Elementwise tuple casts that crash (1/3) " )
113
+ . crashOutputMatches ( " Could not cast value of type 'main.LifetimeA' " )
114
+ . code {
115
+ let abc : ( P , Any , P ) = ( LifetimeA ( value: 1 ) ,
116
+ LifetimeB ( value: 2 ) ,
117
+ LifetimeC ( value: 3 ) )
118
+ expectCrashLater ( )
119
+ _ = castToThree ( abc, LifetimeC . self, LifetimeB . self, LifetimeC . self)
120
+ }
121
+
122
+ tupleCastTests
123
+ . test ( " Elementwise tuple casts that crash (2/3) " )
124
+ . crashOutputMatches ( " Could not cast value of type 'main.LifetimeB " )
125
+ . code {
126
+ let abc : ( P , Any , P ) = ( LifetimeA ( value: 1 ) ,
127
+ LifetimeB ( value: 2 ) ,
128
+ LifetimeC ( value: 3 ) )
129
+ expectCrashLater ( )
130
+ _ = castToThree ( abc, LifetimeA . self, LifetimeC . self, LifetimeC . self)
131
+ }
132
+
133
+ tupleCastTests
134
+ . test ( " Elementwise tuple casts that crash (3/3) " )
135
+ . crashOutputMatches ( " Could not cast value of type 'main.LifetimeC " )
136
+ . code {
137
+ let abc : ( P , Any , P ) = ( LifetimeA ( value: 1 ) ,
138
+ LifetimeB ( value: 2 ) ,
139
+ LifetimeC ( value: 3 ) )
140
+ expectCrashLater ( )
141
+ _ = castToThree ( abc, LifetimeA . self, LifetimeB . self, LifetimeB . self)
142
+ }
143
+
144
+ runAllTests ( )
0 commit comments