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?
Qsh
2
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
}
}
system
Closed
3
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.