3

I'm trying to write a macro like this:

macro_rules! impl_numeric_cast_methods {
    ($($ty:ty)*) => {
        $(
            fn from_$ty(v: $ty) -> Self {
                v as Self
            }
        )*
    }
}

The from_$ty bit doesn't work due to macro hygiene. I found that if $ty was an ident then I could (on unstable) possibly use concat_idents! except that that apparently doesn't work either.

There's a blog post about this issue and future plans to fix it, but my question is: how can I do this at all in today's Rust stable (1.15)? Is there a workaround?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Timmmm
  • 88,195
  • 71
  • 364
  • 509
  • See also http://stackoverflow.com/q/27415011/155423, http://stackoverflow.com/q/24905160/155423, many others. – Shepmaster Feb 05 '17 at 15:11

1 Answers1

2

As a reasonable workaround, you can add the function names as extra parameters. It's not elegant but it works:

macro_rules! impl_numeric_cast_methods {
    ($($ty:ty, $from_ty:ident),*) => {
        $(
            fn $from_ty(v: $ty) -> Self {
                v as Self
            }
        )*
    }
}

Then call like:

impl_numeric_cast_methods(i8, from_i8, u8, from_u8);

A second macro could make the invocation shorter, but that would overcomplicate things in my case.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Timmmm
  • 88,195
  • 71
  • 364
  • 509