mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
146 lines
4.5 KiB
Swift
146 lines
4.5 KiB
Swift
// RUN: %target-run-simple-swift
|
|
// RUN: %target-build-swift -O %s -o %t/a.out.optimized
|
|
// RUN: %target-codesign %t/a.out.optimized
|
|
// RUN: %target-run %t/a.out.optimized
|
|
// REQUIRES: executable_test
|
|
|
|
import StdlibUnittest
|
|
|
|
let tupleCastTests = TestSuite("Tuple casting")
|
|
|
|
func anyToIntPoint(_ x: Any) -> (x: Int, y: Int) {
|
|
return x as! (x: Int, y: Int)
|
|
}
|
|
|
|
func anyToIntPointOpt(_ x: Any) -> (x: Int, y: Int)? {
|
|
return x as? (x: Int, y: Int)
|
|
}
|
|
|
|
func anyToInt2(_ x: Any) -> (Int, Int) {
|
|
return x as! (Int, Int)
|
|
}
|
|
|
|
func anyToPartlyLabeled(_ x: Any) -> (first: Int, Int, third: Int) {
|
|
return x as! (first: Int, Int, third: Int)
|
|
}
|
|
|
|
tupleCastTests.test("Adding/removing labels") {
|
|
expectEqual("(x: 1, y: 2)",
|
|
String(describing: anyToIntPoint((x: 1, y: 2))))
|
|
expectEqual("(x: 3, y: 4)",
|
|
String(describing: anyToIntPoint((3, 4))))
|
|
expectEqual("(x: 5, y: 6)",
|
|
String(describing: anyToIntPoint((x: 5, 6))))
|
|
|
|
expectEqual("(1, 2)", String(describing: anyToInt2((1, 2))))
|
|
expectEqual("(3, 4)", String(describing: anyToInt2((x: 3, y: 4))))
|
|
expectEqual("(5, 6)", String(describing: anyToInt2((x: 5, 6))))
|
|
|
|
expectEqual("(first: 1, 2, third: 3)",
|
|
String(describing: anyToPartlyLabeled((1, 2, 3))))
|
|
}
|
|
|
|
tupleCastTests.test("Incorrect labels conditional cast") {
|
|
expectNil(anyToIntPointOpt((x: 1, z: 2)))
|
|
expectEqual("Optional((x: 1, y: 2))",
|
|
String(describing: anyToIntPointOpt((x: 1, y: 2))))
|
|
}
|
|
|
|
tupleCastTests
|
|
.test("Incorrect labels forced cast")
|
|
.crashOutputMatches("Could not cast value of type '(x: Swift.Int, z: Swift.Int)'")
|
|
.code {
|
|
expectCrashLater()
|
|
_ = anyToIntPoint((x: 1, z: 2))
|
|
}
|
|
|
|
func castToThree<T, U, V>(_ x: Any, _: T.Type, _: U.Type, _: V.Type)
|
|
-> (t: T, u: U, v: V) {
|
|
return x as! (t: T, u: U, v: V)
|
|
}
|
|
|
|
func castToThreeOpt<T, U, V>(_ x: Any, _: T.Type, _: U.Type, _: V.Type)
|
|
-> (t: T, u: U, v: V)? {
|
|
return x as? (t: T, u: U, v: V)
|
|
}
|
|
|
|
class LifetimeA {
|
|
var tracked: LifetimeTracked
|
|
|
|
init(value: Int) {
|
|
tracked = LifetimeTracked(value)
|
|
}
|
|
}
|
|
|
|
class LifetimeB : LifetimeA {
|
|
}
|
|
|
|
class LifetimeC : LifetimeA {
|
|
}
|
|
|
|
protocol P { }
|
|
extension LifetimeA : P { }
|
|
|
|
tupleCastTests.test("Elementwise tuple casts that succeed") {
|
|
let abc: (P, Any, P) = (LifetimeA(value: 1),
|
|
LifetimeB(value: 2),
|
|
LifetimeC(value: 3))
|
|
|
|
expectEqual(
|
|
"(t: main.LifetimeA, u: main.LifetimeB, v: main.LifetimeC)",
|
|
String(describing: castToThree(abc, LifetimeA.self, LifetimeA.self,
|
|
LifetimeA.self)))
|
|
|
|
expectEqual(
|
|
"(t: main.LifetimeA, u: main.LifetimeB, v: main.LifetimeC)",
|
|
String(describing: castToThree((LifetimeA(value: 1),
|
|
LifetimeB(value: 2),
|
|
LifetimeC(value: 3)) as (P, Any, P),
|
|
LifetimeA.self, LifetimeA.self,
|
|
LifetimeA.self)))
|
|
}
|
|
|
|
tupleCastTests.test("Elementwise tuple casts that conditionally fail") {
|
|
let abc: (P, Any, P) = (LifetimeA(value: 1),
|
|
LifetimeB(value: 2),
|
|
LifetimeC(value: 3))
|
|
expectNil(castToThreeOpt(abc, LifetimeA.self, LifetimeB.self, LifetimeB.self))
|
|
expectNil(castToThreeOpt(abc, LifetimeA.self, LifetimeC.self, LifetimeC.self))
|
|
expectNil(castToThreeOpt(abc, LifetimeC.self, LifetimeB.self, LifetimeC.self))
|
|
}
|
|
|
|
tupleCastTests
|
|
.test("Elementwise tuple casts that crash (1/3)")
|
|
.crashOutputMatches("Could not cast value of type 'main.LifetimeA'")
|
|
.code {
|
|
let abc: (P, Any, P) = (LifetimeA(value: 1),
|
|
LifetimeB(value: 2),
|
|
LifetimeC(value: 3))
|
|
expectCrashLater()
|
|
_ = castToThree(abc, LifetimeC.self, LifetimeB.self, LifetimeC.self)
|
|
}
|
|
|
|
tupleCastTests
|
|
.test("Elementwise tuple casts that crash (2/3)")
|
|
.crashOutputMatches("Could not cast value of type 'main.LifetimeB")
|
|
.code {
|
|
let abc: (P, Any, P) = (LifetimeA(value: 1),
|
|
LifetimeB(value: 2),
|
|
LifetimeC(value: 3))
|
|
expectCrashLater()
|
|
_ = castToThree(abc, LifetimeA.self, LifetimeC.self, LifetimeC.self)
|
|
}
|
|
|
|
tupleCastTests
|
|
.test("Elementwise tuple casts that crash (3/3)")
|
|
.crashOutputMatches("Could not cast value of type 'main.LifetimeC")
|
|
.code {
|
|
let abc: (P, Any, P) = (LifetimeA(value: 1),
|
|
LifetimeB(value: 2),
|
|
LifetimeC(value: 3))
|
|
expectCrashLater()
|
|
_ = castToThree(abc, LifetimeA.self, LifetimeB.self, LifetimeB.self)
|
|
}
|
|
|
|
runAllTests()
|