# Generic types in declarative macros

**URL:** <https://internals.rust-lang.org/t/generic-types-in-declarative-macros/6854>\
**Category:** Uncategorized\
**Created:** [February 28, 2018, 11:43am UTC](https://internals.rust-lang.org/t/generic-types-in-declarative-macros/6854 "2018-02-28T11:43:23Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![HadrienG](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/hadrieng/32/3294_2.png) [@HadrienG](https://internals.rust-lang.org/u/HadrienG)\
**Post date:** [February 28, 2018, 11:43am UTC](https://internals.rust-lang.org/t/generic-types-in-declarative-macros/6854/1 "2018-02-28T11:43:23Z")

</div>

I was trying to write a test suite and benchmark generator for a several generic structs which share a common interface (they all implement the same trait, as a matter of fact), and got the impression that declarative macros were the right tool for this. But then I realized that there is no obvious way to use a caller-specified generic type in macros.

Basically, the problem is that I want to instantiate `GenericStruct<T>` for various types T, which are implementation details of the test suite, but it seems there is no way to pass “GenericStruct” to the macro (e.g. as a “ty”) and instantiate it for various type parameters on the inside. Instead, it seems I need to pass all the instantiations of GenericStruct into the macro, which undesirably leaks implementation details and makes the code more brittle in the face of test suite modifications.

Searching around the web for people who encountered similar issues, I did not find anything satisfactory.

So I have two questions:

- Is there a way to do this (creating modules with `#[test]`s inside) without using at least declarative macros?
- Is there a way to instantiate user-specified generic types in declarative macros that I missed?

If the answer to both of these questions is “no” , perhaps this would be a use case to consider for declarative macros 2.0?

---

<div class="post-metadata">

**Author:** ![ExpHP](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/exphp/32/6208_2.png) [@ExpHP](https://internals.rust-lang.org/u/ExpHP)\
**Post date:** [February 28, 2018, 3:41pm UTC](https://internals.rust-lang.org/t/generic-types-in-declarative-macros/6854/2 "2018-02-28T15:41:43Z")

</div>

Can’t you pass it as an `ident`? ~~(or `path`?)~~

**Edit:** Oh dear, it looks like path doesn’t work:

```rust
3 | impl $path<u8> { }
   | ^ expected one of `!`, `+`, `for`, `where`, or `{` here

```

But here’s a PoC for `ident`:

```rust
macro_rules! foo {
    ($path:ident) => {
        impl $path<u8> { }
        impl $path<u16> { }
    }
}

mod a {
    pub struct A<T>(T);
    foo!(A);
}

```

* * *

**Update:** Somewhat astonishingly, `::` works as a separator in repetitions.

```rust
macro_rules! foo {
    ($($path:ident)::+) => {
        impl $($path)::+<u8> { }
        impl $($path)::+<u16> { }
    }
}

mod a {
    pub struct A<T>(T);
}

foo!(a::A);

```

---

<div class="post-metadata">

**Author:** ![petrochenkov](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/petrochenkov/32/2784_2.png) [@petrochenkov](https://internals.rust-lang.org/u/petrochenkov)\
**Post date:** [February 28, 2018, 4:03pm UTC](https://internals.rust-lang.org/t/generic-types-in-declarative-macros/6854/3 "2018-02-28T16:03:18Z")

</div>

cc [https://github.com/rust-lang/rust/issues/47090](https://github.com/rust-lang/rust/issues/47090)

---

<div class="post-metadata">

**Author:** ![ExpHP](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/exphp/32/6208_2.png) [@ExpHP](https://internals.rust-lang.org/u/ExpHP)\
**Post date:** [February 28, 2018, 4:13pm UTC](https://internals.rust-lang.org/t/generic-types-in-declarative-macros/6854/4 "2018-02-28T16:13:26Z")

</div>

> [@HadrienG](#):
>
> perhaps this would be a use case to consider for declarative macros 2.0?

In my rose-colored glasses, I'd rather see this be solved by higher ranked types.

---

<div class="post-metadata">

**Author:** ![HadrienG](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/hadrieng/32/3294_2.png) [@HadrienG](https://internals.rust-lang.org/u/HadrienG)\
**Post date:** [February 28, 2018, 6:00pm UTC](https://internals.rust-lang.org/t/generic-types-in-declarative-macros/6854/5 "2018-02-28T18:00:50Z")

</div>

I initially tried ident, but did not get it to work at the time as I got stuck into “Use of undeclared type or module” errors that I did not understand. At the time, I hazarded a guess that this was because I was trying to shove that ident token in a place where it did not fit. But as it turns out, it was just me misunderstanding how identifier scoping works inside of macros.

With suitable modifications, I managed to get an indent-based version rolling. Thanks!

---

<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 25, 2019, 8:29am UTC](https://internals.rust-lang.org/t/generic-types-in-declarative-macros/6854/6 "2019-03-25T08:29:43Z")

</div>

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