Skip to content
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

inline-const is not an expr in macros, but it should be #84155

Closed
lf- opened this issue Apr 13, 2021 · 4 comments
Closed

inline-const is not an expr in macros, but it should be #84155

lf- opened this issue Apr 13, 2021 · 4 comments
Labels
A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) F-inline_const Inline constants (aka: const blocks, const expressions, anonymous constants)

Comments

@lf-
Copy link
Contributor

lf- commented Apr 13, 2021

While writing a macro thingy that generates match blocks, I had a problem where it was previously using an expr type, but that didn't work[1], as it didn't accept the inline const as an expr, so I tried putting it as a pat instead, but that didn't work[2] as pats aren't accepted in exprs, even if they would be valid in text form.

[1] The subject of this bug report:

macro_rules! doggo {
    ($v:expr) => {4};
}

fn main() {
    doggo!(const { 2 });
}

Compile failure (the subject of this bug):

error: no rules expected the token `const`
 --> src/main.rs:8:12
  |
1 | macro_rules! doggo {
  | ------------------ when calling this macro
...
8 |     doggo!(const { 2 });
  |            ^^^^^ no rules expected this token in macro call

error: aborting due to previous error

error: could not compile `rusttest`

[2] The thing I tried, that I think is probably reasonable behaviour, although the error needs improvement:

#![feature(inline_const)]

macro_rules! doggo {
    ($v:pat) => {
        $v
    };
}

fn main() {
    let v = doggo!(const { 2 });
}

Error:

error: expected expression, found `const{ 2 }`
  --> src/main.rs:5:9
   |
5  |         $v
   |         ^^ expected expression
...
10 |     let v = doggo!(const { 2 });
   |             ------------------- in this macro invocation
   |
   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

Meta

rustc --version --verbose:

rustc 1.53.0-nightly (d0695c908 2021-04-12)
binary: rustc
commit-hash: d0695c9081b16077d0aed368bccaf437d77ff497
commit-date: 2021-04-12
host: x86_64-unknown-linux-gnu
release: 1.53.0-nightly
LLVM version: 12.0.0
@lf- lf- added the C-bug Category: This is a bug. label Apr 13, 2021
@eddyb
Copy link
Member

eddyb commented Apr 13, 2021

Is it possible there's some check for the first keyword of a $...:expr and const should've been added to that list?

Sadly I'm not sure where that would be. I think I've seen a few different things like that but most of them for advanced diagnostics or that "FOLLOW sets" check on macro definitions (whereas this is happening during expansion).

cc @petrochenkov

@jonas-schievink jonas-schievink added A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) F-inline_const Inline constants (aka: const blocks, const expressions, anonymous constants) labels Apr 13, 2021
@petrochenkov
Copy link
Contributor

This was introduced in #80135 to fix a regression.

@lf-
Copy link
Contributor Author

lf- commented Apr 13, 2021

This was introduced in #80135 to fix a regression.

Reading through that, and, oh no. Can we have a different expr type in macros that supports const or something? It seems like it's not possible to avoid this side of the bug because you can't wrap a pattern in {} or turn it into an expr.

lf- added a commit to lf-/rust that referenced this issue Apr 26, 2021
This makes it possible to use `inline_const` (rust-lang#76001) and `let_chains`
(rust-lang#53667) inside macros' `expr` patterns in a future edition by
bifurcating the `expr` nonterminal in a similar way to `pat2021` to
remove some backwards compatibility exceptions that disallow
`const`/`let` at the beginning of an `expr` match.

Fixes rust-lang#84155 and relaxes the backward compat restriction from rust-lang#80135 for
a future edition. This is not intended to go into 2021 as it I don't
think it's simple to write an automatic fix, and certainly not now that
it's past the soft deadline for inclusion in 2021 by a long shot.

Here is a pathological case of rust-lang#79908 that forces this to be an edition
change:

```rust
macro_rules! evil {
    ($e:expr) => {
        // or something else
        const {$e-1}
    };
    (const $b:block) => {
        const {$b}
    }
}
fn main() {
    let x = 5;
    match x {
        evil!(const { 5 }) => panic!("oh no"),
        _ => (),
    };
}
```
@dtolnay
Copy link
Member

dtolnay commented Feb 20, 2023

Closing in favor of #86730.

@dtolnay dtolnay closed this as completed Feb 20, 2023
@dtolnay dtolnay removed the C-bug Category: This is a bug. label Feb 20, 2023
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, ..) F-inline_const Inline constants (aka: const blocks, const expressions, anonymous constants)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants