Repository navigation
Conversation
4lmighty
left a comment
There was a problem hiding this comment.
The source-order/eager-evaluation direction is right, and Build/Style are green, but I don't think this launch mapping is safe to freeze yet. I see two semantic blockers.
First, the canonical shape go(f(prepared_args...)) still calls the C++ function f before go(...). This happens to delay the function body only if every translated callee is guaranteed to be a true lazy C++ coroutine whose body cannot execute during invocation. That invariant is not stated in this contract, and a non-coroutine wrapper that returns an eo::func<> can execute side effects synchronously before launch. Either make the translated-function coroutine invariant explicit and enforce/test it, or make the launch boundary robust by registering an already-prepared thunk/factory whose actual function invocation occurs after launch.
Second, the pointer-receiver rule (auto* receiver = &x) and, more generally, prepared pointer/reference arguments can outlive their C++ local storage once the goroutine runs asynchronously. Go escape semantics keep such storage alive; the current raw-pointer mapping does not. The function-literal paragraph only mentions closure lifetime extension, but this issue also applies to method receivers and ordinary pointer arguments. Until general escaping-local lowering is frozen, this contract should either scope these cases out explicitly or define the required lifetime-preserving storage rule.
I would keep the current adjacent-temp/source-order rule. The remaining issue is making the actual launch boundary and escaping-storage boundary explicit enough that the frozen mapping cannot silently depend on C++ lifetime/coroutine accidents.
Summary
gostatementsMotivation
A naive translation such as
go([&] { f(x()); })evaluatesx()after launch, which changes Go semantics. Go evaluates the function value and call arguments in the launching goroutine before the new goroutine begins executing the function body.This PR freezes that source-shape rule without adding runtime magic:
go(...)remains the launch primitive, while translators make the pre-launch evaluation boundary explicit.Scope
This PR freezes goroutine call evaluation and launch shape. General Go closure lifetime extension remains governed by the existing translation lifetime boundaries and is not expanded here.