Sized (or Sizeable) str, e.g. str<const N: usize>
Rust Internals [Unofficial]
April 30, 2026
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