blob: 74a7942f637a02d8fd759763741bf033148fe214 [file] [log] [blame]
// 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)
}