Swift 6: Array Element Mutation and Data Race Warning

But I think COW is thread safe, right? I wrote an equivalent version using Swift concurrency and it compiles (note the var b = a line). I wonder what's the underlying difference between DispatchQueue version and my version? Does this example indicate Swift concurrency is more powerful?

@concurrent
func perform(_ fn: sending () -> Void) async {
    fn()
}

@MainActor
func test() async {
    var a = [1, 2, 3]
    var b = a 
    for i in 0..<a.count {
        await perform {
            a[i] = 0
        }
    }
}

The sending parameter is a workaround required even when there is no COW involved. See A limitation in RBI caused by closure isolation inference?.

An alternative version without `sending`

This compiles too.

@globalActor actor MyGlobalActor {
    static let shared = MyGlobalActor()
}

@MyGlobalActor
func test() async {
    var a = [1, 2, 3]
    var b = a
    for i in 0..<a.count {
        await perform { @MainActor in
            a[i] = 0
        }
    }
}

@MainActor
func perform(_ fn: @MainActor () -> Void) async {
    fn()
}