Intuitively, I have no problems with this, it's exactly what I would expect (i.e., the borrow checker won't let you use &mut self again until &i32 reference has been dropped).
My question is: what feature permits me to "downgrade" from an &mut to an & like this? Is it "reborrowing"? "Projection"? Or maybe something involving the Deref/DerefMut traits?
BTW, the returned & reference is a bit magic, because it shares a lifetime with the exclusive reference it came from, which makes the shared reference still restricted by the original loan and not as flexible as if you reborrowed &self.
notice that &mut self doesn't even get it's property of &mut because borrower is smart enough to just say "hey, this is redundant". You will end up with just &self -> &i32. You're returning the ref to self, which is correct, but what about this?: let shared_ref: &i32 = &(*self).0;
If you mean get_ref will act like a fn(&self) -> &i32 to the caller, that is incorrect. The function signature determines the API contract, and a &mut _ is required to call it, no matter what the function body does or doesn't do with the &mut _.
It won't even let you use &self while that &mut self -> &_ borrow is active, which is what @kornel was getting at. There have been some ideas about truly downgrading mutability, but we don't have that yet.