1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
// RUN: %target-swift-frontend -emit-sil -Onone %s | %FileCheck %s
// This file contains test cases that shows that we can properly conditional
// compile out code in -Onone contexts using transparent. It is important to
// note that all test cases here should have _BOTH_ generic and concrete
// implementations. Users should be able to depend on this in simple transparent
// cases.
//
// The first check, makes sure our silgen codegen is as we expect it. The second
// makes sure we optimize is as expected.
enum MyEnum {
case first
case second
}
@_cdecl("cFuncOriginal")
@inline(never)
func cFuncOriginal() -> () {}
@_cdecl("cFuncRefinement")
@inline(never)
func cFuncRefinement() -> () {}
class Klass {
final var value: MyEnum = .first
}
protocol OriginalProtocol {
var value: Optional<Klass> { get }
}
extension OriginalProtocol {
@_transparent
var value: Optional<Klass> {
cFuncOriginal()
return nil
}
}
protocol RefinementProtocol : OriginalProtocol {
var klass: Klass { get }
var value: Optional<Klass> { get }
}
extension RefinementProtocol {
@_transparent
var value: Optional<Klass> {
cFuncRefinement()
return klass
}
}
struct OriginalProtocolImpl {}
extension OriginalProtocolImpl : OriginalProtocol {}
struct RefinementProtocolImpl {
private var _klass: Klass = Klass()
@_transparent var klass: Klass { return _klass }
}
extension RefinementProtocolImpl : RefinementProtocol {}
@_transparent
func transparentAddressCallee<T : OriginalProtocol>(_ t: T) -> MyEnum {
if let x = t.value {
return x.value
}
return .second
}
// CHECK-LABEL: sil hidden @$s49mandatory_conditional_compile_out_using_optionals24testOriginalProtocolImplAA6MyEnumOyF : $@convention(thin) () -> MyEnum {
// CHECK-NOT: function_ref @$s49mandatory_conditional_compile_out_using_optionals15cFuncRefinementyyF :
// CHECK: [[FUNCTION_REF:%.*]] = function_ref @$s49mandatory_conditional_compile_out_using_optionals13cFuncOriginalyyF :
// CHECK-NEXT: apply [[FUNCTION_REF]]()
// CHECK-NOT: function_ref @$s49mandatory_conditional_compile_out_using_optionals15cFuncRefinementyyF :
// CHECK: } // end sil function '$s49mandatory_conditional_compile_out_using_optionals24testOriginalProtocolImplAA6MyEnumOyF'
func testOriginalProtocolImpl() -> MyEnum {
let x = OriginalProtocolImpl()
return transparentAddressCallee(x)
}
// CHECK-LABEL: sil hidden @$s49mandatory_conditional_compile_out_using_optionals26testRefinementProtocolImplAA6MyEnumOyF : $@convention(thin) () -> MyEnum {
// CHECK-NOT: function_ref @$s49mandatory_conditional_compile_out_using_optionals13cFuncOriginalyyF :
// CHECK: [[FUNCTION_REF:%.*]] = function_ref @$s49mandatory_conditional_compile_out_using_optionals15cFuncRefinementyyF :
// CHECK-NEXT: apply [[FUNCTION_REF]]()
// CHECK-NOT: function_ref @$s49mandatory_conditional_compile_out_using_optionals13cFuncOriginalyyF :
// CHECK: } // end sil function '$s49mandatory_conditional_compile_out_using_optionals26testRefinementProtocolImplAA6MyEnumOyF'
func testRefinementProtocolImpl() -> MyEnum {
let x = RefinementProtocolImpl()
return transparentAddressCallee(x)
}
@_transparent
func transparentObjectCallee<T : OriginalProtocol>(_ t: T) -> MyEnum where T : AnyObject {
if let x = t.value {
return x.value
}
return .second
}
class OriginalProtocolImplKlass {
}
extension OriginalProtocolImplKlass : OriginalProtocol {
}
class RefinementProtocolImplKlass {
}
extension RefinementProtocolImplKlass : RefinementProtocol {
var klass: Klass {
return Klass()
}
}
// CHECK-LABEL: sil hidden @$s49mandatory_conditional_compile_out_using_optionals29testOriginalProtocolImplKlassAA6MyEnumOyF : $@convention(thin) () -> MyEnum {
// CHECK-NOT: function_ref @$s49mandatory_conditional_compile_out_using_optionals15cFuncRefinementyyF :
// CHECK: [[FUNCTION_REF:%.*]] = function_ref @$s49mandatory_conditional_compile_out_using_optionals13cFuncOriginalyyF :
// CHECK-NEXT: apply [[FUNCTION_REF]]()
// CHECK-NOT: function_ref @$s49mandatory_conditional_compile_out_using_optionals15cFuncRefinementyyF :
// CHECK: } // end sil function '$s49mandatory_conditional_compile_out_using_optionals29testOriginalProtocolImplKlassAA6MyEnumOyF'
func testOriginalProtocolImplKlass() -> MyEnum {
let x = OriginalProtocolImplKlass()
return transparentObjectCallee(x)
}
// CHECK-LABEL: sil hidden @$s49mandatory_conditional_compile_out_using_optionals31testRefinementProtocolImplKlassAA6MyEnumOyF : $@convention(thin) () -> MyEnum {
// CHECK-NOT: function_ref @$s49mandatory_conditional_compile_out_using_optionals13cFuncOriginalyyF :
// CHECK: [[FUNCTION_REF:%.*]] = function_ref @$s49mandatory_conditional_compile_out_using_optionals15cFuncRefinementyyF :
// CHECK-NEXT: apply [[FUNCTION_REF]]()
// CHECK-NOT: function_ref @$s49mandatory_conditional_compile_out_using_optionals13cFuncOriginalyyF :
// CHECK: } // end sil function '$s49mandatory_conditional_compile_out_using_optionals31testRefinementProtocolImplKlassAA6MyEnumOyF'
func testRefinementProtocolImplKlass() -> MyEnum {
let x = RefinementProtocolImplKlass()
return transparentObjectCallee(x)
}
|