Skip to content

Documentation of the block macro metavariable syntax is confusing. #2212

@Kimundi

Description

@Kimundi

In the "Macros by example > Metavariables" section, the syntax of the block metavariable is just described as being a BlockExpression.

However, this is somewhat confusing because this metavariable apparently has more restrictions than a expr metavariable that is passed a block expression would have, and those restrictions are not explicitly mentioned.

As a primary example, block metavariables do not seem to allow inner attributes:

macro_rules! block {
    ($a:block) => {}
}
macro_rules! expr {
    ($a:expr) => {}
}
macro_rules! tt {
    ($a:tt) => {}
}

fn main() {
    block!({ #![warn(unused)] });
    expr!({ #![warn(unused)] });
    tt!({ #![warn(unused)] });
}
error: an inner attribute is not permitted in this context
  --> src/main.rs:12:14
   |
12 |     block!({ #![warn(unused)] });
   |              ^^^^^^^^^^^^^^^^
   |
   = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
   = note: outer attributes, like `#[test]`, annotate the item following them

BlockExpression > Attributes on block expressions does document that inner attributes are only valid in a few places:

  • Function and method bodies.
  • Loop bodies (loop, while, and for).
  • Block expressions used as a statement.
  • Block expressions as elements of array expressions, tuple expressions, call expressions, and tuple-style struct expressions.
  • A block expression as the tail expression of another block expression.

However it is not clear from that description if that means that macro metavariables are also meant to be excluded because they are not listed, or if the restrictions are caused by a completely different mechanism.

To me this means that we should either:

  • Add wording to the block metavariable description to explain the syntactic restrictions more clearly (simialr to other metavariables)
  • Or improve the wording of the Attributes on block expressions section in BlockExpression to make it more clear that for macros their argument syntax is already restricted, and not just the code they expand to.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions