<div dir="ltr"><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, 10 Oct 2024 at 17:10, Walter Bright via Digitalmars-d <<a href="mailto:digitalmars-d@puremagic.com">digitalmars-d@puremagic.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 10/8/2024 10:42 PM, Manu wrote:<br>
> Can you show us some cases?<br>
<br>
I'd get infinite recursion with overload resolution, because the compiler will <br>
try and match the argument to `S` and `ref S`, made even more complicated with <br>
rvalue references enabled.<br>
<br>
The compiler would go into infinite recursion converting a ref to an rvalue and <br>
back to a ref again. There were maybe 10 or more functions in the recursion <br>
stack, looping through the heavy semantic routines.<br>
<br>
Another problem was failure to compile libmir:<br>
```<br>
source/mir/rc/ptr.d(395,15): Error: `mir.rc.ptr.castTo` called with argument <br>
types `(mir_rcptr!(C))` matches both:<br>
   source/mir/rc/ptr.d(275,13):     `mir.rc.ptr.castTo!(I, <br>
C).castTo(mir_rcptr!(C) context)`<br>
   and:<br>
   source/mir/rc/ptr.d(291,25):     `mir.rc.ptr.castTo!(I, <br>
C).castTo(immutable(mir_rcptr!(C)) context)`<br>
<br>
```<br>
If libmir breaks, that means other code will break, too. I eventually decided it <br>
was not a good idea to modify existing semantics (rvalue constructors exist and <br>
are used already), as who knows how much breakage that would ensue. Adding <br>
distinct syntax for the new semantics seemed like a much more practical approach.<br>
<br>
I.e. `this(S)` already is accepted by the compiler and is used.<br>
<br>
<br>
> The story you present is incomplete, let me enhance:<br>
> <br>
> struct S { ... }<br>
> struct Other { ... }<br>
> <br>
> this(ref S) // copy constructor<br>
> this(this)  // postblit<br>
> this(S)     // move constructor<br>
> ~this()     // destructor<br>
<br>
It's not that simple. You can have:<br>
<br>
```<br>
alias T = S;<br>
this(T);     // can't tell if move constructor by syntax<br>
```<br>
<br>
> this(Other) // move from other (Other is an rvalue here)<br>
> this(ref Other) // copy from other (Other is obviously a ref)<br>
<br>
Problems show up when `Other` is implicitly convertible to `S`.<br></blockquote><div><br></div><div>If the overload resolution rules don't prefer an exact match over a conversion, then something is very wrong with the overload selection rules. What situations cause those waters to become murky?</div><div><br></div><div>But, I think you actually missed my point here; I provided a ref and non-ref overload for Other... how do I move-construct from some OTHER type?</div><div>Move constructors can't just be for S s = otherS; that's obviously an important case, but it excludes an enormous range of the "move semantics" landscape.<br></div><div><br></div><div>The fact you're talking about a separate constructor type to identify the move case leads me to suspect that the rvalue semantic only applies to the argument to that particular function and nothing else?</div><div>That's not really "move semantics", that's just a move constructor... and I think I've completely misunderstood your DIP if this is correct?<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
> Likewise, I don't understand why opMove would be necessary to distinguish from <br>
> opAssign?<br>
<br>
Is `a = b` a move or a copy?<br></blockquote><div><br></div><div>is `b` an rvalue or an lvalue? (or had some special sauce tag it with a 'last-use' flag or anything like that)<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
> If you introduce opMove, then you'll end up with opIndexMove, opOpMove, etc.<br>
> Is that something you want? Assuming you want to avoid this; then I also imagine <br>
> solving for that issue would equally solve for the main constructor case?<br>
<br>
This is why I don't like implicit conversions for a struct - you wind up with <br>
impossible tangles of meaning. Oh, and rvalue to ref conversions, too.<br></blockquote><div><br></div><div>I don't feel like I have these problems in C++, which is far less constrictive. I have no way to know or assess whether any of the arrangements of rules you considered or tried actually arrange into a nice tight lattice or not... or if they were generally cohesive and well-formed. We're expected to accept that you tried every possible reasonable arrangement and conclusively determined that it's not workable. I have no idea how we can assess that for reality or not... :/</div></div></div>