Am I the only one surprised by this Rust behavior?
I expected that, due to generics, a separate instance of ONCE would be generated for each monomorphized version of get_name<T>(). However, it appears that there is only a single static instance being reused across different callers.
My questions are:
- Am I the only one finding this unexpected?
- Could someone clarify why my assumption that there should be two distinct instances of
ONCEis incorrect?
#[test]
fn once_lock_with_generics() {
use std::sync::OnceLock;
trait SomeTrait {
const NAME: &'static str;
}
fn get_name<T: SomeTrait>() -> &'static str {
static ONCE: OnceLock<&'static str> = OnceLock::new();
ONCE.get_or_init(|| T::NAME)
}
struct SomeStruct1;
impl SomeTrait for SomeStruct1 {
const NAME: &'static str = "some-struct-1";
}
struct SomeStruct2;
impl SomeTrait for SomeStruct2 {
const NAME: &'static str = "some-struct-2";
}
// This prints 'some-struct-1'
println!("SomeStruct1::NAME: {}", <SomeStruct1 as SomeTrait>::NAME);
// This prints 'some-struct-1'
println!("get_name::<SomeStruct1>: {}", get_name::<SomeStruct1>());
// This prints 'some-struct-2'
println!("SomeStruct2::NAME: {}", <SomeStruct2 as SomeTrait>::NAME);
// This prints 'some-struct-1'!!! WHAT?!? ...confused...
println!("get_name::<SomeStruct2>: {}", get_name::<SomeStruct2>());
}