RFC for attributes on statements and blocks. by huonw · Pull Request #16 · rust-lang/rfcs (original) (raw)
…kfelix
See rust-lang/rfcs#16 and #15701
- Added syntax support for attributes on expressions and all syntax nodes in statement position.
- Extended
#[cfg]folder to allow removal of statements, and of expressions in optional positions like expression lists and trailing block expressions. - Extended lint checker to recognize lint levels on expressions and locals.
- As per RFC, attributes are not yet accepted on
ifexpressions.
Examples:
let x = y;
{
...
}
assert_eq!((1, #[cfg(unset)] 2, 3), (1, 3));
let FOO = 0;Implementation wise, there are a few rough corners and open questions:
- The parser work ended up a bit ugly.
- The pretty printer change was based mostly on guessing.
- Similar to the
ifcase, there are some places in the grammar where a newExprnode starts, but where it seemed weird to accept attributes and hence the parser doesn't. This includes:- const expressions in patterns
- in the middle of an postfix operator chain (that is, after
., before indexing, before calls) - on range expressions, since
#[attr] x .. yparses as(#[attr] x) .. y, which is inconsistent with#[attr] .. ywhich would parse as#[attr] (.. y)
- Attributes are added as additional
Option<Box<Vec<Attribute>>>fields in expressions and locals. - Memory impact has not been measured yet.
- A cfg-away trailing expression in a block does not currently promote the previous
StmtExprin a block to a new trailing expr. That is to say, this won't work:
let x = {
#[cfg(foo)]
Foo { data: x }
#[cfg(not(foo))]
Foo { data: y }
};- One-element tuples can have their inner expression removed to become Unit, but just Parenthesis can't. Eg,
(#[cfg(unset)] x,) == ()but(#[cfg(unset)] x) == error. This seemed reasonable to me since tuples and unit are type constructors, but could probably be argued either way. - Attributes on macro nodes are currently unconditionally dropped during macro expansion, which seemed fine since macro disappear at that point?
- Attributes on
ast::ExprParenswill be prepend-ed to the inner expression in the hir folder. - The work on pretty printer tests for this did trigger, but not fix errors regarding macros:
- expression
foo![]prints asfoo!() - expression
foo!{}prints asfoo!() - statement
foo![];prints asfoo!(); - statement
foo!{};prints asfoo!(); - statement
foo!{}triggers aNoneunwrap ICE.
- expression