This seems to indicate that &*num.get_ref() is equivalent to &*(Deref::deref(&num.get_ref())), but:
fn main() {
let num = Num(1);
let r2 = &*(Deref::deref(&num.get_ref()));
// ^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
// |
// creates a temporary value which is freed while still in use
println!("{r2}");
}
Excuse me but what makes &*num.get_ref() different from &*(Deref::deref(&num.get_ref()))?
Rust should also refuse to compile &*num.get_ref() because it should be always equivalent to &*(Deref::deref(&num.get_ref())), but this is not the case.
If you've read the linked article, the answer will be found
The rules for which temporaries in a let statement get their lifetimes extended is documented in the Rust Reference, but effectively comes down to those expressions where you can tell from just the syntax that extending the lifetime is necessary, independent of any types, function signatures, or trait implementations
let a = f(&temporary()); // Not extended, because it might not be necessary.
In terms of temporaries, they are not the same. &*x is a syntactical tempory lifetime extention, but the other form is not.
The Reference also describes the current behavior on temporaries too:
The temporary scopes for expressions in let statements are sometimes extended to the scope of the block containing the let statement. This is done when the usual temporary scope would be too small, based on certain syntactic rules.
Certain syntactic rule applies for &*x, but not for explicit calls.