token_cell/
ghost.rs

1use core::{cell::UnsafeCell, convert::Infallible};
2
3use crate::core::TokenTrait;
4
5#[derive(Clone, Copy)]
6pub struct InvariantLifetime<'a>(core::marker::PhantomData<UnsafeCell<&'a ()>>);
7impl<'a> InvariantLifetime<'a> {
8    const fn new() -> Self {
9        Self(core::marker::PhantomData)
10    }
11}
12
13/// WARNING: This attempt at recreating GhostCell but with traits does NOT work.
14///
15/// I am leaving this here because I believe there may exist a way to make this type of
16/// token work, and anyone who has ideas of how to do so is welcome to try and make a PR.
17///
18/// To check your theory, clone this repo and use the `ghost.rs` example as a check for
19/// your attempt. If your method works, the example should have some compile error.
20pub struct GhostToken<'brand>(InvariantLifetime<'brand>);
21impl<'brand> TokenTrait for GhostToken<'brand> {
22    type ConstructionError = ();
23    type RunError = Infallible;
24    type Identifier = InvariantLifetime<'brand>;
25    type ComparisonError = Infallible;
26    fn new() -> Result<Self, Self::ConstructionError> {
27        Err(())
28    }
29    fn with_token<R, F: FnOnce(Self) -> R>(f: F) -> Result<R, Self::RunError> {
30        Ok(f(Self(InvariantLifetime::new())))
31    }
32
33    fn identifier(&self) -> InvariantLifetime<'brand> {
34        self.0
35    }
36
37    fn compare(&self, _: &InvariantLifetime<'brand>) -> Result<(), Self::ComparisonError> {
38        Ok(())
39    }
40}