Modifying actor property in closure passed to `withCheckedContinuation`

Hello,

Reading this explanation, it seems that in an actor's isolated method, modifying one of the actor's properties in a closure passed to withCheckedContinuation is an intended use case.

And indeed, the following code compiles without any problem.

actor A1 {
    private var container: [CheckedContinuation<Void, Never>] = []
    func wait() async {
        await withCheckedContinuation { continuation in
            container.append(continuation)
        }
    }
}

However, if the container is not an array but a dictionary, the compiler gives me an error.

actor A2 {
    private var container: [Int: CheckedContinuation<Void, Never>] = [:]
    func wait() async {
        await withCheckedContinuation { continuation in
            container[1] = continuation
        }
    }
}

Actor-isolated property 'container' cannot be passed 'inout' to 'async' function call

Arrays and dictionaries are both structs so I don't see why one works but not the other. Does anyone have an idea?

Thanks,
Vincent

I think the problem here is the use of subscripts. I don't know enough about the use of subscripts and inout with actors to give a comprehensive answer but you'll get the same kind of error if you use an array subscript in your first example. So your examples aren't using the same mechanisms.

You can achieve the behavior of your second example by using updateValue method on the dictionary instead

actor A2 {
    private var container: [Int: CheckedContinuation<Void, Never>] = [:]
    func wait() async {
        await withCheckedContinuation { continuation in
            container.updateValue(continuation, forKey: 1)
        }
    }
}

Oh I did not realize that, thanks a lot! I'll use updateValue.

Wondering if someone knows what's special with subscript. The error message doesn't really make sense.

1 Like

Subscripts definitely shouldn't behave differently here, there's a bug in one direction or another!

Thanks, that's what it looked like to me :smile:
Not sure if they are really looked at, but filed an issue on GitHub: Cannot modify actor property from `withCheckedContinuation` closure when using subscript · Issue #63156 · apple/swift · GitHub
Wondering if also filing a feedback would make it more likely to be fixed.

1 Like