4

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;
}
Uclydde
  • 1,414
  • 3
  • 16
  • 33
  • I said I urge to downvote it, not that I downvoted it ;) But I see your point here. In my opinion, the doc clearly states when it returns `None` and when it does return `Some(_)`, so I ask myself the question whether you read the doc in the first place (you said yes). So your title ask, why it does panic -> because of the `unwrap`. Why is there a `None` value -> the doc states it, because you have more than one Rc that points to the same value. – hellow Jun 08 '21 at 08:50

1 Answers1

10

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.

Silvio Mayolo
  • 62,821
  • 6
  • 74
  • 116