|
| 1 | +// RUN: %target-swift-frontend %s -emit-sil -enable-parameterized-protocol-types -O -o - | %FileCheck %s |
| 2 | + |
| 3 | +public protocol P<T> {} |
| 4 | +public protocol Q: P where T == Int {} |
| 5 | +public struct X: Q { |
| 6 | + public typealias T = Int |
| 7 | +} |
| 8 | +public struct Y<T>: P {} |
| 9 | +extension Y: Q where T == Int {} |
| 10 | + |
| 11 | +@_optimize(none) |
| 12 | +func use<T>(_ t: T) {} |
| 13 | + |
| 14 | +// CHECK-LABEL: sil @$s35cast_folding_parameterized_protocol23concrete_to_existentialyyAA1XV_AA1YVyxGAFySiGtlF : $@convention(thin) <T> (X, Y<T>, Y<Int>) -> () |
| 15 | +public func concrete_to_existential<T>(_ x: X, _ yt: Y<T>, _ yi: Y<Int>) { |
| 16 | + // CHECK:{{%.*}} = init_existential_addr %6 : $*P, $X |
| 17 | + use(x as! any P) |
| 18 | + // CHECK: unconditional_checked_cast_addr X in {{%.*}} : $*X to P<T> in {{%.*}} : $*P<T> |
| 19 | + use(x as! any P<T>) |
| 20 | + // CHECK: unconditional_checked_cast_addr X in {{%.*}} : $*X to P<Int> in {{%.*}} : $*P<Int> |
| 21 | + use(x as! any P<Int>) |
| 22 | + // CHECK: unconditional_checked_cast_addr X in {{%.*}} : $*X to P<String> in {{%.*}} : $*P<String> |
| 23 | + use(x as! any P<String>) |
| 24 | + // CHECK: {{%.*}} = init_existential_addr {{%.*}} : $*Q, $X |
| 25 | + use(x as! any Q) |
| 26 | + |
| 27 | + // CHECK: {{%.*}} = init_existential_addr {{%.*}} : $*P, $Y<T> |
| 28 | + use(yt as! any P) |
| 29 | + // CHECK: unconditional_checked_cast_addr Y<T> in {{%.*}} : $*Y<T> to P<T> in {{%.*}} : $*P<T> |
| 30 | + use(yt as! any P<T>) |
| 31 | + // CHECK: unconditional_checked_cast_addr Y<T> in {{%.*}} : $*Y<T> to P<Int> in {{%.*}} : $*P<Int> |
| 32 | + use(yt as! any P<Int>) |
| 33 | + // CHECK: unconditional_checked_cast_addr Y<T> in {{%.*}} : $*Y<T> to P<String> in {{%.*}} : $*P<String> |
| 34 | + use(yt as! any P<String>) |
| 35 | + // CHECK: unconditional_checked_cast_addr Y<T> in {{%.*}} : $*Y<T> to Q in {{%.*}} : $*Q |
| 36 | + use(yt as! any Q) |
| 37 | + |
| 38 | + // CHECK: {{%.*}} = init_existential_addr {{%.*}} : $*P, $Y<Int> |
| 39 | + use(yi as! any P) |
| 40 | + // CHECK: unconditional_checked_cast_addr Y<Int> in {{%.*}} : $*Y<Int> to P<T> in {{%.*}} : $*P<T> |
| 41 | + use(yi as! any P<T>) |
| 42 | + // CHECK: unconditional_checked_cast_addr Y<Int> in {{%.*}} : $*Y<Int> to P<Int> in {{%.*}} : $*P<Int> |
| 43 | + use(yi as! any P<Int>) |
| 44 | + // CHECK: unconditional_checked_cast_addr Y<Int> in {{%.*}} : $*Y<Int> to P<String> in {{%.*}} : $*P<String> |
| 45 | + use(yi as! any P<String>) |
| 46 | + // CHECK: {{%.*}} = init_existential_addr {{%.*}} : $*Q, $Y<Int> |
| 47 | + use(yi as! any Q) |
| 48 | +} |
| 49 | + |
| 50 | +// CHECK-LABEL: sil @$s35cast_folding_parameterized_protocol23existential_to_concreteyyxm_AA1P_pyxXPtlF : $@convention(thin) <T> (@thick T.Type, @in_guaranteed P<T>) -> () |
| 51 | +public func existential_to_concrete<T>(_: T.Type, _ p: any P<T>) { |
| 52 | + // CHECK: unconditional_checked_cast_addr P<T> in {{%.*}} : $*P<T> to X in {{%.*}} : $*X |
| 53 | + _ = p as! X |
| 54 | + // CHECK: unconditional_checked_cast_addr P<T> in {{%.*}} : $*P<T> to Y<T> in {{%.*}} : $*Y<T> |
| 55 | + _ = p as! Y<T> |
| 56 | + // CHECK: unconditional_checked_cast_addr P<T> in {{%.*}} : $*P<T> to Y<Int> in {{%.*}} : $*Y<Int> |
| 57 | + _ = p as! Y<Int> |
| 58 | + // CHECK: unconditional_checked_cast_addr P<T> in {{%.*}} : $*P<T> to Y<String> in {{%.*}} : $*Y<String> |
| 59 | + _ = p as! Y<String> |
| 60 | +} |
| 61 | + |
| 62 | +// CHECK-LABEL: sil @$s35cast_folding_parameterized_protocol015existential_to_E0yyAA1P_pyxXP_AA1Q_ptlF : $@convention(thin) <T> (@in_guaranteed P<T>, @in_guaranteed Q) -> () |
| 63 | +public func existential_to_existential<T>(_ p: any P<T>, _ q: any Q) { |
| 64 | + // CHECK: unconditional_checked_cast_addr P<T> in {{%.*}} : $*P<T> to Q in {{%.*}} : $*Q |
| 65 | + _ = p as! any Q |
| 66 | + // CHECK: unconditional_checked_cast_addr P<T> in {{%.*}} : $*P<T> to P in {{%.*}} : $*P |
| 67 | + _ = p as! any P |
| 68 | + // CHECK: unconditional_checked_cast_addr P<T> in {{%.*}} : $*P<T> to P<Int> in {{%.*}} : $*P<Int> |
| 69 | + _ = p as! any P<Int> |
| 70 | + // CHECK: unconditional_checked_cast_addr P<T> in {{%.*}} : $*P<T> to P<String> in {{%.*}} : $*P<String> |
| 71 | + _ = p as! any P<String> |
| 72 | + |
| 73 | + // CHECK: unconditional_checked_cast_addr Q in {{%.*}} : $*Q to P in {{%.*}} : $*P |
| 74 | + _ = q as! any P |
| 75 | + // CHECK: unconditional_checked_cast_addr Q in {{%.*}} : $*Q to P<T> in {{%.*}} : $*P<T> |
| 76 | + _ = q as! any P<T> |
| 77 | + // CHECK: unconditional_checked_cast_addr Q in {{%.*}} : $*Q to P<Int> in {{%.*}} : $*P<Int> |
| 78 | + _ = q as! any P<Int> |
| 79 | + // CHECK: unconditional_checked_cast_addr Q in {{%.*}} : $*Q to P<String> in {{%.*}} : $*P<String> |
| 80 | + _ = q as! any P<String> |
| 81 | +} |
0 commit comments