Skip to content

$pat followed by a : is used in the language, but isn't allowed for MBE #87724

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
WaffleLapkin opened this issue Aug 3, 2021 · 4 comments
Open
Labels
A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) C-bug Category: This is a bug.

Comments

@WaffleLapkin
Copy link
Member

I tried this code:

struct Struct {
    field: i32,
}

// Clearly patterns followed by a `:`
fn test(
    _: Struct,
    Struct { .. }: Struct,
    Struct { field }: Struct,
    Struct { field: _ }: Struct,
    Struct { field: aaaa }: Struct,
) {
    let _: Struct = panic!();
}

macro_rules! test {
    // This is allowed for both `let` and function arguments.
    // But not allowed for macros...
    (let $p:pat : $T:ty = $e:expr) => {}
}

(play)

I expected this code to compile, instead, it fails with the following error:

error: `$p:pat` is followed by `:`, which is not allowed for `pat` fragments
  --> src/main.rs:20:17
   |
20 |     (let $p:pat : $T:ty = $e:expr) => {}
   |                 ^ not allowed after `pat` fragments
   |
   = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in`

It's very weird that the language uses patterns followed by a :, but macros-by-example (aka macro_rules!, declarative macros, etc) can't parse it.

Meta

rustc --version --verbose:

rustc 1.56.0-nightly (2827db2b1 2021-08-01)
binary: rustc
commit-hash: 2827db2b137e899242e81f1beea39ae26e245153
commit-date: 2021-08-01
host: x86_64-unknown-linux-gnu
release: 1.56.0-nightly
LLVM version: 12.0.1
@WaffleLapkin WaffleLapkin added the C-bug Category: This is a bug. label Aug 3, 2021
@jonas-schievink jonas-schievink added the A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) label Aug 3, 2021
@WaffleLapkin
Copy link
Member Author

It seems trivial to fix, so if there are no concerns about allowing this, I would make a PR.

@m-ou-se
Copy link
Member

m-ou-se commented Aug 3, 2021

The allowed list of tokens after certain fragments is very conservative to avoid making too many promises about the syntax, but they can be extended carefully. It'd require an FCP though.

cc @rust-lang/lang

@joshtriplett
Copy link
Member

I'd guess the main thing we'd lose by allowing macros to add this would be ascription within patterns, or some other use of : within patterns?

@ExpHP
Copy link
Contributor

ExpHP commented Aug 4, 2021

I know this decision was made deliberately. I can't find where it was (might've been back in the IRC days?), but when I brought it up ages ago, the counter-argument was that we may one day want arg: T to be a pattern, in which case $pat should be expected to match the whole thing.

The way that | patterns have been implemented suggests, however, that perhaps we could still have our cake and eat it too? Basically, if it could be demonstrated that an Edition could be used to smoothly transition from a $pat that matches the pat in pat: Type, to one that matches the whole thing...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

5 participants