Asserting lifetime/dropck equality

I have some code:

pub unsafe trait ArrayRepr<const DIMENSION: usize> {
    /// Safety: must always be `Self` or nested arrays of `Self`
    type Repr;

pub struct Array<T: ArrayRepr<DIMENSION>, const DIMENSION: usize>(T::Repr);

impl<T: ArrayRepr<DIMENSION>, const DIMENSION: usize> Array<T, DIMENSION> {
    pub fn fill(f: impl FnMut() -> T) -> Self {

unsafe impl<T> ArrayRepr<0> for T {
    type Repr = T;

macro_rules! make_reprs {
    ($($dim:literal,)+) => {
        $(unsafe impl<T> ArrayRepr<$dim> for T {
            type Repr = [<T as ArrayRepr<{$dim - 1}>>::Repr; 2];

make_reprs!(1, 2, 3, 4, 5, 6, 7, 8,); // ...

I want to use it generically with arenas:

use core::marker::PhantomData;

pub struct Arena<T, A>(PhantomData<T>, A);

impl<T, A> Arena<T, A> {
    pub fn new(v: A) -> Self {
    pub fn alloc<'a>(&'a self, v: T) -> &'a T {

struct NodeId<'a, const DIMENSION: usize>(Option<&'a NodeData<'a, DIMENSION>>)
    NodeId<'a, DIMENSION>: ArrayRepr<DIMENSION>;

type NodeData<'a, const DIMENSION: usize> = Array<NodeId<'a, DIMENSION>, DIMENSION>;

fn f<A, const DIMENSION: usize>(a: A)
    for<'a> NodeId<'a, DIMENSION>: ArrayRepr<DIMENSION>,
    let arena = Arena::<NodeData<DIMENSION>, A>::new(a);
    let node = arena.alloc(Array::fill(|| NodeId(None)));
    let node2 = arena.alloc(Array::fill(|| NodeId(Some(node))));

How do I say that NodeId::Repr has the same dropck properties as NodeId, which will allow me to write f without tripping the dropck when arena is dropped?

It works just fine for non-generic DIMENSION since rustc can then see that NodeId::Repr is just a nested array of NodeId.

Hmm, it looks like something's missing here... should that say for Array<T, LENGTH>?

This doesn't make sense, because the aliases are mutually recursive... you can't define a type alias in terms of itself like that. The types have to make sense without being aliased.

Edited to fix the code, added a playground link with a working example

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.