Skip to content

mbe matchers can contain dollar ($) #1229

@ehuss

Description

@ehuss

Macro matchers allow $ as the last token of a token tree:

macro_rules! foo {
    ($) => {};
    (last$) => {};
    ({$}) => {};
    ([$]) => {};
    (($)) => {};
}

fn main() {
    foo!($);
    foo!(last$);
    foo!({$});
    foo!([$]);
    foo!(($));
}

This was changed in rust-lang/rust#39419 in 1.17. That PR didn't mention this behavior change, so it is not clear if it was intentional. I believe this behavior is due to this line.

I see quite a lot of crates on crates.io relying on this behavior, so I don't think it is something that can be (easily) changed. I would lean towards just updating the documentation. Or perhaps it could be restricted to be a bare dollar within delimiters like ($) or [$] or {$} which is what almost all of the usages are (I didn't do an exhaustive check for the last$ style).

Initially the parts that could be updated are:

  • MacroMatch rule where it says "except $":
    > &nbsp;&nbsp; &nbsp;&nbsp; [_Token_]<sub>_except `$` and [delimiters]_</sub>\

    This could be updated, though it is starting to get too complex to explain in a subscript.
  • The sentence "The character $ cannot be matched or transcribed literally.":
    instance, the matcher `(())` will match `{()}` but not `{{}}`. The character
    `$` cannot be matched or transcribed literally.

    I think this is wrong on multiple points. $ can be transcribed literally (often used for emitting macros). $ can be matched as the last token of a token tree. $$ can be transcribed to a $ (via Add stable references of macro_metavar_expr #1192).

Generally I think the mbe documentation could use a lot of expansion to describe its behavior more precisely and completely, this is just a small part that could be improved.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions