Re: [PATCH v2 05/11] rust: io: restrict untyped IO access and `register!` to `Region`

Gary Guo
2026-04-28T11:14:33Z

On Tue Apr 28, 2026 at 10:02 AM BST, Andreas Hindborg wrote:
> Gary Guo <gary@garyguo.net> writes:
>
>> Currently the `Io` trait exposes a bunch of untyped IO accesses, but if the
>> `Io` region itself is typed, then it might be weird to have
>>
>> let io: Mmio<u32> = /* ... */;
>> io.read8(1);
>>
>> while not unsound, it is surely strange. Thus, restrict the untyped methods
>> and also the register macro to `Region` type only.
>>
>> The way it is implemented is by adding a generic type to `IoLoc`. This also
>> paves the way to add typed register blocks in the future; for example, we
>> could use this mechanism to block driver A's `register!()` generated macro
>> from being used on driver B's MMIO. The same mechanism could be used for
>> relative IO registers. These are future opoortunities, and for this patch I
>> just restricted everything to require `IoLoc<Region<SIZE>, _>`.
>
> Does this not prevent `usize` from being used to index anything but
> `Mmio<Region<_>>`?
>
> It is my understanding that the following would work before this patch:
>
> fn do_read(io: &Mmio<u32>) -> Result {
> let v: u32 = io.try_read(8usize)?;
> Ok(())
> }
>
> But I think this will no longer work with this patch. Is that the intention?

Your example would always fail, as you're reading 4 bytes from offset 4 from a
region that is only 4 bytes in size. I suppose you're trying to say

fn do_read(io: &Mmio<[u32]>) -> Result {
let v: u32 = io.try_read(8usize)?;
Ok(())
}

? In any case, it's intended to be unsupported. For types regions you can use
projection. So the same code can be written as

fn do_read(io: &Mmio<[u32]>) -> Result {
let v: u32 = io_read!(io, [try: 2]);
Ok(())
}

i.e. reading from index 2 instead of byte offset 8. If one cares about byte
offset they would probably want to use the register macro instead or having the
MMIO region untyped.

Best,
Gary