Inside the body, I need to do value.foo = someFoo()
This works for simple structs but in more complex scenarios I need the type conforming to MyProtocol to be an actor.
I could do this by changing the protocol requirement to func updateFoo(_ newValue: Foo) async but this complicates the case when the type conforming to MyProtocol is a simple struct. Is there a way I can run a block of code that is isolated to the type conforming to MyProtocol if it is an actor, but still support having simple structs conform to MyProtocol?
Hmm, this could be challenging. To start, I'm curious what the actor conformance would look like here. A synchronous setter is usually a problem for anything with static isolation.
To conform your protocol using actor you would have use either @preconcurrency or nonisolated(unsafe), paired with isolated parameter in function (which you'll have to specify explicitly I guess). Both options turn off checks and might crash.
I'd say that open setters on protocols — especially if you expect it to conform to an actor — is better to be replaced with a method. This will give you much more flexibility, and will carry isolation by default, without the need to do some tricks with passing it.
BTW, I've run into a compiler crash when modified function to
error: compile command failed due to signal 11 (use -v to see invocation)
...
1. Apple Swift version 6.0 (swiftlang-6.0.0.9.10 clang-1600.0.26.2)
2. Compiling with the current language version
3. While evaluating request TypeCheckSourceFileRequest
4. While evaluating request TypeCheckFunctionBodyRequest
Please file an issue about that crash. I’ve also run into many crashes when using sending and/or isolated parameters with 6.0. It makes coming up with solutions to tricky isolation problems like this one particularly hard.