blob: e0a0a655d9ace854ce76fb5e209372f91de6e49f [file] [log] [blame]
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-silgen %s | FileCheck %s
// For integration testing, ensure we get through IRGen too.
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-ir -verify -DIRGEN_INTEGRATION_TEST %s
// REQUIRES: objc_interop
import objc_generics
func callInitializer() {
_ = GenericClass(thing: NSObject())
}
// CHECK-LABEL: sil shared @_TFCSo12GenericClassCfT5thingGSQx__GSQGS_x__
// CHECK: thick_to_objc_metatype {{%.*}} : $@thick GenericClass<T>.Type to $@objc_metatype GenericClass<T>.Type
public func genericMethodOnAnyObject(o: AnyObject, b: Bool) -> AnyObject {
return o.thing!()!
}
// CHECK-LABEL: sil @_TF21objc_imported_generic24genericMethodOnAnyObject
// CHECK: dynamic_method [volatile] {{%.*}} : $@opened([[TAG:.*]]) AnyObject, #GenericClass.thing!1.foreign : <T where T : AnyObject> (GenericClass<T>) -> () -> T?, $@convention(objc_method) @pseudogeneric (@opened([[TAG]]) AnyObject) -> @autoreleased Optional<AnyObject>
public func genericMethodOnAnyObjectChained(o: AnyObject, b: Bool) -> AnyObject? {
return o.thing?()
}
// CHECK-LABEL: sil @_TF21objc_imported_generic31genericMethodOnAnyObjectChained
// CHECK: dynamic_method_br %4 : $@opened([[TAG:.*]]) AnyObject, #GenericClass.thing!1.foreign, bb1
// CHECK: bb1({{%.*}} : $@convention(objc_method) @pseudogeneric (@opened([[TAG]]) AnyObject) -> @autoreleased Optional<AnyObject>):
public func genericSubscriptOnAnyObject(o: AnyObject, b: Bool) -> AnyObject? {
return o[0 as UInt16]
}
// CHECK-LABEL: sil @_TF21objc_imported_generic27genericSubscriptOnAnyObject
// CHECK: dynamic_method_br %4 : $@opened([[TAG:.*]]) AnyObject, #GenericClass.subscript!getter.1.foreign, bb1
// CHECK: bb1({{%.*}} : $@convention(objc_method) @pseudogeneric (UInt16, @opened([[TAG]]) AnyObject) -> @autoreleased AnyObject):
public func genericPropertyOnAnyObject(o: AnyObject, b: Bool) -> AnyObject?? {
return o.propertyThing
}
// CHECK-LABEL: sil @_TF21objc_imported_generic26genericPropertyOnAnyObject
// CHECK: dynamic_method_br %4 : $@opened([[TAG:.*]]) AnyObject, #GenericClass.propertyThing!getter.1.foreign, bb1
// CHECK: bb1({{%.*}} : $@convention(objc_method) @pseudogeneric (@opened([[TAG]]) AnyObject) -> @autoreleased Optional<AnyObject>):
public protocol ThingHolder {
associatedtype Thing
init!(thing: Thing!)
func thing() -> Thing?
func arrayOfThings() -> [Thing]
func setArrayOfThings(_: [Thing])
static func classThing() -> Thing?
var propertyThing: Thing? { get set }
var propertyArrayOfThings: [Thing]? { get set }
}
// TODO: Crashes in IRGen because the type metadata for `T` is not found in
// the witness thunk to satisfy the associated type requirement. This could be
// addressed by teaching IRGen to fulfill erased type parameters from protocol
// witness tables (rdar://problem/26602097).
#if !IRGEN_INTEGRATION_TEST
extension GenericClass: ThingHolder {}
#endif
public protocol Ansible: class {
associatedtype Anser: ThingHolder
}
public func genericBlockBridging<T: Ansible>(x: GenericClass<T>) {
let block = x.blockForPerformingOnThings()
x.performBlock(onThings: block)
}
// CHECK-LABEL: sil @_TF21objc_imported_generic20genericBlockBridging
// CHECK: [[BLOCK_TO_FUNC:%.*]] = function_ref @_TTRGRxs9AnyObjectx21objc_imported_generic7AnsiblerXFdCb_dx_ax_XFo_ox_ox_
// CHECK: partial_apply [[BLOCK_TO_FUNC]]<T, {{.*}}>
// CHECK: [[FUNC_TO_BLOCK:%.*]] = function_ref @_TTRGRxs9AnyObjectx21objc_imported_generic7AnsiblerXFo_ox_ox_XFdCb_dx_ax_
// CHECK: init_block_storage_header {{.*}} invoke [[FUNC_TO_BLOCK]]<T,{{.*}}>
// CHECK-LABEL: sil @_TF21objc_imported_generic20arraysOfGenericParam
public func arraysOfGenericParam<T: AnyObject>(y: Array<T>) {
// CHECK: function_ref {{@_TFCSo12GenericClassCfT13arrayOfThings.*}} : $@convention(method) <τ_0_0 where τ_0_0 : AnyObject> (@owned Array<τ_0_0>, @thick GenericClass<τ_0_0>.Type) -> @owned ImplicitlyUnwrappedOptional<GenericClass<τ_0_0>>
let x = GenericClass<T>(arrayOfThings: y)!
// CHECK: class_method [volatile] {{%.*}} : $GenericClass<T>, #GenericClass.setArrayOfThings!1.foreign {{.*}}, $@convention(objc_method) @pseudogeneric <τ_0_0 where τ_0_0 : AnyObject> (NSArray, GenericClass<τ_0_0>) -> ()
x.setArrayOfThings(y)
// CHECK: class_method [volatile] {{%.*}} : $GenericClass<T>, #GenericClass.propertyArrayOfThings!getter.1.foreign {{.*}}, $@convention(objc_method) @pseudogeneric <τ_0_0 where τ_0_0 : AnyObject> (GenericClass<τ_0_0>) -> @autoreleased Optional<NSArray>
_ = x.propertyArrayOfThings
// CHECK: class_method [volatile] {{%.*}} : $GenericClass<T>, #GenericClass.propertyArrayOfThings!setter.1.foreign {{.*}}, $@convention(objc_method) @pseudogeneric <τ_0_0 where τ_0_0 : AnyObject> (Optional<NSArray>, GenericClass<τ_0_0>) -> ()
x.propertyArrayOfThings = y
}
// CHECK-LABEL: sil shared @_TFF21objc_imported_generic11genericFuncuRxs9AnyObjectrFMxT_U_FT_T_ : $@convention(thin) <V where V : AnyObject> () -> () {
// CHECK: [[INIT:%.*]] = function_ref @_TFCSo12GenericClassCfT_GS_x_ : $@convention(method) <τ_0_0 where τ_0_0 : AnyObject> (@thick GenericClass<τ_0_0>.Type) -> @owned GenericClass<τ_0_0>
// CHECK: [[META:%.*]] = metatype $@thick GenericClass<V>.Type
// CHECK: apply [[INIT]]<V>([[META]])
// CHECK: return
func genericFunc<V: AnyObject>(_ v: V.Type) {
let _ = {
var _ = GenericClass<V>()
}
}
// CHECK-LABEL: sil shared [thunk] @_TTOFCSo12GenericClasscfT13arrayOfThings
// CHECK: class_method [volatile] {{%.*}} : $GenericClass<T>, #GenericClass.init!initializer.1.foreign {{.*}}, $@convention(objc_method) @pseudogeneric <τ_0_0 where τ_0_0 : AnyObject> (NSArray, @owned GenericClass<τ_0_0>) -> @owned ImplicitlyUnwrappedOptional<GenericClass<τ_0_0>>