Carbon doesn't do the next logical optimization, and only converts a const& parameter to a value. If a function has parameter "const struct_with_two_floats&", and reads it, calls puts(), then reads it again, Carbon will not be willing to optimize out the "redundant" read.
It seems odd to break with C++ semantics for small parameters only; I'd expect it to either break for all parameters or no parameters.
EDIT: looks like Carbon is not doing this optimization for small values either. Its docs on parameters say, "This binding will be implemented using a pointer, unless it is legal to copy and copying is cheaper". And the OP link says, "the compiler is allowed to convert that to a T [copy] under the as-if rule." That seems like no extra optimization is enabled other than changing the function calling convention. And the "as-if" rule would require looking at the function body to check if the value could be changed (by things like puts()). I hope my understanding is wrong because this does not make sense. The word "legal" is ambiguous, so hopefully they mean something else!
It seems odd to break with C++ semantics for small parameters only; I'd expect it to either break for all parameters or no parameters.
EDIT: looks like Carbon is not doing this optimization for small values either. Its docs on parameters say, "This binding will be implemented using a pointer, unless it is legal to copy and copying is cheaper". And the OP link says, "the compiler is allowed to convert that to a T [copy] under the as-if rule." That seems like no extra optimization is enabled other than changing the function calling convention. And the "as-if" rule would require looking at the function body to check if the value could be changed (by things like puts()). I hope my understanding is wrong because this does not make sense. The word "legal" is ambiguous, so hopefully they mean something else!