|
| 1 | +// RUN: %target-typecheck-verify-swift -swift-version 4 |
| 2 | + |
| 3 | +// Intentionally has lower precedence than assignments and ?: |
| 4 | +infix operator %%%% : LowPrecedence |
| 5 | +precedencegroup LowPrecedence { |
| 6 | + associativity: none |
| 7 | + lowerThan: AssignmentPrecedence |
| 8 | +} |
| 9 | +func %%%%<T, U>(x: T, y: U) -> Int { return 0 } |
| 10 | + |
| 11 | +// Intentionally has lower precedence between assignments and ?: |
| 12 | +infix operator %%% : MiddlingPrecedence |
| 13 | +precedencegroup MiddlingPrecedence { |
| 14 | + associativity: none |
| 15 | + higherThan: AssignmentPrecedence |
| 16 | + lowerThan: TernaryPrecedence |
| 17 | +} |
| 18 | +func %%%<T, U>(x: T, y: U) -> Int { return 1 } |
| 19 | + |
| 20 | +func foo() throws -> Int { return 0 } |
| 21 | +func bar() throws -> Int { return 0 } |
| 22 | + |
| 23 | +var x = try foo() + bar() |
| 24 | +x = try foo() + bar() |
| 25 | +x += try foo() + bar() |
| 26 | +x += try foo() %%%% bar() // expected-error {{'try' following assignment operator does not cover everything to its right}} // expected-error {{call can throw but is not marked with 'try'}} // expected-warning {{result of operator '%%%%' is unused}} |
| 27 | + // expected-note@-1 {{did you mean to use 'try'?}} {{21-21=try }} |
| 28 | + // expected-note@-2 {{did you mean to handle error as optional value?}} {{21-21=try? }} |
| 29 | + // expected-note@-3 {{did you mean to disable error propagation?}} {{21-21=try! }} |
| 30 | +x += try foo() %%% bar() |
| 31 | +x = foo() + try bar() // expected-error {{'try' cannot appear to the right of a non-assignment operator}} // expected-error {{call can throw but is not marked with 'try'}} |
| 32 | + // expected-note@-1 {{did you mean to use 'try'?}} {{5-5=try }} |
| 33 | + // expected-note@-2 {{did you mean to handle error as optional value?}} {{5-5=try? }} |
| 34 | + // expected-note@-3 {{did you mean to disable error propagation?}} {{5-5=try! }} |
| 35 | + |
| 36 | +var y = true ? try foo() : try bar() + 0 |
| 37 | +var z = true ? try foo() : try bar() %%% 0 // expected-error {{'try' following conditional operator does not cover everything to its right}} |
| 38 | + |
| 39 | +var a = try! foo() + bar() |
| 40 | +a = try! foo() + bar() |
| 41 | +a += try! foo() + bar() |
| 42 | +a += try! foo() %%%% bar() // expected-error {{'try!' following assignment operator does not cover everything to its right}} // expected-error {{call can throw but is not marked with 'try'}} // expected-warning {{result of operator '%%%%' is unused}} |
| 43 | + // expected-note@-1 {{did you mean to use 'try'?}} {{22-22=try }} |
| 44 | + // expected-note@-2 {{did you mean to handle error as optional value?}} {{22-22=try? }} |
| 45 | + // expected-note@-3 {{did you mean to disable error propagation?}} {{22-22=try! }} |
| 46 | +a += try! foo() %%% bar() |
| 47 | +a = foo() + try! bar() // expected-error {{'try!' cannot appear to the right of a non-assignment operator}} // expected-error {{call can throw but is not marked with 'try'}} |
| 48 | + // expected-note@-1 {{did you mean to use 'try'?}} {{5-5=try }} |
| 49 | + // expected-note@-2 {{did you mean to handle error as optional value?}} {{5-5=try? }} |
| 50 | + // expected-note@-3 {{did you mean to disable error propagation?}} {{5-5=try! }} |
| 51 | + |
| 52 | +var b = true ? try! foo() : try! bar() + 0 |
| 53 | +var c = true ? try! foo() : try! bar() %%% 0 // expected-error {{'try!' following conditional operator does not cover everything to its right}} |
| 54 | + |
| 55 | +infix operator ?+= : AssignmentPrecedence |
| 56 | +func ?+=(lhs: inout Int?, rhs: Int?) { |
| 57 | + lhs = lhs! + rhs! |
| 58 | +} |
| 59 | + |
| 60 | +var i = try? foo() + bar() |
| 61 | +let _: Double = i // expected-error {{cannot convert value of type 'Int?' to specified type 'Double'}} |
| 62 | +i = try? foo() + bar() |
| 63 | +i ?+= try? foo() + bar() |
| 64 | +i ?+= try? foo() %%%% bar() // expected-error {{'try?' following assignment operator does not cover everything to its right}} // expected-error {{call can throw but is not marked with 'try'}} // expected-warning {{result of operator '%%%%' is unused}} |
| 65 | + // expected-note@-1 {{did you mean to use 'try'?}} {{23-23=try }} |
| 66 | + // expected-note@-2 {{did you mean to handle error as optional value?}} {{23-23=try? }} |
| 67 | + // expected-note@-3 {{did you mean to disable error propagation?}} {{23-23=try! }} |
| 68 | +i ?+= try? foo() %%% bar() |
| 69 | +_ = foo() == try? bar() // expected-error {{'try?' cannot appear to the right of a non-assignment operator}} // expected-error {{call can throw but is not marked with 'try'}} |
| 70 | + // expected-note@-1 {{did you mean to use 'try'?}} {{5-5=try }} |
| 71 | + // expected-note@-2 {{did you mean to handle error as optional value?}} {{5-5=try? }} |
| 72 | + // expected-note@-3 {{did you mean to disable error propagation?}} {{5-5=try! }} |
| 73 | +_ = (try? foo()) == bar() // expected-error {{call can throw but is not marked with 'try'}} |
| 74 | + // expected-note@-1 {{did you mean to use 'try'?}} {{21-21=try }} |
| 75 | + // expected-note@-2 {{did you mean to handle error as optional value?}} {{21-21=try? }} |
| 76 | + // expected-note@-3 {{did you mean to disable error propagation?}} {{21-21=try! }} |
| 77 | +_ = foo() == (try? bar()) // expected-error {{call can throw but is not marked with 'try'}} |
| 78 | + // expected-note@-1 {{did you mean to use 'try'?}} {{5-5=try }} |
| 79 | + // expected-note@-2 {{did you mean to handle error as optional value?}} {{5-5=try? }} |
| 80 | + // expected-note@-3 {{did you mean to disable error propagation?}} {{5-5=try! }} |
| 81 | +_ = (try? foo()) == (try? bar()) |
| 82 | + |
| 83 | +let j = true ? try? foo() : try? bar() + 0 |
| 84 | +let k = true ? try? foo() : try? bar() %%% 0 // expected-error {{'try?' following conditional operator does not cover everything to its right}} |
| 85 | + |
| 86 | +try let singleLet = foo() // expected-error {{'try' must be placed on the initial value expression}} {{1-5=}} {{21-21=try }} |
| 87 | +try var singleVar = foo() // expected-error {{'try' must be placed on the initial value expression}} {{1-5=}} {{21-21=try }} |
| 88 | +try let uninit: Int // expected-error {{'try' must be placed on the initial value expression}} |
| 89 | +try let (destructure1, destructure2) = (foo(), bar()) // expected-error {{'try' must be placed on the initial value expression}} {{1-5=}} {{40-40=try }} |
| 90 | +try let multi1 = foo(), multi2 = bar() // expected-error {{'try' must be placed on the initial value expression}} expected-error 2 {{call can throw but is not marked with 'try'}} |
| 91 | + // expected-note@-1 {{did you mean to use 'try'?}} {{18-18=try }} expected-note@-1 {{did you mean to use 'try'?}} {{34-34=try }} |
| 92 | + // expected-note@-2 {{did you mean to handle error as optional value?}} {{18-18=try? }} expected-note@-2 {{did you mean to handle error as optional value?}} {{34-34=try? }} |
| 93 | + // expected-note@-3 {{did you mean to disable error propagation?}} {{18-18=try! }} expected-note@-3 {{did you mean to disable error propagation?}} {{34-34=try! }} |
| 94 | +class TryDecl { // expected-note {{in declaration of 'TryDecl'}} |
| 95 | + try let singleLet = foo() // expected-error {{'try' must be placed on the initial value expression}} {{3-7=}} {{23-23=try }} |
| 96 | + // expected-error @-1 {{call can throw, but errors cannot be thrown out of a property initializer}} |
| 97 | + try var singleVar = foo() // expected-error {{'try' must be placed on the initial value expression}} {{3-7=}} {{23-23=try }} |
| 98 | + // expected-error @-1 {{call can throw, but errors cannot be thrown out of a property initializer}} |
| 99 | + |
| 100 | + try // expected-error {{expected declaration}} |
| 101 | + func method() {} |
| 102 | +} |
| 103 | + |
| 104 | +func test() throws -> Int { |
| 105 | + try while true { // expected-error {{'try' cannot be used with 'while'}} |
| 106 | + try break // expected-error {{'try' cannot be used with 'break'}} |
| 107 | + } |
| 108 | + |
| 109 | + try throw // expected-error {{'try' must be placed on the thrown expression}} {{3-7=}} {{3-3=try }} expected-error {{expected expression in 'throw' statement}} |
| 110 | + ; // Reset parser. |
| 111 | + |
| 112 | + try return // expected-error {{'try' cannot be used with 'return'}} expected-error {{non-void function should return a value}} |
| 113 | + ; // Reset parser. |
| 114 | + |
| 115 | + try throw foo() // expected-error {{'try' must be placed on the thrown expression}} {{3-7=}} {{13-13=try }} |
| 116 | + // expected-error@-1 {{thrown expression type 'Int' does not conform to 'Error'}} |
| 117 | + try return foo() // expected-error {{'try' must be placed on the returned expression}} {{3-7=}} {{14-14=try }} |
| 118 | +} |
| 119 | + |
| 120 | +// Test operators. |
| 121 | +func *(a : String, b : String) throws -> Int { return 42 } |
| 122 | +let _ = "foo" |
| 123 | + * // expected-error {{operator can throw but expression is not marked with 'try'}} |
| 124 | + // expected-note@-1 {{did you mean to use 'try'?}} {{9-9=try }} |
| 125 | + // expected-note@-2 {{did you mean to handle error as optional value?}} {{9-9=try? }} |
| 126 | + // expected-note@-3 {{did you mean to disable error propagation?}} {{9-9=try! }} |
| 127 | + "bar" |
| 128 | +let _ = try! "foo"*"bar" |
| 129 | +let _ = try? "foo"*"bar" |
| 130 | +let _ = (try? "foo"*"bar") ?? 0 |
| 131 | + |
| 132 | + |
| 133 | +// <rdar://problem/21414023> Assertion failure when compiling function that takes throwing functions and rethrows |
| 134 | +func rethrowsDispatchError(handleError: ((Error) throws -> ()), body: () throws -> ()) rethrows { |
| 135 | + do { |
| 136 | + body() // expected-error {{call can throw but is not marked with 'try'}} |
| 137 | + // expected-note@-1 {{did you mean to use 'try'?}} {{5-5=try }} |
| 138 | + // expected-note@-2 {{did you mean to handle error as optional value?}} {{5-5=try? }} |
| 139 | + // expected-note@-3 {{did you mean to disable error propagation?}} {{5-5=try! }} |
| 140 | + } catch { |
| 141 | + } |
| 142 | +} |
| 143 | + |
| 144 | +// <rdar://problem/21432429> Calling rethrows from rethrows crashes Swift compiler |
| 145 | +struct r21432429 { |
| 146 | + func x(_ f: () throws -> ()) rethrows {} |
| 147 | + func y(_ f: () throws -> ()) rethrows { |
| 148 | + x(f) // expected-error {{call can throw but is not marked with 'try'}} expected-note {{call is to 'rethrows' function, but argument function can throw}} |
| 149 | + } |
| 150 | +} |
| 151 | + |
| 152 | +// <rdar://problem/21427855> Swift 2: Omitting try from call to throwing closure in rethrowing function crashes compiler |
| 153 | +func callThrowingClosureWithoutTry(closure: (Int) throws -> Int) rethrows { |
| 154 | + closure(0) // expected-error {{call can throw but is not marked with 'try'}} expected-warning {{result of call to function returning 'Int' is unused}} |
| 155 | + // expected-note@-1 {{did you mean to use 'try'?}} {{3-3=try }} |
| 156 | + // expected-note@-2 {{did you mean to handle error as optional value?}} {{3-3=try? }} |
| 157 | + // expected-note@-3 {{did you mean to disable error propagation?}} {{3-3=try! }} |
| 158 | +} |
| 159 | + |
| 160 | +func producesOptional() throws -> Int? { return nil } |
| 161 | +let _: String = try? producesOptional() // expected-error {{cannot convert value of type 'Int??' to specified type 'String'}} |
| 162 | + |
| 163 | +let _ = (try? foo())!! // expected-error {{cannot force unwrap value of non-optional type 'Int'}} |
| 164 | + |
| 165 | +func producesDoubleOptional() throws -> Int?? { return 3 } |
| 166 | +let _: String = try? producesDoubleOptional() // expected-error {{cannot convert value of type 'Int???' to specified type 'String'}} |
| 167 | + |
| 168 | +func maybeThrow() throws {} |
| 169 | +try maybeThrow() // okay |
| 170 | +try! maybeThrow() // okay |
| 171 | +try? maybeThrow() // okay since return type of maybeThrow is Void |
| 172 | +_ = try? maybeThrow() // okay |
| 173 | + |
| 174 | +let _: () -> Void = { try! maybeThrow() } // okay |
| 175 | +let _: () -> Void = { try? maybeThrow() } // okay since return type of maybeThrow is Void |
| 176 | + |
| 177 | + |
| 178 | +if try? maybeThrow() { // expected-error {{cannot be used as a boolean}} {{4-4=((}} {{21-21=) != nil)}} |
| 179 | +} |
| 180 | +let _: Int = try? foo() // expected-error {{value of optional type 'Int?' not unwrapped; did you mean to use 'try!' or chain with '?'?}} {{14-18=try!}} |
| 181 | + |
| 182 | +class X {} |
| 183 | +func test(_: X) {} |
| 184 | +func producesObject() throws -> AnyObject { return X() } |
| 185 | +test(try producesObject()) // expected-error {{'AnyObject' is not convertible to 'X'; did you mean to use 'as!' to force downcast?}} {{26-26= as! X}} |
| 186 | + |
| 187 | +_ = "a\(try maybeThrow())b" |
| 188 | +_ = try "a\(maybeThrow())b" |
| 189 | +_ = "a\(maybeThrow())" // expected-error {{call can throw but is not marked with 'try'}} |
| 190 | + // expected-note@-1 {{did you mean to use 'try'?}} {{9-9=try }} |
| 191 | + // expected-note@-2 {{did you mean to handle error as optional value?}} {{9-9=try? }} |
| 192 | + // expected-note@-3 {{did you mean to disable error propagation?}} {{9-9=try! }} |
| 193 | + |
| 194 | +extension DefaultStringInterpolation { |
| 195 | + mutating func appendInterpolation() throws {} |
| 196 | +} |
| 197 | + |
| 198 | +_ = try "a\()b" |
| 199 | +_ = "a\()b" // expected-error {{interpolation can throw but is not marked with 'try'}} |
| 200 | + // expected-note@-1 {{did you mean to use 'try'?}} {{5-5=try }} |
| 201 | + // expected-note@-2 {{did you mean to handle error as optional value?}} {{5-5=try? }} |
| 202 | + // expected-note@-3 {{did you mean to disable error propagation?}} {{5-5=try! }} |
| 203 | +_ = try "\() \(1)" |
| 204 | + |
| 205 | +func testGenericOptionalTry<T>(_ call: () throws -> T ) { |
| 206 | + let _: String = try? call() // expected-error {{cannot convert value of type 'T?' to specified type 'String'}} |
| 207 | +} |
| 208 | + |
| 209 | +func genericOptionalTry<T>(_ call: () throws -> T ) -> T? { |
| 210 | + let x = try? call() // no error expected |
| 211 | + return x |
| 212 | +} |
| 213 | + |
| 214 | +// Test with a non-optional type |
| 215 | +let _: String = genericOptionalTry({ () throws -> Int in return 3 }) // expected-error {{cannot convert value of type 'Int?' to specified type 'String'}} |
| 216 | + |
| 217 | +// Test with an optional type |
| 218 | +let _: String = genericOptionalTry({ () throws -> Int? in return nil }) // expected-error {{cannot convert value of type 'Int??' to specified type 'String'}} |
| 219 | + |
| 220 | +func produceAny() throws -> Any { |
| 221 | + return 3 |
| 222 | +} |
| 223 | + |
| 224 | +let _: Int? = try? produceAny() as? Int // expected-error {{value of optional type 'Int??' not unwrapped; did you mean to use 'try!' or chain with '?'?}} |
| 225 | +let _: Int?? = (try? produceAny()) as? Int // good |
| 226 | +let _: String = try? produceAny() as? Int // expected-error {{cannot convert value of type 'Int??' to specified type 'String'}} |
| 227 | +let _: String = (try? produceAny()) as? Int // expected-error {{cannot convert value of type 'Int?' to specified type 'String'}} |
| 228 | + |
| 229 | + |
| 230 | +struct ThingProducer { |
| 231 | + func produceInt() throws -> Int { return 3 } |
| 232 | + func produceIntNoThrowing() -> Int { return 3 } |
| 233 | + func produceAny() throws -> Any { return 3 } |
| 234 | + func produceOptionalAny() throws -> Any? { return 3 } |
| 235 | + func produceDoubleOptionalInt() throws -> Int?? { return 3 } |
| 236 | +} |
| 237 | + |
| 238 | +let optProducer: ThingProducer? = ThingProducer() |
| 239 | +let _: Int? = try? optProducer?.produceInt() // expected-error {{value of optional type 'Int??' not unwrapped; did you mean to use 'try!' or chain with '?'?}} |
| 240 | +let _: Int = try? optProducer?.produceInt() // expected-error {{cannot convert value of type 'Int??' to specified type 'Int'}} |
| 241 | +let _: String = try? optProducer?.produceInt() // expected-error {{cannot convert value of type 'Int??' to specified type 'String'}} |
| 242 | +let _: Int?? = try? optProducer?.produceInt() // good |
| 243 | + |
| 244 | +let _: Int? = try? optProducer?.produceIntNoThrowing() // expected-error {{value of optional type 'Int??' not unwrapped; did you mean to use 'try!' or chain with '?'?}} |
| 245 | +let _: Int?? = try? optProducer?.produceIntNoThrowing() // expected-warning {{no calls to throwing functions occur within 'try' expression}} |
| 246 | + |
| 247 | +let _: Int? = (try? optProducer?.produceAny()) as? Int // good |
| 248 | +let _: Int? = try? optProducer?.produceAny() as? Int // expected-error {{value of optional type 'Int??' not unwrapped; did you mean to use 'try!' or chain with '?'?}} |
| 249 | +let _: Int?? = try? optProducer?.produceAny() as? Int // good |
| 250 | +let _: String = try? optProducer?.produceAny() as? Int // expected-error {{cannot convert value of type 'Int??' to specified type 'String'}} |
| 251 | + |
| 252 | +let _: String = try? optProducer?.produceDoubleOptionalInt() // expected-error {{cannot convert value of type 'Int???' to specified type 'String'}} |
| 253 | + |
| 254 | +let producer = ThingProducer() |
| 255 | + |
| 256 | +let _: Int = try? producer.produceDoubleOptionalInt() // expected-error {{cannot convert value of type 'Int???' to specified type 'Int'}} |
| 257 | +let _: Int? = try? producer.produceDoubleOptionalInt() // expected-error {{value of optional type 'Int???' not unwrapped; did you mean to use 'try!' or chain with '?'?}} |
| 258 | +let _: Int?? = try? producer.produceDoubleOptionalInt() // expected-error {{value of optional type 'Int???' not unwrapped; did you mean to use 'try!' or chain with '?'?}} |
| 259 | +let _: Int??? = try? producer.produceDoubleOptionalInt() // good |
| 260 | +let _: String = try? producer.produceDoubleOptionalInt() // expected-error {{cannot convert value of type 'Int???' to specified type 'String'}} |
0 commit comments