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.