Why does unwrapping a cloned Rc cause a panic?

Viewed 186

Why does this code panic on line 7? Shouldn't foo_unwrapped be Some(3) on line 5 instead of None?

use std::rc::Rc;
fn main()
{
    let foo: Rc<i32> = Rc::new(3);
    let mut foo_cloned = Rc::clone(&foo);
    let mut foo_unwrapped = Rc::get_mut(&mut foo_cloned).unwrap();  
    foo_unwrapped = &mut 42;
}
1 Answers

From the Rc docs (emphasis mine)

pub fn get_mut(this: &mut Rc<T>) -> Option<&mut T>

Returns a mutable reference into the given Rc, if there are no other Rc or Weak pointers to the same allocation.

Returns None otherwise, because it is not safe to mutate a shared value.

See also make_mut, which will clone the inner value when there are other pointers.

You have two Rc pointers pointing to the same data (namely, foo and foo_cloned), so it's not safe to get a mutable reference to the data.

Rc isn't a magic trick to get out of Rust's borrowing semantics. Rust is still a single-ownership language and still enforces all of the same protections; it's just that in the case of Rc, the enforcement happens at runtime rather than compile-time.

Related