Paolo Bonzini <pbonz...@redhat.com> writes:
> offset_of! was stabilized in Rust 1.77.0. Use an alternative implemenation > that was found on the Rust forums, and whose author agreed to license as > MIT for use in QEMU. > > The alternative allows only one level of field access, but apart > from this can be used just by replacing core::mem::offset_of! with > qemu_api::offset_of!. How about a macro like this (which essentially comes from memoffset crate [1])? It has the same use as core::mem::offset_of! (except the same single-level limitation) and does not need wrapping structures with with_offsets!. macro_rules! offset_of { ($parent:ty, $field:tt) => {{ let uninit = std::mem::MaybeUninit::<$parent>::uninit(); let base = uninit.as_ptr(); // SAFETY: // // MaybeUninit<$parent> has the same size and alignment as $parent, so // projection to $field is in bound. // // addr_of! does not create intermediate references to the uninitialized // memory, thus no UB is involved. let field = unsafe { std::ptr::addr_of!((*base).$field) }; // SAFETY: // // Both base and field point to the MaybeUninit<$parent> and are casted // to u8 for calculating their distance. unsafe { field.cast::<u8>().offset_from(base.cast::<u8>()) as usize } }}; } [1] https://docs.rs/memoffset/latest/memoffset/ -- Best Regards Junjie Mao