mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
164 lines
6.8 KiB
Swift
164 lines
6.8 KiB
Swift
// RUN: %target-swift-frontend -enable-experimental-concurrency -target %target-swift-5.1-abi-triple %s -emit-sil -o /dev/null -verify
|
|
// RUN: %target-swift-frontend -enable-experimental-concurrency -target %target-swift-5.1-abi-triple %s -emit-sil -o /dev/null -verify -strict-concurrency=targeted
|
|
// RUN: %target-swift-frontend -enable-experimental-concurrency -target %target-swift-5.1-abi-triple %s -emit-sil -o /dev/null -verify -strict-concurrency=complete
|
|
|
|
// REQUIRES: concurrency
|
|
|
|
//// Basic definitions and parsing
|
|
|
|
func reasyncFunction(_: () async -> ()) reasync {}
|
|
|
|
func reasyncRethrowsFunction(_: () async throws -> ()) reasync rethrows {}
|
|
|
|
func rethrowsReasyncFunction(_: () async throws -> ()) rethrows reasync {}
|
|
// expected-error@-1 {{'reasync' must precede 'rethrows'}}{{65-73=}}{{56-56=reasync }}
|
|
|
|
func asyncReasyncFunction(_: () async throws -> ()) async reasync {}
|
|
// expected-error@-1 {{'reasync' has already been specified}}{{59-67=}}
|
|
|
|
func reasyncParam(_: () reasync -> ()) {}
|
|
// expected-error@-1 {{only function declarations may be marked 'reasync'; did you mean 'async'?}}{{25-32=async}}
|
|
|
|
//// Invalid cases
|
|
|
|
func noReasyncParams() reasync {}
|
|
// expected-error@-1 {{'reasync' function must take an 'async' function argument}}
|
|
|
|
//// Method override attribute checking
|
|
|
|
class Base {
|
|
func reasyncMethod(_: () async -> ()) reasync {}
|
|
// expected-note@-1 {{overridden declaration is here}}
|
|
}
|
|
|
|
class Derived : Base {
|
|
override func reasyncMethod(_: () async -> ()) async {}
|
|
// expected-error@-1 {{override of 'reasync' method should also be 'reasync'}}
|
|
}
|
|
|
|
//// Reasync call site checking
|
|
|
|
func asyncFunction() async {}
|
|
|
|
func callReasyncFunction() async {
|
|
reasyncFunction { }
|
|
await reasyncFunction { } // expected-warning {{no 'async' operations occur within 'await' expression}}{{3-9=}}
|
|
|
|
reasyncFunction { await asyncFunction() }
|
|
// expected-error@-1:3 {{expression is 'async' but is not marked with 'await'}}{{3-3=await }}
|
|
// expected-note@-2:3 {{call is 'async'}}
|
|
|
|
await reasyncFunction { await asyncFunction() }
|
|
}
|
|
|
|
enum HorseError : Error {
|
|
case colic
|
|
}
|
|
|
|
func callReasyncRethrowsFunction() async throws {
|
|
reasyncRethrowsFunction { }
|
|
await reasyncRethrowsFunction { }
|
|
// expected-warning@-1 {{no 'async' operations occur within 'await' expression}}{{3-9=}}
|
|
try reasyncRethrowsFunction { }
|
|
// expected-warning@-1 {{no calls to throwing functions occur within 'try' expression}}
|
|
try await reasyncRethrowsFunction { }
|
|
// expected-warning@-1 {{no 'async' operations occur within 'await' expression}}{{7-13=}}
|
|
// expected-warning@-2 {{no calls to throwing functions occur within 'try' expression}}
|
|
|
|
reasyncRethrowsFunction { await asyncFunction() }
|
|
// expected-error@-1:3 {{expression is 'async' but is not marked with 'await'}}{{3-3=await }}
|
|
// expected-note@-2:3 {{call is 'async'}}
|
|
|
|
await reasyncRethrowsFunction { await asyncFunction() }
|
|
try reasyncRethrowsFunction { await asyncFunction() }
|
|
// expected-warning@-1 {{no calls to throwing functions occur within 'try' expression}}
|
|
// expected-error@-2:3 {{expression is 'async' but is not marked with 'await'}}{{7-7=await }}
|
|
// expected-note@-3:7 {{call is 'async'}}
|
|
|
|
try await reasyncRethrowsFunction { await asyncFunction() }
|
|
// expected-warning@-1 {{no calls to throwing functions occur within 'try' expression}}
|
|
|
|
reasyncRethrowsFunction { throw HorseError.colic }
|
|
// expected-error@-1 {{call can throw but is not marked with 'try'}}
|
|
// expected-note@-2 {{call is to 'rethrows' function, but argument function can throw}}
|
|
await reasyncRethrowsFunction { throw HorseError.colic }
|
|
// expected-error@-1 {{call can throw but is not marked with 'try'}}
|
|
// expected-note@-2 {{call is to 'rethrows' function, but argument function can throw}}
|
|
// expected-warning@-3 {{no 'async' operations occur within 'await' expression}}{{3-9=}}
|
|
try reasyncRethrowsFunction { throw HorseError.colic }
|
|
try await reasyncRethrowsFunction { throw HorseError.colic }
|
|
// expected-warning@-1 {{no 'async' operations occur within 'await' expression}}{{7-13=}}
|
|
|
|
reasyncRethrowsFunction { await asyncFunction(); throw HorseError.colic }
|
|
// expected-error@-1 {{call can throw but is not marked with 'try'}}
|
|
// expected-note@-2 {{call is to 'rethrows' function, but argument function can throw}}
|
|
// expected-error@-3:3 {{expression is 'async' but is not marked with 'await'}}{{3-3=await }}
|
|
// expected-note@-4:3 {{call is 'async'}}
|
|
await reasyncRethrowsFunction { await asyncFunction(); throw HorseError.colic }
|
|
// expected-error@-1 {{call can throw but is not marked with 'try'}}
|
|
// expected-note@-2 {{call is to 'rethrows' function, but argument function can throw}}
|
|
try reasyncRethrowsFunction { await asyncFunction(); throw HorseError.colic }
|
|
// expected-error@-1:3 {{expression is 'async' but is not marked with 'await'}}{{7-7=await }}
|
|
// expected-note@-2:7 {{call is 'async'}}
|
|
try await reasyncRethrowsFunction { await asyncFunction(); throw HorseError.colic }
|
|
}
|
|
|
|
func computeValue() -> Int {}
|
|
func computeValueAsync() async -> Int {}
|
|
|
|
func reasyncWithAutoclosure(_: @autoclosure () async -> Int) reasync {}
|
|
|
|
func callReasyncWithAutoclosure1() {
|
|
// expected-note@-1 2{{add 'async' to function 'callReasyncWithAutoclosure1()' to make it asynchronous}}
|
|
reasyncWithAutoclosure(computeValue())
|
|
await reasyncWithAutoclosure(await computeValueAsync())
|
|
// expected-error@-1 {{'async' call in a function that does not support concurrency}}
|
|
|
|
await reasyncWithAutoclosure(computeValueAsync())
|
|
// expected-error@-1:32 {{expression is 'async' but is not marked with 'await'}}{{32-32=await }}
|
|
// expected-note@-2:32 {{call is 'async' in an autoclosure argument}}
|
|
// expected-error@-3 {{'async' call in a function that does not support concurrency}}
|
|
}
|
|
|
|
func callReasyncWithAutoclosure2() async {
|
|
reasyncWithAutoclosure(computeValue())
|
|
await reasyncWithAutoclosure(await computeValueAsync())
|
|
|
|
await reasyncWithAutoclosure(15 + computeValueAsync())
|
|
// expected-error@-1:32 {{expression is 'async' but is not marked with 'await'}}{{32-32=await }}
|
|
// expected-note@-2:37 {{call is 'async' in an autoclosure argument}}
|
|
}
|
|
|
|
//// Reasync body checking
|
|
|
|
// FIXME: Need tailored diagnostics to handle 'reasync' vs 'sync'.
|
|
|
|
func invalidReasyncBody(_: () async -> ()) reasync {
|
|
// expected-note@-1 {{add 'async' to function 'invalidReasyncBody' to make it asynchronous}}
|
|
_ = await computeValueAsync()
|
|
// expected-error@-1 {{'async' call in a function that does not support concurrency}}
|
|
}
|
|
|
|
func validReasyncBody(_ fn: () async -> ()) reasync {
|
|
await fn()
|
|
}
|
|
|
|
//// String interpolation
|
|
|
|
func reasyncWithAutoclosure2(_: @autoclosure () async -> String) reasync {}
|
|
|
|
func callReasyncWithAutoclosure3() {
|
|
let world = 123
|
|
reasyncWithAutoclosure2("Hello \(world)")
|
|
}
|
|
|
|
//// async let
|
|
|
|
func callReasyncWithAutoclosure4(_: () async -> ()) reasync {
|
|
await reasyncFunction {
|
|
async let x = 123
|
|
|
|
_ = await x
|
|
}
|
|
}
|