From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: qemu-rust@nongnu.org
Subject: [PATCH 00/15] rust: prepare for splitting crates
Date: Fri, 21 Feb 2025 18:03:27 +0100 [thread overview]
Message-ID: <20250221170342.63591-1-pbonzini@redhat.com> (raw)
This series is logically split in two parts. The first one is more
strictly tied to the objective of splitting qemu_api into multiple crates,
as it breaks the QOM bindings free of the constraints imposed by Rust
orphan rules. The second one instead completes another task that was on
my todo list, namely ensuring that rustc sees the possible changes that
C functions can make when a shared reference &bindings::Foo is passed
via *mut bindings::Foo.
More in detail, patches 1-5 redo the QOM class init mechanism so that
it does not rely on the ClassInitImpl trait. While ClassInitImpl is
very nice in theory, it practice it does not play well with classes
defined outside qemu_api (or more precisely, outside the crate that
defines ClassInitImpl itself). This is because ClassInitImpl relies on
a blanket implementation such as
impl<T> ClassInitImpl<ObjectClass> for T
where
T: ObjectImpl
and this is only possible inside the crate that defines ClassInitImpl.
With these patches the class_init methods move from ClassInitImpl<Class>
to the Class struct itself. More precisely, before the series you
have
<T as ClassInitImpl<ObjectClass>>::class_init
and afterwards
ObjectClass::class_init::<T>
which is assigned to the CLASS_INIT associated const of ObjectImpl.
The problem is that even if CLASS_INIT is always defined the same
way, i.e.
const CLASS_INIT: fn(&mut Self::Class) = Self::Class::class_init::<Self>;
there isn't a way to tell the compiler that the above is valid *in the
definition of ObjectImpl*. Therefore the above line has to be duplicated
in all subclasses; this however is a small issue and in the future it
could be handled by #[derive(Object)].
Patches 6-15 instead introduce a third generic type in qemu_api::cell,
Opaque<T>. This type is similar to a same-named type in Linux; it is
basically a "disable all undefined behavior" switch for the Rust compiler
and it helps maintaining safety at the Rust/C boundary, complementing
the existing BqlCell and BqlRefCell types.
Apart from making things more formally correct, this makes it possible
to implement methods on a struct that is distinct from the one produced
by bindgen. This has a couple of advantages:
- you do not have to disable the Copy trait on structs where you want
to add a Drop trait. This was already a problem for the Timer struct.
- whether Send and Sync are implemented is entirely a decision of the
place that implements the wrapper. Previously, a struct with no
pointers for example would have been always both Send and Sync,
whereas now that can be adjusted depending on the actual
thread-safety of the Rust methods.
- more pertinent to the "multiple crates" plan, you do not have to put
the methods in the same crate as the bindgen-generated bindings.inc.rs.
It also makes Debug output a bit less unwieldy, and in the future one
might want to add specialized implementations of Display and Debug that
are both useful and readable.
Paolo
Paolo Bonzini (15):
rust: add IsA bounds to QOM implementation traits
rust: add SysBusDeviceImpl
rust: qom: add ObjectImpl::CLASS_INIT
rust: pl011, qemu_api tests: do not use ClassInitImpl
rust: qom: get rid of ClassInitImpl
rust: cell: add wrapper for FFI types
rust: qemu_api_macros: add Wrapper derive macro
rust: timer: wrap QEMUTimer with Opaque<>
rust: irq: wrap IRQState with Opaque<>
rust: qom: wrap Object with Opaque<>
rust: qdev: wrap Clock and DeviceState with Opaque<>
rust: sysbus: wrap SysBusDevice with Opaque<>
rust: memory: wrap MemoryRegion with Opaque<>
rust: chardev: wrap Chardev with Opaque<>
rust: bindings: remove more unnecessary Send/Sync impls
docs/devel/rust.rst | 36 +++--
meson.build | 7 -
rust/hw/char/pl011/src/device.rs | 44 +++---
rust/hw/timer/hpet/src/hpet.rs | 7 +-
rust/qemu-api-macros/src/lib.rs | 82 +++++++++++-
rust/qemu-api/meson.build | 7 +-
rust/qemu-api/src/bindings.rs | 26 +---
rust/qemu-api/src/cell.rs | 222 ++++++++++++++++++++++++++++++-
rust/qemu-api/src/chardev.rs | 8 +-
rust/qemu-api/src/irq.rs | 15 ++-
rust/qemu-api/src/memory.rs | 32 ++---
rust/qemu-api/src/qdev.rs | 115 ++++++++++------
rust/qemu-api/src/qom.rs | 203 ++++++++++++++--------------
rust/qemu-api/src/sysbus.rs | 45 ++++---
rust/qemu-api/src/timer.rs | 24 +++-
rust/qemu-api/src/vmstate.rs | 2 +-
rust/qemu-api/tests/tests.rs | 32 ++---
17 files changed, 620 insertions(+), 287 deletions(-)
--
2.48.1
next reply other threads:[~2025-02-21 17:03 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-21 17:03 Paolo Bonzini [this message]
2025-02-21 17:03 ` [PATCH 01/15] rust: add IsA bounds to QOM implementation traits Paolo Bonzini
2025-02-24 14:43 ` Zhao Liu
2025-02-21 17:03 ` [PATCH 02/15] rust: add SysBusDeviceImpl Paolo Bonzini
2025-02-24 14:46 ` Zhao Liu
2025-02-21 17:03 ` [PATCH 03/15] rust: qom: add ObjectImpl::CLASS_INIT Paolo Bonzini
2025-02-24 14:56 ` Zhao Liu
2025-02-21 17:03 ` [PATCH 04/15] rust: pl011, qemu_api tests: do not use ClassInitImpl Paolo Bonzini
2025-02-24 15:14 ` Zhao Liu
2025-02-21 17:03 ` [PATCH 05/15] rust: qom: get rid of ClassInitImpl Paolo Bonzini
2025-02-24 15:24 ` Zhao Liu
2025-02-21 17:03 ` [PATCH 06/15] rust: cell: add wrapper for FFI types Paolo Bonzini
2025-02-25 6:46 ` Zhao Liu
2025-02-21 17:03 ` [PATCH 07/15] rust: qemu_api_macros: add Wrapper derive macro Paolo Bonzini
2025-02-25 7:54 ` Zhao Liu
2025-02-21 17:03 ` [PATCH 08/15] rust: timer: wrap QEMUTimer with Opaque<> Paolo Bonzini
2025-02-25 7:56 ` Zhao Liu
2025-02-21 17:03 ` [PATCH 09/15] rust: irq: wrap IRQState " Paolo Bonzini
2025-02-25 8:26 ` Zhao Liu
2025-02-25 8:28 ` Paolo Bonzini
2025-02-25 9:36 ` Zhao Liu
2025-02-21 17:03 ` [PATCH 10/15] rust: qom: wrap Object " Paolo Bonzini
2025-02-25 8:47 ` Zhao Liu
2025-02-21 17:03 ` [PATCH 11/15] rust: qdev: wrap Clock and DeviceState " Paolo Bonzini
2025-02-25 8:52 ` Zhao Liu
2025-02-21 17:03 ` [PATCH 12/15] rust: sysbus: wrap SysBusDevice " Paolo Bonzini
2025-02-25 8:59 ` Zhao Liu
2025-02-21 17:03 ` [PATCH 13/15] rust: memory: wrap MemoryRegion " Paolo Bonzini
2025-02-25 9:14 ` Zhao Liu
2025-02-25 9:47 ` Paolo Bonzini
2025-02-21 17:03 ` [PATCH 14/15] rust: chardev: wrap Chardev " Paolo Bonzini
2025-02-25 9:19 ` Zhao Liu
2025-02-21 17:03 ` [PATCH 15/15] rust: bindings: remove more unnecessary Send/Sync impls Paolo Bonzini
2025-02-25 9:20 ` Zhao Liu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250221170342.63591-1-pbonzini@redhat.com \
--to=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-rust@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).