Expand description

Pain-free self-referential pinned types.

This crate (currently) requires nightly, as it relies on GATs.

Example

#![feature(generic_associated_types)]
#![feature(pin_macro)]

use core::cell::Cell;
use core::marker::PhantomData;
use core::pin::Pin;
use core::pin::pin;
 
use selfref::Holder;
use selfref::NewWith;
use selfref::OperateIn;
use selfref::SelfRef;
use selfref::opaque;

struct Foo<'a, 'b: 'a> {
    foo: Cell<Option<&'a Foo<'a, 'b>>>,
    t: &'b str,
}
impl<'a, 'b> SelfRef<'a> for Foo<'a, 'b> {}

struct FooKey<'b>(PhantomData<&'b str>);
opaque! {
    impl['b] Opaque for FooKey<'b> {
        type Kind<'a> = Foo<'a, 'b>;
    }
}

fn main() {
    struct FooBuilder<'b>(&'b str);
    impl<'k, 'b: 'k> NewWith<'k, FooKey<'b>> for FooBuilder<'b> {
        fn new_with<'a>(self) -> Foo<'a, 'b> where 'k: 'a {
            Foo {
                foo: Default::default(),
                t: self.0,
            }
        }
    }
    let stack_array: [u8; 5] = *b"hello";
    // a non-'static &str
    let stack_str = core::str::from_utf8(&stack_array).unwrap();
    let holder = pin!(Holder::new_with(FooBuilder(stack_str)));
    // Actually making our Foo refer to itself.
    struct SetFooRef;
    impl<'k, 'b: 'k> OperateIn<'k, FooKey<'b>> for SetFooRef {
        type Out = ();
        fn operate_in<'a>(self, foo: Pin<&'a Foo<'a, 'b>>)
        where 'k: 'a {
            foo.foo.set(Some(foo.get_ref()));
        }
    }
    holder.as_ref().operate_in(SetFooRef);
}

Macros

Creates an opaqueified self-referential struct “key”.

Structs

Holds an “opaqueified” T::Kind.

Traits

Helper trait for creating a Holder.

An opaqueified self-referential struct “key”.

Helper trait for working with a Holder.

A self-referential struct.

Functions

Helper for creating a Holder using a closure.

Helper for working with a Holder using a closure.