mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
129 lines
6.5 KiB
Swift
129 lines
6.5 KiB
Swift
// RUN: %target-parse-verify-swift
|
|
|
|
// Intentionally has lower precedence than assignments and ?:
|
|
infix operator %%%% { associativity none precedence 50 }
|
|
func %%%%<T,U>(x:T, y:U) -> Int { return 0 }
|
|
|
|
// Intentionally has lower precedence between assignments and ?:
|
|
infix operator %%% { associativity none precedence 95 }
|
|
func %%%<T,U>(x:T, y:U) -> Int { return 1 }
|
|
|
|
func foo() throws -> Int { return 0 }
|
|
func bar() throws -> Int { return 0 }
|
|
|
|
var x = try foo() + bar()
|
|
x = try foo() + bar()
|
|
x += try foo() + bar()
|
|
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'}}
|
|
x += try foo() %%% bar()
|
|
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'}}
|
|
|
|
var y = true ? try foo() : try bar() + 0
|
|
var z = true ? try foo() : try bar() %%% 0 // expected-error {{'try' following conditional operator does not cover everything to its right}}
|
|
|
|
var a = try! foo() + bar()
|
|
a = try! foo() + bar()
|
|
a += try! foo() + bar()
|
|
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'}}
|
|
a += try! foo() %%% bar()
|
|
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'}}
|
|
|
|
var b = true ? try! foo() : try! bar() + 0
|
|
var c = true ? try! foo() : try! bar() %%% 0 // expected-error {{'try!' following conditional operator does not cover everything to its right}}
|
|
|
|
infix operator ?+= { associativity right precedence 90 assignment }
|
|
func ?+=(lhs: inout Int?, rhs: Int?) {
|
|
lhs = lhs! + rhs!
|
|
}
|
|
|
|
var i = try? foo() + bar()
|
|
let _: Double = i // expected-error {{cannot convert value of type 'Int?' to specified type 'Double'}}
|
|
i = try? foo() + bar()
|
|
i ?+= try? foo() + bar()
|
|
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'}}
|
|
i ?+= try? foo() %%% bar()
|
|
_ = 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'}}
|
|
_ = (try? foo()) < bar() // expected-error {{call can throw but is not marked with 'try'}}
|
|
_ = foo() < (try? bar()) // expected-error {{call can throw but is not marked with 'try'}}
|
|
_ = (try? foo()) < (try? bar())
|
|
|
|
let j = true ? try? foo() : try? bar() + 0
|
|
let k = true ? try? foo() : try? bar() %%% 0 // expected-error {{'try?' following conditional operator does not cover everything to its right}}
|
|
|
|
try let singleLet = foo() // expected-error {{'try' must be placed on the initial value expression}} {{1-5=}} {{21-21=try }}
|
|
try var singleVar = foo() // expected-error {{'try' must be placed on the initial value expression}} {{1-5=}} {{21-21=try }}
|
|
try let uninit: Int // expected-error {{'try' must be placed on the initial value expression}}
|
|
try let (destructure1, destructure2) = (foo(), bar()) // expected-error {{'try' must be placed on the initial value expression}} {{1-5=}} {{40-40=try }}
|
|
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'}}
|
|
|
|
func test() throws -> Int {
|
|
try while true { // expected-error {{'try' cannot be used with 'while'}}
|
|
try break // expected-error {{'try' cannot be used with 'break'}}
|
|
}
|
|
|
|
try throw // expected-error {{'try' must be placed on the thrown expression}} {{3-7=}} {{3-3=try }} expected-error {{expected expression in 'throw' statement}}
|
|
; // Reset parser.
|
|
|
|
try return // expected-error {{'try' cannot be used with 'return'}} expected-error {{non-void function should return a value}}
|
|
; // Reset parser.
|
|
|
|
try throw foo() // expected-error {{'try' must be placed on the thrown expression}} {{3-7=}} {{13-13=try }}
|
|
// expected-error@-1 {{thrown expression type 'Int' does not conform to 'ErrorProtocol'}}
|
|
try return foo() // expected-error {{'try' must be placed on the returned expression}} {{3-7=}} {{14-14=try }}
|
|
}
|
|
|
|
// Test operators.
|
|
func *(a : String, b : String) throws -> Int { return 42 }
|
|
let _ = "foo"
|
|
* // expected-error {{operator can throw but expression is not marked with 'try'}}
|
|
"bar"
|
|
let _ = try! "foo"*"bar"
|
|
let _ = try? "foo"*"bar"
|
|
let _ = (try? "foo"*"bar") ?? 0
|
|
|
|
|
|
// <rdar://problem/21414023> Assertion failure when compiling function that takes throwing functions and rethrows
|
|
func rethrowsDispatchError(handleError: ((ErrorProtocol) throws -> ()), body: () throws -> ()) rethrows {
|
|
do {
|
|
body() // expected-error {{call can throw but is not marked with 'try'}}
|
|
} catch {
|
|
}
|
|
}
|
|
|
|
// <rdar://problem/21432429> Calling rethrows from rethrows crashes Swift compiler
|
|
struct r21432429 {
|
|
func x(f: () throws -> ()) rethrows {}
|
|
func y(f: () throws -> ()) rethrows {
|
|
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}}
|
|
}
|
|
}
|
|
|
|
// <rdar://problem/21427855> Swift 2: Omitting try from call to throwing closure in rethrowing function crashes compiler
|
|
func callThrowingClosureWithoutTry(closure: Int throws -> Int) rethrows {
|
|
closure(0) // expected-error {{call can throw but is not marked with 'try'}}
|
|
}
|
|
|
|
func producesOptional() throws -> Int? { return nil }
|
|
let doubleOptional = try? producesOptional()
|
|
let _: String = doubleOptional // expected-error {{cannot convert value of type 'Int??' to specified type 'String'}}
|
|
|
|
func maybeThrow() throws {}
|
|
try maybeThrow() // okay
|
|
try! maybeThrow() // okay
|
|
try? maybeThrow() // expected-warning {{result of 'try?' is unused}}
|
|
_ = try? maybeThrow() // okay
|
|
|
|
let _: () -> Void = { try! maybeThrow() } // okay
|
|
let _: () -> Void = { try? maybeThrow() } // expected-warning {{result of 'try?' is unused}}
|
|
|
|
|
|
if try? maybeThrow() { // expected-error {{cannot be used as a boolean}} {{4-4=((}} {{21-21=) != nil)}}
|
|
}
|
|
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!}}
|
|
|
|
class X {}
|
|
func test(_: X) {}
|
|
func producesObject() throws -> AnyObject { return X() }
|
|
test(try producesObject()) // expected-error {{'AnyObject' is not convertible to 'X'; did you mean to use 'as!' to force downcast?}} {{26-26= as! X}}
|
|
|