3 ms·
Rust turns an Option<T> into a raw nullable pointer[1] (with NULL being Option::None). This is cool because a 2-item enum with a single pointer would usually be
by isaacimagine 5y ago
Rust turns an Option<T> into a raw nullable pointer[1] (with NULL being Option::None). This is cool because a 2-item enum with a single pointer would usually be 8 (ptr) + 1 (tag) = 9 (total) ≈ 16 (padded) bytes, but it's only 8 because of this.
I'm simplifying a tad, look up 'null pointer specialization rust' for more. What's cool is the zero-cost abstraction over type layout specification, while allowing the generic Option<T> type to work exactly as expected.
[1]: Assuming T is a non-nullable pointer type.
- loeg 5y ago> Assuming T is a non-nullable pointer type. You can even do the same thing for a few special primitive integer types, such as std::num::NonZeroU64. https://doc.rust-lang.org/std/num/struct.NonZeroU64.html https://doc.rust-lang.org/std/num/struct.NonZeroU64.html : > Option<NonZeroU64> is the same size as u64 Behind the scenes, the type is defined with a magic compiler-internal incantation that isn't usable in user code, unfortunately: #[repr(transparent)] #[rustc_layout_scalar_valid_range_start(1)] #[rustc_nonnull_optimization_guaranteed] https://doc.rust-lang.org/src/core/num/nonzero.rs.html#39 https://doc.rust-lang.org/src/core/num/nonzero.rs.html#39
- tialaramex 5y agoYes, more of these would be nice, the ones we have are very valuable but it would be nice to make our own, ideally safely, but unsafe ones made carefully in a trustworthy library are good too. I would also like being able to tell the compiler about other niches. If a Foozle can be Ding, Ping, Zing or Number(n) where I promise n is from 0 to 199, that all fits in a byte if the compiler is willing to work with me by storing Ding, Ping and Zing as magic sentinels in the niche range 200 to 255 and I'm willing to trade the small runtime cost for the memory usage win.
- loeg 5y ago> If a Foozle can be Ding, Ping, Zing or Number(n) where I promise n is from 0 to 199, that all fits in a byte if the compiler is willing to work with me by storing Ding, Ping and Zing as magic sentinels in the niche range 200 to 255 and I'm willing to trade the small runtime cost for the memory usage win. Yeah, that would be cool. I think it would make sense to represent this as a repr(u8) enum with a range-limited Number variant. Something like: #[repr(u8)] enum Foozle { Ding, Ping, Zing, Number(u8 in 200..=255), // or whatever range syntax }