Accept m!{ .. }.method()
and m!{ .. }?
statements.
#88690
Conversation
r? @nagisa (rust-highfive has picked a reviewer for you, use r? to override) |
m!{ .. }.method()
and m!{ .. }?
statements.
@rust-lang/lang I suppose this requires an FCP? |
I think, before approving something like this, we'd want to know if this restriction is important for any particular reason (e.g. interactions with parsing and follow sets). I don't think it would be, given the examples you gave, but it'd be helpful to have some guidance from someone with clear knowledge of how macros interact with the parser. For my part, assuming it wouldn't break anything, I think this seems reasonable. |
I think this is the right thing to do and don't see any reasons for braced macros cc @Aaron1011 just in case |
+1 from me, I agree that this seems more consistent. |
I'm okay with this change on the implementation side of things.
On the language design side of things I feel like with this adjustment we end up neither here nor there for this syntax element appears to be treated in a fairly inconsistent manner compared to the rest of Rust's syntactic constructs. That is it now acts kind of like an expression but only in very specific contexts. I think it would be a good idea to go all the way to making it act like all the other ExpressionWithBlock
s.
+1 from me as well for making it consistent. Given that things like let x = loop { break 7_u32 }.count_ones(); work, then those same things working after macro_rules with braces seems like the right choice. |
r=me with a negative test added. At this point a FCP seems redundant given that we already had +1 from 3/5 T-lang members. |
@bors r= nagisa |
|
@bors r- |
@bors r=nagisa |
|
…xpr-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 `?`.
…xpr-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 `?`.
…arth Rollup of 9 pull requests Successful merges: - rust-lang#87320 (Introduce -Z remap-cwd-prefix switch) - rust-lang#88619 (Remove `cfg(doc)` from std::os module reexports to fix rustdoc linking issues) - rust-lang#88690 (Accept `m!{ .. }.method()` and `m!{ .. }?` statements. ) - rust-lang#88775 (Revert anon union parsing) - rust-lang#88781 (Tokenize emoji as if they were valid identifiers ) - rust-lang#88841 (feat(rustc_typeck): suggest removing bad parens in `(recv.method)()`) - rust-lang#88892 (Move object safety suggestions to the end of the error) - rust-lang#88915 (`Wrapping<T>` has the same layout and ABI as `T`) - rust-lang#88933 (Remove implementation of `min_align_of` intrinsic) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
…xpr-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 `?`.
…arth Rollup of 8 pull requests Successful merges: - rust-lang#87320 (Introduce -Z remap-cwd-prefix switch) - rust-lang#88619 (Remove `cfg(doc)` from std::os module reexports to fix rustdoc linking issues) - rust-lang#88690 (Accept `m!{ .. }.method()` and `m!{ .. }?` statements. ) - rust-lang#88775 (Revert anon union parsing) - rust-lang#88781 (Tokenize emoji as if they were valid identifiers ) - rust-lang#88841 (feat(rustc_typeck): suggest removing bad parens in `(recv.method)()`) - rust-lang#88915 (`Wrapping<T>` has the same layout and ABI as `T`) - rust-lang#88933 (Remove implementation of `min_align_of` intrinsic) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
…xpr-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 `?`.
…arth Rollup of 8 pull requests Successful merges: - rust-lang#87320 (Introduce -Z remap-cwd-prefix switch) - rust-lang#88619 (Remove `cfg(doc)` from std::os module reexports to fix rustdoc linking issues) - rust-lang#88690 (Accept `m!{ .. }.method()` and `m!{ .. }?` statements. ) - rust-lang#88775 (Revert anon union parsing) - rust-lang#88841 (feat(rustc_typeck): suggest removing bad parens in `(recv.method)()`) - rust-lang#88907 (Highlight the `const fn` if error happened because of a bound on the impl block) - rust-lang#88915 (`Wrapping<T>` has the same layout and ABI as `T`) - rust-lang#88933 (Remove implementation of `min_align_of` intrinsic) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
…xpr-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 `?`.
…arth Rollup of 7 pull requests Successful merges: - rust-lang#88690 (Accept `m!{ .. }.method()` and `m!{ .. }?` statements. ) - rust-lang#88775 (Revert anon union parsing) - rust-lang#88841 (feat(rustc_typeck): suggest removing bad parens in `(recv.method)()`) - rust-lang#88907 (Highlight the `const fn` if error happened because of a bound on the impl block) - rust-lang#88915 (`Wrapping<T>` has the same layout and ABI as `T`) - rust-lang#88933 (Remove implementation of `min_align_of` intrinsic) - rust-lang#88951 (Update books) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
…arth Rollup of 7 pull requests Successful merges: - rust-lang#88690 (Accept `m!{ .. }.method()` and `m!{ .. }?` statements. ) - rust-lang#88775 (Revert anon union parsing) - rust-lang#88841 (feat(rustc_typeck): suggest removing bad parens in `(recv.method)()`) - rust-lang#88907 (Highlight the `const fn` if error happened because of a bound on the impl block) - rust-lang#88915 (`Wrapping<T>` has the same layout and ABI as `T`) - rust-lang#88933 (Remove implementation of `min_align_of` intrinsic) - rust-lang#88951 (Update books) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
…arth Rollup of 8 pull requests Successful merges: - rust-lang#87320 (Introduce -Z remap-cwd-prefix switch) - rust-lang#88690 (Accept `m!{ .. }.method()` and `m!{ .. }?` statements. ) - rust-lang#88775 (Revert anon union parsing) - rust-lang#88841 (feat(rustc_typeck): suggest removing bad parens in `(recv.method)()`) - rust-lang#88907 (Highlight the `const fn` if error happened because of a bound on the impl block) - rust-lang#88915 (`Wrapping<T>` has the same layout and ABI as `T`) - rust-lang#88933 (Remove implementation of `min_align_of` intrinsic) - rust-lang#88951 (Update books) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This PR fixes something that I keep running into when using
quote!{}.into()
in a proc macro to convert theproc_macro2::TokenStream
to aproc_macro::TokenStream
:Before:
After:
(No output, compiles fine.)
Context:
For expressions like
{ 1 }
andif true { 1 } else { 2 }
, we accept them as full statements without a trailing;
, which means the following is not accepted: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:For braced macro invocations, we do not do this:
(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?
.The text was updated successfully, but these errors were encountered: