Can this be done without a proc macro?

we want to turn this:

opaque! {
struct Foo<'a> {
  x: Option<&'a Cell<Foo<'a>>>,
  y: usize,
}
impl<'a> Drop for Foo<'a> {
  fn drop_cell(this: Pin<&'a Cell<Foo<'a>>>) {
        let bar = cell_project!(Foo<'_>, this.x);
        let inner = bar.get().unwrap();
        println!("{:p}", this.get_ref());
        println!("{:p}", inner);
        println!("{}", cell_project!(Foo<'_>, inner.y).get());
        cell_project!(Foo<'_>, inner.y).set(3);
  }
}
}

into all this:

struct Foo<'a> {
  x: Option<&'a Cell<Foo<'a>>>,
  y: usize,
}

#[repr(transparent)]
struct FooOpaque {
    // unsafe field: not actually 'static
    inner: Foo<'static>,
    _pinned: PhantomPinned,
}

impl FooOpaque {
    fn new(foo: impl for<'a> FnOnce(&'a ()) -> Foo<'a>) -> Self {
        #[allow(unreachable_code)]
        fn _prevent_problematic_drop(f: impl for<'x> Fn(&'x ()) -> Foo<'x>) {
            let _arg = ();
            let _foo: Foo<'_> = f(&_arg);
            let _cell = Cell::new(_foo);
            #[inline(never)]
            fn _f<'a>(_x: &'a Cell<Foo<'a>>) {}
            _f(&_cell);
        }
        Self {
            inner: unsafe { std::mem::transmute(foo(&())) },
            _pinned: PhantomPinned,
        }
    }

    fn operate_in<F, R>(pinned_cell: Pin<&Cell<Self>>, f: F) -> R
    where F: for<'a> FnOnce(Pin<&'a Cell<Foo<'a>>>) -> R {
        f(unsafe {
            pinned_cell.map_unchecked(|cell_ref| {
                std::mem::transmute(cell_project!(FooOpaque, cell_ref.inner))
            })
        })
    }
}

impl Drop for FooOpaque {
    fn drop(&mut self) {
        unsafe {
            // assume it was pinned.
            Self::operate_in(std::mem::transmute(self), |cell_ref| {
  fn drop_cell(this: Pin<&'a Cell<Foo<'a>>>) {
        let bar = cell_project!(Foo<'_>, this.x);
        let inner = bar.get().unwrap();
        println!("{:p}", this.get_ref());
        println!("{:p}", inner);
        println!("{}", cell_project!(Foo<'_>, inner.y).get());
        cell_project!(Foo<'_>, inner.y).set(3);
  }
                drop_cell(cell_ref)
            });
        }
    }
}

but we'd like to do it without a proc macro. is this possible without a proc macro?

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.