See https://github.com/rust-lang/rfcs/pull/16 and https://github.com/rust-lang/rust/issues/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 `if` expressions.
Examples:
```rust
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 `if` case, there are some places in the grammar where a new `Expr` node 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 .. y` parses as `(#[attr] x) .. y`, which is inconsistent with
`#[attr] .. y` which 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 `StmtExpr` in a block to a new trailing expr. That is to say, this won't work:
```rust
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::ExprParens` will 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 as `foo!()`
- expression `foo!{}` prints as `foo!()`
- statement `foo![];` prints as `foo!();`
- statement `foo!{};` prints as `foo!();`
- statement `foo!{}` triggers a `None` unwrap ICE.
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.
This PR removes random remaining `Ident`s outside of libsyntax and performs general cleanup
In particular, interfaces of `Name` and `Ident` are tidied up, `Name`s and `Ident`s being small `Copy` aggregates are always passed to functions by value, and `Ident`s are never used as keys in maps, because `Ident` comparisons are tricky.
Although this PR closes https://github.com/rust-lang/rust/issues/6993 there's still work related to it:
- `Name` can be made `NonZero` to compress numerous `Option<Name>`s and `Option<Ident>`s but it requires const unsafe functions.
- Implementation of `PartialEq` on `Ident` should be eliminated and replaced with explicit hygienic, non-hygienic or member-wise comparisons.
- Finally, large parts of AST can potentially be converted to `Name`s in the same way as HIR to clearly separate identifiers used in hygienic and non-hygienic contexts.
r? @nrc
Make sure Name, SyntaxContext and Ident are passed by value
Make sure Idents don't serve as keys (or parts of keys) in maps, Ident comparison is not well defined
This is a [breaking-change] for syntax extension authors. The fix is to use MultiModifier or MultiDecorator, which have the same functionality but are more flexible. Users of syntax extensions are unaffected.
This is a [breaking-change] for syntax extension authors. The fix is to use MultiModifier or MultiDecorator, which have the same functionality but are more flexible. Users of syntax extensions are unaffected.
This is theoretically a breaking change, but GitHub search turns up no
uses of it, and most non-built-in cfg's are passed via cargo features,
which look like `feature = "..."`, and hence can't overlap.
This pull request implements the functionality for [RFC 873](https://github.com/rust-lang/rfcs/blob/master/text/0873-type-macros.md). This is currently just an update of @freebroccolo's branch from January, the corresponding commits are linked in each commit message.
@nikomatsakis and I had talked about updating the macro language to support a lifetime fragment specifier, and it is possible to do that work on this branch as well. If so we can (collectively) talk about it next week during the pre-RustCamp work week.