]> git.lizzy.rs Git - rust.git/commit - src/tools/miri
Rollup merge of #88690 - m-ou-se:macro-braces-dot-question-expr-parse, r=nagisa
authorManish Goregaokar <manishsmail@gmail.com>
Wed, 15 Sep 2021 21:56:57 +0000 (14:56 -0700)
committerGitHub <noreply@github.com>
Wed, 15 Sep 2021 21:56:57 +0000 (14:56 -0700)
commit4b568409ad86ac516ae7397ac31b1b47b0a2e1a7
treee78ac2a325333b0667817f57123826fda52c518d
parent84646e9d67a5941d52bfa5a2ae4e4e29e30808fe
parent7d8d7a03412f6db1402f2713ee96a2040cfb24d2
Rollup merge of #88690 - m-ou-se:macro-braces-dot-question-expr-parse, r=nagisa

Accept `m!{ .. }.method()` and `m!{ .. }?` statements.

This PR fixes something that I keep running into when using `quote!{}.into()` in a proc macro to convert the `proc_macro2::TokenStream` to a `proc_macro::TokenStream`:

Before:

```
error: expected expression, found `.`
 --> src/lib.rs:6:6
  |
4 |     quote! {
5 |         ...
6 |     }.into()
  |      ^ expected expression
```

After:
```
```
(No output, compiles fine.)

---

Context:

For expressions like `{ 1 }` and `if true { 1 } else { 2 }`, we accept them as full statements without a trailing `;`, which means the following is not accepted:

```rust
{ 1 } - 1 // error
```

since that is parsed as two statements: `{ 1 }` and `-1`. Syntactically correct, but the type of `{ 1 }` should be `()` as there is no `;`.

However, for specifically `.` and `?` after the `}`, we do [continue parsing it as an expression](https://github.com/rust-lang/rust/blob/13db8440bbbe42870bc828d4ec3e965b38670277/compiler/rustc_parse/src/parser/expr.rs#L864-L876):

```rust
{ "abc" }.len(); // ok
```

For braced macro invocations, we do not do this:

```rust
vec![1, 2, 3].len(); // ok
vec!{1, 2, 3}.len(); // error
```

(It parses `vec!{1, 2, 3}` as a full statement, and then complains about `.len()` not being a valid expression.)

This PR changes this to also look for a `.` and `?` after a braced macro invocation. We can be sure the macro is an expression and not a full statement in those cases, since no statement can start with a `.` or `?`.
compiler/rustc_parse/src/parser/stmt.rs