1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
//! Attribute macro `#[compact_option(repr(R = …, sentinel = …))]` for emitting
//! `CompactRepr` for enums and structs.
//!
//! Used with `CompactOption` for niche-packing optional storage: `NONE`/`Some(T)` encoded in
//! exactly as much memory as raw `R`, by reserving one of `R`'s spare bit patterns as the sentinel.
//! Primarily `#[repr(u8)]` enums with fewer than 256 variants.
//!
//! # What this macro does (and does not)
//!
//! **Does:** parses `R` and `sentinel`, re-emits your item, and appends `unsafe impl const CompactRepr<R>`.
//! For structs it also emits `const` `size_of` / `align_of` checks against `R` so layout mismatches
//! fail in rustc const-eval (not token comparison).
//!
//! **Does not:** read `#[repr(...)]`, compute enum discriminants, compare sentinel to discriminants,
//! or validate `repr(transparent)` / field count. Those invariants are the implementer’s responsibility
//! per the `CompactRepr` safety contract; use tests and Miri.
//!
//! A trailing `, verify_discriminants = …` after `repr(...)` is accepted for compatibility and ignored.
//!
//! # Examples
//!
//! ## `repr(u8)` enum
//!
//! ```ignore
//! use compact_option_proc_macro::compact_option;
//!
//! #[compact_option(repr(R = u8, sentinel = 0xFF))]
//! #[repr(u8)]
//! #[derive(Clone, Copy)]
//! pub enum Letter {
//! A = 0,
//! B = 1,
//! }
//! ```
//!
//! ## `repr(transparent)` newtype
//!
//! ```ignore
//! use compact_option_proc_macro::compact_option;
//!
//! #[compact_option(repr(R = u8, sentinel = 0xFE))]
//! #[repr(transparent)]
//! #[derive(Clone, Copy)]
//! pub struct ByteSlot(pub u8);
//! ```
//!
//! # Safety
//!
//! This macro only emits `unsafe impl const CompactRepr` plus struct layout asserts. It does **not**
//! prove transmute soundness. Use Miri and the `CompactRepr` documentation.
use TokenStream;
use ;
use AttrArgs;
/// `#[compact_option(repr(R = <type>, sentinel = <expr>))]` on an enum or struct.
///
/// Optional trailing `, verify_discriminants = <bool>` is parsed and ignored.
///
/// # Limitations
///
/// - No analysis of enum discriminants or whether `sentinel` collides with them.
/// - No verification that `R` matches the enum’s integer `repr` or the newtype’s field type.
/// - For structs, only the emitted `size_of` / `align_of` checks tie layout to `R`.