I feel like we discussed exactly this at dconf fairly extensively, with pictures and diagrams and stuff...

Just write `T move(ref T)` as an intrinsic.
There's potentially more work to do than this operation; the intrinsic will also (in the future) include internal logic to end the lifetime of the memory region, and possibly logic to record the transfer of ownership for the value. This is all not expressible in-language... it's most appropriate as an intrinsic; this is mega-fundamental stuff. Remember, the goal is to murder core.lifetime with fire.

We don't want a function for this, no call/ret, do not want to pollute the program flow in that way and definitely don't want to create weird program flow while stepping through code while debugging. Intrinsic that initially just strips off ref, and can be enhanced with lifetime management logic in future.

On Tue, 1 Oct 2024, 02:11 Walter Bright via Digitalmars-d, <digitalmars-d@puremagic.com> wrote:
I've been implementing move constructors. They are working, at least on my test
cases so far. They are distinguished by a copy constructor takes its argument by
ref, and a move constructor by value:

```
struct S
{
     this(ref S); // copy constructor
     this(S);     // move constructor
}
```
So far, so good. Consider:
```
void phone(S s)
{
     S t = s;  // copy constructor
}
```
But what if we want to initialize `t` via a move constructor? Somehow, `s` has
to be converted from an lvalue to an rvalue. This is done via the function rvalue():
```
S rvalue(ref S s) { return s; }

S t = rvalue(s);
```
Unfortunately, rvalue() gives us this:
```
S __copytmp = 0;
this(&__copytmp,&s);  // copy construction of s
*__H1D1 = __copytmp;
return __H1D1;
```
which is correct, but not what we want, which is:
```
return &s;
```
and also not pass an extra hidden parameter for the return value, aka __H1D1.

I have thought of several ways to do this, none of which seem particularly
attractive as they are all not expressible in conventional D. I won't say what
they are in order to not bias anyone.

So, does anyone have any brilliant ideas for how to make the compiler treat an
lvalue as an rvalue?

P.S. C++ uses the std::move function to do it:

https://learn.microsoft.com/en-us/cpp/standard-library/utility-functions?view=msvc-170#move

which relies on rvalue references:

https://learn.microsoft.com/en-us/cpp/cpp/rvalue-reference-declarator-amp-amp?view=msvc-170

which is a major feature which I prefer to avoid.