Uh oh!
There was an error while loading. Please reload this page.
add raw_type! macro for ABI-safe raw newtypes - #314
Conversation
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
b9fd642 to
4c96a1fCompare
phip1611
left a comment
There was a problem hiding this comment.
Getting closer. Please make sure to run all CI test also locally (e.g. rustdoc fails).
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
c1c7c34 to
8d03ffbCompare| /// The newtype must debug-print the semantic of its value. | ||
| #[test] | ||
| fn test_debug() { | ||
| assert_eq!(format!("{:?}", TestRaw::new(0)), "Foo"); |
There was a problem hiding this comment.
Debug should always be Foo(x) where x is the known discriminant. Display impl should be Foo for known variants and Custom(x) for the custom value.
| pub struct ConsoleHeaderTagFlagsRaw(u32); | ||
| /// Possible flags for [`ConsoleHeaderTag`]. | ||
| /// The console flags of the [`ConsoleHeaderTag`]. The values are taken |
There was a problem hiding this comment.
"The values are take from the example C Code"... remove! The crate is spec compliant so this is clear. Also make sure you do not use such doc elsewhere.
| /// representation (`u32`). This value stands in the `arch` property of | ||
| /// [`crate::Multiboot2BasicHeader`]. | ||
| /// ABI compatible representation of the ISA/ARCH of a Multiboot2 header, | ||
| /// matching the binary representation (`u32`). This value stands in the |
There was a problem hiding this comment.
A single sentence introducing the type, then a newline, then a new paragraph. also in other doc comments you are touching.
Several #[repr(C)] structures across the workspace store fields typed as Rust enums with a restricted set of valid discriminants. As these structures are parsed from raw bootloader-provided memory, any unknown value is undefined behavior. The macro generates the fix once: a #[repr(transparent)] newtype (Raw suffix) for which every bit pattern is valid, a high-level open-set enum with a generated Custom fallback variant, and all conversions between newtype, enum, and integer.
Renames the hand-written newtype to follow the new Raw-suffix convention of the macro. No behavioral change. The MbiTagTypeId re-export of multiboot2-header follows the rename to MbiTagTypeRaw so that every commit builds.
Also lets MemoryArea::typ() return the high-level MemoryAreaType and MemoryArea::new() take impl Into<MemoryAreaType>. The newtype becomes #[repr(transparent)] instead of #[repr(C)] (identical layout).
new() now takes &[MbiTagType] and requests() returns an iterator over MbiTagType; the raw representation stays an internal storage detail. Follows the rename of MbiTagTypeId to MbiTagTypeRaw.
The type field was a Rust enum with three valid discriminants, so parsing a tag with an unknown framebuffer type was undefined behavior. The field now stores the FramebufferTypeRaw newtype generated by raw_type!; the open-set FramebufferKind enum drives the dispatch in buffer_type(), which reports unknown values as UnknownFramebufferType, as before.
The memory_model field was a Rust enum with eight valid discriminants, while the VBE spec reserves 0x08..=0x0F and assigns 0x10..=0xFF to the OEM. The field is now typed as the VBEMemoryModelRaw newtype generated by raw_type!; VBEMemoryModel gained a Custom variant.
The tag type was a Rust enum with eleven valid discriminants and is read for every tag during iteration of raw memory, so any custom or future tag type was undefined behavior. HeaderTagHeader now stores the HeaderTagTypeRaw newtype generated by raw_type!; the typ() getters keep returning HeaderTagType, which gained a Custom variant. The unused HeaderTagType::count() was removed.
The arch field was the HeaderTagISA enum with two valid discriminants (0 and 4), so loading an image with any other architecture value was undefined behavior. The field now stores the HeaderTagISARaw newtype generated by raw_type!; the arch() getters keep returning HeaderTagISA, which gained a Custom variant.
The preference field was a Rust enum with three valid discriminants, so parsing a tag with any other value was undefined behavior. The tag now stores the RelocatableHeaderTagPreferenceRaw newtype generated by raw_type!; preference() keeps returning the high-level enum, which gained a Custom variant.
The flags field of every header tag was the HeaderTagFlag enum with two valid discriminants, so parsing a tag with any other value was undefined behavior. HeaderTagHeader now stores the HeaderTagFlagRaw newtype generated by raw_type!; the flags() getters keep returning HeaderTagFlag, which gained a Custom variant.
The enum discriminants did not match the specification: per the example C code, console-required is value 1 and EGA text support is value 2, but the enum serialized them as 0 and 1. A bootloader therefore read a ConsoleRequired tag as "no console required", and parsing any other value was undefined behavior. The tag now stores the ConsoleHeaderTagFlagsRaw newtype generated by raw_type!, and the enum carries the spec-mandated values plus a Custom variant.
Replaces the test_assert_size()/test_layout()-style unit tests with const assertions placed right after the respective type definitions. This checks the layout on every build instead of only when running the test suite.
Raw types start with "ABI compatible representation of ..."; the high-level enums first explain what the type is and then reference the raw type they abstract.
Raw types consistently start with "ABI compatible representation of ..."; the high-level enums first explain what the type is according to the spec and then reference the raw type they abstract.
…enums Raw types consistently start with "ABI compatible representation of ..."; the high-level enums first explain what the type is according to the spec and then reference the raw type they abstract.
c06fcbf to
0b197e3CompareUh oh!
There was an error while loading. Please reload this page.
UB-free safe parsing of enums and bitflags from binary data structures via a new
raw_type!macro.