What is the meaning of PhantomData<*const ()> for a RegisterBlock struct?

Hello everyone. I'm studying some low level code used to access memory mapped I/O (specifically the PAC for the RP2040, but I've seen it happen for other MCUs as well). If I understand correctly a RegisterBlock struct that allows to access the specific registers is defined for each device class (e.g. UART); it then is integrated into a struct for every instance of the device (e.g. UART0); finally a DevicePeripheral is implemented on top of the device instance type.
All of this using zero cost abstractions to ensure that the ultimate register access is as efficient as possible.

I have yet to understand fully those abstraction and I need help with the first one: the UART0 device instance type, for example, is declared as:

pub struct UART0 {
    _marker<PhantomData<* const ()>>;
}

See the exact loc.
Now, I was under the impression that PhantomData is a zero-sized type useful only to make a type depends on another without needing to actually allocate memory for an instance. Here however the parameter is just *const (), which doesn't make UART0 depend on anything.

Why couldn't UART0 just be an empty struct? What does PhantomData achieve here?

It's the way to impl !Send + !Sync for UART0.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.