I am trying to understand how are the values exactly passed around. When I pass a large struct to a function does it pass a mutable reference behind the schenes or actually creates a new struct identical to the one I just passed in ?
Conceptually, it creates a new struct identical to the one you passed in (a shallow copy, if it contains things like
I say "conceptually" because there are two answers to this question: the behavior of the language, and the behavior of a particular set of compiler optimizations. In practice, if you compile without
--release, you will get code that literally copies the entire struct to a new location. With optimizations enabled, however, it depends on context.
I have never seen
rustc optimize the passing of a large argument struct by passing a reference. It's not clear to me that this optimization is possible (as the callee would need to own the space for the struct). Returning a struct can often be done without copying, as the caller passes in a pointer to some uninitialized memory where the struct should be deposited.
However, if the function you're calling gets inlined by the compiler, this stops mattering, and the "passing" of the struct usually disappears completely.
rustc is pretty aggressive about inlining.
If you're asking this question because of performance concerns, if you can pass a struct by reference or owned pointer (such as
Box), and the struct is bigger than a few pointers in size, it will generally be faster than passing it by value, and this will be true whether or not the optimization gods smile on you today.
Clippy also has a helpful lint for finding where pass-by-value is likely to be faster. Their heuristic is 'if the value is
Copy and is smaller than two general purpose registers'.