Shouldn't `&self` be `ref self` to be consistent?

Wouldn't &self better be written ref self to be consistent with patterns elsewhere?


impl Foo {
    pub fn f(ref mut self) { ... }

so as to be consistent with:

let ref mut foo = an_object;

&T is consistent with &val inside patterns. &val matches a reference and puts the pointed to value in val.

But that's exactly the opposite of what happens for &self. self becomes a reference.

1 Like

Exactly! A pattern and value are meant to be the exact opposite. So the expression Some(1) makes an Option<u32>, while the pattern Some(val) matches some Option<u32>.

1 Like

Function parameters are patterns.

&self is a symtax sugar for self: &Self and nothing more. Shorter form was introduced as we write it every day.


I understand, all I'm saying is ref self would be more consistent sugar.


I'd say ref self is equally inconsistent with &self since it neither reduce nor adds up any reference.


The ref self means we have the current object by value but are binding self to a reference to it, which is different to what you think it will do.

Let's use this example:

struct Foo;

fn type_name<T>(_: T) -> &'static str {

impl Foo {
    fn ref_method(ref this: Self) {
        println!("ref method: {:?}", type_name(this));

    fn ref_borrow_method(ref this: &Self) {
        println!("ref borrow method: {:?}", type_name(this));

    fn ampersand_self(&self) {
        println!("ampersand self: {:?}", type_name(self));

fn main() {
    let f = Foo;
    // Foo::ref_method(f);  // ERROR: Use of moved value


The generated output is this:

ampersand self: "&playground::Foo"
ref borrow method: "&&playground::Foo"
ref method: "&playground::Foo"

If we had ref self (the ref_borrow_method() method) as syntactic sugar for a &Self parameter then we'd actually end up with the self variable being bound to a &&Self, adding one more level of indirection. Whereas if we had ref self: Self, the self variable would be bound to a &Self, but we would consume the Self object by value.

So it might feel more consistent, but using the ref keyword will add another level of indirection.


I think this "should" is correct and have often wished that Rust used &Self instead of &self (etc.) for the same reason. Of course, it's way too late to change something so fundamental about the language.


It's a bit unfair to come up with the example of ref this: &Self, because here you combine two things (& on the type and ref on the variable name). That's not what the original post was about.

@Michael-F-Bryan, what you showed is that the ref_method indeed returns "&playground:Foo", in the same way as the ampersand_self method does.

Considering that the syntactic sugar places the & before a variable name – and not before a type – I would agree with @tczajka's original post.

However, as ref this: &Self actually consumes the value, the ref syntax could be be dangerously misleading. Afterall &self is a special sort of syntax anyway, as @Hyeonu pointed out:

Nonetheless, I think @tczajka has a point here. I still prefer &self though (and dislike ref anyway).

1 Like

It should never be too late :stuck_out_tongue: (but I prefer &self anyway).

It's too late to implement without breaking Rust's guarantee of backward compatibility. Thus Rust avoids becoming a negative lesson in edition churn. (I'm looking at you, Python.)


Rust (so far) made an amazing job to correct errors from the past while maintaining backward compatibility (also because of the Editions system).

Either way: I like when people question language constructs (I often do that myself :sweat_smile:), and this forum should be a place to get (constructive) feedback on breaking ideas.

1 Like

This forum (URLO) is an okay place to initiate such exploratory discussions. The parallel Rust forum IRLO is for serious consideration of language and tooling (rustc, cargo, etc) changes; many of the language and tooling designers read that forum but seldom visit URLO.

I think the original post didn't mean to propose a language change, but was merely an interesting thought-experiment. For me, as a user, it showed up an interesting perspective.

There is no danger of seeing ref self in the next version of Rust, so I guess we shouldn't criticize the original idea/thought that badly. I find the idea interesting, so thumbs up from my side :+1:

That doesn't mean I want to change the language. I like &self.

1 Like

Me too! Given how often we need self: &Self it's a lot more convenient to be able to simply write &self.

I'm a bit surprised that this moves the parameter into the function (consumes it):

fn foo(ref x: Foo) {}

Wouldn't it make sense to treat the signature of this function as equivalent to the following, and not move the object into the function?

fn foo(x: &Foo)

After all, this works and doesn't consume:

let a = Foo;
let ref b = a;
let ref c = a;

Now that you say it, it surprises me too. :thinking:

But indeed it does (playground).

1 Like

The technical explanation is that passed parameters are value expressions but the initializer is a place expression.

Binding in place for function calls would be backwards-incompatible.

fn foo(ref mut x: i32) {
    *x = 0;

fn main() {
    // n.b. `i32` implements `Copy`
    let i = 42;
    assert_eq!(i, 42);

    let mut j = 42;
    let ref mut x = j;
    *x = 0;
    assert_eq!(j, 0);