rust/qdev: Test bit property for #property

There's a diference between Rust and C:

Though C macro (e.g., DEFINE_PROP_BIT or DEFINE_PROP_BIT64) always
requires default value, Rust side allows to omit this "default" field
in #property, and provides a default value ("0" - false) for this
field.

This minor difference does not break user habits and should be
acceptable. Therefore, the test cases also cover this scenario.

Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Link: https://lore.kernel.org/r/20250920160520.3699591-10-zhao1.liu@intel.com
This commit is contained in:
Zhao Liu 2025-09-21 00:05:17 +08:00 committed by Paolo Bonzini
parent 9686aa9a05
commit a8f080215f

View file

@ -89,6 +89,19 @@ fn test_derive_device() {
"Duplicate argument",
"Already used here",
);
derive_compile_fail!(
derive_device_or_error,
quote! {
#[repr(C)]
#[derive(Device)]
struct DummyState {
#[property(bit = 0, bit = 1)]
flags: u32,
}
},
"Duplicate argument",
"Already used here",
);
// Check that the field name is preserved when `rename` isn't used:
derive_compile!(
derive_device_or_error,
@ -145,6 +158,92 @@ fn test_derive_device() {
}
}
);
// Check that `bit` value is used for the bit property without default
// value (note: though C macro (e.g., DEFINE_PROP_BIT) always requires
// default value, Rust side allows to default this field to "0"):
derive_compile!(
derive_device_or_error,
quote! {
#[repr(C)]
#[derive(Device)]
pub struct DummyState {
parent: ParentField<DeviceState>,
#[property(bit = 3)]
flags: u32,
}
},
quote! {
unsafe impl ::hwcore::DevicePropertiesImpl for DummyState {
const PROPERTIES: &'static [::hwcore::bindings::Property] = &[
::hwcore::bindings::Property {
name: ::std::ffi::CStr::as_ptr(c"flags"),
info: <u32 as ::hwcore::QDevProp>::BIT_INFO,
offset: ::core::mem::offset_of!(DummyState, flags) as isize,
bitnr: 3,
set_default: false,
defval: ::hwcore::bindings::Property__bindgen_ty_1 { u: 0 as u64 },
..::common::Zeroable::ZERO
}
];
}
}
);
// Check that `bit` value is used for the bit property when used:
derive_compile!(
derive_device_or_error,
quote! {
#[repr(C)]
#[derive(Device)]
pub struct DummyState {
parent: ParentField<DeviceState>,
#[property(bit = 3, default = true)]
flags: u32,
}
},
quote! {
unsafe impl ::hwcore::DevicePropertiesImpl for DummyState {
const PROPERTIES: &'static [::hwcore::bindings::Property] = &[
::hwcore::bindings::Property {
name: ::std::ffi::CStr::as_ptr(c"flags"),
info: <u32 as ::hwcore::QDevProp>::BIT_INFO,
offset: ::core::mem::offset_of!(DummyState, flags) as isize,
bitnr: 3,
set_default: true,
defval: ::hwcore::bindings::Property__bindgen_ty_1 { u: true as u64 },
..::common::Zeroable::ZERO
}
];
}
}
);
// Check that `bit` value is used for the bit property with rename when used:
derive_compile!(
derive_device_or_error,
quote! {
#[repr(C)]
#[derive(Device)]
pub struct DummyState {
parent: ParentField<DeviceState>,
#[property(rename = "msi", bit = 3, default = false)]
flags: u64,
}
},
quote! {
unsafe impl ::hwcore::DevicePropertiesImpl for DummyState {
const PROPERTIES: &'static [::hwcore::bindings::Property] = &[
::hwcore::bindings::Property {
name: ::std::ffi::CStr::as_ptr(c"msi"),
info: <u64 as ::hwcore::QDevProp>::BIT_INFO,
offset: ::core::mem::offset_of!(DummyState, flags) as isize,
bitnr: 3,
set_default: true,
defval: ::hwcore::bindings::Property__bindgen_ty_1 { u: false as u64 },
..::common::Zeroable::ZERO
}
];
}
}
);
}
#[test]