External Publication
Visit Post

Sized (or Sizeable) str, e.g. str<const N: usize>

Rust Internals [Unofficial] April 30, 2026
Source

daniel-pfeiffer:

Is there already a way of achieving this?

Given that you’re already using macros-pretending-to-be-literals, you can obtain the string length at compile time to derive the type from the literal value:

#[repr(transparent)]
pub struct SizStr<const LEN: usize>([u8; LEN]);

impl<const LEN: usize> SizStr<LEN> {
    pub const fn strict_from_ref(s: &str) -> &Self {
        // as long as you use the macro, this assertion cannot fail
        assert!(s.len() == LEN);
        // SAFETY: Self is a transparent wrapper, the input bytes are UTF-8,
        // and we checked the length.
        unsafe { &*(&raw const *s).cast::<Self>() }
    }

    pub fn as_str(&self) -> &str {
        // SAFETY: Length and utf-8 was checked at construction time
        unsafe { core::str::from_utf8_unchecked(self.as_array()) }
    }

    pub fn as_array(&self) -> &[u8; LEN] {
        &self.0
    }
}

macro_rules! sizstr {
    ($text:literal) => {
        SizStr::<{ $text.len() }>::strict_from_ref($text)
    };
}

fn main() {
    let s: &'static SizStr<5> = sizstr!("hello");
    println!("{:?} {:?}", s.as_str(), s.as_array());

    // this will be a type error, not a const eval error!
    // let _: &'static SizStr<6> = sizstr!("hello");
}

Discussion in the ATmosphere

Loading comments...