// RUN: %target-swift-frontend -O -emit-sil %s | %FileCheck %s // RUN: %target-swift-frontend -Xllvm -sil-disable-pass=FunctionSignatureOpts -Xllvm -sil-disable-pass=PerfInliner -enable-ownership-stripping-after-serialization -O -emit-sil %s | %FileCheck %s // We want to check two things here: // - Correctness // - That certain "is" checks are eliminated based on static analysis at compile-time // // In ideal world, all those testNN functions should be simplified down to a single basic block // which returns either true or false, i.e. all type checks should folded statically. public protocol P {} public protocol R {} protocol Q: P {} class A: P {} class AA: A {} class X {} class B: P {} private struct S: P {} struct T: Q {} private struct U {} public protocol CP1: class {} public protocol CP2: class {} // Class D implements only one of class protocols // and it cannot be extended elsewhere as it is private private class D: CP1 {} private final class F: CP1 {} // Class E implements both class protocols at once class E: CP1, CP2 {} func cast0(_ a: T) -> Bool { // Succeeds if T is A return type(of: A()) is T.Type } func cast1(_ a: T) -> Bool { // Succeeds if T is A return type(of: (A() as AnyObject)) is T.Type } func cast2(_ a: T) -> Bool { // Succeeds if T is A let ao: AnyObject = A() as AnyObject return type(of: ao) is T.Type } func cast3(_ p: AnyObject) -> Bool { // Always fails return type(of: p) is AnyObject.Protocol } func cast4(_ p: AnyObject) -> Bool { return type(of: p) is A.Type } func cast5(_ t: AnyObject.Type) -> Bool { // Succeeds if t is B.self return t is B.Type } func cast6(_ t: T) -> Bool { // Always fails return AnyObject.self is T.Type } func cast7(_ t: T.Type) -> Bool { // Succeeds if t is AnyObject.self return t is AnyObject.Protocol } func cast8(_ a: T) -> Bool { // Succeeds if T is A return type(of: (A() as P)) is T.Type } func cast9(_ a: T) -> Bool { // Succeeds if T is A let ao: P = A() as P return type(of: ao) is T.Type } func cast10(_ p: P) -> Bool { return type(of: p) is P.Protocol } func cast11(_ p: P) -> Bool { // Succeeds if p is of type A return type(of: p) is A.Type } func cast12(_ t: P.Type) -> Bool { return t is B.Type } func cast13(_ t: T) -> Bool { // Succeeds if T is P return P.self is T.Type } func cast14(_ t: T.Type) -> Bool { // Succeeds if p is P.self return t is P.Protocol } func cast15(_ t: T) -> Bool { // Succeeds if T is P return P.self is T.Type } func cast16(_ t: T) -> Bool { // Succeeds if T is P return T.self is P.Protocol } func cast17(_ t: T) -> Bool { // Succeeds if T is AnyObject return AnyObject.self is T.Type } func cast18(_ t: T) -> Bool { // Succeeds if T is AnyObject return T.self is AnyObject.Protocol } func cast20(_ t: T) -> Bool { // Succeeds if T is P return T.self is P.Type } func cast21(_ t: T) -> Bool { // Succeeds if T is P return T.self is P.Protocol } func cast22(_ existential: P.Type) -> Bool { // Succeeds if existential is S.self return existential is S.Type } func cast23(_ concrete: P.Protocol) -> Bool { // Always fails return concrete is S.Type } func cast24(_ existential: P.Type) -> Bool { // Succeeds if existential is Q.self return existential is Q.Type } func cast25(_ concrete: P.Protocol) -> Bool { // Always fails, because P != Q return concrete is Q.Type } func cast26(_ existential: Q.Type) -> Bool { // Succeeds always, because Q: P return existential is P.Type } func cast27(_ existential: CP1.Type) -> Bool { // Fails always, because existential is a class // and it cannot be struct return existential is S.Type } func cast28(_ existential: CP1.Type) -> Bool { // Succeeds if existential conforms to CP1 and CP2 return existential is CP2.Type } func cast29(_ o: Any) -> Bool { // Succeeds if o is P.Type return o is P.Type } func cast30(_ o: AnyObject) -> Bool { // Succeeds if o is P.Type return o is P.Type } func cast32(_ p: P) -> Bool { // Fails always, because a metatype cannot conform to a protocol return p is P.Type } func cast33(_ p: P) -> Bool { // Same as above, but non-existential metatype return p is X.Type } func cast38(_ t: T) -> Bool { return t is (Int, Int) } func cast39(_ t: T) -> Bool { return t is (x: Int, y: Int) } func cast40(_ t: T) -> Bool { return t is (x: Int, y: A) } func cast41(_ t: T, _ mt: T.Type) -> Bool { let typ = type(of: t as Any) return typ is AnyClass } func cast42(_ p: P) -> Bool { return type(of: p as Any) is AnyClass } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding5test0SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test0() -> Bool { return cast0(A()) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding5test1SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test1() -> Bool { return cast1(A()) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding5test2SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test2() -> Bool { return cast2(A()) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding5test3SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, 0 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test3() -> Bool { return cast3(A()) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding5test4SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test4() -> Bool { return cast4(A()) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding7test5_1SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test5_1() -> Bool { return cast5(B.self) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding7test5_2SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, 0 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test5_2() -> Bool { return cast5(AnyObject.self) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding7test6_1SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, 0 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test6_1() -> Bool { return cast6(B.self) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding7test6_2SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, 0 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test6_2() -> Bool { return cast6(AnyObject.self) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding7test7_1SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, 0 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test7_1() -> Bool { return cast7(B.self) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding7test7_2SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test7_2() -> Bool { return cast7(AnyObject.self) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding5test8SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test8() -> Bool { return cast8(A()) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding5test9SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test9() -> Bool { return cast9(A()) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding6test10SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, 0 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test10() -> Bool { return cast10(A()) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding6test11SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test11() -> Bool { return cast11(A()) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding6test12SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, 0 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test12() -> Bool { return cast12(A.self) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding8test13_1SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, 0 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test13_1() -> Bool { return cast13(A.self) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding8test13_2SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, 0 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test13_2() -> Bool { return cast13(P.self) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding8test13_3SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test13_3() -> Bool { return cast13(A() as P) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding8test14_1SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, 0 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test14_1() -> Bool { return cast14(A.self) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding8test14_2SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test14_2() -> Bool { return cast14(P.self) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding8test15_1SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, 0 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test15_1() -> Bool { return cast15(A()) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding8test15_2SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test15_2() -> Bool { return cast15(A() as P) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding8test16_1SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, 0 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test16_1() -> Bool { return cast16(A()) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding8test16_2SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test16_2() -> Bool { return cast16(A() as P) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding8test17_1SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, 0 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test17_1() -> Bool { return cast17(A()) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding8test17_2SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test17_2() -> Bool { return cast17(A() as AnyObject) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding8test18_1SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, 0 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test18_1() -> Bool { return cast18(A()) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding8test18_2SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test18_2() -> Bool { return cast18(A() as AnyObject) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding6test19SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test19() -> Bool { let t: Any.Type = type(of: 1 as Any) return t is Int.Type } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding8test20_1SbyF : $@convention(thin) () -> Bool @inline(never) func test20_1() -> Bool { return cast20(S.self) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding8test20_2SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, 0 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test20_2() -> Bool { return cast20(U()) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding8test21_1SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, 0 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test21_1() -> Bool { return cast21(S.self) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding8test21_2SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test21_2() -> Bool { return cast21(A() as P) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding8test22_1SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, 0 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test22_1() -> Bool { return cast22(T.self) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding8test22_2SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test22_2() -> Bool { return cast22(S.self) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding6test23SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, 0 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test23() -> Bool { return cast23(P.self) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding8test24_1SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test24_1() -> Bool { return cast24(T.self) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding8test24_2SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, 0 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test24_2() -> Bool { return cast24(S.self) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding6test25SbyF : $@convention(thin) () -> Bool // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, 0 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test25() -> Bool { return cast25(P.self) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding6test26SbyF // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test26() -> Bool { return cast26(T.self) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding6test27SbyF // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, 0 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test27() -> Bool { return cast27(D.self) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding8test28_1SbyF // CHECK: checked_cast // CHECK: return @inline(never) func test28_1() -> Bool { return cast28(D.self) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding8test28_2SbyF // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test28_2() -> Bool { return cast28(E.self) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding8test28_3SbyF // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, 0 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) func test28_3() -> Bool { return cast28(F.self) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding6test29SbyF // CHECK: bb0 // CHECK: checked_cast // CHECK: return @inline(never) func test29() -> Bool { return cast29(X()) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding6test30SbyF // CHECK: bb0 // CHECK: checked_cast // CHECK: return @inline(never) func test30() -> Bool { return cast30(X()) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding6test32SbyF // CHECK: bb0 // CHECK: checked_cast // CHECK: return @inline(never) func test32() -> Bool { // We don't actually fold this right now, but at least make sure it // doesn't crash return cast32(A()) } // CHECK-LABEL: sil hidden [noinline] @$s12cast_folding6test33SbyF // CHECK: bb0 // CHECK: checked_cast // CHECK: return @inline(never) func test33() -> Bool { // Ditto... return cast33(A()) } protocol PP { func foo() -> Int } public class CC : PP { func foo() -> Int { return 0 } } public class DD : PP { func foo() -> Int { return 1 } } // Check that the body of the function // contains a trap followed by unreachable // and no code afterwards. // CHECK-LABEL: sil @$s12cast_folding7getAsDDyAA0E0CAA2CCCF // CHECK: builtin "int_trap" // CHECK-NEXT: unreachable // CHECK-NEXT: } public func getAsDD(_ c: CC) -> DD { return c as! DD } // Check that the body of the function // contains a trap followed by unreachable // and no code afterwards. // CHECK-LABEL: sil @$s12cast_folding7callFooySiAA2CCCF // CHECK: builtin "int_trap" // CHECK-NEXT: unreachable // CHECK-NEXT: } public func callFoo(_ c: CC) -> Int { return (c as! DD).foo() } @inline(never) func callFooGeneric(_ c: T) -> Int { return (c as! DD).foo() } // Check that the inlined version of callFooGeneric contains only a trap // followed by unreachable and no code afterwards // CHECK-LABEL: sil [noinline] @$s12cast_folding16callForGenericCCyyAA0F0CF // CHECK: builtin "int_trap" // CHECK-NEXT: unreachable // CHECK-NEXT: } @inline(never) public func callForGenericCC(_ c: CC) { callFoo(c) } // Check that this conversion does not crash a compiler. @inline(never) public func test34() { if let _ = A.self as? P { print("A: dice") } else { print("A: no dice") } } // Check that this conversion does not crash a compiler. @inline(never) public func test35() { if let _ = X.self as? P { print("X: dice") } else { print("X: no dice") } } // Check that we do not eliminate casts from AnyHashable to a type that // implements Hashable. // CHECK-LABEL: sil [noinline] @$s12cast_folding6test36{{[_0-9a-zA-Z]*}}F // CHECK: checked_cast_addr_br take_always AnyHashable in {{.*}} to Int @inline(never) public func test36(ah: AnyHashable) { if let _ = ah as? Int { print("success") } else { print("failure") } } // Check that we do not eliminate casts to AnyHashable from an opaque type // that might implement Hashable. // CHECK-LABEL: sil [noinline] @$s12cast_folding6test37{{[_0-9a-zA-Z]*}}F // CHECK: checked_cast_addr_br take_always T in {{.*}} to AnyHashable @inline(never) public func test37(ah: T) { if let _ = ah as? AnyHashable { print("success") } else { print("failure") } } // CHECK-LABEL: sil [noinline] @$s12cast_folding7test38a{{[_0-9a-zA-Z]*}}F // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) public func test38a() -> Bool { return cast38((1, 2)) } // CHECK-LABEL: sil [noinline] @$s12cast_folding7test38b{{[_0-9a-zA-Z]*}}F // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) public func test38b() -> Bool { return cast38((x: 1, y: 2)) } // CHECK-LABEL: sil [noinline] @$s12cast_folding7test38c{{[_0-9a-zA-Z]*}}F // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) public func test38c() -> Bool { return cast38((z: 1, y: 2)) } // CHECK-LABEL: sil [noinline] @$s12cast_folding7test39a{{[_0-9a-zA-Z]*}}F // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) public func test39a() -> Bool { return cast39((1, 2)) } // CHECK-LABEL: sil [noinline] @$s12cast_folding7test39b{{[_0-9a-zA-Z]*}}F // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) public func test39b() -> Bool { return cast39((x: 1, y: 2)) } // CHECK-LABEL: sil [noinline] @$s12cast_folding7test39c{{[_0-9a-zA-Z]*}}F // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, 0 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) public func test39c() -> Bool { return cast39((z: 1, y: 2)) } // CHECK-LABEL: sil [noinline] @$s12cast_folding7test39d{{[_0-9a-zA-Z]*}}F // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, 0 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) public func test39d() -> Bool { return cast39((1, 2, 3)) } // CHECK-LABEL: sil [noinline] @$s12cast_folding7test40a{{[_0-9a-zA-Z]*}}F // CHECK: bb0 // FIXME: Would love to fold this to just "true" // CHECK-NOT: return: // CHECK: unconditional_checked_cast_addr @inline(never) public func test40a() -> Bool { return cast40((1, A())) } // CHECK-LABEL: sil [noinline] @$s12cast_folding7test40b{{[_0-9a-zA-Z]*}}F // CHECK: bb0 // FIXME: Would love to fold this to just "true" // CHECK-NOT: return: // CHECK: unconditional_checked_cast_addr @inline(never) public func test40b() -> Bool { return cast40((1, AA())) } // CHECK-LABEL: sil [noinline] @$s12cast_folding7test40c{{[_0-9a-zA-Z]*}}F // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, 0 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) public func test40c() -> Bool { return cast40((1, S())) } // CHECK-LABEL: sil [noinline] @$s12cast_folding7test40d{{[_0-9a-zA-Z]*}}F // CHECK: bb0 // CHECK-NOT: return // CHECK: checked_cast_addr_br take_always (Int, Any) in @inline(never) public func test40d(_ a: Any) -> Bool { return cast40((1, a)) } // CHECK-LABEL: sil [noinline] @$s12cast_folding6test41SbyF // CHECK: bb0 // FIXME: Would love to fold this to just "true" // CHECK-NOT: return: // CHECK: checked_cast_br // CHECK: //{{.*}}$s12cast_folding6test41{{.*}}F @inline(never) public func test41() -> Bool { return cast41(A(), P.self) } // CHECK-LABEL: sil [noinline] @$s12cast_folding6test42{{.*}}F // CHECK: bb0 // CHECK-NOT: return: // CHECK: checked_cast // CHECK: //{{.*}}$s12cast_folding6test42{{.*}}F @inline(never) public func test42(_ p: P) -> Bool { return cast42(p) } // CHECK-LABEL: sil [noinline] @{{.*}}test43{{.*}} // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) public func test43() -> Bool { return P.self is Any.Type } // CHECK-LABEL: sil [noinline] @{{.*}}test44{{.*}} // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) public func test44() -> Bool { return Any.self is Any.Type } // CHECK-LABEL: sil [noinline] @{{.*}}test45{{.*}} // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) public func test45() -> Bool { return (P & R).self is Any.Type } // CHECK-LABEL: sil [noinline] @{{.*}}test46{{.*}} // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) public func test46() -> Bool { return AnyObject.self is Any.Type } // CHECK-LABEL: sil [noinline] @{{.*}}test47{{.*}} // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) public func test47() -> Bool { return Any.Type.self is Any.Type } // CHECK-LABEL: sil [noinline] @{{.*}}test48{{.*}} // CHECK: bb0 // CHECK-NEXT: %0 = integer_literal $Builtin.Int1, 0 // CHECK-NEXT: %1 = struct $Bool // CHECK-NEXT: return %1 @inline(never) public func test48() -> Bool { return Any.Type.self is Any.Type.Type } func cast(_ u: U.Type) -> V? { return u as? V } // CHECK-LABEL: sil [noinline] @{{.*}}testCastAnyObjectProtocolTo{{.*}}Type // CHECK: %0 = enum $Optional{{.*}}, #Optional.none!enumelt // CHECK-NEXT: return %0 @inline(never) public func testCastAnyObjectProtocolToAnyObjectType() -> AnyObject.Type? { return cast(AnyObject.self) } // CHECK-LABEL: // testCastProtocolTypeProtocolToProtocolTypeType // CHECK: sil [noinline] @{{.*}}testCastProtocol{{.*}}$@convention(thin) () -> Optional<@thick P.Type.Type> // CHECK: %0 = enum $Optional{{.*}}, #Optional.none!enumelt // CHECK-NEXT: return %0 @inline(never) public func testCastProtocolTypeProtocolToProtocolTypeType() -> P.Type.Type? { return P.Type.self as? P.Type.Type } protocol PForOptional { } extension Optional: PForOptional { } func testCastToPForOptional(_ t: T) -> Bool { if let _ = t as? PForOptional { return true } return false } // CHECK-LABEL: // testCastToPForOptionalSuccess() // CHECK: [[RES:%.*]] = integer_literal $Builtin.Int1, -1 // CHECK: [[RET:%.*]] = struct $Bool ([[RES]] : $Builtin.Int1) // CHECK: return [[RET]] : $Bool @inline(never) public func testCastToPForOptionalSuccess() -> Bool { let t: Int? = 42 return testCastToPForOptional(t) } // CHECK-LABEL: // testCastToPForOptionalFailure() // CHECK: [[RES:%.*]] = integer_literal $Builtin.Int1, 0 // CHECK: [[RET:%.*]] = struct $Bool ([[RES]] : $Builtin.Int1) // CHECK: return [[RET]] : $Bool @inline(never) public func testCastToPForOptionalFailure() -> Bool { let t: Int = 42 return testCastToPForOptional(t) } print("test0=\(test0())") print("test1=\(test1())") print("test2=\(test2())") print("test3=\(test3())") print("test4=\(test4())") print("test5_1=\(test5_1())") print("test5_2=\(test5_2())") print("test6_1=\(test6_1())") print("test6_2=\(test6_2())") print("test7_1=\(test7_1())") print("test7_2=\(test7_2())") print("test8=\(test8())") print("test9=\(test9())") print("test10=\(test10())") print("test11=\(test11())") print("test12=\(test12())") print("test13_1=\(test13_1())") print("test13_2=\(test13_2())") print("test13_3=\(test13_3())") print("test14_1=\(test14_1())") print("test14_2=\(test14_2())") print("test15_1=\(test15_1())") print("test15_2=\(test15_2())") print("test16_1=\(test16_1())") print("test16_2=\(test16_2())") print("test17_1=\(test17_1())") print("test17_2=\(test17_2())") print("test18_1=\(test18_1())") print("test18_2=\(test18_2())") print("test19=\(test19())") print("test20_1=\(test20_1())") print("test20_2=\(test20_2())") print("test21_1=\(test21_1())") print("test21_2=\(test21_2())") print("test22_1=\(test22_1())") print("test22_2=\(test22_2())") print("test23=\(test23())") print("test24_1=\(test24_1())") print("test24_2=\(test24_2())") print("test25=\(test25())") print("test26=\(test26())") print("test27=\(test27())") print("test28_1=\(test28_1())") print("test28_2=\(test28_2())") print("test28_3=\(test28_3))") print("test29=\(test29())") print("test30=\(test30())") print("test32=\(test32())") print("test33=\(test33())")