Thx!
Right but this is sugar for one part of the more general task group APIs. This desire for lexical scope checking isn't new or specific to this proposal: we ideally want the same thing in the withUnsafePointer APIs, withoutActuallyEscaping, etc. In practice, those APIs aren't graced with syntactic sugar and don't provide that static guarantee of correctness, but they are highly precedented and safe enough in practice.
My understanding is that the failure can still be handled "safely" with a dynamic check. I bet that future work on ownership types would even allow directly expressing the nice thing with static checks.
I agree that this sort of syntax optimization requires a language feature, but I personally don't think it justifies it. The type obfuscation and magic behavior may look great in small examples, but it add surprising behavior.
I don't see why this should be required: unless I'm missing something, a SIL pass should be able to do the same thing with a simple escape analysis (similar stack allocation of classes). This would be a generally useful thing, instead of being tied to one syntax.
But the base proposal already has a thing in its task group API.
Right, this is a sugar only feature 
Awesome, that's great, I'm glad that checking is in place. Is there any reason you prefer this to be a special parallel reimplementation of the same logic, instead of having it just fall out of the existing closure logic?
Ok, but shouldn't it be possible to have multiple executors and for them to interoperate?
This is one of the big idealogical arrows through the set of proposals that I still don't understand. The proposals seem to imply that actors and structured concurrency will be "the" way to do concurrency in Swift. This is exciting, but of course the reality is that we'll have code using them with a mix of pthreads, GCD, and lots of other ad-hoc stuff over time. I don't see an obvious reason why the notion of "structured concurrency" needs to be tied to "the global executor" as proposed - it seems simpler and more flexible to keep these things orthogonal.
Such an approach seems simpler and easier to explain, allows partial adoption of new features (e.g. when you have an existing executor-like-thing you have to use), and forces more orthogonality into the design. For example, less special cases for the "spawn one thing" case means that the general task group API would benefit as well.
Soapbox: "Simple things that compose" is an important design principle that helps shape "today" problems well while allowing for unplanned "future" problems to work out well. Monolithic designs can be finely honed for the today case, but are less adaptable as the language and world around it evolves.
Ok, I'm glad that there is some answer here, but I don't see why this is a great design: The transfer doesn't happen at the declaration of the variable, it happens when the async let is executed, and the two points can be very distant in the code. With this approach, the attribute would be better spelled UnsafeTransferrable since it is a property of the declaration and not a property of a use. Furthermore, this approach really doesn't work well with rvalues in general - things like values returned from functions, arguments to the current function that are being passed into the async let, etc.
In contrast, if you go with a closure based design (of any sort), you'd have this behavior:
func test(object3: MyClass) async { // Arguments are fine!
let object = MyClass()
let object2 = MyClass() // Ok, these are just declarations.
....
let x = spawn { object.doSomething() } // error, object used from concurrency code has non-ActorSendable type MyClass
let y = spawn { [@UnsafeTransfer object2] in object2.doSomething() }
// Works with arbitrary rvalues
let z = spawn { [@UnsafeTransfer object3] in object3.doSomething() }
let z2 = spawn { [@UnsafeTransfer object4 = foo()] in object4.doSomething() }
I think it is very nice that this all dovetails with existing syntax and programming language concepts we already have, rather than introducing a basket of new special cases and concepts. It also clearly delineates where the concurrency boundaries / captures are and allows library-based extensibility.
In any case, I can see that there are tradeoffs here. Given that this is sugar, I would recommend splitting this out of the base "structured concurrency" feature and tackle this in a follow up once we get some experience with the base proposal.
-Chris