1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
// 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")
}
}
// Failable initializers must produce correct diagnostics
struct A {
var x: Int // expected-note {{'self.x' not initialized}}
init?(i: Int) {
if i > 0 {
self.x = i
}
} // expected-error {{return from initializer without initializing all stored properties}}
}
// Delegating, failable initializers that doesn't initialize along all paths must produce correct diagnostics.
extension Int {
init?(i: Int) {
if i > 0 {
self.init(i)
}
} // expected-error {{'self.init' isn't called on all paths before returning from initializer}}
}
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
}
}
}
|