In C++, expr.field is an lvalue iff expr is an lvalue. This is not the case in Rust; expr.field is always a place (i.e., an lvalue). You can always assign to places. Meanwhile, you can take the reference of anything, which, when we take the reference of a value, produces a reference to the stack. We can dereference the pointer to obtain a place. This is why the following is valid Rust, and should be valid Rust:
*&mut 23 = 7;
This is a nop, because it only fusses around on the stack, unobservable from the outside. I also think it should be linted against, because it’s dead code.
On the other hand, you suggest that assigning to values should be allowed. On one hand, I am ok with this, because we’d just spit out a dead code warning and move on with our lives. But then you’re allowed to write bizarre things like
const C: u8 = 0;
C = 1;
which I think should be a hard error, like in C++, for our collective sanity. As much as I think const items are really just a typed #define, I think we should stick to some degree of common-sense usage.
I think I’d like to hear other internals folks weigh in on this, since I think a lot of this comes down to a matter of taste, and what is a lint versus a hard error.