//===--- FunctionConversion.swift -----------------------------------------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// // RUN: %target-run-simple-swift // REQUIRES: executable_test // REQUIRES: rdar24874073 // // XFAIL: interpret import StdlibUnittest // Also import modules which are used by StdlibUnittest internally. This // workaround is needed to link all required libraries in case we compile // StdlibUnittest with -sil-serialize-all. import SwiftPrivate #if _runtime(_ObjC) import ObjectiveC #endif var FunctionConversionTestSuite = TestSuite("FunctionConversion") protocol Quilt { var n: Int8 { get } } protocol Patchwork : Quilt {} struct Trivial : Patchwork { let n: Int8 } struct Loadable : Patchwork { let c: Fabric var n: Int8 { return c.n } init(n: Int8) { c = Fabric(n: n) } } struct AddrOnly : Patchwork { let a: Any var n: Int8 { return a as! Int8 } init(n: Int8) { a = n } } class Fabric { let n: Int8 init(n: Int8) { self.n = n } } class Parent : Patchwork { let n: Int8 required init(n: Int8) { self.n = n } } class Child : Parent {} func t1(s: Trivial?) -> Trivial { return Trivial(n: s!.n * 2) } func l1(s: Loadable?) -> Loadable { return Loadable(n: s!.n * 2) } func a1(s: AddrOnly?) -> AddrOnly { return AddrOnly(n: s!.n * 2) } FunctionConversionTestSuite.test("Optional") { let g11: Trivial -> Trivial? = t1 let g12: Trivial! -> Trivial? = t1 expectEqual(22, g11(Trivial(n: 11))?.n) expectEqual(24, g12(Trivial(n: 12))?.n) let g21: Loadable? -> Loadable? = l1 let g22: Loadable! -> Loadable? = l1 expectEqual(42, g21(Loadable(n: 21))?.n) expectEqual(44, g22(Loadable(n: 22))?.n) let g31: AddrOnly? -> AddrOnly? = a1 let g32: AddrOnly! -> AddrOnly? = a1 expectEqual(62, g31(AddrOnly(n: 31))?.n) expectEqual(64, g32(AddrOnly(n: 32))?.n) } func t2(s: Quilt) -> Trivial { return s as! Trivial } func t3(s: Quilt?) -> Trivial { return s! as! Trivial } func l2(s: Quilt) -> Loadable { return s as! Loadable } func l3(s: Quilt?) -> Loadable { return s! as! Loadable } func a2(s: Quilt) -> AddrOnly { return s as! AddrOnly } func a3(s: Quilt?) -> AddrOnly { return s! as! AddrOnly } FunctionConversionTestSuite.test("Existential") { let g11: Trivial -> Patchwork = t2 let g12: Trivial? -> Patchwork = t3 let g13: Patchwork -> Patchwork = t2 expectEqual(11, g11(Trivial(n: 11)).n) expectEqual(12, g12(Trivial(n: 12)).n) expectEqual(13, g13(Trivial(n: 13)).n) let g21: Loadable -> Patchwork = l2 let g22: Loadable? -> Patchwork = l3 let g23: Patchwork -> Patchwork = l2 expectEqual(21, g21(Loadable(n: 21)).n) expectEqual(22, g22(Loadable(n: 22)).n) expectEqual(23, g23(Loadable(n: 23)).n) let g31: AddrOnly -> Patchwork = a2 let g32: AddrOnly -> Patchwork = a3 let g33: Patchwork -> Patchwork = a2 expectEqual(31, g31(AddrOnly(n: 31)).n) expectEqual(32, g32(AddrOnly(n: 32)).n) expectEqual(33, g33(AddrOnly(n: 33)).n) } func em(t: Quilt.Type?) -> Trivial.Type { return t! as! Trivial.Type } FunctionConversionTestSuite.test("ExistentialMetatype") { let g1: Trivial.Type -> Patchwork.Type = em let g2: Trivial.Type? -> Patchwork.Type = em let g3: Patchwork.Type -> Patchwork.Type = em let g4: Patchwork.Type -> Any = em let result1 = g1(Trivial.self) let result2 = g2(Trivial.self) let result3 = g3(Trivial.self) let result4 = g4(Trivial.self) expectEqual(true, result1 == Trivial.self) expectEqual(true, result2 == Trivial.self) expectEqual(true, result3 == Trivial.self) expectEqual(true, result4 as! Trivial.Type == Trivial.self) } func c1(p: Parent) -> (Child, Trivial) { return (Child(n: p.n), Trivial(n: p.n)) } func c2(p: Parent?) -> (Child, Trivial) { return (Child(n: p!.n), Trivial(n: p!.n)) } FunctionConversionTestSuite.test("ClassUpcast") { let g1: Child -> (Parent, Trivial?) = c1 let g2: Child -> (Parent?, Trivial?) = c2 expectEqual(g1(Child(n: 2)).0.n, 2) expectEqual(g2(Child(n: 4)).0!.n, 4) } func cm1(p: Parent.Type) -> (Child.Type, Trivial) { return (Child.self, Trivial(n: 0)) } func cm2(p: Parent.Type?) -> (Child.Type, Trivial) { return (Child.self, Trivial(n: 0)) } FunctionConversionTestSuite.test("ClassMetatypeUpcast") { let g1: Child.Type -> (Parent.Type, Trivial?) = cm1 let g2: Child.Type -> (Parent.Type, Trivial?) = cm2 let g3: Child.Type? -> (Parent.Type?, Trivial?) = cm2 let result1 = g1(Child.self) let result2 = g2(Child.self) let result3 = g3(Child.self) expectEqual(true, result1.0 == Child.self) expectEqual(true, result2.0 == Child.self) expectEqual(true, result3.0! == Child.self) } func sq(i: Int) -> Int { return i * i } func f1(f: Any) -> Int -> Int { return f as! (Int -> Int) } FunctionConversionTestSuite.test("FuncExistential") { let g11: (Int -> Int) -> Any = f1 expectEqual(100, f1(g11(sq))(10)) } func generic1(t: Parent) -> (T, Trivial) { return (t as! T, Trivial(n: 0)) } func generic2(f: Parent -> (T, Trivial), t: T) -> Child -> (Parent, Trivial?) { return f } FunctionConversionTestSuite.test("ClassArchetypeUpcast") { let g11: Child -> (Parent, Trivial?) = generic2(generic1, t: Child(n: 10)) expectEqual(10, g11(Child(n: 10)).0.n) } func doesNotThrow() {} FunctionConversionTestSuite.test("ThrowVariance") { let g: () throws -> () = doesNotThrow do { try print(g()) } catch {} } runAllTests()