From: Paolo Bonzini <pbonzini@redhat.com>
To: Junjie Mao <junjie.mao@hotmail.com>
Cc: Zhao Liu <zhao1.liu@intel.com>,
qemu-devel@nongnu.org, qemu-rust@nongnu.org,
qemu-stable@nongnu.org
Subject: Re: vtables and procedural macros (was Re: [PATCH] rust: pl011: convert pl011_create to safe Rust)
Date: Tue, 11 Feb 2025 13:27:50 +0100 [thread overview]
Message-ID: <CABgObfaYNZ1JZddOhdGfMhPAVK+trX08B_wBS5MbvrUNdCGebA@mail.gmail.com> (raw)
In-Reply-To: <SY0P300MB1026E0CE5AFBEA4E713F73F595FD2@SY0P300MB1026.AUSP300.PROD.OUTLOOK.COM>
On Tue, Feb 11, 2025 at 12:34 PM Junjie Mao <junjie.mao@hotmail.com> wrote:
> Essentially we want a naming convention that (1) avoids any potential
> name conflicts, and (2) applies consistently to (ideally) all APIs. For
> goal (1), we need something at API call sites that can resolve the
> potential ambiguity.
I now agree that (1) is more important than (2). Adding a function like
fn realize(&self, bus: *mut BusState) {
// TODO: return an Error
assert!(bql_locked());
unsafe {
bindings::qdev_realize(self.as_mut_ptr(),
bus, addr_of_mut!(bindings::error_fatal));
}
}
to DeviceMethods is enough to cause an error:
error[E0034]: multiple applicable items in scope
--> hw/char/pl011/src/device.rs:714:9
|
714 | dev.realize();
| ^^^^^^^ multiple `realize` found
> So instead of dev.realize(), we may write:
>
> a) dev.sysbus_realize()
> b) SysBusDeviceMethods::realize(&dev); dev.realize() is still ok if
> there is no ambiguity
> c) dev.as_ref::<SysBusDevice>().realize()
>
> (any more options?)
>
> None looks perfect, unfortunately. Option (a) introduces inconsistent
> naming conventions as mentioned earlier; (b) cannot prevent confusions
> when a device has both a "reset()" method and "dev.reset()" calls; (c)
> deviates from how wrappers are auto-delegated to child classes today and
> is the longest to write.
There is one more, which is a variant of (c): use Deref to delegate to
the superclass, and traits for interfaces only. Then the default would
always be the closest to the class you're defining, and you could
override it with SysBusDevice::realize(&dev).
It requires more glue code, but creating it could be delegated to
#[derive(Object)].
I think we can use (a) as proposed by Zhao and yourself, and document
this convention
(1) whenever a name is unique in the hierarchy, do not add the prefix
(2) whenever a name is not unique in the hierarchy, always add the
prefix to the classes that are lower in the hierarchy; for the top
class, decide on a case by case basis.
For example, you'd have
DeviceMethods::cold_reset()
PciDeviceMethods::pci_device_reset()
PciBridgeMethods::pci_bridge_reset()
PciDeviceMethods adds the prefix because the three methods have
different functionality. Subclasses of PciBridgeMethods may need to
call either pci_device_reset() or pci_bridge_reset().
And also, because there is a similar name in DeviceMethods,
PciDeviceMethods::reset() would be confusing.
(As an aside, pci_device_reset() probably should be implemented at the
Resettable level, e.g. RESET_TYPE_BUS, but that's a different story).
Or perhaps pci_bridge_reset() becomes PciBridgeCap::reset(), which is
not a trait. That's okay too, and it's not a problem for the naming of
pci_device_reset().
but:
DeviceMethods::realize()
SysbusDeviceMethods::sysbus_realize()
PciDeviceMethods::pci_realize()
Here, DeviceMethods does not add the prefix because generally the
lower classes only add casts and compile-time typing but not
functionality. The basic realize() functionality is the same for all
devices.
What about confusion with the realize function on the struct? It's
unlikely to be an issue because it has a different signature than
DeviceMethods::realize(), which takes a BusState too. But if I'm wrong
and there _is_ confusion, renaming DeviceMethods::realize() is easy.
> Just found the lint: https://rust-lang.github.io/rust-clippy/master/index.html#same_name_method
Almost: "It lints if a struct has two methods with the same name: one
from a trait, another not from a trait." - it doesn't check two
traits. Also I think in this case it doesn't fire because the trait is
implemented for &PL011State, not PL011State.
Paolo
next prev parent reply other threads:[~2025-02-11 12:29 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-06 11:15 [PATCH] rust: add --rust-target option for bindgen Paolo Bonzini
2025-02-06 11:15 ` [PATCH] rust: pl011: convert pl011_create to safe Rust Paolo Bonzini
2025-02-10 9:59 ` Zhao Liu
2025-02-10 10:47 ` vtables and procedural macros (was Re: [PATCH] rust: pl011: convert pl011_create to safe Rust) Paolo Bonzini
2025-02-11 5:21 ` Junjie Mao
2025-02-11 9:00 ` Paolo Bonzini
2025-02-11 10:31 ` Junjie Mao
2025-02-11 12:16 ` Junjie Mao
2025-02-11 12:27 ` Paolo Bonzini [this message]
2025-02-12 1:22 ` Junjie Mao
2025-02-06 11:37 ` [PATCH] rust: add --rust-target option for bindgen Philippe Mathieu-Daudé
2025-02-06 11:38 ` Paolo Bonzini
2025-02-06 11:43 ` Philippe Mathieu-Daudé
2025-02-08 14:03 ` Stefan Hajnoczi
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=CABgObfaYNZ1JZddOhdGfMhPAVK+trX08B_wBS5MbvrUNdCGebA@mail.gmail.com \
--to=pbonzini@redhat.com \
--cc=junjie.mao@hotmail.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-rust@nongnu.org \
--cc=qemu-stable@nongnu.org \
--cc=zhao1.liu@intel.com \
/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).