pub struct Holder<'k, T> where
    T: Opaque + 'k, 
{ /* private fields */ }
Expand description

Holds an “opaqueified” T::Kind.

Note the lifetime, 'k. This can be anything, as long as T outlives it.

Examples

#![feature(generic_associated_types)]

use core::cell::Cell;
 
use selfref::Holder;
use selfref::new_with_closure;
use selfref::opaque;

#[derive(Default)]
struct Foo<'a> {
    foo: Cell<Option<&'a Foo<'a>>>,
}

struct FooKey;
opaque! {
    impl Opaque for FooKey {
        type Kind<'a> = Foo<'a>;
    }
}

fn main() {
    // We can use a closure here, but we need to give the compiler a hint.
    let holder = Holder::<'_, FooKey>::new_with(
        new_with_closure::<FooKey, _>(|foo| Foo::default())
    );
}

Implementations

Creates a new holder.

Examples

Simple example:

#![feature(generic_associated_types)]

use core::cell::Cell;
 
use selfref::Holder;
use selfref::new_with_closure;
use selfref::opaque;

#[derive(Default)]
struct Foo<'a> {
    foo: Cell<Option<&'a Foo<'a>>>,
}

struct FooKey;
opaque! {
    impl Opaque for FooKey {
        type Kind<'a> = Foo<'a>;
    }
}

fn main() {
    // We can use a closure here, but we need to help the compiler.
    let holder = Holder::<'_, FooKey>::new_with(
        new_with_closure::<FooKey, _>(|foo| Foo::default())
    );
}

Lifetime parameters:

#![feature(generic_associated_types)]

use core::cell::Cell;
use core::marker::PhantomData;
 
use selfref::Holder;
use selfref::NewWith;
use selfref::opaque;

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

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 = Holder::new_with(FooBuilder(stack_str));
}

Operates in this (pinned) holder.

This “unwraps” the value in this holder, and binds its lifetime to a new stack frame.

Examples

Simple example:

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

use core::cell::Cell;
use core::pin::pin;
 
use selfref::Holder;
use selfref::new_with_closure;
use selfref::opaque;
use selfref::operate_in_closure;

#[derive(Default)]
struct Foo<'a> {
    foo: Cell<Option<&'a Foo<'a>>>,
}

struct FooKey;
opaque! {
    impl Opaque for FooKey {
        type Kind<'a> = Foo<'a>;
    }
}

fn main() {
    let holder = pin!(Holder::<'_, FooKey>::new_with(
        new_with_closure::<FooKey, _>(|foo| Foo::default())
    ));
    // Actually making our Foo refer to itself.
    holder.as_ref().operate_in(
        operate_in_closure::<FooKey, _, _>(|foo| {
            foo.foo.set(Some(foo.get_ref()));
        })
    );
}

With lifetime parameters:

#![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::opaque;

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

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);
}

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.