From the book
Shared access is read-only access. Values borrowed by shared references are read-only. Across the lifetime of a shared reference, neither its referent, nor anything reachable from that referent, can be changed by anything. There exist no live mutable references to anything in that structure, its owner is held read-only, and so on. It’s really frozen.
My doubt is this line
nor anything reachable from that referent. Here the two nodes that are marked
not read-only are clearly reachable from the referent. So by above definition they should be marked read-only. Why am I arriving at this contradiction?
From my understanding they should be marked
read-only and yet they are marked as
You question cannot be answered because it depends on the definition of the nodes and edges in your diagram, which you haven't defined.
Here's an example showing that fields can be mutated without invalidating a
&mut to their sibling field.
The diagram gives me a lot of slightly-off vibes. For example, why does heap allocated matter?
More on topic, you'll eventually learn about Rust's interior mutability (aka shared mutability), which allows values to be mutated through a shared reference, provided they're in an interior mutability container. Those bottom circles aren't inherently "read-only", they're non-exclusively borrowed (so you can't get an exclusive borrow of them -- a
&mut -- while the shared reference is valid).
The confusion may be that the "referent" in the second diagram is incorrect. The referent is the thing the reference points to, so it is what is at the end of the arrow from the
&. Its siblings in the ownership tree can be separately borrowed, even mutably borrowed and changed.
Also, as @quinedot noted, heap allocation doesn't necessarily affect things here, this could apply just as well to nested structs on the stack, or things with mutable references to things on the stack.