Assert that `addr_of!` does not perform any deref coercions

I'm writing a macro with syntax like this:

dma_read!(my_dma[idx].foo);

Here, my_dma is a struct Dma<T> for some type T and it represents a memory region containing an array of T. I want to compute the offset of field foo in the type T, which you can naively do by having the macro emit:

let ptr = unsafe { &raw mut (*dma_ptr).foo };

where dma_ptr is a pointer of type T. However, the problem is that if T doesn't have a field called foo, then maybe the type implements Deref and then the compiler turns *dma_ptr into a &T and calls T::deref on it, at which point we have already triggered UB because the &T points into memory that might be modified by hardware.

How can one assert that no Deref coercion happens? One option is offset_of! macro, but that macro requires you to actually write T out, and I don't want to force the user to write out what the type is every time they invoke dma_read.

5 Likes

Actually, I found a solution:

trigger an ambiguity error if Deref is implemented

7 Likes