No way to have + or * as separator token in macros

0d6ea38
Opened by Bouke van der Bijl at 2020-06-09 09:06:07

I'm trying to write a macro that sums a list of expressions, but it doesn't work because it's not possible to have + or * as the seperator token. For example:

macro_rules! sum {
    (
        $($e:expr)+ => (
        $($e)++ // ???
    )
}

It'll interpret is as there being no seperator token, and it seems to just stick a + at the end. Escaping the first + doesn't work either.

I'm using rust head

@bstrie

  1. Triage: no change. Not sure this is going to be implemented with the current macro system.

    Steve Klabnik at 2016-02-02 22:08:08

  2. @nrc will macros 3.0 or whatever potentially enable this?

    Aria Desires at 2016-02-02 22:55:51

  3. It's not part of my plans, but it seems like something we could address separately (once the new system is in place I mean, not in the old system).

    Nick Cameron at 2016-02-03 04:55:58

  4. Triage: no change

    Steve Klabnik at 2017-09-30 16:04:24

  5. There's a workaround for this, just use the following utility macro:

    macro_rules! strip_plus {
        {+ $($rest:tt)* } => { $($rest)* }
    }
    

    Then, in your main macro instead of writing $($e)++, write strip_plus!($(+ $e)+). Obviously a slight modification makes this work for * too.

    AlphaModder at 2019-10-09 05:03:12

  6. There is a similar problem with separators in patterns:

    macro_rules! example {
        ( $( $i:ident )+* ) => {}
    }
    

    This is allowed, however it works as 'at least one ident and a * token at the end', and not as '0 or more ident separated by + token'.

    There is also a workaround:

    macro_rules! workaround {
        ( $( $first:ident $( + $rest:ident )* )? ) => {}
    }
    

    But it makes the macro a lot less readable (and forces you to repeat the pattern twice).

    Are there any plans to do something with this issue? (maybe reopen https://github.com/rust-lang/rfcs/pull/944 ?)

    waffle at 2020-06-09 09:06:07