[rust-dev] Fwd: &self/&mut self in traits considered harmful(?)

Sebastian Gesemann s.gesemann at gmail.com
Mon Jun 16 07:32:12 PDT 2014

The following message got sent to Patrick instead to the list by mistake.
Sorry, Patrick!

---------- Forwarded message ----------
From: s.gesemann at gmail.com
Date: Mon, Jun 16, 2014 at 4:29 PM
Subject: Re: [rust-dev] &self/&mut self in traits considered harmful(?)
To: Patrick Walton <pcwalton at mozilla.com>

On Sat, Jun 14, 2014 at 2:46 AM, Patrick Walton wrote:
> I have filed RFC #118 for this:
> https://github.com/rust-lang/rfcs/pull/118
> Patrick

Bold move. But I'm not convinced that this is a good idea. I may be
missing something, but forcing a move as opposed to forcing an
immutable reference seems just as bad as an approach. Also, I'm not
sure why you mention C++ rvalue references there. References in C++
are not objects/values like C++ Pointers or References in Rust. They
are auto-borrowing and auto-deref'ing non-values, so to speak. These
different kinds of L- and Rvalue references combined with overloading
is what makes C++ enable move semantics.

I think one aspect of the issue is Rust's Trait system itself. It
tries to kill two birds with one stone: (1) Having "Interfaces" with
runtime dispatching where Traits are used as dynamically-sized types
and (2) as type bound for generics. Initially, I found this to be a
very cool Rust feature. But now, I'm not so sure about that anymore.
Back in 2009 when "concepts" were considered for C++ standardization,
I spent much time on understanding the intricacies of that C++ topic.
This initial "concepts" design also tried to define some type
requirements in terms of function signatures. But this actually
interacted somewhat badly with rvalue references (among other things)
and I think this is one of the reasons why "concepts lite" (a new and
simplified incarnation of the concepts design, expected to augment
C++1y standard in form of a technical report) replaced the function
signatures with "usage patterns". As a user of some well-behaved type,
I don't really care about what kind of optimizations it offers for +
or * and how they work. I'm just glad that I can "use" the "pattern"
x*y where x and y refer to instances of some type. Whether the
implementer of that type distinguishes between lvalues and rvalues via
overloading or not is kind of an implementation detail that does not
affect how the type is being used syntactically. So, I expect "C++
concepts lite" to be able to specify type requirements in terms of
"usage patters" in a way that it allows "models" of these "concepts"
to satisfy the requirements in a number of ways (with move
optimizations being optional but possible).

Another thing I'm not 100% comfortable with (yet?) is the funky way
references are used in Rust in combination with auto-borrowing (for
operators and self at least) and auto-deref'ing while at the same
time, they are used as "values" (like C++ pointers as opposed to C++
references). I've trouble putting this into words. But it feels to me
like the lines are blurred which could cause some trouble or bad

Assuming this RFC is accepted: How would I have to implement Add for a
custom type T where moving doesn't make much sense and I'd rather use
immutable references to bind the operands? I could write

   impl Add<&T,T> for &T {...}

but it seems to me that this requires explicit borrowing in the user code à la

   let x: T = ...;
   let y: T = ...;
   let c = &x + &y;

Or is this also handled via implicit borrowing for operators (making
operators a special case)?

Still, I find it very weird to impl Add for &T instead of T and have
this asymmetry between &T and T for operands and return value.

Can you shed some more light on your RFC? Maybe including examples? A
discussion about the implications? How it would affect Trait-lookup,
implicit borrowing etc? What did you mean by "The AutorefArgs stuff in
typeck will be removed; all overloaded operators will typecheck as
though they were DontAutorefArgs."? Many thanks in advance!


More information about the Rust-dev mailing list