macro_rules! test_fields {
    (@root $struct:ident $(<$life:lifetime>)? { $($input:tt)* } ) => { ... };
    (@munch $struct:ident $(<$life:lifetime>)?
        (
            $(#[$attr_end:meta])*
            ($size:expr => @END),
        )
        : $stmts:expr
    ) => { ... };
    (@munch $struct:ident $(<$life:lifetime>)?
        (
            $(#[$attr:meta])*
            ($offset_start:expr => $vis:vis $field:ident: $ty:ty),
            $(#[$attr_next:meta])*
            ($offset_end:expr => $($next:tt)*),
            $($after:tt)*
        )
        : $output:expr
    ) => { ... };
    (@munch $struct:ident $(<$life:lifetime>)?
        (
            $(#[$attr:meta])*
            ($offset_start:expr => $padding:ident),
            $(#[$attr_next:meta])*
            ($offset_end:expr => $($next:tt)*),
            $($after:tt)*
        )
        : $output:expr
    ) => { ... };
}
Expand description

Statically validate the size and offsets of the fields defined within the register struct through the register_structs!() macro.

This macro expands to an expression which contains static assertions about various parameters of the individual fields in the register struct definition. It will test for:

  • Proper start offset of padding fields. It will fail in cases such as

    # #[macro_use]
    # extern crate tock_registers;
    # use tock_registers::register_structs;
    # use tock_registers::registers::ReadWrite;
    register_structs! {
        UartRegisters {
            (0x04 => _reserved),
            (0x08 => foo: ReadWrite<u32>),
            (0x0C => @END),
        }
    }
    # // This is required for rustdoc to not place this code snipped into an
    # // fn main() {...} function.
    # fn main() { }
    

    In this example, the start offset of _reserved should have been 0x00 instead of 0x04.

  • Correct start offset and end offset (start offset of next field) in actual fields. It will fail in cases such as

    # #[macro_use]
    # extern crate tock_registers;
    # use tock_registers::register_structs;
    # use tock_registers::registers::ReadWrite;
    register_structs! {
        UartRegisters {
            (0x00 => foo: ReadWrite<u32>),
            (0x05 => bar: ReadWrite<u32>),
            (0x08 => @END),
        }
    }
    # // This is required for rustdoc to not place this code snipped into an
    # // fn main() {...} function.
    # fn main() { }
    

    In this example, the start offset of bar and thus the end offset of foo should have been 0x04 instead of 0x05.

  • Invalid alignment of fields.

  • That the end marker matches the actual generated struct size. This will fail in cases such as

    # #[macro_use]
    # extern crate tock_registers;
    # use tock_registers::register_structs;
    # use tock_registers::registers::ReadWrite;
    register_structs! {
        UartRegisters {
            (0x00 => foo: ReadWrite<u32>),
            (0x04 => bar: ReadWrite<u32>),
            (0x10 => @END),
        }
    }
    # // This is required for rustdoc to not place this code snipped into an
    # // fn main() {...} function.
    # fn main() { }