Closed
Description
use std::mem;
pub trait Arena {
type Dyn : ?Sized;
}
pub struct DynRef {
_dummy: [()],
}
pub struct Ref<T, A: Arena> {
_value: T,
_dyn_arena: A::Dyn,
}
pub struct Obstack;
impl Arena for Obstack {
type Dyn = DynRef;
}
fn main() {
mem::size_of::<&Ref<u8, Obstack>>();
}
produces:
$ rustc ice-dyn.rs
error: internal compiler error: src/librustc_codegen_llvm/context.rs:867: failed to get layout for `&Ref<u8, Obstack>`: the type `<Obstack as Arena>::Dyn` has an unknown layout
thread 'rustc' panicked at 'Box<Any>', src/librustc_errors/lib.rs:620:9
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
error: aborting due to previous error
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports
note: rustc 1.34.1 (fc50f328b 2019-04-24) running on x86_64-unknown-linux-gnu
Some context as to what that's actually for: the idea was to use the len metadata of the slice within the DynRef
to smuggle a pointer to the arena in question. At first glance you'd think you could also do:
pub struct Ref<T, A: Arena> {
marker: PhantomData<A>,
value: T,
arena: [()],
}
But the problem is that is mutable borrows: if Ref
implements DerefMut
there's no way to both access the value and the arena at the same time. You need them separate, and deliberately public:
pub struct Ref<T, A: Arena> {
pub this: T,
pub arena: A::Dyn,
}
allowing implementations like:
impl<A: Arena> Foo {
fn frob(self: &mut Ref<Foo, A>) {
self.arena.get(self.this.bar);
}
}
...and as for why the object can't just own a reference to the arena it's in, tl;dr: memmap;