# Type matching

**URL:** <https://internals.rust-lang.org/t/type-matching/20008>\
**Category:** language design\
**Created:** [December 9, 2023, 8:33am UTC](https://internals.rust-lang.org/t/type-matching/20008 "2023-12-09T08:33:17Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![caellian](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/caellian/32/9680_2.png) [@caellian](https://internals.rust-lang.org/u/caellian)\
**Post date:** [December 9, 2023, 8:33am UTC](https://internals.rust-lang.org/t/type-matching/20008/1 "2023-12-09T08:33:17Z")

</div>

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:

```rust
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.

---

<div class="post-metadata">

**Author:** ![dlight](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/dlight/32/8462_2.png) [@dlight](https://internals.rust-lang.org/u/dlight)\
**Post date:** [December 9, 2023, 11:43am UTC](https://internals.rust-lang.org/t/type-matching/20008/2 "2023-12-09T11:43:23Z")

</div>

I know you can do this if instead of const generics, you use [typenum](https://docs.rs/typenum/latest/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.

---

<div class="post-metadata">

**Author:** ![Jules-Bertholet](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jules-bertholet/32/10671_2.png) [@Jules-Bertholet](https://internals.rust-lang.org/u/Jules-Bertholet)\
**Post date:** [December 9, 2023, 4:06pm UTC](https://internals.rust-lang.org/t/type-matching/20008/3 "2023-12-09T16:06:32Z")

</div>

[Pattern types](https://gist.github.com/joboet/0cecbce925ee2ad1ee3e5520cec81e30) might enable this.

---

<div class="post-metadata">

**Author:** ![caellian](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/caellian/32/9680_2.png) [@caellian](https://internals.rust-lang.org/u/caellian)\
**Post date:** [December 9, 2023, 7:43pm UTC](https://internals.rust-lang.org/t/type-matching/20008/4 "2023-12-09T19:43:53Z")

</div>

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

**typenum** solution would look something like:

```rust
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.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [March 8, 2024, 7:44pm UTC](https://internals.rust-lang.org/t/type-matching/20008/5 "2024-03-08T19:44:42Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
