|
| 1 | +// RUN: %empty-directory(%t) |
| 2 | + |
| 3 | +// 1. functional test: |
| 4 | + |
| 5 | +// RUN: %target-build-swift -parse-as-library -wmo -emit-module -emit-module-path=%t/Classes.swiftmodule -module-name=Classes %S/Inputs/classes.swift -c -o %t/classes.o |
| 6 | +// RUN: %target-build-swift -parse-as-library -wmo -enable-library-evolution -emit-module -emit-module-path=%t/ResilientClasses.swiftmodule -module-name=ResilientClasses %S/Inputs/classes.swift -c -o %t/resilientclasses.o |
| 7 | +// RUN: %target-build-swift -wmo -module-name=Main -I%t %s -c -o %t/main.o |
| 8 | +// RUN: %target-swiftc_driver %t/main.o %t/classes.o %t/resilientclasses.o -o %t/a.out |
| 9 | +// RUN: %target-codesign %t/a.out |
| 10 | +// RUN: %target-run %t/a.out | %FileCheck %s -check-prefix=CHECK-OUTPUT |
| 11 | + |
| 12 | +// 2. check if the generated IR looks like expected: |
| 13 | + |
| 14 | +// RUN: %target-swift-frontend -module-name=Main -I%t %s -emit-ir -g -o - | %FileCheck %s |
| 15 | + |
| 16 | +// REQUIRES: executable_test |
| 17 | + |
| 18 | + |
| 19 | +import Classes |
| 20 | +import ResilientClasses |
| 21 | + |
| 22 | +final class Internal : Classes.OpenBase, Hashable { |
| 23 | + func hash(into hasher: inout Hasher) {} |
| 24 | + static func == (lhs: Internal, rhs: Internal) -> Bool { return false } |
| 25 | +} |
| 26 | + |
| 27 | +final class DerivedFromResilient : ResilientClasses.OpenBase { |
| 28 | +} |
| 29 | + |
| 30 | +final class Generic<T> : Classes.OpenBase { |
| 31 | +} |
| 32 | + |
| 33 | +// CHECK-LABEL: define {{.*}} @"$s4Main14castToNonfinaly7Classes0D0CSgAC4BaseCF" |
| 34 | +// CHECK: @swift_dynamicCastClass |
| 35 | +// CHECK: } |
| 36 | +@inline(never) |
| 37 | +func castToNonfinal(_ b: Classes.Base) -> Classes.Nonfinal? { |
| 38 | + return b as? Classes.Nonfinal |
| 39 | +} |
| 40 | + |
| 41 | +// CHECK-LABEL: define {{.*}} @"$s4Main11castToFinaly7Classes0D0CSgAC4BaseCF" |
| 42 | +// CHECK-NOT: @swift_dynamicCastClass |
| 43 | +// CHECK: } |
| 44 | +@inline(never) |
| 45 | +func castToFinal(_ b: Classes.Base) -> Classes.Final? { |
| 46 | + return b as? Classes.Final |
| 47 | +} |
| 48 | + |
| 49 | +// CHECK-LABEL: define {{.*}} @"$s4Main24unconditionalCastToFinaly7Classes0E0CAC4BaseCF" |
| 50 | +// CHECK-NOT: @swift_dynamicCastClass |
| 51 | +// CHECK: } |
| 52 | +@inline(never) |
| 53 | +func unconditionalCastToFinal(_ b: Classes.Base) -> Classes.Final { |
| 54 | + return b as! Classes.Final |
| 55 | +} |
| 56 | + |
| 57 | +// CHECK-LABEL: define {{.*}} @"$s4Main20castToResilientFinaly0D7Classes0E0CSgAC4BaseCF" |
| 58 | +// CHECK: @swift_dynamicCastClass |
| 59 | +// CHECK: } |
| 60 | +@inline(never) |
| 61 | +func castToResilientFinal(_ b: ResilientClasses.Base) -> ResilientClasses.Final? { |
| 62 | + return b as? ResilientClasses.Final |
| 63 | +} |
| 64 | + |
| 65 | +// CHECK-LABEL: define {{.*}} @"$s4Main19castProtocolToFinaly7Classes0E0CSgAC1P_pF" |
| 66 | +// CHECK-NOT: @swift_dynamicCastClass |
| 67 | +// CHECK: } |
| 68 | +@inline(never) |
| 69 | +func castProtocolToFinal(_ p: Classes.P) -> Classes.Final? { |
| 70 | + return p as? Classes.Final |
| 71 | +} |
| 72 | + |
| 73 | +// CHECK-LABEL: define {{.*}} @"$s4Main14castToInternalyAA0D0CSg7Classes8OpenBaseCF" |
| 74 | +// CHECK-NOT: @swift_dynamicCastClass |
| 75 | +// CHECK: } |
| 76 | +@inline(never) |
| 77 | +func castToInternal(_ b: Classes.OpenBase) -> Internal? { |
| 78 | + return b as? Internal |
| 79 | +} |
| 80 | + |
| 81 | +// CHECK-LABEL: define {{.*}} @"$s4Main23castAnyObjectToInternalyAA0F0CSgyXlF" |
| 82 | +// CHECK: @swift_dynamicCastClass |
| 83 | +// CHECK: } |
| 84 | +@inline(never) |
| 85 | +func castAnyObjectToInternal(_ a: AnyObject) -> Internal? { |
| 86 | + return a as? Internal |
| 87 | +} |
| 88 | + |
| 89 | +// CHECK-LABEL: define {{.*}} @"$s4Main26castToDerivedFromResilientyAA0deF0CSg0F7Classes8OpenBaseCF" |
| 90 | +// CHECK: @swift_dynamicCastClass |
| 91 | +// CHECK: } |
| 92 | +@inline(never) |
| 93 | +func castToDerivedFromResilient(_ b: ResilientClasses.OpenBase) -> DerivedFromResilient? { |
| 94 | + return b as? DerivedFromResilient |
| 95 | +} |
| 96 | + |
| 97 | +// CHECK-LABEL: define {{.*}} @"$s4Main13castToGenericyAA0D0CySiGSg7Classes8OpenBaseCF" |
| 98 | +// CHECK: @swift_dynamicCastClass |
| 99 | +// CHECK: } |
| 100 | +@inline(never) |
| 101 | +func castToGeneric(_ b: Classes.OpenBase) -> Generic<Int>? { |
| 102 | + return b as? Generic<Int> |
| 103 | +} |
| 104 | + |
| 105 | +// CHECK-LABEL: define {{.*}} @"$s4Main14getAnyHashableys0cD0VAA8InternalCF" |
| 106 | +@inline(never) |
| 107 | +func getAnyHashable(_ i: Internal) -> AnyHashable { |
| 108 | + return i |
| 109 | +} |
| 110 | + |
| 111 | +func test() { |
| 112 | + // CHECK-OUTPUT: nil |
| 113 | + print(castToNonfinal(Classes.Base()) as Any) |
| 114 | + // CHECK-OUTPUT: Optional(Classes.Nonfinal) |
| 115 | + print(castToNonfinal(Classes.Nonfinal()) as Any) |
| 116 | + |
| 117 | + // CHECK-OUTPUT: nil |
| 118 | + print(castToFinal(Classes.Base()) as Any) |
| 119 | + // CHECK-OUTPUT: Optional(Classes.Final) |
| 120 | + print(castToFinal(Classes.Final()) as Any) |
| 121 | + // CHECK-OUTPUT: Classes.Final |
| 122 | + print(unconditionalCastToFinal(Classes.Final()) as Any) |
| 123 | + |
| 124 | + // CHECK-OUTPUT: nil |
| 125 | + print(castToResilientFinal(ResilientClasses.Base()) as Any) |
| 126 | + // CHECK-OUTPUT: Optional(ResilientClasses.Final) |
| 127 | + print(castToResilientFinal(ResilientClasses.Final()) as Any) |
| 128 | + |
| 129 | + // CHECK-OUTPUT: nil |
| 130 | + print(castProtocolToFinal(Classes.Nonfinal()) as Any) |
| 131 | + // CHECK-OUTPUT: Optional(Classes.Final) |
| 132 | + print(castProtocolToFinal(Classes.Final()) as Any) |
| 133 | + |
| 134 | + // CHECK-OUTPUT: nil |
| 135 | + print(castToInternal(Classes.OpenBase()) as Any) |
| 136 | + // CHECK-OUTPUT: Optional(Main.Internal) |
| 137 | + print(castToInternal(Internal()) as Any) |
| 138 | + |
| 139 | + // CHECK-OUTPUT: nil |
| 140 | + print(castAnyObjectToInternal(Classes.OpenBase()) as Any) |
| 141 | + // CHECK-OUTPUT: Optional(Main.Internal) |
| 142 | + let i = Internal() |
| 143 | + print(castAnyObjectToInternal(i) as Any) |
| 144 | + let i2 = castAnyObjectToInternal(getAnyHashable(i) as! AnyObject) |
| 145 | + precondition(i === i2) |
| 146 | + |
| 147 | + // CHECK-OUTPUT: nil |
| 148 | + print(castToDerivedFromResilient(ResilientClasses.OpenBase()) as Any) |
| 149 | + // CHECK-OUTPUT: Optional(Main.DerivedFromResilient) |
| 150 | + print(castToDerivedFromResilient(DerivedFromResilient()) as Any) |
| 151 | + |
| 152 | + // CHECK-OUTPUT: nil |
| 153 | + print(castToGeneric(Classes.OpenBase()) as Any) |
| 154 | + // CHECK-OUTPUT: Optional(Main.Generic<Swift.Int>) |
| 155 | + print(castToGeneric(Generic<Int>()) as Any) |
| 156 | +} |
| 157 | + |
| 158 | +test() |
| 159 | + |
0 commit comments