Note that there's some discussion about the name of that proposal, because "optimization" gives the wrong idea (that it's optional or could depend on the backend).
Note that there's some discussion about the name of that proposal, because "optimization" gives the wrong idea (that it's optional or could depend on the backend).
"Any structures larger than x, or any structures marked with a marker type, are returned by the caller providing an outref to a buffer with correct size, and the callee directly writes the structure into that buffer."
Then you could just write normal code like
fn initialize() -> A {
// the initialization code
}
and it would just work? And it would reduce unnecessary copies in a lot of other situations too?
Given how much work has been put into this issue, and how much less convenient the proposed solutions are, I feel like I must be missing something.Essentially the problem is composability. If you are building a large type from a sequence of other large types, and one or more step is fallible, the normal return ABI breaks down very quickly.
AIUI, that's why MaybeUninit<T> exists. But even if you address the issue of it being unsafe to assert that a MaybeUninit has been initialized (which &out references could in principle solve) there are real problems with this; for example, MaybeUninit<T> has no niches or free-for-use padding even when T does, so you can't just "project" MaybeUninit to individual fields except in special cases. My understanding is that C++ partial initialization has the exact same issues in principle, they just don't come up as often because the standard for code correctness is a lot less rigorous.