Trait selfref::Opaque

source ·
pub unsafe trait Opaque {
    type Kind<'a>: ?Sized
       where Self: 'a;
}
Expand description

An opaqueified self-referential struct “key”.

Safety

This is unsafe because there are a bunch of soundness invariants that need to be upheld. The following list is non-exhaustive:

  • Kind must not have a Drop impl in any “path” that may trace back to the original self-referential type, if said Drop impl can observe the self-referential type.
  • We assume Kind has the same layout for any 'a. This is true as of the time of writing this, and relies on Rust not having lifetime specialization.

It’s recommended to use the selfref::opaque! macro instead, which enforces these invariants. For example, this doesn’t compile:

use std::cell::Cell;
use selfref::opaque;

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

impl<'a> Drop for Foo<'a> {
    fn drop(&mut self) {
    }
}

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

But by removing the Drop impl, it compiles:

use std::cell::Cell;
use selfref::opaque;

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

//impl<'a> Drop for Foo<'a> {
//    fn drop(&mut self) {
//    }
//}

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

Examples

use core::cell::Cell;
 
use selfref::Opaque;

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

struct FooKey;
// SAFETY: Foo has no Drop impl and has the same layout for any 'a.
unsafe impl Opaque for FooKey {
    type Kind<'a> = Foo<'a>;
}

Required Associated Types§

source

type Kind<'a>: ?Sized where Self: 'a

The actual self-referential struct.

Implementors§