A lightweight implementation of ::ghost with macro_rules.
use ghost_lite::ghost;ghost!{/// `ghost` macro defines a custom `PhantomData`,/// which can be used as both a type and a value.pubstructMyPhantomData<T>
}fnmain(){let _:MyPhantomData<i32> = MyPhantomData;let _ = MyPhantomData::<&str>;}deriveshould be in inner attributes (#![derive(...)]). Only the following traits are supported.ghost_lite::ghost! { #![derive(Clone,Copy,Default,Hash,PartialOrd,Ord,PartialEq,Eq,Debug)]pubstructMyPhantom<T> }/// `String` is not copy, but `MyPhantom` is always Copy, like `PhantomData`fntest() -> implCopy{MyPhantom::<String>} # fnmain(){}
derivein outer attributes will be directly prepended to the generatedenum, which works like normal derive macros.ghost_lite::ghost! {/// MyPhantom is `Clone` and `Copy` only if T is `Clone` and `Copy` #[derive(Clone,Copy)]pubstructMyPhantom<T> }/// `String` is not copy, so `MyPhantom` is not Copyfntest() -> implCopy{MyPhantom::<String>} # fnmain(){}
The implementation relies on a
modname. To define multiple custom PhantomData types in the same module, you must provide custommodname with#![mod_value_namespace = my_phantom_data].ghost_lite::ghost! {structMyPhantomData1<T> } ghost_lite::ghost! {structMyPhantomData2<T> } # fnmain(){}
ghost_lite::ghost! {structMyPhantomData1<T> } ghost_lite::ghost! { #![mod_value_namespace = my_phantom_data_2]structMyPhantomData2<T> } # fnmain(){}
Move type generic bounds to
whereclause ifghost!reports error.Parsing tokens is limited with
macro_rules, so complex type bounds are not supported.For example:
ghost_lite::ghost! {structMyPhantomData<T:Clone + PartialEq> } # fnmain(){}
ghost_lite::ghost! {structMyPhantomData<T> whereT:Clone + PartialEq} # fnmain(){}
Please don't add a trailing semicolon
;.ghost_lite::ghost! {structMyPhantomData<T>;} # fnmain(){}
ghost_lite::ghost! {structMyPhantomData<T> } # fnmain(){}