Once things have a name and you can take their address they are no longer an rvalue. It would require a much more sophisticated type system to do this automatically (when you pass a reference to another function, does it capture it?). It would also be non-obvious when you were moving. Think of Java style escape analysis vs C++ stack allocation (implicit vs explicit). There is one case where the compiler will do this though, when you return a stack allocated value from a function, it is implicitly moved.
The argument here is that in the body of the constructor the developer probably doesn't use s, so a trivial analysis of the function can say "oh, it doesn't matter if I destroy s, so in the one place where it is used I'll just move it". It doesn't then matter if it is obvious it happens or not, because the semantics of the program wouldn't be maintained (and honestly, I'd argue it is never quite obvious when what happens in different contexts given the large number of rules involved: you kind of just have to have some trust).
There are a number of considerations because the compiler can't prove it in general without augmenting the type system or doing whole-program analysis.
Do you allow, but not require, the compiler to do this substitution whenever it can prove a value is never used again? This is unreliable across build options and compilers so it would be unwise to depend on it. There is an opportunity here for a tool that could identify places where you could insert move, perhaps even a -W option for the trivial cases such as above, but I am not convinced the language should allow the compiler to do this.
Do you make it mandatory and add more special cases for the compiler to have to implement? This would require the compiler to track references to make sure they don't get passed to some other function. It would need someone to codify the special cases in the standard and this might be very difficult. It would also be fragile, there would be cases where implicit move used to kick in but some added function call inhibits it even though a move is still the right thing to do.
You seem to be assuming that optimizations are only of value if they can be depended on happening consistently as a defined property of the language on every single platform for which there exists a compiler: in practice, compilers perform numerous optimizations (such as static branch prediction) that only work probabilistically even for the case of a specific version of a specific compiler on a specific operating system; I know of very few people (maybe you are one of them, however) who consider this to be a detriment. For a more obvious comparison: yes, I could sit around constructing object pools in my Java program to avoid heap allocations and their associated garbage collection penalty, but if rudimentary escape analysis manages to pick up a lot of the value, even if "fragile" or nondeterministic, I might not need to spend the time anymore to worry about that kind of detail in my software as the cost benefit analysis shows that the toolchain is now a more efficient usage of resources towards that issue (I could be spending my energy working on algorithm design, for example, instead of object pools). As long as the semantics of the language support the optimization, and as it doesn't seem to be difficult to implement, it would be useful to have the compiler perform this optimization for the developer, and one would expect such an optimization to either already be there or be "in the works".
This is a very different kind of optimization than the other things you are talking about. This is something that is operating at a high level and potentially has implications that might not be obvious. You are changing the type of something and effecting the function overloads which are resolved. I think its important for what functions you are calling to be deterministic. My previous post was just touching on what possible value can be gained from allowing this and my conclusion is that it would be very little.
Also, your example of escape analysis is precisely because Java doesn't allow you to express what you are wanting to do, whereas C++ does allow you to express moves.
edit: I would compare this to C++'s copy elision, but that has a very high value and is much less intrusive.
I understand that, but it's clearly not used in the body. I was hoping it would be a legal and implemented optimization.
move calls strike me as ugly and kinda dangerous. What if you do wind up wanting to refer to s in the body later on? It'd be nice if the compiler just handled it.