Type matching

I wrote a proc_macro for generating 1k structures for different levels of an Octree that's supposed to be linear and implemented a common trait for them for accessing value and children.

What I actually wanted all along was to write something like:

type OctreeNode<T, const Size: usize> = match Size {
  0 => T,
  _ => NodeImpl<T, Size>,
};

which is exhaustive and wouldn't require me to generate 1k+ structures from a proc_macro to mimic the same pattern.

This is possible in C++ due to how templates work, but it left me wondering whether there's any talk about supporting this pattern in Rust as it's very useful for recursive data structures and I've found myself needing it several times.

The same thing is doable with pointers but it requires unsafe code that can be avoided.

1 Like

I know you can do this if instead of const generics, you use typenum, then NodeImpl<T, Size> becomes an projection of an associated type of a trait.

Or rather, it's commonly said that Rust doesn't have struct specialization, but since associated types are type-level functions, if a struct includes an associated type it essentially can do pattern matching at type level, but with a more cumbersome syntax rather than your proposed syntax.

Maybe this is possible with const generics too.

1 Like

Pattern types might enable this.

1 Like

Thanks for the input so far. I guess both answers solve the issue with way less (generated) code.

typenum solution would look something like:

trait OctreeNode<T>  {
  type Value;
}
impl<T> OctreeNode<T> for U0 {
  type Value = T;
}
impl<T, Other: NonZero + Unsigned> OctreeNode<T> for Other {
  type Value = NodeImpl<T, Other::USIZE>;
}

I ended up doing it with pointers in meantime, but the typenum approach would remove an unstable feature so I might switch to that in the future.