Skip to content

Instantly share code, notes, and snippets.

@lmmx
Last active May 16, 2025 20:32
Show Gist options
  • Save lmmx/8360701f6f1dff6f99b8f1ccb3635b44 to your computer and use it in GitHub Desktop.
Save lmmx/8360701f6f1dff6f99b8f1ccb3635b44 to your computer and use it in GitHub Desktop.
spez! macro monomorphisation to detect type parameterised Spans
//! ```cargo
//! [dependencies]
//! spez = "0.1.2"
//! ```
use spez::spez;
use core::marker::PhantomData;
#[derive(Debug)] pub enum Cooked {}
#[derive(Debug)] pub enum Raw {}
pub type Pos = usize;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Span<C = Cooked> {
pub start: Pos,
pub len: usize,
_p: PhantomData<C>,
}
impl<C> Span<C> {
pub fn new(start: Pos, len: usize) -> Self {
Self { start, len, _p: PhantomData }
}
}
/* ---- macro: every expansion is monomorphic ---- */
macro_rules! show_span {
($span:expr) => {
spez! {
for s = $span;
match Span<Cooked> {
println!("✓ cooked span: {:?}", s);
}
match Span<Raw> {
println!("✓ raw span: {:?}", s);
}
}
};
}
fn main() {
let normal = Span::new(12, 34);
let cooked = Span::<Cooked>::new(12, 34);
let raw = Span::<Raw>::new(56, 78);
show_span!(normal); // expands with Span<C = Cooked> → first arm
show_span!(cooked); // expands with Span<Cooked> → first arm
show_span!(raw); // expands with Span<Raw> → second arm
}
@lmmx
Copy link
Author

lmmx commented May 16, 2025

✓ cooked span: Span { start: 12, len: 34, _p: PhantomData<main_f452924a62bf1149e2ac941b::Cooked> }
✓ cooked span: Span { start: 12, len: 34, _p: PhantomData<main_f452924a62bf1149e2ac941b::Cooked> }
✓  raw   span: Span { start: 56, len: 78, _p: PhantomData<main_f452924a62bf1149e2ac941b::Raw> }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment