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
|
// RUN: %target-swift-frontend -enable-experimental-concurrency -disable-availability-checking %s -emit-sil -o /dev/null -verify
// RUN: %target-swift-frontend -enable-experimental-concurrency -disable-availability-checking %s -emit-sil -o /dev/null -verify -strict-concurrency=targeted
// RUN: %target-swift-frontend -enable-experimental-concurrency -disable-availability-checking %s -emit-sil -o /dev/null -verify -strict-concurrency=complete
// RUN: %target-swift-frontend -enable-experimental-concurrency -disable-availability-checking %s -emit-sil -o /dev/null -verify -strict-concurrency=complete -enable-upcoming-feature RegionBasedIsolation
// REQUIRES: concurrency
// REQUIRES: asserts
//// 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}}
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}}
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}}
// 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}}
try reasyncRethrowsFunction { throw HorseError.colic }
try await reasyncRethrowsFunction { throw HorseError.colic }
// expected-warning@-1 {{no 'async' operations occur within 'await' expression}}
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
}
}
|