blob: fab2d930e43a85e8fd1a8d232c5a45d9f56b9978 [file] [log] [blame]
// RUN: %target-swift-emit-sil -swift-version 4 -verify %s | %FileCheck %s
// RUN: %target-swift-emit-sil -swift-version 5 -verify %s | %FileCheck %s
// Integration test to ensure that `type(of: self)` keeps working in
// class convenience initializers, even though they are now implemented as
// allocating entry points.
class C {
required init() { }
required init(throwingDesignated: ()) throws {}
convenience init(normal: ()) {
_ = (type(of: self), type(of: self))
self.init()
_ = (type(of: self), type(of: self))
}
convenience init(throwing: ()) throws {
do {
_ = (type(of: self), type(of: self))
try self.init(throwingDesignated: ())
_ = (type(of: self), type(of: self))
} catch {
_ = (type(of: self), type(of: self))
throw error
}
_ = (type(of: self), type(of: self))
}
convenience init?(optional: Bool) {
_ = (type(of: self), type(of: self))
if optional {
_ = (type(of: self), type(of: self))
self.init()
} else {
_ = (type(of: self), type(of: self))
return nil
}
_ = (type(of: self), type(of: self))
}
convenience init(closureCapture: ()) {
let t = type(of: self)
let fn = { t.init() }
_ = fn()
self.init()
}
}
protocol P {
static var n: Int { get }
init(_: Int)
}
extension P {
// FIXME: SILGen inserts an unnecessary copy when 'self' is
// address-only.
/* init(selfInit: ()) {
self.init(type(of: self).n)
}
init(selfAssign: ()) {
self = type(of: self).init(0)
} */
}
protocol PA : AnyObject {
static var n: Int { get }
init(_: Int)
}
extension PA {
init(selfInit: ()) {
// This is OK; we can get the type of 'self' from the self metatype
// argument.
self.init(type(of: self).n)
}
// FIXME: Not yet supported, but should be
/* init(selfAssign: ()) {
self = type(of: self).init(0)
} */
}
class CC {
class var n: Int { 0 }
required init(_: Int) {}
}
protocol PC : CC {}
extension PC {
// CHECK-LABEL: sil hidden @$s042definite_init_type_of_self_in_convenience_B02PCPAAE0E4Initxyt_tcfC : $@convention(method) <Self where Self : PC> (@thick Self.Type) -> @owned Self {
init(selfInit: ()) {
// This is OK; we can get the type of 'self' from the self metatype
// argument.
self.init(type(of: self).n)
// CHECK: [[SELF:%.*]] = upcast %0 : $@thick Self.Type to $@thick CC.Type
// CHECK: [[INIT:%.*]] = class_method [[SELF]] : $@thick CC.Type, #CC.init!allocator : (CC.Type) -> (Int) -> CC, $@convention(method) (Int, @thick CC.Type) -> @owned CC
// CHECK: apply [[INIT]]({{.*}}, [[SELF]]) : $@convention(method) (Int, @thick CC.Type) -> @owned CC
}
// FIXME: Not yet supported, but should be
/* init(selfAssign: ()) {
self = type(of: self).init(0)
} */
}