Properly handle attributes on statements
We now collect tokens for the underlying node wrapped by `StmtKind`
instead of storing tokens directly in `Stmt`.
`LazyTokenStream` now supports capturing a trailing semicolon after it
is initially constructed. This allows us to avoid refactoring statement
parsing to wrap the parsing of the semicolon in `parse_tokens`.
Attributes on item statements
(e.g. `fn foo() { #[bar] struct MyStruct; }`) are now treated as
item attributes, not statement attributes, which is consistent with how
we handle attributes on other kinds of statements. The feature-gating
code is adjusted so that proc-macro attributes are still allowed on item
statements on stable.
Two built-in macros (`#[global_allocator]` and `#[test]`) needed to be
adjusted to support being passed `Annotatable::Stmt`.
This commit is contained in:
@@ -1274,12 +1274,6 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
|
||||
// we'll expand attributes on expressions separately
|
||||
if !stmt.is_expr() {
|
||||
let attr = if stmt.is_item() {
|
||||
// FIXME: Implement proper token collection for statements
|
||||
if let StmtKind::Item(item) = &mut stmt.kind {
|
||||
stmt.tokens = item.tokens.take()
|
||||
} else {
|
||||
unreachable!()
|
||||
};
|
||||
self.take_first_attr(&mut stmt)
|
||||
} else {
|
||||
// Ignore derives on non-item statements for backwards compatibility.
|
||||
@@ -1295,7 +1289,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
|
||||
}
|
||||
|
||||
if let StmtKind::MacCall(mac) = stmt.kind {
|
||||
let MacCallStmt { mac, style, attrs } = mac.into_inner();
|
||||
let MacCallStmt { mac, style, attrs, tokens: _ } = mac.into_inner();
|
||||
self.check_attributes(&attrs);
|
||||
let mut placeholder =
|
||||
self.collect_bang(mac, stmt.span, AstFragmentKind::Stmts).make_stmts();
|
||||
@@ -1312,10 +1306,10 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
|
||||
}
|
||||
|
||||
// The placeholder expander gives ids to statements, so we avoid folding the id here.
|
||||
let ast::Stmt { id, kind, span, tokens } = stmt;
|
||||
let ast::Stmt { id, kind, span } = stmt;
|
||||
noop_flat_map_stmt_kind(kind, self)
|
||||
.into_iter()
|
||||
.map(|kind| ast::Stmt { id, kind, span, tokens: tokens.clone() })
|
||||
.map(|kind| ast::Stmt { id, kind, span })
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user