aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2025-05-02 10:35:49 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2025-05-06 16:02:04 +0200
commitb134a09ffab3b918979007cf40f603e5b54ed597 (patch)
tree5272bd8852bc433ae6e2045a5b30f69c8ccda17c
parent5df3fe062fb0be9a6689dc0336087b214dd30e5c (diff)
downloadqemu-b134a09ffab3b918979007cf40f603e5b54ed597.zip
qemu-b134a09ffab3b918979007cf40f603e5b54ed597.tar.gz
qemu-b134a09ffab3b918979007cf40f603e5b54ed597.tar.bz2
rust: remove offset_of replacement
Reviewed-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--docs/devel/rust.rst6
-rw-r--r--rust/Cargo.lock1
-rw-r--r--rust/Cargo.toml2
-rw-r--r--rust/hw/char/pl011/src/device.rs4
-rw-r--r--rust/hw/timer/hpet/src/hpet.rs4
-rw-r--r--rust/qemu-api-macros/src/lib.rs29
-rw-r--r--rust/qemu-api/Cargo.toml3
-rw-r--r--rust/qemu-api/build.rs7
-rw-r--r--rust/qemu-api/meson.build4
-rw-r--r--rust/qemu-api/src/lib.rs4
-rw-r--r--rust/qemu-api/src/offset_of.rs168
-rw-r--r--rust/qemu-api/src/qdev.rs6
-rw-r--r--rust/qemu-api/src/vmstate.rs10
-rw-r--r--rust/qemu-api/tests/tests.rs2
-rw-r--r--rust/qemu-api/tests/vmstate_tests.rs5
15 files changed, 16 insertions, 239 deletions
diff --git a/docs/devel/rust.rst b/docs/devel/rust.rst
index a315f668..5cfafc5 100644
--- a/docs/devel/rust.rst
+++ b/docs/devel/rust.rst
@@ -84,12 +84,6 @@ are missing:
* ``c"" literals`` (stable in 1.77.0). QEMU provides a ``c_str!()`` macro
to define ``CStr`` constants easily
-* ``offset_of!`` (stable in 1.77.0). QEMU uses ``offset_of!()`` heavily; it
- provides a replacement in the ``qemu_api`` crate, but it does not support
- lifetime parameters and therefore ``&'a Something`` fields in the struct
- may have to be replaced by ``NonNull<Something>``. *Nested* ``offset_of!``
- was only stabilized in Rust 1.82.0, but it is not used.
-
* inline const expression (stable in 1.79.0), currently worked around with
associated constants in the ``FnCall`` trait.
diff --git a/rust/Cargo.lock b/rust/Cargo.lock
index 2ebf0a1..13d580c 100644
--- a/rust/Cargo.lock
+++ b/rust/Cargo.lock
@@ -108,7 +108,6 @@ version = "0.1.0"
dependencies = [
"libc",
"qemu_api_macros",
- "version_check",
]
[[package]]
diff --git a/rust/Cargo.toml b/rust/Cargo.toml
index a328634..4f6fe17 100644
--- a/rust/Cargo.toml
+++ b/rust/Cargo.toml
@@ -17,7 +17,7 @@ rust-version = "1.77.0"
[workspace.lints.rust]
unexpected_cfgs = { level = "deny", check-cfg = [
'cfg(MESON)', 'cfg(HAVE_GLIB_WITH_ALIGNED_ALLOC)',
- 'cfg(has_offset_of)'] }
+] }
# Occasionally, we may need to silence warnings and clippy lints that
# were only introduced in newer Rust compiler versions. Do not croak
diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs
index bb2a0f2..7c563ad 100644
--- a/rust/hw/char/pl011/src/device.rs
+++ b/rust/hw/char/pl011/src/device.rs
@@ -74,7 +74,7 @@ impl std::ops::Index<u32> for Fifo {
}
#[repr(C)]
-#[derive(Debug, Default, qemu_api_macros::offsets)]
+#[derive(Debug, Default)]
pub struct PL011Registers {
#[doc(alias = "fr")]
pub flags: registers::Flags,
@@ -98,7 +98,7 @@ pub struct PL011Registers {
}
#[repr(C)]
-#[derive(qemu_api_macros::Object, qemu_api_macros::offsets)]
+#[derive(qemu_api_macros::Object)]
/// PL011 Device Model in QEMU
pub struct PL011State {
pub parent_obj: ParentField<SysBusDevice>,
diff --git a/rust/hw/timer/hpet/src/hpet.rs b/rust/hw/timer/hpet/src/hpet.rs
index b7a1be0..719343a 100644
--- a/rust/hw/timer/hpet/src/hpet.rs
+++ b/rust/hw/timer/hpet/src/hpet.rs
@@ -183,7 +183,7 @@ fn timer_handler(timer_cell: &BqlRefCell<HPETTimer>) {
/// HPET Timer Abstraction
#[repr(C)]
-#[derive(Debug, qemu_api_macros::offsets)]
+#[derive(Debug)]
pub struct HPETTimer {
/// timer N index within the timer block (`HPETState`)
#[doc(alias = "tn")]
@@ -523,7 +523,7 @@ impl HPETTimer {
/// HPET Event Timer Block Abstraction
#[repr(C)]
-#[derive(qemu_api_macros::Object, qemu_api_macros::offsets)]
+#[derive(qemu_api_macros::Object)]
pub struct HPETState {
parent_obj: ParentField<SysBusDevice>,
iomem: MemoryRegion,
diff --git a/rust/qemu-api-macros/src/lib.rs b/rust/qemu-api-macros/src/lib.rs
index 0bffd26..dc14cac 100644
--- a/rust/qemu-api-macros/src/lib.rs
+++ b/rust/qemu-api-macros/src/lib.rs
@@ -6,7 +6,7 @@ use proc_macro::TokenStream;
use quote::quote;
use syn::{
parse_macro_input, parse_quote, punctuated::Punctuated, spanned::Spanned, token::Comma, Data,
- DeriveInput, Field, Fields, FieldsUnnamed, Ident, Meta, Path, Token, Type, Variant, Visibility,
+ DeriveInput, Field, Fields, FieldsUnnamed, Ident, Meta, Path, Token, Variant,
};
mod utils;
@@ -151,33 +151,6 @@ pub fn derive_opaque(input: TokenStream) -> TokenStream {
TokenStream::from(expanded)
}
-#[rustfmt::skip::macros(quote)]
-fn derive_offsets_or_error(input: DeriveInput) -> Result<proc_macro2::TokenStream, MacroError> {
- is_c_repr(&input, "#[derive(offsets)]")?;
-
- let name = &input.ident;
- let fields = get_fields(&input, "#[derive(offsets)]")?;
- let field_names: Vec<&Ident> = fields.iter().map(|f| f.ident.as_ref().unwrap()).collect();
- let field_types: Vec<&Type> = fields.iter().map(|f| &f.ty).collect();
- let field_vis: Vec<&Visibility> = fields.iter().map(|f| &f.vis).collect();
-
- Ok(quote! {
- ::qemu_api::with_offsets! {
- struct #name {
- #(#field_vis #field_names: #field_types,)*
- }
- }
- })
-}
-
-#[proc_macro_derive(offsets)]
-pub fn derive_offsets(input: TokenStream) -> TokenStream {
- let input = parse_macro_input!(input as DeriveInput);
- let expanded = derive_offsets_or_error(input).unwrap_or_else(Into::into);
-
- TokenStream::from(expanded)
-}
-
#[allow(non_snake_case)]
fn get_repr_uN(input: &DeriveInput, msg: &str) -> Result<Path, MacroError> {
let repr = input.attrs.iter().find(|attr| attr.path().is_ident("repr"));
diff --git a/rust/qemu-api/Cargo.toml b/rust/qemu-api/Cargo.toml
index ca1b042..c96cf50 100644
--- a/rust/qemu-api/Cargo.toml
+++ b/rust/qemu-api/Cargo.toml
@@ -17,9 +17,6 @@ rust-version.workspace = true
qemu_api_macros = { path = "../qemu-api-macros" }
libc = "0.2.162"
-[build-dependencies]
-version_check = "~0.9"
-
[features]
default = ["debug_cell"]
allocator = []
diff --git a/rust/qemu-api/build.rs b/rust/qemu-api/build.rs
index 471e6c6..470be2a 100644
--- a/rust/qemu-api/build.rs
+++ b/rust/qemu-api/build.rs
@@ -8,8 +8,6 @@ use std::os::unix::fs::symlink as symlink_file;
use std::os::windows::fs::symlink_file;
use std::{env, fs::remove_file, io::Result, path::Path};
-use version_check as rustc;
-
fn main() -> Result<()> {
// Placing bindings.inc.rs in the source directory is supported
// but not documented or encouraged.
@@ -38,11 +36,6 @@ fn main() -> Result<()> {
}
symlink_file(file, dest_path)?;
- // Check for available rustc features
- if rustc::is_min_version("1.77.0").unwrap_or(false) {
- println!("cargo:rustc-cfg=has_offset_of");
- }
-
println!("cargo:rerun-if-changed=build.rs");
Ok(())
}
diff --git a/rust/qemu-api/meson.build b/rust/qemu-api/meson.build
index 858685d..95e6564 100644
--- a/rust/qemu-api/meson.build
+++ b/rust/qemu-api/meson.build
@@ -5,9 +5,6 @@ _qemu_api_cfg = run_command(rustc_args,
libc_dep = dependency('libc-0.2-rs')
# _qemu_api_cfg += ['--cfg', 'feature="allocator"']
-if rustc.version().version_compare('>=1.77.0')
- _qemu_api_cfg += ['--cfg', 'has_offset_of']
-endif
if get_option('debug_mutex')
_qemu_api_cfg += ['--cfg', 'feature="debug_cell"']
endif
@@ -28,7 +25,6 @@ _qemu_api_rs = static_library(
'src/irq.rs',
'src/memory.rs',
'src/module.rs',
- 'src/offset_of.rs',
'src/prelude.rs',
'src/qdev.rs',
'src/qom.rs',
diff --git a/rust/qemu-api/src/lib.rs b/rust/qemu-api/src/lib.rs
index c3641e8..90c1963 100644
--- a/rust/qemu-api/src/lib.rs
+++ b/rust/qemu-api/src/lib.rs
@@ -23,7 +23,6 @@ pub mod errno;
pub mod irq;
pub mod memory;
pub mod module;
-pub mod offset_of;
pub mod qdev;
pub mod qom;
pub mod sysbus;
@@ -165,6 +164,3 @@ unsafe impl GlobalAlloc for QemuAllocator {
}
}
}
-
-#[cfg(has_offset_of)]
-pub use core::mem::offset_of;
diff --git a/rust/qemu-api/src/offset_of.rs b/rust/qemu-api/src/offset_of.rs
deleted file mode 100644
index 373229b..0000000
--- a/rust/qemu-api/src/offset_of.rs
+++ /dev/null
@@ -1,168 +0,0 @@
-// SPDX-License-Identifier: MIT
-
-#![doc(hidden)]
-//! This module provides macros that emulate the functionality of
-//! `core::mem::offset_of` on older versions of Rust.
-//!
-//! Documentation is hidden because it only exposes macros, which
-//! are exported directly from `qemu_api`.
-
-/// This macro provides the same functionality as `core::mem::offset_of`,
-/// except that only one level of field access is supported. The declaration
-/// of the struct must be wrapped with `with_offsets! { }`.
-///
-/// It is needed because `offset_of!` was only stabilized in Rust 1.77.
-#[cfg(not(has_offset_of))]
-#[macro_export]
-macro_rules! offset_of {
- ($Container:ty, $field:ident) => {
- <$Container>::OFFSET_TO__.$field
- };
-}
-
-/// A wrapper for struct declarations, that allows using `offset_of!` in
-/// versions of Rust prior to 1.77
-#[macro_export]
-macro_rules! with_offsets {
- // This method to generate field offset constants comes from:
- //
- // https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=10a22a9b8393abd7b541d8fc844bc0df
- //
- // used under MIT license with permission of Yandros aka Daniel Henry-Mantilla
- (
- $(#[$struct_meta:meta])*
- $struct_vis:vis
- struct $StructName:ident {
- $(
- $(#[$field_meta:meta])*
- $field_vis:vis
- $field_name:ident : $field_ty:ty
- ),*
- $(,)?
- }
- ) => (
- #[cfg(not(has_offset_of))]
- const _: () = {
- struct StructOffsetsHelper<T>(std::marker::PhantomData<T>);
- const END_OF_PREV_FIELD: usize = 0;
-
- // populate StructOffsetsHelper<T> with associated consts,
- // one for each field
- $crate::with_offsets! {
- @struct $StructName
- @names [ $($field_name)* ]
- @tys [ $($field_ty ,)*]
- }
-
- // now turn StructOffsetsHelper<T>'s consts into a single struct,
- // applying field visibility. This provides better error messages
- // than if offset_of! used StructOffsetsHelper::<T> directly.
- pub
- struct StructOffsets {
- $(
- $field_vis
- $field_name: usize,
- )*
- }
- impl $StructName {
- pub
- const OFFSET_TO__: StructOffsets = StructOffsets {
- $(
- $field_name: StructOffsetsHelper::<$StructName>::$field_name,
- )*
- };
- }
- };
- );
-
- (
- @struct $StructName:ident
- @names []
- @tys []
- ) => ();
-
- (
- @struct $StructName:ident
- @names [$field_name:ident $($other_names:tt)*]
- @tys [$field_ty:ty , $($other_tys:tt)*]
- ) => (
- #[allow(non_local_definitions)]
- #[allow(clippy::modulo_one)]
- impl StructOffsetsHelper<$StructName> {
- #[allow(nonstandard_style)]
- const $field_name: usize = {
- const ALIGN: usize = std::mem::align_of::<$field_ty>();
- const TRAIL: usize = END_OF_PREV_FIELD % ALIGN;
- END_OF_PREV_FIELD + (if TRAIL == 0 { 0usize } else { ALIGN - TRAIL })
- };
- }
- const _: () = {
- const END_OF_PREV_FIELD: usize =
- StructOffsetsHelper::<$StructName>::$field_name +
- std::mem::size_of::<$field_ty>()
- ;
- $crate::with_offsets! {
- @struct $StructName
- @names [$($other_names)*]
- @tys [$($other_tys)*]
- }
- };
- );
-}
-
-#[cfg(test)]
-mod tests {
- use crate::offset_of;
-
- #[repr(C)]
- struct Foo {
- a: u16,
- b: u32,
- c: u64,
- d: u16,
- }
-
- #[repr(C)]
- struct Bar {
- pub a: u16,
- pub b: u64,
- c: Foo,
- d: u64,
- }
-
- crate::with_offsets! {
- #[repr(C)]
- struct Bar {
- pub a: u16,
- pub b: u64,
- c: Foo,
- d: u64,
- }
- }
-
- #[repr(C)]
- pub struct Baz {
- b: u32,
- a: u8,
- }
- crate::with_offsets! {
- #[repr(C)]
- pub struct Baz {
- b: u32,
- a: u8,
- }
- }
-
- #[test]
- fn test_offset_of() {
- const OFFSET_TO_C: usize = offset_of!(Bar, c);
-
- assert_eq!(offset_of!(Bar, a), 0);
- assert_eq!(offset_of!(Bar, b), 8);
- assert_eq!(OFFSET_TO_C, 16);
- assert_eq!(offset_of!(Bar, d), 40);
-
- assert_eq!(offset_of!(Baz, b), 0);
- assert_eq!(offset_of!(Baz, a), 4);
- }
-}
diff --git a/rust/qemu-api/src/qdev.rs b/rust/qemu-api/src/qdev.rs
index 17c7fec..1279d7a 100644
--- a/rust/qemu-api/src/qdev.rs
+++ b/rust/qemu-api/src/qdev.rs
@@ -190,7 +190,7 @@ macro_rules! define_property {
// use associated function syntax for type checking
name: ::std::ffi::CStr::as_ptr($name),
info: $prop,
- offset: $crate::offset_of!($state, $field) as isize,
+ offset: ::std::mem::offset_of!($state, $field) as isize,
bitnr: $bitnr,
set_default: true,
defval: $crate::bindings::Property__bindgen_ty_1 { u: $defval as u64 },
@@ -202,7 +202,7 @@ macro_rules! define_property {
// use associated function syntax for type checking
name: ::std::ffi::CStr::as_ptr($name),
info: $prop,
- offset: $crate::offset_of!($state, $field) as isize,
+ offset: ::std::mem::offset_of!($state, $field) as isize,
set_default: true,
defval: $crate::bindings::Property__bindgen_ty_1 { u: $defval as u64 },
..$crate::zeroable::Zeroable::ZERO
@@ -213,7 +213,7 @@ macro_rules! define_property {
// use associated function syntax for type checking
name: ::std::ffi::CStr::as_ptr($name),
info: $prop,
- offset: $crate::offset_of!($state, $field) as isize,
+ offset: ::std::mem::offset_of!($state, $field) as isize,
set_default: false,
..$crate::zeroable::Zeroable::ZERO
}
diff --git a/rust/qemu-api/src/vmstate.rs b/rust/qemu-api/src/vmstate.rs
index c0f29f7..205f35a 100644
--- a/rust/qemu-api/src/vmstate.rs
+++ b/rust/qemu-api/src/vmstate.rs
@@ -205,8 +205,8 @@ macro_rules! vmstate_of {
name: ::core::concat!(::core::stringify!($field_name), "\0")
.as_bytes()
.as_ptr() as *const ::std::os::raw::c_char,
- offset: $crate::offset_of!($struct_name, $field_name),
- $(num_offset: $crate::offset_of!($struct_name, $num),)?
+ offset: ::std::mem::offset_of!($struct_name, $field_name),
+ $(num_offset: ::std::mem::offset_of!($struct_name, $num),)?
$(field_exists: $crate::vmstate_exist_fn!($struct_name, $test_fn),)?
// The calls to `call_func_with_field!` are the magic that
// computes most of the VMStateField from the type of the field.
@@ -483,10 +483,10 @@ macro_rules! vmstate_struct {
name: ::core::concat!(::core::stringify!($field_name), "\0")
.as_bytes()
.as_ptr() as *const ::std::os::raw::c_char,
- $(num_offset: $crate::offset_of!($struct_name, $num),)?
+ $(num_offset: ::std::mem::offset_of!($struct_name, $num),)?
offset: {
$crate::assert_field_type!($struct_name, $field_name, $type $(, num = $num)?);
- $crate::offset_of!($struct_name, $field_name)
+ ::std::mem::offset_of!($struct_name, $field_name)
},
size: ::core::mem::size_of::<$type>(),
flags: $crate::bindings::VMStateFlags::VMS_STRUCT,
@@ -518,7 +518,7 @@ macro_rules! vmstate_clock {
$field_name,
$crate::qom::Owned<$crate::qdev::Clock> $(, num = $num)?
);
- $crate::offset_of!($struct_name, $field_name)
+ ::std::mem::offset_of!($struct_name, $field_name)
},
size: ::core::mem::size_of::<*const $crate::qdev::Clock>(),
flags: $crate::bindings::VMStateFlags(
diff --git a/rust/qemu-api/tests/tests.rs b/rust/qemu-api/tests/tests.rs
index 99a7aab..d045808 100644
--- a/rust/qemu-api/tests/tests.rs
+++ b/rust/qemu-api/tests/tests.rs
@@ -26,7 +26,6 @@ pub static VMSTATE: VMStateDescription = VMStateDescription {
..Zeroable::ZERO
};
-#[derive(qemu_api_macros::offsets)]
#[repr(C)]
#[derive(qemu_api_macros::Object)]
pub struct DummyState {
@@ -79,7 +78,6 @@ impl DeviceImpl for DummyState {
}
}
-#[derive(qemu_api_macros::offsets)]
#[repr(C)]
#[derive(qemu_api_macros::Object)]
pub struct DummyChildState {
diff --git a/rust/qemu-api/tests/vmstate_tests.rs b/rust/qemu-api/tests/vmstate_tests.rs
index 9a56ffd..cc3527a 100644
--- a/rust/qemu-api/tests/vmstate_tests.rs
+++ b/rust/qemu-api/tests/vmstate_tests.rs
@@ -33,7 +33,7 @@ const FOO_ARRAY_MAX: usize = 3;
// - VMSTATE_VARRAY_UINT16_UNSAFE
// - VMSTATE_VARRAY_MULTIPLY
#[repr(C)]
-#[derive(Default, qemu_api_macros::offsets)]
+#[derive(Default)]
struct FooA {
arr: [u8; FOO_ARRAY_MAX],
num: u16,
@@ -154,7 +154,7 @@ fn test_vmstate_varray_multiply() {
// - VMSTATE_ARRAY
// - VMSTATE_STRUCT_VARRAY_UINT8 with BqlCell wrapper & test_fn
#[repr(C)]
-#[derive(Default, qemu_api_macros::offsets)]
+#[derive(Default)]
struct FooB {
arr_a: [FooA; FOO_ARRAY_MAX],
num_a: u8,
@@ -329,7 +329,6 @@ struct FooCWrapper([Opaque<*mut u8>; FOO_ARRAY_MAX]); // Though Opaque<> array i
impl_vmstate_forward!(FooCWrapper);
#[repr(C)]
-#[derive(qemu_api_macros::offsets)]
struct FooC {
ptr: *const i32,
ptr_a: NonNull<FooA>,