<div dir="ltr"><div>I guess I forgot that C++ ref counted pointers (pre-11) generally have a move version of the type. Thanks for pointing that out.<br><br></div>I agree it would be odd to copy that design (Rc/RcTemp) in a language which has move semantics by default. I wonder if we could come up with _some_ design that would be better than the current one. My reasoning is that copy-with-increment is the (overwhelmingly) common case for ref-counted pointers and so should be easier/prettier than the less common case (moving). One could argue that the more efficient case (moving) should be prettier and I think that is valid. I'm not sure how to square the two arguments. I do think this deserves more thought than just accepting the current (`.clone()`) situation - I think it is very un-ergonimic. Having two types rather than two copying mechanisms seems more preferable to me, but I hope there is a better solution.<br>
</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Sat, Jun 21, 2014 at 6:21 PM, Cameron Zwarich <span dir="ltr"><<a href="mailto:zwarich@mozilla.com" target="_blank">zwarich@mozilla.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="">On Jun 20, 2014, at 11:06 PM, Nick Cameron <<a href="mailto:lists@ncameron.org">lists@ncameron.org</a>> wrote:<br>

<br>
> zwarich: I haven't thought this through to a great extent, and I don't think here is the right place to plan the API. But, you ought to still have control over whether an Rc pointer is copied or referenced. If you have an Rc<T> object and pass it to a function which takes an Rc<T>, it is copied, if it takes a &Rc<T> or a &T then it references (in the latter case with an autoderef-ref). If the function is parametric over U and takes a &U, then we instantiate U with either Rc<T> or T (in either case it would be passed by ref without an increment, deciding which is not changed by having a copy constructor). If the function takes a U literal, then U must be instantiated with Rc<T>. So, you still get to control whether you reference with an increment or not.<br>

><br>
> I think if Rc is copy, then it is always copied. I would not expect it to ever move. I don't think that is untenable, performance wise, after all it is what everyone is currently doing in C++. I agree the second option seems unpredictable and thus less pleasant.<br>

<br>
</div>Copying on every single transfer of a ref-counted smart pointer is definitely *not* what everyone is doing in C++. In C++11, move constructors were added, partially to enable smart pointers to behave sanely and eliminate extra copies in this fashion (albeit in some cases requiring explicit moves rather than implicit ones like in Rust).<br>

<br>
Before that, it was possible to encode this idiom using a separate smart pointer for the expiring value. WebKit relies on (or relied on, before C++11) a scheme like this for adequate performance:<br>
<br>
<a href="https://www.webkit.org/coding/RefPtr.html" target="_blank">https://www.webkit.org/coding/RefPtr.html</a><br>
<br>
In theory, you could encode such a scheme into this “always copy on clone" version of Rust, where Rc would always copy, and RcTemp wouldn’t even implement clone, and would only be moveable and convertible back to an Rc. However, it seems strange to go out of your way to encode a bad version of move semantics back into a language that has native move semantics.<br>

<span class="HOEnZb"><font color="#888888"><br>
Cameron</font></span></blockquote></div><br></div>