rust-lang / rust-lang/reference
The definition of fragment specifier is inconsistent
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 1.6k
- Forks
- 607
- PR merge metrics
- PR metrics pending
Description
Consider this example:
macro_rules! test{
($id:ident, $e:expr)=>{
$id.$e
}
}
fn main() {
let a = (1,);
test!(a,0);
}
The compiler reports an error
error: unexpected token: `expr` metavariable
--> src/main.rs:3:13
|
3 | $id.$e
| ^^
...
8 | test!(a,0);
| ---------- in this macro invocation
|
= note: this error originates in the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
IIUC, the reason can be interpreted by the syntax
Valid fragment specifiers are:
- expr: an Expression
$e is defined as an expr fragment specifier, which can match LiteralExpression; however, the valid syntax of Tuple indexing expressions is defined as
The component following . is TUPLE_INDEX in which an Expression cannot appear. So, this is the reason for the error, which is ruled by syntax.
However, see the definition of path
path: a TypePath
This is a fixed version by https://github.com/rust-lang/reference/pull/2248
A TypePath is
TypePath → ::? TypePathSegment ( :: TypePathSegment )*
Instead, a path in an expression should be
PathExpression →
PathInExpression
| QualifiedPathInExpression
The path that appears in an expression doesn't expect the syntax TypePath, that is, the following code should have had a similar error as the first example:
macro_rules! test2{
($id:ident,$p:path)=>{
$id = $p;
}
}
mod S{
pub const I:i32 = 0;
}
fn main() {
let mut i = 0;
test2!(i,S::I);
}
However, this code is ok.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by comparing the Reference definitions for macro fragment specifiers, expressions, paths, TypePath, and PathExpression linked in the issue. Trace how the expr and path examples fit those grammars, then clarify the inconsistent definitions and add or update an example showing the intended behavior. Done means the relevant grammar and prose consistently describe both cases.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- documentation
- Issue type
- Documentation
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100