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.
pub struct MyPhantomData<T>
}
fn main() {
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)] pub struct MyPhantom<T> } /// `String` is not copy, but `MyPhantom` is always Copy, like `PhantomData` fn test() -> impl Copy { MyPhantom::<String> } # fn main() {}
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)] pub struct MyPhantom<T> } /// `String` is not copy, so `MyPhantom` is not Copy fn test() -> impl Copy { MyPhantom::<String> } # fn main() {}
-
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! { struct MyPhantomData1<T> } ghost_lite::ghost! { struct MyPhantomData2<T> } # fn main() {}
ghost_lite::ghost! { struct MyPhantomData1<T> } ghost_lite::ghost! { #![mod_value_namespace = my_phantom_data_2] struct MyPhantomData2<T> } # fn main() {}
-
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! { struct MyPhantomData<T: Clone + PartialEq> } # fn main() {}
ghost_lite::ghost! { struct MyPhantomData<T> where T: Clone + PartialEq } # fn main() {}
-
Please don't add a trailing semicolon
;.ghost_lite::ghost! { struct MyPhantomData<T>; } # fn main() {}
ghost_lite::ghost! { struct MyPhantomData<T> } # fn main() {}