// check-pass #![feature(inline_const, generic_const_exprs)] #![allow(incomplete_features)] use std::marker::PhantomData; pub struct Equal(); pub trait True {} impl True for Equal {} // replacement for generativity pub struct Id<'id>(PhantomData &'id ()>); pub struct Guard<'id>(Id<'id>); fn make_guard<'id>(i: &'id Id<'id>) -> Guard<'id> { Guard(Id(PhantomData)) } impl<'id> Into> for Guard<'id> { fn into(self) -> Id<'id> { self.0 } } pub struct Arena<'life> { bytes: *mut [u8], //bitmap: RefCell, _token: PhantomData>, } #[repr(transparent)] pub struct Item<'life, T> { data: T, _phantom: PhantomData>, } #[repr(transparent)] pub struct Token<'life, 'borrow, 'compact, 'reborrow, T> where 'life: 'reborrow, T: Tokenize<'life, 'borrow, 'compact, 'reborrow>, { //ptr: *mut ::Tokenized, ptr: core::ptr::NonNull, _phantom: PhantomData>, _compact: PhantomData<&'borrow Guard<'compact>>, _result: PhantomData<&'reborrow T::Untokenized>, } impl<'life> Arena<'life> { pub fn tokenize<'before, 'compact, 'borrow, 'reborrow, T, U>( &self, guard: &'borrow Guard<'compact>, item: Item<'life, &'before mut T>, ) -> Token<'life, 'borrow, 'compact, 'reborrow, U> where T: Tokenize<'life, 'borrow, 'compact, 'reborrow, Untokenized = U>, T::Untokenized: Tokenize<'life, 'borrow, 'compact, 'reborrow>, Equal<{ core::mem::size_of::() }, { core::mem::size_of::() }>: True, 'compact: 'borrow, 'life: 'reborrow, 'life: 'compact, 'life: 'borrow, // 'borrow: 'before ?? { let dst = item.data as *mut T as *mut T::Tokenized; Token { ptr: core::ptr::NonNull::new(dst as *mut _).unwrap(), _phantom: PhantomData, _compact: PhantomData, _result: PhantomData, } } } pub trait Tokenize<'life, 'borrow, 'compact, 'reborrow> where 'compact: 'borrow, 'life: 'reborrow, 'life: 'borrow, 'life: 'compact, { type Tokenized; type Untokenized; const TO: fn(&Arena<'life>, &'borrow Guard<'compact>, Self) -> Self::Tokenized; const FROM: fn(&'reborrow Arena<'life>, Self::Tokenized) -> Self::Untokenized; } macro_rules! tokenize { ($to:expr, $from:expr) => { const TO: fn(&Arena<'life>, &'borrow Guard<'compact>, Self) -> Self::Tokenized = $to; const FROM: fn(&'reborrow Arena<'life>, Self::Tokenized) -> Self::Untokenized = $from; }; } struct Foo<'life, 'borrow>(Option>); struct TokenFoo<'life, 'borrow, 'compact, 'reborrow>( Option>, ); struct Bar(u8); impl<'life, 'before, 'borrow, 'compact, 'reborrow> Tokenize<'life, 'borrow, 'compact, 'reborrow> for Foo<'life, 'before> where 'compact: 'borrow, 'life: 'reborrow, 'life: 'borrow, 'life: 'compact, { type Tokenized = TokenFoo<'life, 'borrow, 'compact, 'reborrow>; type Untokenized = Foo<'life, 'reborrow>; tokenize!(foo_to, foo_from); } impl<'life, 'borrow, 'compact, 'reborrow> Tokenize<'life, 'borrow, 'compact, 'reborrow> for Bar where 'compact: 'borrow, 'life: 'reborrow, 'life: 'borrow, 'life: 'compact, { type Tokenized = Bar; type Untokenized = Bar; tokenize!(bar_to, bar_from); } fn bar_to<'life, 'borrow, 'compact>( arena: &Arena<'life>, guard: &'borrow Guard<'compact>, s: Bar, ) -> Bar { s } fn bar_from<'life, 'reborrow>(arena: &'reborrow Arena<'life>, s: Bar) -> Bar { s } fn foo_to<'life, 'borrow, 'compact, 'reborrow, 'before>( arena: &'before Arena<'life>, guard: &'borrow Guard<'compact>, s: Foo<'life, 'before>, ) -> TokenFoo<'life, 'borrow, 'compact, 'reborrow> { let Foo(bar) = s; TokenFoo(bar.map(|bar| arena.tokenize(guard, bar))) } fn foo_from<'life, 'borrow, 'compact, 'reborrow>( arena: &'reborrow Arena<'life>, s: TokenFoo<'life, 'borrow, 'compact, 'reborrow>, ) -> Foo<'life, 'reborrow> { Foo(s.0.map(|bar| panic!())) } fn main() {}