What's the type signature of asterisk operator?

What's the return type of asterisk operator if applied at a &mut T type?
What's the return type of asterisk operator if applied at a &T type?
Why the code below can't compile? (I know it shouldn't compile but why it can't compile?)

let a = 1;
let b = &mut * &a;

Why the code below compiles? (I know it should compile but why it can compile?)

let mut a = 1;
let b = &mut * &mut a;

Unary * is the Deref operator and in the case of &mut T and &T, it compiles to a place expression corresponding to T, either with or without the ability to mutate. What happens next depends on the context of the expression; if you try to read the value for example, you'll try to move (or copy) the value out of that place, which may or may not be possible. The type of the expression is T in both cases.

In your example, the context results in trying to explicitly reborrow the same place. You can reborrow a &'x mut T as a &'y mut T where 'y is no longer than 'x, but you can't reborrow a &T as a &mut T. That's part of the language, but not part of the type system per se. The type of *&T and *&mut T is the same, but one is a mutable place expression and the other, immutable.

So the answer to your question is that *&a is an immutable place expression you can't take a &mut to, but *&mut a is a mutable place expression, and it's fine to take a &mut to that.

2 Likes

We could loosely say that the "type" of *&a is i32 and the "type" of *&mut a is mut i32. These are not actual types because types don't carry mutability like that, but this notation suggests the actual difference.

(A third case is places that can be moved out of, but those are rarely produced by *.)

1 Like

You explained everything very well! Thank you very much!