What does `let _ = unsafe{ Rc::from_raw(ptr) };` achieve?

Hi!

  1. I am reading hash_by_ref – which is precisely what I want to use – equality + hashing based on address of pointer, not value of object pointed to.

  2. I see this line here:
    https://github.com/eqv/hash_by_ref/blob/master/src/lib.rs#L19
    and I can not figure out what it is doing.

because it is let _ = ... we do not care about the returned value

The created Rc then goes out of scope, so we’re not using it to increment any ref count.

Lastly, we already know that self.val is a valid Rc (before the start of the function) – so what is the point of calling the Rc::from_raw on ptr ?

Thanks!

It’s turning the pointer back into an Rc so the refcount can be decremented, so it doesn’t leak memory.

1 Like

In general, you can interpret let _ = <EXPR>; as execute <EXPR> and store the result, but I don't care about naming the storage place.
The net effect of the code you mention would be to turn the raw ptr back into an Rc so that there is no memleak, but at the same time the code doesn’t care about using the resulting Rc itself. It only cares that the *const T -> Rc<T> conversion happens.

The main reason for the let _ = part would be to keep the compiler quiet. I don’t think in this case the compiler would otherwise complain as the Rc type is not marked with the #[must_use] attribute, but if the <EXPR> had yielded a Result<X, Y> value (which is marked with #[must_use]), then the compiler would complain if nothing is done with the <EXPR> result value. Thus, the let _ = ... is a way to pre-empt that warning no matter the type.

1 Like

Small nitpick, because I had the same misconception before: let _ = does not store anything, nor does it move the right-hand side. It’s materially different from let _x =. Demo: https://play.rust-lang.org/?gist=0caf6639eb6e9631123ebf652f384195

4 Likes

Ah, so the line’s purpose is “decrease ref count by 1 to avoid mem leak”

Thanks everyone!

1 Like