Re: [PATCH v4 07/20] rust: io: implement `Mmio` as view type
From: Alexandre Courbot
Date: Mon Jun 15 2026 - 20:18:29 EST
On Tue Jun 16, 2026 at 12:13 AM JST, Gary Guo wrote:
> On Mon Jun 15, 2026 at 3:52 PM BST, Alexandre Courbot wrote:
>> On Fri Jun 12, 2026 at 1:28 AM JST, Gary Guo wrote:
>> <...>
>>> +/// A view of memory-mapped I/O region.
>>> +///
>>> +/// # Invariant
>>> +///
>>> +/// `ptr` points to a valid and aligned memory-mapped I/O region for the duration lifetime `'a`.
>>> +pub struct Mmio<'a, T: ?Sized> {
>>> + ptr: *mut T,
>>> + phantom: PhantomData<&'a ()>,
>>> +}
>>> +
>>> +impl<T: ?Sized> Copy for Mmio<'_, T> {}
>>> +impl<T: ?Sized> Clone for Mmio<'_, T> {
>>> + #[inline]
>>> + fn clone(&self) -> Self {
>>> + *self
>>> + }
>>> +}
>>> +
>>> +impl<'a, T: ?Sized> Mmio<'a, T> {
>>> + /// Create a `Mmio`, providing the accessors to the MMIO mapping.
>>> + ///
>>> + /// # Safety
>>> + ///
>>> + /// `raw` represents an valid and aligned memory-mapped I/O region while `'a` is alive.
>>
>> typo: "a valid".
>>
>> <...>
>>> -/// [`MmioOwned`] wrapper using relaxed accessors.
>>> +/// [`Mmio`] but using relaxed accessors.
>>> ///
>>> /// This type provides an implementation of [`Io`] that uses relaxed I/O MMIO operands instead of
>>> /// the regular ones.
>>> ///
>>> -/// See [`MmioOwned::relaxed`] for a usage example.
>>> -#[repr(transparent)]
>>> -pub struct RelaxedMmio<const SIZE: usize = 0>(MmioOwned<SIZE>);
>>> +/// See [`Mmio::relaxed`] for a usage example.
>>> +///
>>> +/// # Invariant
>>> +///
>>> +/// `ptr` points to a valid and aligned memory-mapped I/O region for the duration lifetime `'a`.
>>> +pub struct RelaxedMmio<'a, T: ?Sized> {
>>> + ptr: *mut T,
>>> + phantom: PhantomData<&'a ()>,
>>> +}
>>
>> Is there a reason for not just declaring `RelaxedMmio` as
>>
>> #[repr(transparent)]
>> pub struct RelaxedMmio<'a, T: ?Sized>(Mmio<'a, T>);
>>
>> similarly to what the original code did with `MmioOwned`?
>>
>> I tried locally and could build. This avoids declaring `Mmio` and
>> `RelaxedMmio` as basically identical types, and lets us remove the
>> explicit `Send` and `Sync` implementations. IIUC you can also reduce or
>> even remove the invariant section as it is enforced by `Mmio`.
>
> This is what I did originally, but this would cause duplication for
> RelaxedMmioBackend, as now you have to do
>
> unsafe { bindings::$read_fn(view.0.ptr.cast_const().cast()) }
>
> and the `.0` causes the macro not being shared with MmioBackend.
Since `MmioBackend` and `RelaxedMmioBackend` both implement `IoBackend`,
I think using `IoBackend::as_ptr` in the macro should let you avoid the
duplication?