I cannot get this simple while loop with 2 conditions to compile:
actor Actor1 {
func isBusy() -> Bool { false }
}
actor Actor2 {
func isBusy() -> Bool { false }
}
let a1 = Actor1()
let a2 = Actor2()
while await a1.isBusy() && await a2.isBusy() {
// 'await' cannot appear to the right of a non-assignment operator
// 'await' in an autoclosure that does not support concurrency
// Actor-isolated instance method 'isBusy()' can not be referenced from a non-isolated context
}
while (await a1.isBusy()) && (await a2.isBusy()) {
// 'await' in an autoclosure that does not support concurrency
// Actor-isolated instance method 'isBusy()' can not be referenced from a non-isolated context
}
while await a1.isBusy() {
// One condition compiles fine
}
Does anybody have any recommendations?
tera
2
I believe that should be:
while await a1.isBusy() && a2.isBusy() {
...
}
But that doesn't work (compiler bug?)
Perhaps this as a workaround:
while true {
if !(await a1.isBusy()) { break }
if !(await a2.isBusy()) { break }
...
}
BTW, while busy looks like a busy waiting anti-pattern.
1 Like
I agree the example looks like an anti-pattern, but my actual usage of it isn't and that's beyond the scope of this question. I simply would like to know the appropriate syntax. If the appropriate syntax doesn't work I can file a compiler bug.
somu
(somu)
5
I thought && would work, not sure why it doesn't (is it a bug?).
The following code compiles ok, see if it matches your expectation.
while await a1.isBusy(),
await a2.isBusy() {
}
1 Like
pyrtsa
(Pyry Jahkola)
6
You could replace && with a comma , in the first example. I think it's the @autoclosure of the rhs parameter to && which can't currently support async.
3 Likes
tera
8
Good catch. This example proves your finding:
extension Bool {
static func & (a: Bool, b: Bool) -> Bool {
a && b
}
}
func foo() async {
while await a1.isBusy() & a2.isBusy() { // compiles ok
}
}
extension Bool {
static func & (a: Bool, b: @autoclosure () -> Bool) -> Bool {
a && b()
}
}
func foo() async {
while await a1.isBusy() & a2.isBusy() { // Error
}
}