Simple code to understand how lifetime of IterMut work

I wrote simple program to understand how doesmultiple next() call to IterMut::next(&mut self) work. I realized that lifetime of return value of next() and IterMut itself is distinct. Is there's problem with unsafe usage of my simple program? I don't think it's possible without unsafe code.

use mut_view::MutView;

fn main() {
    let mut x = 1;
    let mut view = MutView::new(&mut x);

    let v = view.get_mut().unwrap();

    assert_eq!(view.get_mut(), None);

    //we can drop view since lifetime of x and view is not connected.
    drop(view);

    //compile error. x is borrowed.
    //x = 5;

    //ok. lifetime of reference returned by view.get_mut() is tied to x not view.
    *v = 4;

    println!("{x:?}");
}

mod mut_view {
    //lifetime of Self is not tied to memory location that it points to.
    pub struct MutView<'a, T>(Option<&'a mut T>);

    impl<'a, T> MutView<'a, T> {
        pub fn new(r: &'a mut T) -> MutView<'a, T> {
            MutView(Some(r))
        }

        pub fn get_mut(&mut self) -> Option<&'a mut T> {
            //make sure not to give out unique access more than once
            Some(unsafe { &mut *(self.0.take()? as *mut _) })
        }
    }
}

You already have an Option<&'a mut T>, so you don't need to do any unsafe to return something independent of the lifetime on &mut self:

         pub fn get_mut(&mut self) -> Option<&'a mut T> {
             //make sure not to give out unique access more than once
-            Some(unsafe { &mut *(self.0.take()? as *mut _) })
+            self.0.take()
         }

Playground.

5 Likes