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 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
|
// RUN: %target-typecheck-verify-swift -parse-as-library
lazy func lazy_func() {} // expected-error {{'lazy' may only be used on 'var' declarations}} {{1-6=}}
lazy var b = 42 // expected-error {{'lazy' cannot be used on an already-lazy global}} {{1-6=}}
struct S {
lazy static var lazy_global = 42 // expected-error {{'lazy' cannot be used on an already-lazy global}} {{3-8=}}
}
protocol SomeProtocol {
lazy var x : Int // expected-error {{'lazy' cannot be used on a protocol requirement}} {{3-8=}}
// expected-error@-1 {{property in protocol must have explicit { get } or { get set } specifier}} {{19-19= { get <#set#> \}}}
// expected-error@-2 {{lazy properties must have an initializer}}
lazy var y : Int { get } // expected-error {{'lazy' cannot be used on a protocol requirement}} {{3-8=}}
// expected-error@-1 {{'lazy' cannot be used on a computed property}}
// expected-error@-2 {{lazy properties must have an initializer}}
}
class TestClass {
lazy var a = 42
lazy var a1 : Int = 42
lazy let b = 42 // expected-error {{'lazy' cannot be used on a let}} {{3-8=}}
lazy var c : Int { return 42 } // expected-error {{'lazy' cannot be used on a computed property}} {{3-8=}}
// expected-error@-1 {{lazy properties must have an initializer}}
lazy var d : Int // expected-error {{lazy properties must have an initializer}} {{3-8=}}
lazy var (e, f) = (1,2) // expected-error 2{{'lazy' cannot destructure an initializer}} {{3-8=}}
lazy var g = { 0 }() // single-expr closure
lazy var h : Int = { 0 }() // single-expr closure
lazy var i = { () -> Int in return 0 }()+1 // multi-stmt closure
lazy var j : Int = { return 0 }()+1 // multi-stmt closure
lazy var k : Int = { () -> Int in return 0 }()+1 // multi-stmt closure
lazy var l : Int = 42 { // Okay
didSet {}
willSet {}
}
lazy var m : Int = 42 { // Okay
didSet {}
}
lazy var n : Int = 42 {
willSet {} // Okay
}
init() {
lazy var localvar = 42 // Okay
localvar += 1
_ = localvar
}
}
struct StructTest {
lazy var p1 : Int = 42
mutating func f1() -> Int {
return p1
}
// expected-note @+1 {{mark method 'mutating' to make 'self' mutable}} {{3-3=mutating }}
func f2() -> Int {
return p1 // expected-error {{cannot use mutating getter on immutable value: 'self' is immutable}}
}
static func testStructInits() {
let a = StructTest() // default init
let b = StructTest(p1: 42) // Override the lazily init'd value.
_ = a; _ = b
}
}
// <rdar://problem/16889110> capture lists in lazy member properties cannot use self
class CaptureListInLazyProperty {
lazy var closure1 = { [weak self] in return self!.i }
lazy var closure2: () -> Int = { [weak self] in return self!.i }
var i = 42
}
// Crash when initializer expression is type-checked both to infer the
// property type and also as part of the getter
class WeShouldNotReTypeCheckStatements {
lazy var firstCase = {
_ = nil // expected-error{{'nil' requires a contextual type}}
_ = ()
}
lazy var secondCase = {
_ = ()
_ = ()
}
}
protocol MyProtocol {
func f() -> Int
}
struct MyStruct : MyProtocol {
func f() -> Int { return 0 }
}
struct Outer {
static let p: MyProtocol = MyStruct()
struct Inner {
lazy var x = p.f()
lazy var y = {_ = 3}()
// expected-warning@-1 {{variable 'y' inferred to have type '()', which may be unexpected}}
// expected-note@-2 {{add an explicit type annotation to silence this warning}} {{15-15=: ()}}
}
}
// https://github.com/apple/swift/issues/45221
struct Construction {
init(x: Int, y: Int? = 42) { }
}
class Constructor {
lazy var myQ = Construction(x: 3)
}
// Problems with self references
class BaseClass {
var baseInstanceProp = 42
static var baseStaticProp = 42
}
class ReferenceSelfInLazyProperty : BaseClass {
lazy var refs = (i, f())
lazy var trefs: (Int, Int) = (i, f())
lazy var qrefs = (self.i, self.f())
lazy var qtrefs: (Int, Int) = (self.i, self.f())
lazy var crefs = { (i, f()) }()
lazy var ctrefs: (Int, Int) = { (i, f()) }()
lazy var cqrefs = { (self.i, self.f()) }()
lazy var cqtrefs: (Int, Int) = { (self.i, self.f()) }()
lazy var mrefs = { () -> (Int, Int) in return (i, f()) }()
lazy var mtrefs: (Int, Int) = { return (i, f()) }()
lazy var mqrefs = { () -> (Int, Int) in (self.i, self.f()) }()
lazy var mqtrefs: (Int, Int) = { return (self.i, self.f()) }()
lazy var lcqrefs = { [unowned self] in (self.i, self.f()) }()
lazy var lcqtrefs: (Int, Int) = { [unowned self] in (self.i, self.f()) }()
lazy var lmrefs = { [unowned self] () -> (Int, Int) in return (i, f()) }()
lazy var lmtrefs: (Int, Int) = { [unowned self] in return (i, f()) }()
lazy var lmqrefs = { [unowned self] () -> (Int, Int) in (self.i, self.f()) }()
lazy var lmqtrefs: (Int, Int) = { [unowned self] in return (self.i, self.f()) }()
var i = 42
func f() -> Int { return 0 }
lazy var refBaseClassProp = baseInstanceProp
}
class ReferenceStaticInLazyProperty {
lazy var refs1 = i
// expected-error@-1 {{static member 'i' cannot be used on instance of type 'ReferenceStaticInLazyProperty'}}
lazy var refs2 = f()
// expected-error@-1 {{static member 'f' cannot be used on instance of type 'ReferenceStaticInLazyProperty'}}
lazy var trefs1: Int = i
// expected-error@-1 {{static member 'i' cannot be used on instance of type 'ReferenceStaticInLazyProperty'}}
lazy var trefs2: Int = f()
// expected-error@-1 {{static member 'f' cannot be used on instance of type 'ReferenceStaticInLazyProperty'}}
static var i = 42
static func f() -> Int { return 0 }
}
// Explicit access to the lazy variable storage
class LazyVarContainer {
lazy var foo: Int = {
return 0
}()
func accessLazyStorage() {
$__lazy_storage_$_foo = nil // expected-error {{access to the underlying storage of a lazy property is not allowed}}
print($__lazy_storage_$_foo!) // expected-error {{access to the underlying storage of a lazy property is not allowed}}
_ = $__lazy_storage_$_foo == nil // expected-error {{access to the underlying storage of a lazy property is not allowed}}
}
}
// Make sure we can still access a synthesized variable with the same name as a lazy storage variable
// i.e. $__lazy_storage_$_{property_name} when using property wrapper where the property name is
// '__lazy_storage_$_{property_name}'.
@propertyWrapper
struct Wrapper {
var wrappedValue: Int { 1 }
var projectedValue: Int { 1 }
}
struct PropertyWrapperContainer {
@Wrapper var __lazy_storage_$_foo
func test() {
_ = $__lazy_storage_$_foo // This is okay.
}
}
// rdar://problem/129255769
struct X {
struct Y { }
func f() {
_ = {
lazy var x: [Y] = []
_ = Y()
}
}
}
|