|
| 1 | +// RUN: %target-typecheck-verify-swift -parse-as-library -module-name MyModule |
| 2 | + |
| 3 | +struct Value { |
| 4 | + static let defaultValue = Value(a: Nested(b: 1)) |
| 5 | + |
| 6 | + struct Nested { |
| 7 | + var b: Int |
| 8 | + |
| 9 | + @discardableResult |
| 10 | + mutating func setToZero() -> Int { |
| 11 | + let prev = b |
| 12 | + b = 0 |
| 13 | + return prev |
| 14 | + } |
| 15 | + } |
| 16 | + |
| 17 | + var a: Nested |
| 18 | + |
| 19 | + subscript(_ i: Int) -> Nested { |
| 20 | + get { a } |
| 21 | + set { a = newValue } |
| 22 | + } |
| 23 | + |
| 24 | + @discardableResult |
| 25 | + mutating func setToZero() -> Int { |
| 26 | + let prev = a.b |
| 27 | + a.setToZero() |
| 28 | + return prev |
| 29 | + } |
| 30 | +} |
| 31 | + |
| 32 | +struct BaseStruct { |
| 33 | + var available: Value = .defaultValue |
| 34 | + |
| 35 | + var unavailableGetter: Value { |
| 36 | + @available(*, unavailable) |
| 37 | + get { fatalError() } // expected-note 24 {{getter for 'unavailableGetter' has been explicitly marked unavailable here}} |
| 38 | + set {} |
| 39 | + } |
| 40 | + |
| 41 | + var unavailableSetter: Value { |
| 42 | + get { .defaultValue } |
| 43 | + @available(*, unavailable) |
| 44 | + set { fatalError() } // expected-note 12 {{setter for 'unavailableSetter' has been explicitly marked unavailable here}} |
| 45 | + } |
| 46 | + |
| 47 | + var unavailableGetterAndSetter: Value { |
| 48 | + @available(*, unavailable) |
| 49 | + get { fatalError() } // expected-note 24 {{getter for 'unavailableGetterAndSetter' has been explicitly marked unavailable here}} |
| 50 | + @available(*, unavailable) |
| 51 | + set { fatalError() } // expected-note 12 {{setter for 'unavailableGetterAndSetter' has been explicitly marked unavailable here}} |
| 52 | + } |
| 53 | +} |
| 54 | + |
| 55 | +func takesIntInOut(_ i: inout Int) -> Int { |
| 56 | + return 0 |
| 57 | +} |
| 58 | + |
| 59 | +let someValue = Value.defaultValue |
| 60 | + |
| 61 | +func testRValueLoads() { |
| 62 | + var x = BaseStruct() // expected-warning {{variable 'x' was never mutated; consider changing to 'let' constant}} |
| 63 | + |
| 64 | + _ = x.available |
| 65 | + _ = x.available.a |
| 66 | + _ = x.available[0] |
| 67 | + _ = x.available[0].b |
| 68 | + |
| 69 | + _ = x.unavailableGetter // expected-error {{getter for 'unavailableGetter' is unavailable}} |
| 70 | + _ = x.unavailableGetter.a // expected-error {{getter for 'unavailableGetter' is unavailable}} |
| 71 | + _ = x.unavailableGetter[0] // expected-error {{getter for 'unavailableGetter' is unavailable}} |
| 72 | + _ = x.unavailableGetter[0].b // expected-error {{getter for 'unavailableGetter' is unavailable}} |
| 73 | + |
| 74 | + _ = x.unavailableSetter |
| 75 | + _ = x.unavailableSetter.a |
| 76 | + _ = x.unavailableSetter[0] |
| 77 | + _ = x.unavailableSetter[0].b |
| 78 | + |
| 79 | + _ = x.unavailableGetterAndSetter // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} |
| 80 | + _ = x.unavailableGetterAndSetter.a // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} |
| 81 | + _ = x.unavailableGetterAndSetter[0] // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} |
| 82 | + _ = x.unavailableGetterAndSetter[0].b // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} |
| 83 | +} |
| 84 | + |
| 85 | +func testLValueAssignments() { |
| 86 | + var x = BaseStruct() |
| 87 | + |
| 88 | + x.available = someValue |
| 89 | + x.available.a = someValue.a |
| 90 | + x.available[0] = someValue.a |
| 91 | + x.available[0].b = 1 |
| 92 | + |
| 93 | + x.unavailableGetter = someValue |
| 94 | + x.unavailableGetter.a = someValue.a // expected-error {{getter for 'unavailableGetter' is unavailable}} |
| 95 | + x.unavailableGetter[0] = someValue.a // expected-error {{getter for 'unavailableGetter' is unavailable}} |
| 96 | + x.unavailableGetter[0].b = 1 // expected-error {{getter for 'unavailableGetter' is unavailable}} |
| 97 | + |
| 98 | + x.unavailableSetter = someValue // expected-error {{setter for 'unavailableSetter' is unavailable}} |
| 99 | + x.unavailableSetter.a = someValue.a // FIXME: missing diagnostic for setter |
| 100 | + x.unavailableSetter[0] = someValue.a // expected-error {{setter for 'unavailableSetter' is unavailable}} |
| 101 | + x.unavailableSetter[0].b = 1 // expected-error {{setter for 'unavailableSetter' is unavailable}} |
| 102 | + |
| 103 | + x.unavailableGetterAndSetter = someValue // expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}} |
| 104 | + x.unavailableGetterAndSetter.a = someValue.a // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} FIXME: missing diagnostic for setter |
| 105 | + x.unavailableGetterAndSetter[0] = someValue.a // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}} |
| 106 | + x.unavailableGetterAndSetter[0].b = 1 // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}} |
| 107 | +} |
| 108 | + |
| 109 | +func testKeyPathLoads() { |
| 110 | + let a = [0] |
| 111 | + var x = BaseStruct() |
| 112 | + |
| 113 | + _ = x[keyPath: \.available] |
| 114 | + _ = x[keyPath: \.available.a] |
| 115 | + _ = x[keyPath: \.available[0]] |
| 116 | + _ = x[keyPath: \.available[0].b] |
| 117 | + _ = a[keyPath: \.[takesIntInOut(&x.available.a.b)]] |
| 118 | + _ = a[keyPath: \.[takesIntInOut(&x.available[0].b)]] |
| 119 | + |
| 120 | + _ = x[keyPath: \.unavailableGetter] // FIXME: missing diagnostic for getter |
| 121 | + _ = x[keyPath: \.unavailableGetter.a] // FIXME: missing diagnostic for getter |
| 122 | + _ = x[keyPath: \.unavailableGetter[0]] // FIXME: missing diagnostic for getter |
| 123 | + _ = x[keyPath: \.unavailableGetter[0].b] // FIXME: missing diagnostic for getter |
| 124 | + _ = a[keyPath: \.[takesIntInOut(&x.unavailableGetter.a.b)]] // expected-error {{getter for 'unavailableGetter' is unavailable}} |
| 125 | + _ = a[keyPath: \.[takesIntInOut(&x.unavailableGetter[0].b)]] // expected-error {{getter for 'unavailableGetter' is unavailable}} |
| 126 | + |
| 127 | + _ = x[keyPath: \.unavailableSetter] |
| 128 | + _ = x[keyPath: \.unavailableSetter.a] |
| 129 | + _ = x[keyPath: \.unavailableSetter[0]] |
| 130 | + _ = x[keyPath: \.unavailableSetter[0].b] |
| 131 | + _ = a[keyPath: \.[takesIntInOut(&x.unavailableSetter.a.b)]] // FIXME: missing diagnostic for setter |
| 132 | + _ = a[keyPath: \.[takesIntInOut(&x.unavailableSetter[0].b)]] // expected-error {{setter for 'unavailableSetter' is unavailable}} |
| 133 | + |
| 134 | + _ = x[keyPath: \.unavailableGetterAndSetter] // FIXME: missing diagnostic for getter |
| 135 | + _ = x[keyPath: \.unavailableGetterAndSetter.a] // FIXME: missing diagnostic for getter |
| 136 | + _ = x[keyPath: \.unavailableGetterAndSetter[0]] // FIXME: missing diagnostic for getter |
| 137 | + _ = x[keyPath: \.unavailableGetterAndSetter[0].b] // FIXME: missing diagnostic for getter |
| 138 | + _ = a[keyPath: \.[takesIntInOut(&x.unavailableGetterAndSetter.a.b)]] // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} FIXME: missing diagnostic for setter |
| 139 | + _ = a[keyPath: \.[takesIntInOut(&x.unavailableGetterAndSetter[0].b)]] // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}} |
| 140 | +} |
| 141 | + |
| 142 | +func testKeyPathAssignments() { |
| 143 | + var a = [0] |
| 144 | + var x = BaseStruct() |
| 145 | + |
| 146 | + x[keyPath: \.available] = someValue |
| 147 | + x[keyPath: \.available.a] = someValue.a |
| 148 | + x[keyPath: \.available[0]] = someValue.a |
| 149 | + x[keyPath: \.available[0].b] = 1 |
| 150 | + x[keyPath: \.available] = someValue |
| 151 | + a[keyPath: \.[takesIntInOut(&x.available.a.b)]] = 0 |
| 152 | + a[keyPath: \.[takesIntInOut(&x.available[0].b)]] = 0 |
| 153 | + |
| 154 | + x[keyPath: \.unavailableGetter] = someValue |
| 155 | + x[keyPath: \.unavailableGetter.a] = someValue.a // FIXME: missing diagnostic for getter |
| 156 | + x[keyPath: \.unavailableGetter[0]] = someValue.a // FIXME: missing diagnostic for getter |
| 157 | + x[keyPath: \.unavailableGetter[0].b] = 1 // FIXME: missing diagnostic for getter |
| 158 | + a[keyPath: \.[takesIntInOut(&x.unavailableGetter.a.b)]] = 0 // expected-error {{getter for 'unavailableGetter' is unavailable}} |
| 159 | + a[keyPath: \.[takesIntInOut(&x.unavailableGetter[0].b)]] = 0 // expected-error {{getter for 'unavailableGetter' is unavailable}} |
| 160 | + |
| 161 | + x[keyPath: \.unavailableSetter] = someValue |
| 162 | + x[keyPath: \.unavailableSetter.a] = someValue.a // FIXME: missing diagnostic for setter |
| 163 | + x[keyPath: \.unavailableSetter[0]] = someValue.a // FIXME: missing diagnostic for setter |
| 164 | + x[keyPath: \.unavailableSetter[0].b] = 1 // FIXME: missing diagnostic for setter |
| 165 | + a[keyPath: \.[takesIntInOut(&x.unavailableSetter.a.b)]] = 0 // FIXME: missing diagnostic for setter |
| 166 | + a[keyPath: \.[takesIntInOut(&x.unavailableSetter[0].b)]] = 0 // expected-error {{setter for 'unavailableSetter' is unavailable}} |
| 167 | + |
| 168 | + x[keyPath: \.unavailableGetterAndSetter] = someValue |
| 169 | + x[keyPath: \.unavailableGetterAndSetter.a] = someValue.a // FIXME: missing diagnostics for getter and setter |
| 170 | + x[keyPath: \.unavailableGetterAndSetter[0]] = someValue.a // FIXME: missing diagnostics for getter and setter |
| 171 | + x[keyPath: \.unavailableGetterAndSetter[0].b] = 1 // FIXME: missing diagnostics for getter and setter |
| 172 | + a[keyPath: \.[takesIntInOut(&x.unavailableGetterAndSetter.a.b)]] = 0 // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} FIXME: missing diagnostic for setter |
| 173 | + a[keyPath: \.[takesIntInOut(&x.unavailableGetterAndSetter[0].b)]] = 0 // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}} |
| 174 | +} |
| 175 | + |
| 176 | +func testMutatingMember() { |
| 177 | + var x = BaseStruct() |
| 178 | + let a = [0] |
| 179 | + |
| 180 | + x.available.setToZero() |
| 181 | + x.available[0].setToZero() |
| 182 | + _ = a[x.available.setToZero()] |
| 183 | + _ = a[x.available.a.setToZero()] |
| 184 | + _ = a[x.available[0].setToZero()] |
| 185 | + |
| 186 | + x.unavailableGetter.setToZero() // expected-error {{getter for 'unavailableGetter' is unavailable}} |
| 187 | + x.unavailableGetter[0].setToZero() // expected-error {{getter for 'unavailableGetter' is unavailable}} |
| 188 | + _ = a[x.unavailableGetter.setToZero()] // expected-error {{getter for 'unavailableGetter' is unavailable}} |
| 189 | + _ = a[x.unavailableGetter.a.setToZero()] // expected-error {{getter for 'unavailableGetter' is unavailable}} |
| 190 | + _ = a[x.unavailableGetter[0].setToZero()] // expected-error {{getter for 'unavailableGetter' is unavailable}} |
| 191 | + |
| 192 | + x.unavailableSetter.setToZero() // expected-error {{setter for 'unavailableSetter' is unavailable}} |
| 193 | + x.unavailableSetter[0].setToZero() // expected-error {{setter for 'unavailableSetter' is unavailable}} |
| 194 | + _ = a[x.unavailableSetter.setToZero()] // expected-error {{setter for 'unavailableSetter' is unavailable}} |
| 195 | + _ = a[x.unavailableSetter.a.setToZero()] // FIXME: missing diagnostic for setter |
| 196 | + _ = a[x.unavailableSetter[0].setToZero()] // expected-error {{setter for 'unavailableSetter' is unavailable}} |
| 197 | + |
| 198 | + x.unavailableGetterAndSetter.setToZero() // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}} |
| 199 | + x.unavailableGetterAndSetter[0].setToZero() // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}} |
| 200 | + _ = a[x.unavailableGetterAndSetter.setToZero()] // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}} |
| 201 | + _ = a[x.unavailableGetterAndSetter.a.setToZero()] // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} FIXME: should diagnose setter |
| 202 | + _ = a[x.unavailableGetterAndSetter[0].setToZero()] // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}} |
| 203 | +} |
| 204 | + |
| 205 | +func testPassAsInOutParameter() { |
| 206 | + func takesInOut<T>(_ t: inout T) {} |
| 207 | + |
| 208 | + var x = BaseStruct() |
| 209 | + |
| 210 | + takesInOut(&x.available) |
| 211 | + takesInOut(&x.available.a) |
| 212 | + takesInOut(&x.available[0]) |
| 213 | + takesInOut(&x.available[0].b) |
| 214 | + |
| 215 | + takesInOut(&x.unavailableGetter) // expected-error {{getter for 'unavailableGetter' is unavailable}} |
| 216 | + takesInOut(&x.unavailableGetter.a) // expected-error {{getter for 'unavailableGetter' is unavailable}} |
| 217 | + takesInOut(&x.unavailableGetter[0]) // expected-error {{getter for 'unavailableGetter' is unavailable}} |
| 218 | + takesInOut(&x.unavailableGetter[0].b) // expected-error {{getter for 'unavailableGetter' is unavailable}} |
| 219 | + |
| 220 | + takesInOut(&x.unavailableSetter) // expected-error {{setter for 'unavailableSetter' is unavailable}} |
| 221 | + takesInOut(&x.unavailableSetter.a) // |
| 222 | + takesInOut(&x.unavailableSetter[0]) // expected-error {{setter for 'unavailableSetter' is unavailable}} |
| 223 | + takesInOut(&x.unavailableSetter[0].b) // expected-error {{setter for 'unavailableSetter' is unavailable}} |
| 224 | + |
| 225 | + takesInOut(&x.unavailableGetterAndSetter) // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}} |
| 226 | + takesInOut(&x.unavailableGetterAndSetter.a) // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} FIXME: missing diagnostic for setter |
| 227 | + takesInOut(&x.unavailableGetterAndSetter[0]) // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}} |
| 228 | + takesInOut(&x.unavailableGetterAndSetter[0].b) // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}} |
| 229 | +} |
| 230 | + |
| 231 | +var global = BaseStruct() |
| 232 | + |
| 233 | +struct TestPatternBindingInitExprs { |
| 234 | + var available = global.available |
| 235 | + var available_a = global.available.a |
| 236 | + var available_0 = global.available[0] |
| 237 | + var available_0_b = global.available[0].b |
| 238 | + |
| 239 | + var unavailableGetter = global.unavailableGetter // expected-error {{getter for 'unavailableGetter' is unavailable}} |
| 240 | + var unavailableGetter_a = global.unavailableGetter.a // expected-error {{getter for 'unavailableGetter' is unavailable}} |
| 241 | + var unavailableGetter_0 = global.unavailableGetter[0] // expected-error {{getter for 'unavailableGetter' is unavailable}} |
| 242 | + var unavailableGetter_0_b = global.unavailableGetter[0].b // expected-error {{getter for 'unavailableGetter' is unavailable}} |
| 243 | + |
| 244 | + var unavailableSetter = global.unavailableSetter |
| 245 | + var unavailableSetter_a = global.unavailableSetter.a |
| 246 | + var unavailableSetter_0 = global.unavailableSetter[0] |
| 247 | + var unavailableSetter_0_b = global.unavailableSetter[0].b |
| 248 | + |
| 249 | + var unavailableGetterAndSetter = global.unavailableGetterAndSetter // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} |
| 250 | + var unavailableGetterAndSetter_a = global.unavailableGetterAndSetter.a // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} |
| 251 | + var unavailableGetterAndSetter_0 = global.unavailableGetterAndSetter[0] // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} |
| 252 | + var unavailableGetterAndSetter_0_b = global.unavailableGetterAndSetter[0].b // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} |
| 253 | +} |
0 commit comments