Could you maybe share a bit more context on what kind of things you’re trying (in code examples, I guess) when reasoning about return-value-optimization in the context of Rust?
I know RVO mostly from (limited) C++ knowledge, but the situation in that language is a lot different because of implicit (expensive) copy constructors. RVO is important – for example – in particular to avoid expense of copy constructors (which could end up recursively copying a bunch of heap data); the stack size of objects also isn’t too large all that often, so that’s often only a minor concern.
C++ is also “fun” in how their (version of doing) moves is rather complex, sometimes requires explicit annotations (std::move
), and for example for RVO of a local variable, usage of the std::move
function can actually be detrimental.
So while e.g.
// Rust
let y = x.clone();
is Rust’s analogous syntax for C++’s
// C++
auto y = x;
whereas
// Rust
let y = x;
(for non-Copy
types) is more like
// C++
auto y = std::move(x);
With RVO in mind however, returning a local variable x
from a function in C++ should not use
// C++
return std::move(x);
but instead
// C++
return x;
but this absolutely does not mean that e.g.
// Rust
return x.clone();
would be an analogous choice in Rust. In Rust, there is no rule for any clone
-elision. Clone::clone
isn’t anything special at all anyway, it’s mostly a library-concept.
In case that’s what you were trying, i.e.
// Rust
return x.field.clone();
to check out whether some sort of “RVO” can kick in to eliminate that .clone()
, … not that does not work. But you shouldn’t need it anyway; just don’t do .clone()
when you don’t need it.
I’m reading your sentence of
if I am returning a struct member ( the return statement complains that there is no clone on the root object […] )
as that this above might possibly be what you tried, but of course this is only me guessing, and can be completely wrong. You simply don’t sufficiently explain at all what you were actually doing here, so I can’t possibly know 