#![allow(dead_code, deprecated, unused_variables, unused_mut)] mod unique { use std::any::TypeId; use std::collections::BTreeSet; use std::marker::PhantomData; use std::sync::Mutex; static ID_SET: Mutex> = Mutex::new(BTreeSet::new()); #[derive(Debug, PartialEq)] pub struct Unique(PhantomData); impl Unique { pub fn new() -> Option { let mut set = ID_SET.lock().unwrap(); (set.insert(TypeId::of::())).then(|| Self(PhantomData)) } } impl Drop for Unique { fn drop(&mut self) { let mut set = ID_SET.lock().unwrap(); (!set.remove(&TypeId::of::())) .then(|| panic!("duplicity detected")); } } } use unique::Unique; type TheOneRing = fn(&'static ()); type OtherRing = fn(&()); fn main() { let the_one_ring: Unique = Unique::new().unwrap(); assert_eq!(Unique::< TheOneRing >::new(), None); let other_ring: Unique = Unique::new().unwrap(); let fake_one_ring: Unique = other_ring; assert_eq!(fake_one_ring, the_one_ring); std::mem::forget(fake_one_ring); }