mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
A parse-only option is needed for parse performance tracking and the current option also includes semantic analysis.
469 lines
16 KiB
Swift
469 lines
16 KiB
Swift
// RUN: %target-typecheck-verify-swift
|
|
|
|
// Tests for initializer delegation via self.init(...).
|
|
|
|
// Initializer delegation: classes
|
|
class C0 {
|
|
convenience init() {
|
|
self.init(value: 5)
|
|
}
|
|
|
|
init(value: Int) { /* ... */ }
|
|
}
|
|
|
|
class C1 {
|
|
convenience init() {
|
|
self.init(value: 5)
|
|
}
|
|
|
|
init(value: Int) { /* ... */ }
|
|
init(value: Double) { /* ... */ }
|
|
}
|
|
|
|
// Initializer delegation: structs
|
|
struct S0 {
|
|
init() {
|
|
self.init(value: 5)
|
|
}
|
|
|
|
init(value: Int) { /* ... */ }
|
|
}
|
|
|
|
struct S1 {
|
|
init() {
|
|
self.init(value: 5)
|
|
}
|
|
|
|
init(value: Int) { /* ... */ }
|
|
init(value: Double) { /* ... */ }
|
|
}
|
|
|
|
// Initializer delegation: enum
|
|
enum E0 {
|
|
case A
|
|
case B
|
|
|
|
init() {
|
|
self.init(value: 5)
|
|
}
|
|
|
|
init(value: Int) { /* ... */ }
|
|
}
|
|
|
|
enum E1 {
|
|
case A
|
|
case B
|
|
|
|
init() {
|
|
self.init(value: 5)
|
|
}
|
|
|
|
init(value: Int) { /* ... */ }
|
|
init(value: Double) { /* ... */ }
|
|
}
|
|
|
|
// Ill-formed initializer delegation: no matching constructor
|
|
class Z0 {
|
|
init() { // expected-error {{designated initializer for 'Z0' cannot delegate (with 'self.init'); did you mean this to be a convenience initializer?}} {{3-3=convenience }}
|
|
// expected-note @+2 {{delegation occurs here}}
|
|
|
|
self.init(5, 5) // expected-error{{cannot invoke 'Z0.init' with an argument list of type '(Int, Int)'}}
|
|
// expected-note @-1 {{overloads for 'Z0.init' exist with these partially matching parameter lists: (), (value: Int), (value: Double)}}
|
|
}
|
|
|
|
init(value: Int) { /* ... */ }
|
|
init(value: Double) { /* ... */ }
|
|
}
|
|
|
|
struct Z1 {
|
|
init() {
|
|
self.init(5, 5) // expected-error{{cannot invoke 'Z1.init' with an argument list of type '(Int, Int)'}}
|
|
// expected-note @-1 {{overloads for 'Z1.init' exist with these partially matching parameter lists: (), (value: Int), (value: Double)}}
|
|
}
|
|
|
|
init(value: Int) { /* ... */ }
|
|
init(value: Double) { /* ... */ }
|
|
}
|
|
|
|
enum Z2 {
|
|
case A
|
|
case B
|
|
|
|
init() {
|
|
self.init(5, 5) // expected-error{{cannot invoke 'Z2.init' with an argument list of type '(Int, Int)'}}
|
|
// expected-note @-1 {{overloads for 'Z2.init' exist with these partially matching parameter lists: (), (value: Int), (value: Double)}}
|
|
}
|
|
|
|
init(value: Int) { /* ... */ }
|
|
init(value: Double) { /* ... */ }
|
|
}
|
|
|
|
// Ill-formed initialization: wrong context.
|
|
class Z3 {
|
|
func f() {
|
|
self.init() // expected-error{{'init' is a member of the type; use 'type(of: ...)' to initialize a new object of the same dynamic type}} {{10-10=type(of: }} {{14-14=)}}
|
|
}
|
|
|
|
init() { }
|
|
}
|
|
|
|
// 'init' is a static-ish member.
|
|
class Z4 {
|
|
init() {} // expected-note{{selected non-required initializer}}
|
|
|
|
convenience init(other: Z4) {
|
|
other.init() // expected-error{{'init' is a member of the type; use 'type(of: ...)' to initialize a new object of the same dynamic type}} {{11-11=type(of: }} {{15-15=)}}
|
|
type(of: other).init() // expected-error{{must use a 'required' initializer}} expected-warning{{unused}}
|
|
}
|
|
}
|
|
|
|
class Z5 : Z4 {
|
|
override init() { }
|
|
|
|
convenience init(other: Z5) {
|
|
other.init() // expected-error{{'init' is a member of the type; use 'type(of: ...)' to initialize a new object of the same dynamic type}} {{11-11=type(of: }} {{15-15=)}}
|
|
}
|
|
}
|
|
|
|
// Ill-formed initialization: failure to call initializer.
|
|
class Z6 {
|
|
convenience init() {
|
|
var _ : () -> Z6 = self.init // expected-error{{partial application of 'self.init' initializer delegation is not allowed}}
|
|
}
|
|
|
|
init(other: Z6) { }
|
|
}
|
|
|
|
// Ill-formed initialization: both superclass and delegating.
|
|
class Z7Base { }
|
|
|
|
class Z7 : Z7Base {
|
|
override init() { }
|
|
|
|
init(b: Bool) {
|
|
if b { super.init() } // expected-note{{previous chaining call is here}}
|
|
else { self.init() } // expected-error{{initializer cannot both delegate ('self.init') and chain to a }}
|
|
}
|
|
}
|
|
|
|
struct RDar16603812 {
|
|
var i = 42
|
|
init() {}
|
|
func foo() {
|
|
self.init() // expected-error {{'init' is a member of the type; use 'type(of: ...)' to initialize a new object of the same dynamic type}} {{12-12=type(of: }} {{16-16=)}}
|
|
type(of: self).init() // expected-warning{{result of 'RDar16603812' initializer is unused}}
|
|
}
|
|
}
|
|
|
|
class RDar16666631 {
|
|
var i: Int
|
|
var d: Double
|
|
var s: String
|
|
init(i: Int, d: Double, s: String) {
|
|
self.i = i
|
|
self.d = d
|
|
self.s = s
|
|
}
|
|
convenience init(i: Int, s: String) {
|
|
self.init(i: i, d: 0.1, s: s)
|
|
}
|
|
}
|
|
let rdar16666631 = RDar16666631(i: 5, d: 6) // expected-error {{incorrect argument label in call (have 'i:d:', expected 'i:s:')}}
|
|
|
|
|
|
struct S {
|
|
init() {
|
|
let _ = S.init()
|
|
self.init()
|
|
let _ = self.init // expected-error{{partial application of 'self.init' initializer delegation is not allowed}}
|
|
}
|
|
}
|
|
|
|
class C {
|
|
convenience init() { // expected-note 11 {{selected non-required initializer 'init()'}}
|
|
self.init()
|
|
let _: C = self.init() // expected-error{{cannot convert value of type '()' to specified type 'C'}}
|
|
let _: () -> C = self.init // expected-error{{partial application of 'self.init' initializer delegation is not allowed}}
|
|
}
|
|
|
|
init(x: Int) {} // expected-note 11 {{selected non-required initializer 'init(x:)'}}
|
|
|
|
required init(required: Double) {}
|
|
}
|
|
|
|
class D: C {
|
|
override init(x: Int) {
|
|
super.init(x: x)
|
|
let _: C = super.init() // expected-error{{cannot convert value of type '()' to specified type 'C'}}
|
|
let _: () -> C = super.init // expected-error{{partial application of 'super.init' initializer chain is not allowed}}
|
|
}
|
|
|
|
func foo() {
|
|
self.init(x: 0) // expected-error{{'init' is a member of the type; use 'type(of: ...)' to initialize a new object of the same dynamic type}} {{10-10=type(of: }} {{14-14=)}}
|
|
}
|
|
func bar() {
|
|
super.init(x: 0) // expected-error{{'super.init' cannot be called outside of an initializer}}
|
|
}
|
|
|
|
class func zim() -> Self {
|
|
return self.init(required: 0)
|
|
}
|
|
|
|
class func zang() -> C {
|
|
return super.init(required: 0)
|
|
}
|
|
|
|
required init(required: Double) {}
|
|
}
|
|
|
|
func init_tests() {
|
|
var s = S.self
|
|
var s1 = s.init()
|
|
|
|
var ss1 = S.init()
|
|
|
|
var c: C.Type = D.self
|
|
var c1 = c.init(required: 0)
|
|
var c2 = c.init(x: 0) // expected-error{{'required' initializer}}
|
|
var c3 = c.init() // expected-error{{'required' initializer}}
|
|
|
|
var c1a = c.init(required: 0)
|
|
var c2a = c.init(x: 0) // expected-error{{'required' initializer}}
|
|
var c3a = c.init() // expected-error{{'required' initializer}}
|
|
|
|
var cf1: (Double) -> C = c.init
|
|
var cf2: (Int) -> C = c.init // expected-error{{'required' initializer}}
|
|
var cf3: () -> C = c.init // expected-error{{'required' initializer}}
|
|
|
|
var cs1 = C.init(required: 0)
|
|
var cs2 = C.init(x: 0)
|
|
var cs3 = C.init()
|
|
|
|
var csf1: (Double) -> C = C.init
|
|
var csf2: (Int) -> C = C.init
|
|
var csf3: () -> C = C.init
|
|
|
|
var cs1a = C(required: 0)
|
|
var cs2a = C(x: 0)
|
|
var cs3a = C()
|
|
|
|
var y = x.init() // expected-error{{use of unresolved identifier 'x'}}
|
|
}
|
|
|
|
protocol P {
|
|
init(proto: String)
|
|
}
|
|
|
|
func foo<T: C>(_ x: T, y: T.Type) where T: P {
|
|
var c1 = type(of: x).init(required: 0)
|
|
var c2 = type(of: x).init(x: 0) // expected-error{{'required' initializer}}
|
|
var c3 = type(of: x).init() // expected-error{{'required' initializer}}
|
|
var c4 = type(of: x).init(proto: "")
|
|
|
|
var cf1: (Double) -> T = type(of: x).init
|
|
var cf2: (Int) -> T = type(of: x).init // expected-error{{'required' initializer}}
|
|
var cf3: () -> T = type(of: x).init // expected-error{{'required' initializer}}
|
|
var cf4: (String) -> T = type(of: x).init
|
|
|
|
var c1a = type(of: x).init(required: 0)
|
|
var c2a = type(of: x).init(x: 0) // expected-error{{'required' initializer}}
|
|
var c3a = type(of: x).init() // expected-error{{'required' initializer}}
|
|
var c4a = type(of: x).init(proto: "")
|
|
|
|
var ci1 = x.init(required: 0) // expected-error{{'init' is a member of the type; use 'type(of: ...)' to initialize a new object of the same dynamic type}} {{15-15=type(of: }} {{19-19=)}}
|
|
var ci2 = x.init(x: 0) // expected-error{{'init' is a member of the type; use 'type(of: ...)' to initialize a new object of the same dynamic type}} {{15-15=type(of: }} {{19-19=)}}
|
|
var ci3 = x.init() // expected-error{{'init' is a member of the type; use 'type(of: ...)' to initialize a new object of the same dynamic type}} {{15-15=type(of: }} {{19-19=)}}
|
|
var ci4 = x.init(proto: "") // expected-error{{'init' is a member of the type; use 'type(of: ...)' to initialize a new object of the same dynamic type}} {{15-15=type(of: }} {{19-19=)}}
|
|
|
|
var ci1a = x(required: 0) // expected-error{{cannot call value of non-function type 'T'}}
|
|
var ci2a = x(x: 0) // expected-error{{cannot call value of non-function type 'T'}}
|
|
var ci3a = x() // expected-error{{cannot call value of non-function type 'T'}}{{15-17=}}
|
|
var ci4a = x(proto: "") // expected-error{{cannot call value of non-function type 'T'}}
|
|
|
|
var cm1 = y.init(required: 0)
|
|
var cm2 = y.init(x: 0) // expected-error{{'required' initializer}}
|
|
var cm3 = y.init() // expected-error{{'required' initializer}}
|
|
var cm4 = y.init(proto: "")
|
|
|
|
var cm1a = y.init(required: 0)
|
|
var cm2a = y.init(x: 0) // expected-error{{'required' initializer}}
|
|
var cm3a = y.init() // expected-error{{'required' initializer}}
|
|
var cm4a = y.init(proto: "")
|
|
|
|
var cs1 = T.init(required: 0)
|
|
var cs2 = T.init(x: 0) // expected-error{{'required' initializer}}
|
|
var cs3 = T.init() // expected-error{{'required' initializer}}
|
|
var cs4 = T.init(proto: "")
|
|
var cs5 = T.init(notfound: "") // expected-error{{argument labels '(notfound:)' do not match any available overloads}}
|
|
// expected-note @-1 {{overloads for 'T.Type.init' exist with these partially matching parameter lists: (x: Int), (required: Double), (proto: String)}}
|
|
|
|
var csf1: (Double) -> T = T.init
|
|
var csf2: (Int) -> T = T.init // expected-error{{'required' initializer}}
|
|
var csf3: () -> T = T.init // expected-error{{'required' initializer}}
|
|
var csf4: (String) -> T = T.init
|
|
|
|
var cs1a = T(required: 0)
|
|
var cs2a = T(x: 0) // expected-error{{'required' initializer}}
|
|
var cs3a = T() // expected-error{{'required' initializer}}
|
|
var cs4a = T(proto: "")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
class TestOverloadSets {
|
|
convenience init() {
|
|
self.init(5, 5) // expected-error{{cannot invoke 'TestOverloadSets.init' with an argument list of type '(Int, Int)'}}
|
|
// expected-note @-1 {{overloads for 'TestOverloadSets.init' exist with these partially matching parameter lists: (), (a: Z0), (value: Int), (value: Double)}}
|
|
}
|
|
|
|
convenience init(a : Z0) {
|
|
self.init(42 as Int8) // expected-error{{argument labels '(_:)' do not match any available overloads}}
|
|
// expected-note @-1 {{overloads for 'TestOverloadSets.init' exist with these partially matching parameter lists: (a: Z0), (value: Int), (value: Double)}}
|
|
}
|
|
|
|
init(value: Int) { /* ... */ }
|
|
init(value: Double) { /* ... */ }
|
|
}
|
|
|
|
class TestNestedExpr {
|
|
init() {}
|
|
init?(fail: Bool) {}
|
|
init(error: Bool) throws {}
|
|
|
|
convenience init(a: Int) {
|
|
let x: () = self.init() // expected-error {{initializer delegation ('self.init') cannot be nested in another statement}}
|
|
// expected-warning@-1 {{immutable value 'x' was never used; consider replacing with '_' or removing it}}
|
|
}
|
|
|
|
convenience init(b: Int) {
|
|
func use(_ x: ()) {}
|
|
use(self.init()) // expected-error {{initializer delegation ('self.init') cannot be nested in another expression}}
|
|
}
|
|
|
|
convenience init(c: Int) {
|
|
_ = ((), self.init()) // expected-error {{initializer delegation ('self.init') cannot be nested in another expression}}
|
|
}
|
|
|
|
convenience init(d: Int) {
|
|
let x: () = self.init(fail: true)! // expected-error {{initializer delegation ('self.init') cannot be nested in another statement}}
|
|
// expected-warning@-1 {{immutable value 'x' was never used; consider replacing with '_' or removing it}}
|
|
}
|
|
|
|
convenience init(e: Int) {
|
|
func use(_ x: ()) {}
|
|
use(self.init(fail: true)!) // expected-error {{initializer delegation ('self.init') cannot be nested in another expression}}
|
|
}
|
|
|
|
convenience init(f: Int) {
|
|
_ = ((), self.init(fail: true)!) // expected-error {{initializer delegation ('self.init') cannot be nested in another expression}}
|
|
}
|
|
|
|
convenience init(g: Int) {
|
|
let x: () = try! self.init(error: true) // expected-error {{initializer delegation ('self.init') cannot be nested in another statement}}
|
|
// expected-warning@-1 {{immutable value 'x' was never used; consider replacing with '_' or removing it}}
|
|
}
|
|
|
|
convenience init(h: Int) {
|
|
func use(_ x: ()) {}
|
|
use(try! self.init(error: true)) // expected-error {{initializer delegation ('self.init') cannot be nested in another expression}}
|
|
}
|
|
|
|
convenience init(i: Int) {
|
|
_ = ((), try! self.init(error: true)) // expected-error {{initializer delegation ('self.init') cannot be nested in another expression}}
|
|
}
|
|
}
|
|
|
|
class TestNestedExprSub : TestNestedExpr {
|
|
init(a: Int) {
|
|
let x: () = super.init() // expected-error {{initializer chaining ('super.init') cannot be nested in another statement}}
|
|
// expected-warning@-1 {{immutable value 'x' was never used; consider replacing with '_' or removing it}}
|
|
}
|
|
|
|
init(b: Int) {
|
|
func use(_ x: ()) {}
|
|
use(super.init()) // expected-error {{initializer chaining ('super.init') cannot be nested in another expression}}
|
|
}
|
|
|
|
init(c: Int) {
|
|
_ = ((), super.init()) // expected-error {{initializer chaining ('super.init') cannot be nested in another expression}}
|
|
}
|
|
|
|
init(d: Int) {
|
|
let x: () = super.init(fail: true)! // expected-error {{initializer chaining ('super.init') cannot be nested in another statement}}
|
|
// expected-warning@-1 {{immutable value 'x' was never used; consider replacing with '_' or removing it}}
|
|
}
|
|
|
|
init(e: Int) {
|
|
func use(_ x: ()) {}
|
|
use(super.init(fail: true)!) // expected-error {{initializer chaining ('super.init') cannot be nested in another expression}}
|
|
}
|
|
|
|
init(f: Int) {
|
|
_ = ((), super.init(fail: true)!) // expected-error {{initializer chaining ('super.init') cannot be nested in another expression}}
|
|
}
|
|
|
|
init(g: Int) {
|
|
let x: () = try! super.init(error: true) // expected-error {{initializer chaining ('super.init') cannot be nested in another statement}}
|
|
// expected-warning@-1 {{immutable value 'x' was never used; consider replacing with '_' or removing it}}
|
|
}
|
|
|
|
init(h: Int) {
|
|
func use(_ x: ()) {}
|
|
use(try! super.init(error: true)) // expected-error {{initializer chaining ('super.init') cannot be nested in another expression}}
|
|
}
|
|
|
|
init(i: Int) {
|
|
_ = ((), try! super.init(error: true)) // expected-error {{initializer chaining ('super.init') cannot be nested in another expression}}
|
|
}
|
|
}
|
|
|
|
|
|
class TestOptionalTry {
|
|
init() throws {}
|
|
convenience init(a: Int) { // expected-note {{propagate the failure with 'init?'}} {{19-19=?}}
|
|
try? self.init() // expected-error {{a non-failable initializer cannot use 'try?' to delegate to another initializer}}
|
|
// expected-note@-1 {{force potentially-failing result with 'try!'}} {{5-9=try!}}
|
|
}
|
|
|
|
init?(fail: Bool) throws {}
|
|
|
|
convenience init(failA: Int) { // expected-note {{propagate the failure with 'init?'}} {{19-19=?}}
|
|
try? self.init(fail: true)! // expected-error {{a non-failable initializer cannot use 'try?' to delegate to another initializer}}
|
|
// expected-note@-1 {{force potentially-failing result with 'try!'}} {{5-9=try!}}
|
|
}
|
|
|
|
convenience init(failB: Int) { // expected-note {{propagate the failure with 'init?'}} {{19-19=?}}
|
|
try! self.init(fail: true) // expected-error {{a non-failable initializer cannot delegate to failable initializer 'init(fail:)' written with 'init?'}}
|
|
// expected-note@-1 {{force potentially-failing result with '!'}} {{31-31=!}}
|
|
}
|
|
|
|
convenience init(failC: Int) {
|
|
try! self.init(fail: true)! // okay
|
|
}
|
|
|
|
convenience init?(failD: Int) {
|
|
try? self.init(fail: true) // okay
|
|
}
|
|
|
|
convenience init?(failE: Int) {
|
|
try! self.init(fail: true) // okay
|
|
}
|
|
|
|
convenience init?(failF: Int) {
|
|
try! self.init(fail: true)! // okay
|
|
}
|
|
|
|
convenience init?(failG: Int) {
|
|
try? self.init(fail: true) // okay
|
|
}
|
|
}
|
|
|
|
class TestOptionalTrySub : TestOptionalTry {
|
|
init(a: Int) { // expected-note {{propagate the failure with 'init?'}} {{7-7=?}}
|
|
try? super.init() // expected-error {{a non-failable initializer cannot use 'try?' to chain to another initializer}}
|
|
// expected-note@-1 {{force potentially-failing result with 'try!'}} {{5-9=try!}}
|
|
}
|
|
}
|