add raw_type! macro for ABI-safe raw newtypes - #314
Merged
Conversation
phip1611
commented
Aug 25, 2026
phip1611
force-pushed
the
fix/open-enum-newtypes
branch
from
August 25, 2026 16:03
b9fd642 to
4c96a1f
Compare
phip1611
commented
Aug 26, 2026
phip1611
left a comment
Member
Author
There was a problem hiding this comment.
Getting closer. Please make sure to run all CI test also locally (e.g. rustdoc fails).
phip1611
force-pushed
the
fix/open-enum-newtypes
branch
3 times, most recently
from
August 26, 2026 05:43
c1c7c34 to
8d03ffb
Compare
phip1611
commented
Aug 26, 2026
| /// The newtype must debug-print the semantic of its value. | ||
| #[test] | ||
| fn test_debug() { | ||
| assert_eq!(format!("{:?}", TestRaw::new(0)), "Foo"); |
Member
Author
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.
phip1611
commented
Aug 26, 2026
| pub struct ConsoleHeaderTagFlagsRaw(u32); | ||
|
|
||
| /// Possible flags for [`ConsoleHeaderTag`]. | ||
| /// The console flags of the [`ConsoleHeaderTag`]. The values are taken |
Member
Author
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.
phip1611
commented
Aug 26, 2026
| /// 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 |
Member
Author
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.
phip1611
force-pushed
the
fix/open-enum-newtypes
branch
from
August 26, 2026 06:16
c06fcbf to
0b197e3
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
UB-free safe parsing of enums and bitflags from binary data structures via a new
raw_type!macro.