That's been done before. The original Modula 1 compiler had that. In a language where the default parameter mode is a read-only reference, it's an obvious optimization.
The reverse is true. Anything passed by value can be treated as const reference by the compiler if the compiler knows enough about access and lifetime. The compiler must be able to determine that the parameter is neither deallocated nor modified while the function is using it. Rust compilers should be able to do that.
Derived types (structures etc) and non-standard scalar types are passed in a register if and only if their memory- stored image is register-size aligned and fits into a register. [...]
All other arguments are passed by reference. The callee must copy the argument if it writes it or takes its address."
The reverse is true. Anything passed by value can be treated as const reference by the compiler if the compiler knows enough about access and lifetime. The compiler must be able to determine that the parameter is neither deallocated nor modified while the function is using it. Rust compilers should be able to do that.