Whats the mean of &mut *smth?

Similar situation as your OP, the generic parameter doesn't reborrow when instantiated with a &mut _.

See also.

    let works: &mut _ = dst;
    let works: &mut _ = dst;
    
    let fails_second_time: _ = dst;
    let fails_second_time: _ = dst;
3 Likes

Indeed, a good rule of thumb in my experience is that function arguments do create an implicit re-borrow only if the “&mut” is written explicitly in the signature and doesn’t come out of instantiating/inferring a generic.

Of course it’s not really about the literal appearance of the signature… it’s actually only about type inference [1], and another interesting case to look at is that

fn borrow<T>(_: T) {}

fn foo2() {
    let mut i = 0;
    let dst = &mut i;
    borrow::<&mut _>(dst);
    borrow(dst);
}

does work again, since the &mut is provided explicitly and no longer needs to be inferred.

I personally hope, this distinction could be eliminated one day, it certainly doesn’t serve any purpose, and seems more like a kind of ”this is the best we could manage in our compiler implementation” kind of deal. It’s no the worst thing in the world, as you could always explicitly re-borrow as

fn borrow<T>(_: T) {}

fn foo3() {
    let mut i = 0;
    let dst = &mut i;
    borrow(&mut *dst);
    borrow(dst);
}

  1. @quinedot's example involving simple let statements goes to show the same kind of difference as the following foo2 example, compared to your foo ↩︎

6 Likes