mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
174 lines
4.0 KiB
Swift
174 lines
4.0 KiB
Swift
// 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{{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}}
|
|
}
|