blob: 4195c17efde93368a74bf719d02b8cc6a6afb4d6 [file] [log] [blame]
// RUN: %target-swift-frontend -emit-sil -disable-objc-attr-requires-foundation-module -verify %s
// High-level tests that DI rejects certain invalid idioms for early
// return from initializers.
// <rdar://problem/19267795> failable initializers that call noreturn function produces bogus diagnostics
class FailableInitThatFailsReallyHard {
init?() { // no diagnostics generated.
fatalError("bad")
}
}
class BaseClass {}
final class DerivedClass : BaseClass {
init(x : ()) {
fatalError("bad") // no diagnostics.
}
}
func something(_ x: Int) {}
func something(_ x: inout Int) {}
func something(_ x: AnyObject) {}
func something(_ x: Any.Type) {}
// <rdar://problem/22946400> DI needs to diagnose self usages in error block
//
// FIXME: bad QoI
class ErrantBaseClass {
init() throws {}
}
class ErrantClass : ErrantBaseClass {
let x: Int
var y: Int
override init() throws {
x = 10
y = 10
try super.init()
}
init(invalidEscapeDesignated: ()) {
x = 10
y = 10
do {
try super.init()
} catch {}
} // expected-error {{'self' used inside 'catch' block reachable from super.init call}}
init(invalidEscapeDesignated2: ()) throws {
x = 10
y = 10
do {
try super.init()
} catch {
try super.init() // expected-error {{'self' used inside 'catch' block reachable from super.init call}}
}
}
init(invalidEscapeDesignated3: ()) {
x = 10
y = 10
do {
try super.init()
} catch {
print(self.x) // expected-error {{'self' used inside 'catch' block reachable from super.init call}}
self.y = 20 // expected-error {{'self' used inside 'catch' block reachable from super.init call}}
}
} // expected-error {{'self' used inside 'catch' block reachable from super.init call}}
init(invalidEscapeDesignated4: ()) throws {
x = 10
y = 10
do {
try super.init()
} catch let e {
print(self.x) // expected-error {{'self' used inside 'catch' block reachable from super.init call}}
throw e
}
}
convenience init(invalidEscapeConvenience: ()) {
do {
try self.init()
} catch {}
} // expected-error {{'self.init' isn't called on all paths}}
convenience init(okEscapeConvenience2: ()) throws {
do {
try self.init()
} catch {
try self.init()
}
}
convenience init(invalidEscapeConvenience3: ()) throws {
do {
try self.init()
} catch let e {
print(self) // expected-error {{'self' used before 'self.init'}}
throw e
}
}
init(noEscapeDesignated: ()) throws {
x = 10
y = 10
do {
try super.init()
} catch let e {
throw e // ok
}
}
convenience init(noEscapeConvenience: ()) throws {
do {
try self.init()
} catch let e {
throw e // ok
}
}
convenience init(invalidAccess: ()) throws {
do {
try self.init()
} catch let e {
something(x) // expected-error {{'self' used before 'self.init'}}
something(self.x) // expected-error {{'self' used before 'self.init'}}
something(y) // expected-error {{'self' used before 'self.init'}}
something(self.y) // expected-error {{'self' used before 'self.init'}}
something(&y) // expected-error {{'self' used before 'self.init'}}
something(&self.y) // expected-error {{'self' used before 'self.init'}}
something(self) // expected-error {{'self' used before 'self.init'}}
something(type(of: self))
throw e
}
}
}