blob: 4784a31cd34744b4eba0d4ddb4779f9af5fb504f [file] [log] [blame]
// RUN: %target-typecheck-verify-swift
// ---------------------------------------------------------------------------
// Declaration of complete object initializers and basic semantic checking
// ---------------------------------------------------------------------------
class A {
convenience init(int i: Int) { // expected-note{{convenience initializer is declared here}}
self.init(double: Double(i))
}
convenience init(float f: Float) {
self.init(double: Double(f))
}
init(double d: Double) {
}
convenience init(crazy : A) {
self.init(int: 42)
}
}
class OtherA {
init(double d: Double, negated: Bool) { // expected-error{{designated initializer for 'OtherA' cannot delegate (with 'self.init'); did you mean this to be a convenience initializer?}}{{3-3=convenience }}
self.init(double: negated ? -d : d) // expected-note{{delegation occurs here}}
}
init(double d: Double) {
}
}
class DerivesA : A {
init(int i: Int) {
super.init(int: i) // expected-error{{must call a designated initializer of the superclass 'A'}}
}
convenience init(string: String) {
super.init(double: 3.14159) // expected-error{{convenience initializer for 'DerivesA' must delegate (with 'self.init') rather than chaining to a superclass initializer (with 'super.init')}}
}
}
struct S {
convenience init(int i: Int) { // expected-error{{delegating initializers in structs are not marked with 'convenience'}}
self.init(double: Double(i))
}
init(double d: Double) {
}
}
class DefaultInitComplete {
convenience init() {
self.init(string: "foo")
}
init(string: String) { }
}
class SubclassDefaultInitComplete : DefaultInitComplete {
init() { }
}
// ---------------------------------------------------------------------------
// Inheritance of initializers
// ---------------------------------------------------------------------------
// inherits convenience initializers
class B1 : A {
override init(double d: Double) {
super.init(double: d)
}
}
func testConstructB1(_ i: Int, f: Float, d: Double) {
let b1a = B1(int: i)
let b1b = B1(float: f)
let b1c = B1(double: d)
var b: B1 = b1a
b = b1b
b = b1c
_ = b
}
// does not inherit convenience initializers
class B2 : A {
var s: String
init() {
s = "hello"
super.init(double: 1.5)
}
}
func testConstructB2(_ i: Int) {
var b2a = B2()
var b2b = B2(int: i) // expected-error{{argument passed to call that takes no arguments}}
var b2: B2 = b2a
}
// Initializer inheritance can satisfy the requirement for an
// @required initializer within a subclass.
class Ab1 {
required init() { }
}
class Ab2 : Ab1 {
var s: String
// Subclasses can use this to satisfy the required initializer
// requirement.
required convenience init() { // expected-note{{'required' initializer is declared in superclass here}}
self.init(string: "default")
}
init(string s: String) {
self.s = s
super.init()
}
}
class Ab3 : Ab2 {
override init(string s: String) {
super.init(string: s)
}
}
class Ab4 : Ab3 {
init(int: Int) {
super.init(string:"four")
}
// expected-error{{'required' initializer 'init()' must be provided by subclass of 'Ab2'}}
func blah() { }
}
// Only complete object initializers are allowed in extensions
class Extensible { }
extension Extensible {
init(int i: Int) { // expected-error{{designated initializer cannot be declared in an extension of 'Extensible'; did you mean this to be a convenience initializer?}}{{3-3=convenience }}
self.init()
}
}
// <rdar://problem/17785840>
protocol Protocol {
init(string: String)
}
class Parent: Protocol {
required init(string: String) {}
}
class Child: Parent {
convenience required init(string: String) {
self.init(string: "")
}
}
// overriding
class Parent2 {
init() { }
convenience init(int: Int) { self.init() }
}
class Child2 : Parent2 {
convenience init(int: Int) { self.init() }
}
func testOverride(_ int: Int) {
Child2(int: int) // okay, picks Child2.init // expected-warning{{unused}}
}