`pin!` macro and return value optimization

This is not exactly a regular RVO, but what if pin! had support for the following syntax:

fn self_ref<'req>() -> Pin<&'req mut usize> { // 'req is provided by caller
    pin!(12)
}

But for the sake of example now, it can be supported on pure faith. While the pin! macro could get more power and start guaranteeing this:

struct SelfRef {
    x: i32,
    y: NonNull<i32>,
}

impl SelfRef {
    #[inline(always)] // needed for llvm rvo 
    pub fn new() -> Self { // can't use Pin; it doesn't know about place address
        let mut tmp = Self { x: 0, y: NonNull::dangling() };
        tmp.y = NonNull::from(&tmp.x);
        tmp
    }
}

// not guarantee, but it's work 
let srf = SelfRef::new();
assert_eq!(&srf.x as *const _, srf.y.as_ptr());

Do you think this is possible and appropriate?

You may need something like this:

pub struct Uninit<T> {
    inner: MaybeUninit<T>,
}

pub struct Guard<'s, T> {
    ptr: &'s mut T,
    marker: PhantomData<T>,
}

unsafe impl<'s, #[may_dangle] T> Drop for Guard<'s, T> {
    fn drop(&mut self) {
        unsafe { drop_in_place(self.ptr); }
    }
}

impl<T> Default for Uninit<T> {
    fn default() -> Self {
        Self { inner: MaybeUninit::uninit() }
    }
}

impl<T> Uninit<T> {
    pub fn init(&mut self, value: T) -> Guard<T> {
        Guard { ptr: self.inner.write(value), marker: PhantomData }
    }

    /// # Safety
    /// This function is unsafe because we cannot guarantee that the [`Guard<T>`] will not be [`std::mem::forget`]
    pub unsafe fn init_pin(&mut self, value: T) -> Pin<Guard<T>> {
        unsafe { Pin::new_unchecked(self.init(value)) }
    }
}


impl<'s, T> Deref for Guard<'s, T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        self.ptr
    }
}

impl<'s, T> DerefMut for Guard<'s, T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        self.ptr
    }
}

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.