From de88bf148b122b27ce48a4a6679c41c834d33019 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 17 Nov 2020 14:27:44 -0500 Subject: [PATCH 1/7] 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`. --- compiler/rustc_ast/src/ast.rs | 48 ++++- compiler/rustc_ast/src/mut_visit.rs | 14 +- compiler/rustc_ast/src/tokenstream.rs | 11 ++ compiler/rustc_ast/src/visit.rs | 2 +- .../src/deriving/debug.rs | 3 +- .../rustc_builtin_macros/src/deriving/mod.rs | 1 - compiler/rustc_expand/src/base.rs | 2 - compiler/rustc_expand/src/build.rs | 26 +-- compiler/rustc_expand/src/expand.rs | 12 +- compiler/rustc_expand/src/placeholders.rs | 11 +- compiler/rustc_interface/src/util.rs | 2 - compiler/rustc_parse/src/lib.rs | 23 +-- compiler/rustc_parse/src/parser/mod.rs | 19 +- .../rustc_parse/src/parser/nonterminal.rs | 4 +- compiler/rustc_parse/src/parser/stmt.rs | 121 ++++++++---- .../ui/proc-macro/allowed-attr-stmt-expr.rs | 2 + .../proc-macro/allowed-attr-stmt-expr.stdout | 186 ++++++++++++++---- src/test/ui/proc-macro/attr-stmt-expr.rs | 2 + src/test/ui/proc-macro/attr-stmt-expr.stderr | 2 +- src/test/ui/proc-macro/attr-stmt-expr.stdout | 179 +++++++++++++---- 20 files changed, 484 insertions(+), 186 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 328086af183d6..770ee81bcf147 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -901,10 +901,39 @@ pub struct Stmt { pub id: NodeId, pub kind: StmtKind, pub span: Span, - pub tokens: Option, } impl Stmt { + pub fn tokens(&self) -> Option<&LazyTokenStream> { + match self.kind { + StmtKind::Local(ref local) => local.tokens.as_ref(), + StmtKind::Item(ref item) => item.tokens.as_ref(), + StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => expr.tokens.as_ref(), + StmtKind::Empty => None, + StmtKind::MacCall(ref mac) => mac.tokens.as_ref(), + } + } + + pub fn tokens_mut(&mut self) -> Option<&mut LazyTokenStream> { + match self.kind { + StmtKind::Local(ref mut local) => local.tokens.as_mut(), + StmtKind::Item(ref mut item) => item.tokens.as_mut(), + StmtKind::Expr(ref mut expr) | StmtKind::Semi(ref mut expr) => expr.tokens.as_mut(), + StmtKind::Empty => None, + StmtKind::MacCall(ref mut mac) => mac.tokens.as_mut(), + } + } + + pub fn set_tokens(&mut self, tokens: Option) { + match self.kind { + StmtKind::Local(ref mut local) => local.tokens = tokens, + StmtKind::Item(ref mut item) => item.tokens = tokens, + StmtKind::Expr(ref mut expr) | StmtKind::Semi(ref mut expr) => expr.tokens = tokens, + StmtKind::Empty => {} + StmtKind::MacCall(ref mut mac) => mac.tokens = tokens, + } + } + pub fn has_trailing_semicolon(&self) -> bool { match &self.kind { StmtKind::Semi(_) => true, @@ -912,18 +941,25 @@ impl Stmt { _ => false, } } + + /// Converts a parsed `Stmt` to a `Stmt` with + /// a trailing semicolon. + /// + /// This only modifies the parsed AST struct, not the attached + /// `LazyTokenStream`. The parser is responsible for calling + /// `CreateTokenStream::add_trailing_semi` when there is actually + /// a semicolon in the tokenstream. pub fn add_trailing_semicolon(mut self) -> Self { self.kind = match self.kind { StmtKind::Expr(expr) => StmtKind::Semi(expr), StmtKind::MacCall(mac) => { - StmtKind::MacCall(mac.map(|MacCallStmt { mac, style: _, attrs }| MacCallStmt { - mac, - style: MacStmtStyle::Semicolon, - attrs, + StmtKind::MacCall(mac.map(|MacCallStmt { mac, style: _, attrs, tokens }| { + MacCallStmt { mac, style: MacStmtStyle::Semicolon, attrs, tokens } })) } kind => kind, }; + self } @@ -963,6 +999,7 @@ pub struct MacCallStmt { pub mac: MacCall, pub style: MacStmtStyle, pub attrs: AttrVec, + pub tokens: Option, } #[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)] @@ -988,6 +1025,7 @@ pub struct Local { pub init: Option>, pub span: Span, pub attrs: AttrVec, + pub tokens: Option, } /// An arm of a 'match'. diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index ddae0ab03e404..8dd16ed0fcebe 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -576,13 +576,14 @@ pub fn noop_visit_parenthesized_parameter_data( } pub fn noop_visit_local(local: &mut P, vis: &mut T) { - let Local { id, pat, ty, init, span, attrs } = local.deref_mut(); + let Local { id, pat, ty, init, span, attrs, tokens } = local.deref_mut(); vis.visit_id(id); vis.visit_pat(pat); visit_opt(ty, |ty| vis.visit_ty(ty)); visit_opt(init, |init| vis.visit_expr(init)); vis.visit_span(span); visit_thin_attrs(attrs, vis); + visit_lazy_tts(tokens, vis); } pub fn noop_visit_attribute(attr: &mut Attribute, vis: &mut T) { @@ -1325,16 +1326,12 @@ pub fn noop_filter_map_expr(mut e: P, vis: &mut T) -> Optio } pub fn noop_flat_map_stmt( - Stmt { kind, mut span, mut id, mut tokens }: Stmt, + Stmt { kind, mut span, mut id }: Stmt, vis: &mut T, ) -> SmallVec<[Stmt; 1]> { vis.visit_id(&mut id); vis.visit_span(&mut span); - visit_lazy_tts(&mut tokens, vis); - noop_flat_map_stmt_kind(kind, vis) - .into_iter() - .map(|kind| Stmt { id, kind, span, tokens: tokens.clone() }) - .collect() + noop_flat_map_stmt_kind(kind, vis).into_iter().map(|kind| Stmt { id, kind, span }).collect() } pub fn noop_flat_map_stmt_kind( @@ -1351,9 +1348,10 @@ pub fn noop_flat_map_stmt_kind( StmtKind::Semi(expr) => vis.filter_map_expr(expr).into_iter().map(StmtKind::Semi).collect(), StmtKind::Empty => smallvec![StmtKind::Empty], StmtKind::MacCall(mut mac) => { - let MacCallStmt { mac: mac_, style: _, attrs } = mac.deref_mut(); + let MacCallStmt { mac: mac_, style: _, attrs, tokens } = mac.deref_mut(); vis.visit_mac_call(mac_); visit_thin_attrs(attrs, vis); + visit_lazy_tts(tokens, vis); smallvec![StmtKind::MacCall(mac)] } } diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index fe67b905bf30f..b2207f2281620 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -121,10 +121,14 @@ where } pub trait CreateTokenStream: sync::Send + sync::Sync { + fn add_trailing_semi(&self) -> Box; fn create_token_stream(&self) -> TokenStream; } impl CreateTokenStream for TokenStream { + fn add_trailing_semi(&self) -> Box { + panic!("Cannot call `add_trailing_semi` on a `TokenStream`!"); + } fn create_token_stream(&self) -> TokenStream { self.clone() } @@ -141,6 +145,13 @@ impl LazyTokenStream { LazyTokenStream(Lrc::new(Box::new(inner))) } + /// Extends the captured stream by one token, + /// which must be a trailing semicolon. This + /// affects the `TokenStream` created by `make_tokenstream`. + pub fn add_trailing_semi(&self) -> LazyTokenStream { + LazyTokenStream(Lrc::new(self.0.add_trailing_semi())) + } + pub fn create_token_stream(&self) -> TokenStream { self.0.create_token_stream() } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 560064182e18d..857220bde233d 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -686,7 +686,7 @@ pub fn walk_stmt<'a, V: Visitor<'a>>(visitor: &mut V, statement: &'a Stmt) { StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => visitor.visit_expr(expr), StmtKind::Empty => {} StmtKind::MacCall(ref mac) => { - let MacCallStmt { ref mac, style: _, ref attrs } = **mac; + let MacCallStmt { ref mac, style: _, ref attrs, tokens: _ } = **mac; visitor.visit_mac_call(mac); for attr in attrs.iter() { visitor.visit_attribute(attr); diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index 9381264f498f3..5c21329069bfc 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -132,6 +132,7 @@ fn stmt_let_underscore(cx: &mut ExtCtxt<'_>, sp: Span, expr: P) -> as id: ast::DUMMY_NODE_ID, span: sp, attrs: ast::AttrVec::new(), + tokens: None, }); - ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Local(local), span: sp, tokens: None } + ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Local(local), span: sp } } diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs index 8c7e85f1eeb77..1651180817b9d 100644 --- a/compiler/rustc_builtin_macros/src/deriving/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs @@ -64,7 +64,6 @@ impl MultiItemModifier for BuiltinDerive { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Item(a.expect_item()), span, - tokens: None, }))); }); } else { diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 1b5c06a96bcbd..b1071bf430851 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -374,7 +374,6 @@ macro_rules! make_stmts_default { id: ast::DUMMY_NODE_ID, span: e.span, kind: ast::StmtKind::Expr(e), - tokens: None }] }) }; @@ -617,7 +616,6 @@ impl MacResult for DummyResult { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Expr(DummyResult::raw_expr(self.span, self.is_error)), span: self.span, - tokens: None }]) } diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 30f0fc6cddfa2..fe67b401fccf9 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -140,12 +140,7 @@ impl<'a> ExtCtxt<'a> { } pub fn stmt_expr(&self, expr: P) -> ast::Stmt { - ast::Stmt { - id: ast::DUMMY_NODE_ID, - span: expr.span, - kind: ast::StmtKind::Expr(expr), - tokens: None, - } + ast::Stmt { id: ast::DUMMY_NODE_ID, span: expr.span, kind: ast::StmtKind::Expr(expr) } } pub fn stmt_let(&self, sp: Span, mutbl: bool, ident: Ident, ex: P) -> ast::Stmt { @@ -162,13 +157,9 @@ impl<'a> ExtCtxt<'a> { id: ast::DUMMY_NODE_ID, span: sp, attrs: AttrVec::new(), - }); - ast::Stmt { - id: ast::DUMMY_NODE_ID, - kind: ast::StmtKind::Local(local), - span: sp, tokens: None, - } + }); + ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Local(local), span: sp } } // Generates `let _: Type;`, which is usually used for type assertions. @@ -180,17 +171,13 @@ impl<'a> ExtCtxt<'a> { id: ast::DUMMY_NODE_ID, span, attrs: AttrVec::new(), + tokens: None, }); - ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Local(local), span, tokens: None } + ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Local(local), span } } pub fn stmt_item(&self, sp: Span, item: P) -> ast::Stmt { - ast::Stmt { - id: ast::DUMMY_NODE_ID, - kind: ast::StmtKind::Item(item), - span: sp, - tokens: None, - } + ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Item(item), span: sp } } pub fn block_expr(&self, expr: P) -> P { @@ -200,7 +187,6 @@ impl<'a> ExtCtxt<'a> { id: ast::DUMMY_NODE_ID, span: expr.span, kind: ast::StmtKind::Expr(expr), - tokens: None, }], ) } diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index ce560c6c17827..4ba75c21cf058 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -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() } diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs index f0e5826f403fb..ce19e813bb3a6 100644 --- a/compiler/rustc_expand/src/placeholders.rs +++ b/compiler/rustc_expand/src/placeholders.rs @@ -104,8 +104,9 @@ pub fn placeholder( mac: mac_placeholder(), style: ast::MacStmtStyle::Braces, attrs: ast::AttrVec::new(), + tokens: None, }); - ast::Stmt { id, span, kind: ast::StmtKind::MacCall(mac), tokens: None } + ast::Stmt { id, span, kind: ast::StmtKind::MacCall(mac) } }]), AstFragmentKind::Arms => AstFragment::Arms(smallvec![ast::Arm { attrs: Default::default(), @@ -331,12 +332,8 @@ impl<'a, 'b> MutVisitor for PlaceholderExpander<'a, 'b> { // FIXME: We will need to preserve the original semicolon token and // span as part of #15701 - let empty_stmt = ast::Stmt { - id: ast::DUMMY_NODE_ID, - kind: ast::StmtKind::Empty, - span: DUMMY_SP, - tokens: None, - }; + let empty_stmt = + ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Empty, span: DUMMY_SP }; if let Some(stmt) = stmts.pop() { if stmt.has_trailing_semicolon() { diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index b43cbf46d61e3..f34990a1a1037 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -810,7 +810,6 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> { id: resolver.next_node_id(), kind: ast::StmtKind::Expr(expr), span: rustc_span::DUMMY_SP, - tokens: None, } } @@ -827,7 +826,6 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> { id: self.resolver.next_node_id(), span: rustc_span::DUMMY_SP, kind: ast::StmtKind::Expr(loop_expr), - tokens: None, }; if self.within_static_or_const { diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index 8a6b0230023ff..9f565efec839f 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -6,6 +6,7 @@ #![feature(or_patterns)] use rustc_ast as ast; +use rustc_ast::attr::HasAttrs; use rustc_ast::token::{self, DelimToken, Nonterminal, Token, TokenKind}; use rustc_ast::tokenstream::{self, LazyTokenStream, TokenStream, TokenTree}; use rustc_ast_pretty::pprust; @@ -249,29 +250,23 @@ pub fn nt_to_tokenstream(nt: &Nonterminal, sess: &ParseSess, span: Span) -> Toke // before we fall back to the stringification. let convert_tokens = - |tokens: &Option| tokens.as_ref().map(|t| t.create_token_stream()); + |tokens: Option<&LazyTokenStream>| tokens.as_ref().map(|t| t.create_token_stream()); let tokens = match *nt { Nonterminal::NtItem(ref item) => prepend_attrs(&item.attrs, item.tokens.as_ref()), - Nonterminal::NtBlock(ref block) => convert_tokens(&block.tokens), - Nonterminal::NtStmt(ref stmt) => { - // FIXME: We currently only collect tokens for `:stmt` - // matchers in `macro_rules!` macros. When we start collecting - // tokens for attributes on statements, we will need to prepend - // attributes here - convert_tokens(&stmt.tokens) - } - Nonterminal::NtPat(ref pat) => convert_tokens(&pat.tokens), - Nonterminal::NtTy(ref ty) => convert_tokens(&ty.tokens), + Nonterminal::NtBlock(ref block) => convert_tokens(block.tokens.as_ref()), + Nonterminal::NtStmt(ref stmt) => prepend_attrs(stmt.attrs(), stmt.tokens()), + Nonterminal::NtPat(ref pat) => convert_tokens(pat.tokens.as_ref()), + Nonterminal::NtTy(ref ty) => convert_tokens(ty.tokens.as_ref()), Nonterminal::NtIdent(ident, is_raw) => { Some(tokenstream::TokenTree::token(token::Ident(ident.name, is_raw), ident.span).into()) } Nonterminal::NtLifetime(ident) => { Some(tokenstream::TokenTree::token(token::Lifetime(ident.name), ident.span).into()) } - Nonterminal::NtMeta(ref attr) => convert_tokens(&attr.tokens), - Nonterminal::NtPath(ref path) => convert_tokens(&path.tokens), - Nonterminal::NtVis(ref vis) => convert_tokens(&vis.tokens), + Nonterminal::NtMeta(ref attr) => convert_tokens(attr.tokens.as_ref()), + Nonterminal::NtPath(ref path) => convert_tokens(path.tokens.as_ref()), + Nonterminal::NtVis(ref vis) => convert_tokens(vis.tokens.as_ref()), Nonterminal::NtTT(ref tt) => Some(tt.clone().into()), Nonterminal::NtExpr(ref expr) | Nonterminal::NtLiteral(ref expr) => { if expr.tokens.is_none() { diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 40aa2db58c720..2a779c37b8962 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -1213,14 +1213,20 @@ impl<'a> Parser<'a> { // // This also makes `Parser` very cheap to clone, since // there is no intermediate collection buffer to clone. + #[derive(Clone)] struct LazyTokenStreamImpl { start_token: (Token, Spacing), cursor_snapshot: TokenCursor, num_calls: usize, desugar_doc_comments: bool, + trailing_semi: bool, } impl CreateTokenStream for LazyTokenStreamImpl { fn create_token_stream(&self) -> TokenStream { + let mut num_calls = self.num_calls; + if self.trailing_semi { + num_calls += 1; + } // The token produced by the final call to `next` or `next_desugared` // was not actually consumed by the callback. The combination // of chaining the initial token and using `take` produces the desired @@ -1228,17 +1234,25 @@ impl<'a> Parser<'a> { // and omit the final token otherwise. let mut cursor_snapshot = self.cursor_snapshot.clone(); let tokens = std::iter::once(self.start_token.clone()) - .chain((0..self.num_calls).map(|_| { + .chain((0..num_calls).map(|_| { if self.desugar_doc_comments { cursor_snapshot.next_desugared() } else { cursor_snapshot.next() } })) - .take(self.num_calls); + .take(num_calls); make_token_stream(tokens) } + fn add_trailing_semi(&self) -> Box { + if self.trailing_semi { + panic!("Called `add_trailing_semi` twice!"); + } + let mut new = self.clone(); + new.trailing_semi = true; + Box::new(new) + } } let lazy_impl = LazyTokenStreamImpl { @@ -1246,6 +1260,7 @@ impl<'a> Parser<'a> { num_calls: self.token_cursor.num_next_calls - cursor_snapshot.num_next_calls, cursor_snapshot, desugar_doc_comments: self.desugar_doc_comments, + trailing_semi: false, }; Ok((ret, Some(LazyTokenStream::new(lazy_impl)))) } diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs index ab88362dad954..c007f96a79800 100644 --- a/compiler/rustc_parse/src/parser/nonterminal.rs +++ b/compiler/rustc_parse/src/parser/nonterminal.rs @@ -117,8 +117,8 @@ impl<'a> Parser<'a> { let (stmt, tokens) = self.collect_tokens(|this| this.parse_stmt())?; match stmt { Some(mut s) => { - if s.tokens.is_none() { - s.tokens = tokens; + if s.tokens().is_none() { + s.set_tokens(tokens); } token::NtStmt(s) } diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 131ff1ae6b3da..b41aba9b627e2 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -7,8 +7,10 @@ use super::{BlockMode, Parser, Restrictions, SemiColonMode}; use crate::maybe_whole; use rustc_ast as ast; +use rustc_ast::attr::HasAttrs; use rustc_ast::ptr::P; use rustc_ast::token::{self, TokenKind}; +use rustc_ast::tokenstream::LazyTokenStream; use rustc_ast::util::classify; use rustc_ast::{AttrStyle, AttrVec, Attribute, MacCall, MacCallStmt, MacStmtStyle}; use rustc_ast::{Block, BlockCheckMode, Expr, ExprKind, Local, Stmt, StmtKind, DUMMY_NODE_ID}; @@ -31,45 +33,75 @@ impl<'a> Parser<'a> { } fn parse_stmt_without_recovery(&mut self) -> PResult<'a, Option> { - maybe_whole!(self, NtStmt, |x| Some(x)); - - let attrs = self.parse_outer_attributes()?; + let mut attrs = self.parse_outer_attributes()?; + let has_attrs = !attrs.is_empty(); let lo = self.token.span; - let stmt = if self.eat_keyword(kw::Let) { - self.parse_local_mk(lo, attrs.into())? - } else if self.is_kw_followed_by_ident(kw::Mut) { - self.recover_stmt_local(lo, attrs.into(), "missing keyword", "let mut")? - } else if self.is_kw_followed_by_ident(kw::Auto) { - self.bump(); // `auto` - let msg = "write `let` instead of `auto` to introduce a new variable"; - self.recover_stmt_local(lo, attrs.into(), msg, "let")? - } else if self.is_kw_followed_by_ident(sym::var) { - self.bump(); // `var` - let msg = "write `let` instead of `var` to introduce a new variable"; - self.recover_stmt_local(lo, attrs.into(), msg, "let")? - } else if self.check_path() && !self.token.is_qpath_start() && !self.is_path_start_item() { - // We have avoided contextual keywords like `union`, items with `crate` visibility, - // or `auto trait` items. We aim to parse an arbitrary path `a::b` but not something - // that starts like a path (1 token), but it fact not a path. - // Also, we avoid stealing syntax from `parse_item_`. - self.parse_stmt_path_start(lo, attrs)? - } else if let Some(item) = self.parse_item_common(attrs.clone(), false, true, |_| true)? { - // FIXME: Bad copy of attrs - self.mk_stmt(lo.to(item.span), StmtKind::Item(P(item))) - } else if self.eat(&token::Semi) { - // Do not attempt to parse an expression if we're done here. - self.error_outer_attrs(&attrs); - self.mk_stmt(lo, StmtKind::Empty) - } else if self.token != token::CloseDelim(token::Brace) { - // Remainder are line-expr stmts. - let e = self.parse_expr_res(Restrictions::STMT_EXPR, Some(attrs.into()))?; - self.mk_stmt(lo.to(e.span), StmtKind::Expr(e)) + maybe_whole!(self, NtStmt, |stmt| { + let mut stmt = stmt; + stmt.visit_attrs(|stmt_attrs| { + mem::swap(stmt_attrs, &mut attrs); + stmt_attrs.extend(attrs); + }); + Some(stmt) + }); + + let parse_stmt_inner = |this: &mut Self| { + let stmt = if this.eat_keyword(kw::Let) { + this.parse_local_mk(lo, attrs.into())? + } else if this.is_kw_followed_by_ident(kw::Mut) { + this.recover_stmt_local(lo, attrs.into(), "missing keyword", "let mut")? + } else if this.is_kw_followed_by_ident(kw::Auto) { + this.bump(); // `auto` + let msg = "write `let` instead of `auto` to introduce a new variable"; + this.recover_stmt_local(lo, attrs.into(), msg, "let")? + } else if this.is_kw_followed_by_ident(sym::var) { + this.bump(); // `var` + let msg = "write `let` instead of `var` to introduce a new variable"; + this.recover_stmt_local(lo, attrs.into(), msg, "let")? + } else if this.check_path() + && !this.token.is_qpath_start() + && !this.is_path_start_item() + { + // We have avoided contextual keywords like `union`, items with `crate` visibility, + // or `auto trait` items. We aim to parse an arbitrary path `a::b` but not something + // that starts like a path (1 token), but it fact not a path. + // Also, we avoid stealing syntax from `parse_item_`. + this.parse_stmt_path_start(lo, attrs)? + } else if let Some(item) = + this.parse_item_common(attrs.clone(), false, true, |_| true)? + { + // FIXME: Bad copy of attrs + this.mk_stmt(lo.to(item.span), StmtKind::Item(P(item))) + } else if this.eat(&token::Semi) { + // Do not attempt to parse an expression if we're done here. + this.error_outer_attrs(&attrs); + this.mk_stmt(lo, StmtKind::Empty) + } else if this.token != token::CloseDelim(token::Brace) { + // Remainder are line-expr stmts. + let e = this.parse_expr_res(Restrictions::STMT_EXPR, Some(attrs.into()))?; + this.mk_stmt(lo.to(e.span), StmtKind::Expr(e)) + } else { + this.error_outer_attrs(&attrs); + return Ok(None); + }; + Ok(Some(stmt)) + }; + + let stmt = if has_attrs { + let (mut stmt, tokens) = self.collect_tokens(parse_stmt_inner)?; + if let Some(stmt) = &mut stmt { + // If we already have tokens (e.g. due to encounting an `NtStmt`), + // use those instead. + if stmt.tokens().is_none() { + stmt.set_tokens(tokens); + } + } + stmt } else { - self.error_outer_attrs(&attrs); - return Ok(None); + parse_stmt_inner(self)? }; - Ok(Some(stmt)) + Ok(stmt) } fn parse_stmt_path_start(&mut self, lo: Span, attrs: Vec) -> PResult<'a, Stmt> { @@ -107,7 +139,7 @@ impl<'a> Parser<'a> { let kind = if delim == token::Brace || self.token == token::Semi || self.token == token::Eof { - StmtKind::MacCall(P(MacCallStmt { mac, style, attrs })) + StmtKind::MacCall(P(MacCallStmt { mac, style, attrs, tokens: None })) } else { // Since none of the above applied, this is an expression statement macro. let e = self.mk_expr(lo.to(hi), ExprKind::MacCall(mac), AttrVec::new()); @@ -219,7 +251,7 @@ impl<'a> Parser<'a> { } }; let hi = if self.token == token::Semi { self.token.span } else { self.prev_token.span }; - Ok(P(ast::Local { ty, pat, init, id: DUMMY_NODE_ID, span: lo.to(hi), attrs })) + Ok(P(ast::Local { ty, pat, init, id: DUMMY_NODE_ID, span: lo.to(hi), attrs, tokens: None })) } /// Parses the RHS of a local variable declaration (e.g., '= 14;'). @@ -376,6 +408,12 @@ impl<'a> Parser<'a> { None => return Ok(None), }; + let add_semi_token = |tokens: Option<&mut LazyTokenStream>| { + if let Some(tokens) = tokens { + *tokens = tokens.add_trailing_semi(); + } + }; + let mut eat_semi = true; match stmt.kind { // Expression without semicolon. @@ -417,6 +455,7 @@ impl<'a> Parser<'a> { *expr = self.mk_expr_err(sp); } } + StmtKind::Expr(_) | StmtKind::MacCall(_) => {} StmtKind::Local(ref mut local) => { if let Err(e) = self.expect_semi() { // We might be at the `,` in `let x = foo;`. Try to recover. @@ -430,6 +469,9 @@ impl<'a> Parser<'a> { } } eat_semi = false; + // We just checked that there's a semicolon in the tokenstream, + // so capture it + add_semi_token(local.tokens.as_mut()); } StmtKind::Empty => eat_semi = false, _ => {} @@ -437,6 +479,9 @@ impl<'a> Parser<'a> { if eat_semi && self.eat(&token::Semi) { stmt = stmt.add_trailing_semicolon(); + // We just checked that we have a semicolon in the tokenstream, + // so capture it + add_semi_token(stmt.tokens_mut()); } stmt.span = stmt.span.to(self.prev_token.span); Ok(Some(stmt)) @@ -447,7 +492,7 @@ impl<'a> Parser<'a> { } pub(super) fn mk_stmt(&self, span: Span, kind: StmtKind) -> Stmt { - Stmt { id: DUMMY_NODE_ID, kind, span, tokens: None } + Stmt { id: DUMMY_NODE_ID, kind, span } } pub(super) fn mk_stmt_err(&self, span: Span) -> Stmt { diff --git a/src/test/ui/proc-macro/allowed-attr-stmt-expr.rs b/src/test/ui/proc-macro/allowed-attr-stmt-expr.rs index 03c10a4324898..e68c5ea53de49 100644 --- a/src/test/ui/proc-macro/allowed-attr-stmt-expr.rs +++ b/src/test/ui/proc-macro/allowed-attr-stmt-expr.rs @@ -25,6 +25,8 @@ fn print_str(string: &'static str) { macro_rules! make_stmt { ($stmt:stmt) => { + #[print_attr] + #[allow(unused)] $stmt } } diff --git a/src/test/ui/proc-macro/allowed-attr-stmt-expr.stdout b/src/test/ui/proc-macro/allowed-attr-stmt-expr.stdout index 0c7ac4fb682ae..189d2383b7bc1 100644 --- a/src/test/ui/proc-macro/allowed-attr-stmt-expr.stdout +++ b/src/test/ui/proc-macro/allowed-attr-stmt-expr.stdout @@ -1,43 +1,84 @@ +PRINT-ATTR INPUT (DISPLAY): #[allow(unused)] struct Foo { } +PRINT-ATTR INPUT (DEBUG): TokenStream [ + Punct { + ch: '#', + spacing: Alone, + span: $DIR/allowed-attr-stmt-expr.rs:29:9: 29:10 (#12), + }, + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + ident: "allow", + span: $DIR/allowed-attr-stmt-expr.rs:29:11: 29:16 (#12), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "unused", + span: $DIR/allowed-attr-stmt-expr.rs:29:17: 29:23 (#12), + }, + ], + span: $DIR/allowed-attr-stmt-expr.rs:29:16: 29:24 (#12), + }, + ], + span: $DIR/allowed-attr-stmt-expr.rs:29:10: 29:25 (#12), + }, + Ident { + ident: "struct", + span: $DIR/allowed-attr-stmt-expr.rs:42:16: 42:22 (#0), + }, + Ident { + ident: "Foo", + span: $DIR/allowed-attr-stmt-expr.rs:42:23: 42:26 (#0), + }, + Group { + delimiter: Brace, + stream: TokenStream [], + span: $DIR/allowed-attr-stmt-expr.rs:42:27: 42:29 (#0), + }, +] PRINT-ATTR INPUT (DISPLAY): #[expect_let] let string = "Hello, world!" ; PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:45:5: 45:6 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "expect_let", - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:45:7: 45:17 (#0), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:45:6: 45:18 (#0), }, Ident { ident: "let", - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:46:5: 46:8 (#0), }, Ident { ident: "string", - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:46:9: 46:15 (#0), }, Punct { ch: '=', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:46:16: 46:17 (#0), }, Literal { kind: Str, symbol: "Hello, world!", suffix: None, - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:46:18: 46:33 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:46:33: 46:34 (#0), }, ] PRINT-ATTR INPUT (DISPLAY): #[expect_print_stmt] println ! ("{}", string) ; @@ -45,26 +86,26 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:49:5: 49:6 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "expect_print_stmt", - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:49:7: 49:24 (#0), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:49:6: 49:25 (#0), }, Ident { ident: "println", - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:50:5: 50:12 (#0), }, Punct { ch: '!', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:50:12: 50:13 (#0), }, Group { delimiter: Parenthesis, @@ -73,36 +114,36 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ kind: Str, symbol: "{}", suffix: None, - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:50:14: 50:18 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:50:18: 50:19 (#0), }, Ident { ident: "string", - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:50:20: 50:26 (#0), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:50:13: 50:27 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:50:27: 50:28 (#0), }, ] PRINT-ATTR INPUT (DISPLAY): second_make_stmt ! (#[allow(dead_code)] struct Bar { }) ; PRINT-ATTR INPUT (DEBUG): TokenStream [ Ident { ident: "second_make_stmt", - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:53:5: 53:21 (#0), }, Punct { ch: '!', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:53:21: 53:22 (#0), }, Group { delimiter: Parenthesis, @@ -110,78 +151,149 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:53:23: 53:24 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "allow", - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:53:25: 53:30 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "dead_code", - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:53:31: 53:40 (#0), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:53:30: 53:41 (#0), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:53:24: 53:42 (#0), }, Ident { ident: "struct", - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:53:43: 53:49 (#0), }, Ident { ident: "Bar", - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:53:50: 53:53 (#0), }, Group { delimiter: Brace, stream: TokenStream [], - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:53:54: 53:56 (#0), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:53:22: 53:57 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:53:57: 53:58 (#0), }, ] -PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] struct Other { } +PRINT-ATTR INPUT (DISPLAY): #[allow(unused)] #[allow(dead_code)] struct Bar { } PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:29:9: 29:10 (#34), + }, + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + ident: "allow", + span: $DIR/allowed-attr-stmt-expr.rs:29:11: 29:16 (#34), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "unused", + span: $DIR/allowed-attr-stmt-expr.rs:29:17: 29:23 (#34), + }, + ], + span: $DIR/allowed-attr-stmt-expr.rs:29:16: 29:24 (#34), + }, + ], + span: $DIR/allowed-attr-stmt-expr.rs:29:10: 29:25 (#34), + }, + Punct { + ch: '#', + spacing: Alone, + span: $DIR/allowed-attr-stmt-expr.rs:53:23: 53:24 (#0), + }, + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + ident: "allow", + span: $DIR/allowed-attr-stmt-expr.rs:53:25: 53:30 (#0), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "dead_code", + span: $DIR/allowed-attr-stmt-expr.rs:53:31: 53:40 (#0), + }, + ], + span: $DIR/allowed-attr-stmt-expr.rs:53:30: 53:41 (#0), + }, + ], + span: $DIR/allowed-attr-stmt-expr.rs:53:24: 53:42 (#0), + }, + Ident { + ident: "struct", + span: $DIR/allowed-attr-stmt-expr.rs:53:43: 53:49 (#0), + }, + Ident { + ident: "Bar", + span: $DIR/allowed-attr-stmt-expr.rs:53:50: 53:53 (#0), + }, + Group { + delimiter: Brace, + stream: TokenStream [], + span: $DIR/allowed-attr-stmt-expr.rs:53:54: 53:56 (#0), + }, +] +PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] struct Other { } ; +PRINT-ATTR INPUT (DEBUG): TokenStream [ + Punct { + ch: '#', + spacing: Alone, + span: $DIR/allowed-attr-stmt-expr.rs:56:5: 56:6 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "rustc_dummy", - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:56:7: 56:18 (#0), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:56:6: 56:19 (#0), }, Ident { ident: "struct", - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:57:5: 57:11 (#0), }, Ident { ident: "Other", - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:57:12: 57:17 (#0), }, Group { delimiter: Brace, stream: TokenStream [], - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:57:18: 57:20 (#0), + }, + Punct { + ch: ';', + spacing: Alone, + span: $DIR/allowed-attr-stmt-expr.rs:57:20: 57:21 (#0), }, ] diff --git a/src/test/ui/proc-macro/attr-stmt-expr.rs b/src/test/ui/proc-macro/attr-stmt-expr.rs index ca1b163c986e0..40e5432185223 100644 --- a/src/test/ui/proc-macro/attr-stmt-expr.rs +++ b/src/test/ui/proc-macro/attr-stmt-expr.rs @@ -24,6 +24,8 @@ fn print_str(string: &'static str) { macro_rules! make_stmt { ($stmt:stmt) => { + #[print_attr] + #[allow(unused)] $stmt } } diff --git a/src/test/ui/proc-macro/attr-stmt-expr.stderr b/src/test/ui/proc-macro/attr-stmt-expr.stderr index 7bd60e8ee77f9..1cc7d474fcf16 100644 --- a/src/test/ui/proc-macro/attr-stmt-expr.stderr +++ b/src/test/ui/proc-macro/attr-stmt-expr.stderr @@ -8,7 +8,7 @@ LL | #[expect_print_expr] = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable error[E0658]: attributes on expressions are experimental - --> $DIR/attr-stmt-expr.rs:55:5 + --> $DIR/attr-stmt-expr.rs:57:5 | LL | #[expect_expr] | ^^^^^^^^^^^^^^ diff --git a/src/test/ui/proc-macro/attr-stmt-expr.stdout b/src/test/ui/proc-macro/attr-stmt-expr.stdout index 5c1b586725b24..59543fb0ca3ff 100644 --- a/src/test/ui/proc-macro/attr-stmt-expr.stdout +++ b/src/test/ui/proc-macro/attr-stmt-expr.stdout @@ -1,43 +1,84 @@ +PRINT-ATTR INPUT (DISPLAY): #[allow(unused)] struct Foo { } +PRINT-ATTR INPUT (DEBUG): TokenStream [ + Punct { + ch: '#', + spacing: Alone, + span: $DIR/attr-stmt-expr.rs:28:9: 28:10 (#12), + }, + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + ident: "allow", + span: $DIR/attr-stmt-expr.rs:28:11: 28:16 (#12), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "unused", + span: $DIR/attr-stmt-expr.rs:28:17: 28:23 (#12), + }, + ], + span: $DIR/attr-stmt-expr.rs:28:16: 28:24 (#12), + }, + ], + span: $DIR/attr-stmt-expr.rs:28:10: 28:25 (#12), + }, + Ident { + ident: "struct", + span: $DIR/attr-stmt-expr.rs:40:16: 40:22 (#0), + }, + Ident { + ident: "Foo", + span: $DIR/attr-stmt-expr.rs:40:23: 40:26 (#0), + }, + Group { + delimiter: Brace, + stream: TokenStream [], + span: $DIR/attr-stmt-expr.rs:40:27: 40:29 (#0), + }, +] PRINT-ATTR INPUT (DISPLAY): #[expect_let] let string = "Hello, world!" ; PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:43:5: 43:6 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "expect_let", - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:43:7: 43:17 (#0), }, ], - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:43:6: 43:18 (#0), }, Ident { ident: "let", - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:44:5: 44:8 (#0), }, Ident { ident: "string", - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:44:9: 44:15 (#0), }, Punct { ch: '=', spacing: Alone, - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:44:16: 44:17 (#0), }, Literal { kind: Str, symbol: "Hello, world!", suffix: None, - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:44:18: 44:33 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:44:33: 44:34 (#0), }, ] PRINT-ATTR INPUT (DISPLAY): #[expect_print_stmt] println ! ("{}", string) ; @@ -45,26 +86,26 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:47:5: 47:6 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "expect_print_stmt", - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:47:7: 47:24 (#0), }, ], - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:47:6: 47:25 (#0), }, Ident { ident: "println", - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:48:5: 48:12 (#0), }, Punct { ch: '!', spacing: Alone, - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:48:12: 48:13 (#0), }, Group { delimiter: Parenthesis, @@ -73,36 +114,36 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ kind: Str, symbol: "{}", suffix: None, - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:48:14: 48:18 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:48:18: 48:19 (#0), }, Ident { ident: "string", - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:48:20: 48:26 (#0), }, ], - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:48:13: 48:27 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:48:27: 48:28 (#0), }, ] PRINT-ATTR INPUT (DISPLAY): second_make_stmt ! (#[allow(dead_code)] struct Bar { }) ; PRINT-ATTR INPUT (DEBUG): TokenStream [ Ident { ident: "second_make_stmt", - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:51:5: 51:21 (#0), }, Punct { ch: '!', spacing: Alone, - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:51:21: 51:22 (#0), }, Group { delimiter: Parenthesis, @@ -110,48 +151,114 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:51:23: 51:24 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "allow", - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:51:25: 51:30 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "dead_code", - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:51:31: 51:40 (#0), }, ], - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:51:30: 51:41 (#0), }, ], - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:51:24: 51:42 (#0), }, Ident { ident: "struct", - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:51:43: 51:49 (#0), }, Ident { ident: "Bar", - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:51:50: 51:53 (#0), }, Group { delimiter: Brace, stream: TokenStream [], - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:51:54: 51:56 (#0), }, ], - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:51:22: 51:57 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:51:57: 51:58 (#0), + }, +] +PRINT-ATTR INPUT (DISPLAY): #[allow(unused)] #[allow(dead_code)] struct Bar { } +PRINT-ATTR INPUT (DEBUG): TokenStream [ + Punct { + ch: '#', + spacing: Alone, + span: $DIR/attr-stmt-expr.rs:28:9: 28:10 (#34), + }, + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + ident: "allow", + span: $DIR/attr-stmt-expr.rs:28:11: 28:16 (#34), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "unused", + span: $DIR/attr-stmt-expr.rs:28:17: 28:23 (#34), + }, + ], + span: $DIR/attr-stmt-expr.rs:28:16: 28:24 (#34), + }, + ], + span: $DIR/attr-stmt-expr.rs:28:10: 28:25 (#34), + }, + Punct { + ch: '#', + spacing: Alone, + span: $DIR/attr-stmt-expr.rs:51:23: 51:24 (#0), + }, + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + ident: "allow", + span: $DIR/attr-stmt-expr.rs:51:25: 51:30 (#0), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "dead_code", + span: $DIR/attr-stmt-expr.rs:51:31: 51:40 (#0), + }, + ], + span: $DIR/attr-stmt-expr.rs:51:30: 51:41 (#0), + }, + ], + span: $DIR/attr-stmt-expr.rs:51:24: 51:42 (#0), + }, + Ident { + ident: "struct", + span: $DIR/attr-stmt-expr.rs:51:43: 51:49 (#0), + }, + Ident { + ident: "Bar", + span: $DIR/attr-stmt-expr.rs:51:50: 51:53 (#0), + }, + Group { + delimiter: Brace, + stream: TokenStream [], + span: $DIR/attr-stmt-expr.rs:51:54: 51:56 (#0), }, ] PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] struct Other { } @@ -159,29 +266,29 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:54:5: 54:6 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "rustc_dummy", - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:54:7: 54:18 (#0), }, ], - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:54:6: 54:19 (#0), }, Ident { ident: "struct", - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:55:5: 55:11 (#0), }, Ident { ident: "Other", - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:55:12: 55:17 (#0), }, Group { delimiter: Brace, stream: TokenStream [], - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:55:18: 55:20 (#0), }, ] From 758834d3e2b2589f73b62df386780c8096ed7ae1 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 25 Nov 2020 16:52:24 -0500 Subject: [PATCH 2/7] Only eat semicolons for statements that need them When parsing a statement (e.g. inside a function body), we now consider `struct Foo {};` and `$stmt;` to each consist of two statements: `struct Foo {}` and `;`, and `$stmt` and `;`. As a result, an attribute macro invoke as `fn foo() { #[attr] struct Bar{}; }` will see `struct Bar{}` as its input. Additionally, the 'unused semicolon' lint now fires in more places. --- compiler/rustc_parse/src/parser/stmt.rs | 3 +-- src/test/ui/proc-macro/allowed-attr-stmt-expr.stdout | 7 +------ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index b41aba9b627e2..e974556f43a49 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -473,8 +473,7 @@ impl<'a> Parser<'a> { // so capture it add_semi_token(local.tokens.as_mut()); } - StmtKind::Empty => eat_semi = false, - _ => {} + StmtKind::Empty | StmtKind::Item(_) | StmtKind::Semi(_) => eat_semi = false, } if eat_semi && self.eat(&token::Semi) { diff --git a/src/test/ui/proc-macro/allowed-attr-stmt-expr.stdout b/src/test/ui/proc-macro/allowed-attr-stmt-expr.stdout index 189d2383b7bc1..0b9ce8cdfdb3b 100644 --- a/src/test/ui/proc-macro/allowed-attr-stmt-expr.stdout +++ b/src/test/ui/proc-macro/allowed-attr-stmt-expr.stdout @@ -261,7 +261,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ span: $DIR/allowed-attr-stmt-expr.rs:53:54: 53:56 (#0), }, ] -PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] struct Other { } ; +PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] struct Other { } PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', @@ -291,9 +291,4 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ stream: TokenStream [], span: $DIR/allowed-attr-stmt-expr.rs:57:18: 57:20 (#0), }, - Punct { - ch: ';', - spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:57:20: 57:21 (#0), - }, ] From db0d0e8c435f96bd36184c76e8bc01ecbcbc4ea3 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 25 Nov 2020 16:58:10 -0500 Subject: [PATCH 3/7] Add additional semicolon test --- .../ui/proc-macro/allowed-attr-stmt-expr.rs | 15 +- .../proc-macro/allowed-attr-stmt-expr.stdout | 181 ++++++++++-------- src/test/ui/proc-macro/attr-stmt-expr.rs | 2 +- src/test/ui/proc-macro/attr-stmt-expr.stdout | 36 +--- 4 files changed, 126 insertions(+), 108 deletions(-) diff --git a/src/test/ui/proc-macro/allowed-attr-stmt-expr.rs b/src/test/ui/proc-macro/allowed-attr-stmt-expr.rs index e68c5ea53de49..9e82ccd9bed86 100644 --- a/src/test/ui/proc-macro/allowed-attr-stmt-expr.rs +++ b/src/test/ui/proc-macro/allowed-attr-stmt-expr.rs @@ -26,8 +26,9 @@ fn print_str(string: &'static str) { macro_rules! make_stmt { ($stmt:stmt) => { #[print_attr] - #[allow(unused)] - $stmt + #[rustc_dummy] + $stmt; // This semicolon is *not* passed to the macro, + // since `$stmt` is already a statement. } } @@ -37,6 +38,10 @@ macro_rules! second_make_stmt { } } +// The macro will see a semicolon here +#[print_attr] +struct ItemWithSemi; + fn main() { make_stmt!(struct Foo {}); @@ -56,6 +61,12 @@ fn main() { #[rustc_dummy] struct Other {}; + // The macro also sees a semicolon, + // for consistency with the `ItemWithSemi` case above. + #[print_attr] + #[rustc_dummy] + struct NonBracedStruct; + #[expect_expr] print_str("string") } diff --git a/src/test/ui/proc-macro/allowed-attr-stmt-expr.stdout b/src/test/ui/proc-macro/allowed-attr-stmt-expr.stdout index 0b9ce8cdfdb3b..be14e368c046d 100644 --- a/src/test/ui/proc-macro/allowed-attr-stmt-expr.stdout +++ b/src/test/ui/proc-macro/allowed-attr-stmt-expr.stdout @@ -1,42 +1,48 @@ -PRINT-ATTR INPUT (DISPLAY): #[allow(unused)] struct Foo { } +PRINT-ATTR INPUT (DISPLAY): struct ItemWithSemi ; +PRINT-ATTR INPUT (DEBUG): TokenStream [ + Ident { + ident: "struct", + span: $DIR/allowed-attr-stmt-expr.rs:43:1: 43:7 (#0), + }, + Ident { + ident: "ItemWithSemi", + span: $DIR/allowed-attr-stmt-expr.rs:43:8: 43:20 (#0), + }, + Punct { + ch: ';', + spacing: Alone, + span: $DIR/allowed-attr-stmt-expr.rs:43:20: 43:21 (#0), + }, +] +PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] struct Foo { } PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:29:9: 29:10 (#12), + span: $DIR/allowed-attr-stmt-expr.rs:29:9: 29:10 (#15), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { - ident: "allow", - span: $DIR/allowed-attr-stmt-expr.rs:29:11: 29:16 (#12), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [ - Ident { - ident: "unused", - span: $DIR/allowed-attr-stmt-expr.rs:29:17: 29:23 (#12), - }, - ], - span: $DIR/allowed-attr-stmt-expr.rs:29:16: 29:24 (#12), + ident: "rustc_dummy", + span: $DIR/allowed-attr-stmt-expr.rs:29:11: 29:22 (#15), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:29:10: 29:25 (#12), + span: $DIR/allowed-attr-stmt-expr.rs:29:10: 29:23 (#15), }, Ident { ident: "struct", - span: $DIR/allowed-attr-stmt-expr.rs:42:16: 42:22 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:47:16: 47:22 (#0), }, Ident { ident: "Foo", - span: $DIR/allowed-attr-stmt-expr.rs:42:23: 42:26 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:47:23: 47:26 (#0), }, Group { delimiter: Brace, stream: TokenStream [], - span: $DIR/allowed-attr-stmt-expr.rs:42:27: 42:29 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:47:27: 47:29 (#0), }, ] PRINT-ATTR INPUT (DISPLAY): #[expect_let] let string = "Hello, world!" ; @@ -44,41 +50,41 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:45:5: 45:6 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:50:5: 50:6 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "expect_let", - span: $DIR/allowed-attr-stmt-expr.rs:45:7: 45:17 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:50:7: 50:17 (#0), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:45:6: 45:18 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:50:6: 50:18 (#0), }, Ident { ident: "let", - span: $DIR/allowed-attr-stmt-expr.rs:46:5: 46:8 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:51:5: 51:8 (#0), }, Ident { ident: "string", - span: $DIR/allowed-attr-stmt-expr.rs:46:9: 46:15 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:51:9: 51:15 (#0), }, Punct { ch: '=', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:46:16: 46:17 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:51:16: 51:17 (#0), }, Literal { kind: Str, symbol: "Hello, world!", suffix: None, - span: $DIR/allowed-attr-stmt-expr.rs:46:18: 46:33 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:51:18: 51:33 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:46:33: 46:34 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:51:33: 51:34 (#0), }, ] PRINT-ATTR INPUT (DISPLAY): #[expect_print_stmt] println ! ("{}", string) ; @@ -86,26 +92,26 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:49:5: 49:6 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:54:5: 54:6 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "expect_print_stmt", - span: $DIR/allowed-attr-stmt-expr.rs:49:7: 49:24 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:54:7: 54:24 (#0), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:49:6: 49:25 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:54:6: 54:25 (#0), }, Ident { ident: "println", - span: $DIR/allowed-attr-stmt-expr.rs:50:5: 50:12 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:55:5: 55:12 (#0), }, Punct { ch: '!', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:50:12: 50:13 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:55:12: 55:13 (#0), }, Group { delimiter: Parenthesis, @@ -114,36 +120,36 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ kind: Str, symbol: "{}", suffix: None, - span: $DIR/allowed-attr-stmt-expr.rs:50:14: 50:18 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:55:14: 55:18 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:50:18: 50:19 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:55:18: 55:19 (#0), }, Ident { ident: "string", - span: $DIR/allowed-attr-stmt-expr.rs:50:20: 50:26 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:55:20: 55:26 (#0), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:50:13: 50:27 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:55:13: 55:27 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:50:27: 50:28 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:55:27: 55:28 (#0), }, ] PRINT-ATTR INPUT (DISPLAY): second_make_stmt ! (#[allow(dead_code)] struct Bar { }) ; PRINT-ATTR INPUT (DEBUG): TokenStream [ Ident { ident: "second_make_stmt", - span: $DIR/allowed-attr-stmt-expr.rs:53:5: 53:21 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:58:5: 58:21 (#0), }, Punct { ch: '!', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:53:21: 53:22 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:58:21: 58:22 (#0), }, Group { delimiter: Parenthesis, @@ -151,114 +157,104 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:53:23: 53:24 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:58:23: 58:24 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "allow", - span: $DIR/allowed-attr-stmt-expr.rs:53:25: 53:30 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:58:25: 58:30 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "dead_code", - span: $DIR/allowed-attr-stmt-expr.rs:53:31: 53:40 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:58:31: 58:40 (#0), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:53:30: 53:41 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:58:30: 58:41 (#0), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:53:24: 53:42 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:58:24: 58:42 (#0), }, Ident { ident: "struct", - span: $DIR/allowed-attr-stmt-expr.rs:53:43: 53:49 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:58:43: 58:49 (#0), }, Ident { ident: "Bar", - span: $DIR/allowed-attr-stmt-expr.rs:53:50: 53:53 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:58:50: 58:53 (#0), }, Group { delimiter: Brace, stream: TokenStream [], - span: $DIR/allowed-attr-stmt-expr.rs:53:54: 53:56 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:58:54: 58:56 (#0), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:53:22: 53:57 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:58:22: 58:57 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:53:57: 53:58 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:58:57: 58:58 (#0), }, ] -PRINT-ATTR INPUT (DISPLAY): #[allow(unused)] #[allow(dead_code)] struct Bar { } +PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] #[allow(dead_code)] struct Bar { } PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:29:9: 29:10 (#34), + span: $DIR/allowed-attr-stmt-expr.rs:29:9: 29:10 (#37), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { - ident: "allow", - span: $DIR/allowed-attr-stmt-expr.rs:29:11: 29:16 (#34), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [ - Ident { - ident: "unused", - span: $DIR/allowed-attr-stmt-expr.rs:29:17: 29:23 (#34), - }, - ], - span: $DIR/allowed-attr-stmt-expr.rs:29:16: 29:24 (#34), + ident: "rustc_dummy", + span: $DIR/allowed-attr-stmt-expr.rs:29:11: 29:22 (#37), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:29:10: 29:25 (#34), + span: $DIR/allowed-attr-stmt-expr.rs:29:10: 29:23 (#37), }, Punct { ch: '#', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:53:23: 53:24 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:58:23: 58:24 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "allow", - span: $DIR/allowed-attr-stmt-expr.rs:53:25: 53:30 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:58:25: 58:30 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "dead_code", - span: $DIR/allowed-attr-stmt-expr.rs:53:31: 53:40 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:58:31: 58:40 (#0), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:53:30: 53:41 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:58:30: 58:41 (#0), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:53:24: 53:42 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:58:24: 58:42 (#0), }, Ident { ident: "struct", - span: $DIR/allowed-attr-stmt-expr.rs:53:43: 53:49 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:58:43: 58:49 (#0), }, Ident { ident: "Bar", - span: $DIR/allowed-attr-stmt-expr.rs:53:50: 53:53 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:58:50: 58:53 (#0), }, Group { delimiter: Brace, stream: TokenStream [], - span: $DIR/allowed-attr-stmt-expr.rs:53:54: 53:56 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:58:54: 58:56 (#0), }, ] PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] struct Other { } @@ -266,29 +262,60 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:56:5: 56:6 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:61:5: 61:6 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "rustc_dummy", - span: $DIR/allowed-attr-stmt-expr.rs:56:7: 56:18 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:61:7: 61:18 (#0), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:56:6: 56:19 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:61:6: 61:19 (#0), }, Ident { ident: "struct", - span: $DIR/allowed-attr-stmt-expr.rs:57:5: 57:11 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:62:5: 62:11 (#0), }, Ident { ident: "Other", - span: $DIR/allowed-attr-stmt-expr.rs:57:12: 57:17 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:62:12: 62:17 (#0), }, Group { delimiter: Brace, stream: TokenStream [], - span: $DIR/allowed-attr-stmt-expr.rs:57:18: 57:20 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:62:18: 62:20 (#0), + }, +] +PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] struct NonBracedStruct ; +PRINT-ATTR INPUT (DEBUG): TokenStream [ + Punct { + ch: '#', + spacing: Alone, + span: $DIR/allowed-attr-stmt-expr.rs:67:5: 67:6 (#0), + }, + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + ident: "rustc_dummy", + span: $DIR/allowed-attr-stmt-expr.rs:67:7: 67:18 (#0), + }, + ], + span: $DIR/allowed-attr-stmt-expr.rs:67:6: 67:19 (#0), + }, + Ident { + ident: "struct", + span: $DIR/allowed-attr-stmt-expr.rs:68:5: 68:11 (#0), + }, + Ident { + ident: "NonBracedStruct", + span: $DIR/allowed-attr-stmt-expr.rs:68:12: 68:27 (#0), + }, + Punct { + ch: ';', + spacing: Alone, + span: $DIR/allowed-attr-stmt-expr.rs:68:27: 68:28 (#0), }, ] diff --git a/src/test/ui/proc-macro/attr-stmt-expr.rs b/src/test/ui/proc-macro/attr-stmt-expr.rs index 40e5432185223..4f18ce9bf486d 100644 --- a/src/test/ui/proc-macro/attr-stmt-expr.rs +++ b/src/test/ui/proc-macro/attr-stmt-expr.rs @@ -25,7 +25,7 @@ fn print_str(string: &'static str) { macro_rules! make_stmt { ($stmt:stmt) => { #[print_attr] - #[allow(unused)] + #[rustc_dummy] $stmt } } diff --git a/src/test/ui/proc-macro/attr-stmt-expr.stdout b/src/test/ui/proc-macro/attr-stmt-expr.stdout index 59543fb0ca3ff..ed8af761a5571 100644 --- a/src/test/ui/proc-macro/attr-stmt-expr.stdout +++ b/src/test/ui/proc-macro/attr-stmt-expr.stdout @@ -1,4 +1,4 @@ -PRINT-ATTR INPUT (DISPLAY): #[allow(unused)] struct Foo { } +PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] struct Foo { } PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', @@ -9,21 +9,11 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ delimiter: Bracket, stream: TokenStream [ Ident { - ident: "allow", - span: $DIR/attr-stmt-expr.rs:28:11: 28:16 (#12), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [ - Ident { - ident: "unused", - span: $DIR/attr-stmt-expr.rs:28:17: 28:23 (#12), - }, - ], - span: $DIR/attr-stmt-expr.rs:28:16: 28:24 (#12), + ident: "rustc_dummy", + span: $DIR/attr-stmt-expr.rs:28:11: 28:22 (#12), }, ], - span: $DIR/attr-stmt-expr.rs:28:10: 28:25 (#12), + span: $DIR/attr-stmt-expr.rs:28:10: 28:23 (#12), }, Ident { ident: "struct", @@ -195,7 +185,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ span: $DIR/attr-stmt-expr.rs:51:57: 51:58 (#0), }, ] -PRINT-ATTR INPUT (DISPLAY): #[allow(unused)] #[allow(dead_code)] struct Bar { } +PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] #[allow(dead_code)] struct Bar { } PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', @@ -206,21 +196,11 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ delimiter: Bracket, stream: TokenStream [ Ident { - ident: "allow", - span: $DIR/attr-stmt-expr.rs:28:11: 28:16 (#34), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [ - Ident { - ident: "unused", - span: $DIR/attr-stmt-expr.rs:28:17: 28:23 (#34), - }, - ], - span: $DIR/attr-stmt-expr.rs:28:16: 28:24 (#34), + ident: "rustc_dummy", + span: $DIR/attr-stmt-expr.rs:28:11: 28:22 (#34), }, ], - span: $DIR/attr-stmt-expr.rs:28:10: 28:25 (#34), + span: $DIR/attr-stmt-expr.rs:28:10: 28:23 (#34), }, Punct { ch: '#', From 6f91c32da68aac9956c894608bd0a85f554d98c6 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 25 Nov 2020 17:00:28 -0500 Subject: [PATCH 4/7] Fix new 'unnecessary trailing semicolon' warnings --- compiler/rustc_codegen_ssa/src/mir/block.rs | 2 +- compiler/rustc_lint/src/builtin.rs | 2 +- compiler/rustc_lint/src/types.rs | 2 +- compiler/rustc_middle/src/mir/visit.rs | 6 +++--- compiler/rustc_middle/src/ty/instance.rs | 2 +- compiler/rustc_mir/src/interpret/util.rs | 2 +- compiler/rustc_ty_utils/src/ty.rs | 2 +- compiler/rustc_typeck/src/check/check.rs | 2 +- library/alloc/tests/vec.rs | 6 +++--- library/core/src/fmt/mod.rs | 2 +- library/core/src/future/poll_fn.rs | 2 +- library/core/src/mem/maybe_uninit.rs | 2 +- library/core/tests/ptr.rs | 2 +- library/test/src/lib.rs | 4 ++-- .../ui/associated-type-bounds/dyn-impl-trait-type.rs | 2 +- src/test/ui/associated-type-bounds/dyn-lcsit.rs | 2 +- src/test/ui/associated-type-bounds/dyn-rpit-and-let.rs | 2 +- src/test/ui/associated-type-bounds/lcsit.rs | 2 +- src/test/ui/associated-type-bounds/rpit.rs | 2 +- .../associated-type-bounds/trait-alias-impl-trait.rs | 2 +- src/test/ui/const-generics/min_const_generics/macro.rs | 10 +++++----- src/test/ui/issues/issue-10767.rs | 2 +- src/test/ui/issues/issue-2074.rs | 4 ++-- src/test/ui/macros/macro-2.rs | 2 +- src/test/ui/macros/macro-path.rs | 2 +- src/test/ui/structs-enums/nested-enum-same-names.rs | 4 ++-- src/test/ui/try-is-identifier-edition2015.rs | 2 +- src/test/ui/zero-sized/zero-size-type-destructors.rs | 2 +- 28 files changed, 39 insertions(+), 39 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 9651d0505e684..e59832a8eed5f 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -451,7 +451,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { Inhabited, ZeroValid, UninitValid, - }; + } let panic_intrinsic = intrinsic.and_then(|i| match i { sym::assert_inhabited => Some(AssertIntrinsic::Inhabited), sym::assert_zero_valid => Some(AssertIntrinsic::ZeroValid), diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index c65cf65b1c777..676c85e4afdce 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2345,7 +2345,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { enum InitKind { Zeroed, Uninit, - }; + } /// Information about why a type cannot be initialized this way. /// Contains an error message and optionally a span to point at. diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 38c71e6e92589..9ad9d53cd0db3 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1131,7 +1131,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { fn check_for_opaque_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool { struct ProhibitOpaqueTypes<'a, 'tcx> { cx: &'a LateContext<'tcx>, - }; + } impl<'a, 'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueTypes<'a, 'tcx> { type BreakTy = Ty<'tcx>; diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index ad47c6e75d354..7538818b8afc3 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -254,7 +254,7 @@ macro_rules! make_mir_visitor { macro_rules! basic_blocks { (mut) => (body.basic_blocks_mut().iter_enumerated_mut()); () => (body.basic_blocks().iter_enumerated()); - }; + } for (bb, data) in basic_blocks!($($mutability)?) { self.visit_basic_block_data(bb, data); } @@ -275,7 +275,7 @@ macro_rules! make_mir_visitor { macro_rules! type_annotations { (mut) => (body.user_type_annotations.iter_enumerated_mut()); () => (body.user_type_annotations.iter_enumerated()); - }; + } for (index, annotation) in type_annotations!($($mutability)?) { self.visit_user_type_annotation( @@ -909,7 +909,7 @@ macro_rules! make_mir_visitor { macro_rules! basic_blocks { (mut) => (body.basic_blocks_mut()); () => (body.basic_blocks()); - }; + } let basic_block = & $($mutability)? basic_blocks!($($mutability)?)[location.block]; if basic_block.statements.len() == location.statement_index { if let Some(ref $($mutability)? terminator) = basic_block.terminator { diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index f52466d85f890..413c9cca589d9 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -540,7 +540,7 @@ fn polymorphize<'tcx>( struct PolymorphizationFolder<'tcx> { tcx: TyCtxt<'tcx>, - }; + } impl ty::TypeFolder<'tcx> for PolymorphizationFolder<'tcx> { fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { diff --git a/compiler/rustc_mir/src/interpret/util.rs b/compiler/rustc_mir/src/interpret/util.rs index e49b1c9f64d44..ec90f063a5524 100644 --- a/compiler/rustc_mir/src/interpret/util.rs +++ b/compiler/rustc_mir/src/interpret/util.rs @@ -15,7 +15,7 @@ where struct UsedParamsNeedSubstVisitor<'tcx> { tcx: TyCtxt<'tcx>, - }; + } impl<'tcx> TypeVisitor<'tcx> for UsedParamsNeedSubstVisitor<'tcx> { type BreakTy = (); diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 720ad42da2aaa..aa1de6d51cba2 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -309,7 +309,7 @@ fn well_formed_types_in_env<'tcx>( InherentImpl, Fn, Other, - }; + } let node_kind = match node { Node::TraitItem(item) => match item.kind { diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index d5518dfc15a1b..11ca42872c523 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -477,7 +477,7 @@ pub(super) fn check_opaque_for_inheriting_lifetimes( struct ProhibitOpaqueVisitor<'tcx> { opaque_identity_ty: Ty<'tcx>, generics: &'tcx ty::Generics, - }; + } impl<'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueVisitor<'tcx> { type BreakTy = Option>; diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index 47ebe56f9fd3b..e19406d7a0697 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -919,7 +919,7 @@ fn test_from_iter_partially_drained_in_place_specialization() { #[test] fn test_from_iter_specialization_with_iterator_adapters() { - fn assert_in_place_trait(_: &T) {}; + fn assert_in_place_trait(_: &T) {} let src: Vec = vec![0usize; 256]; let srcptr = src.as_ptr(); let iter = src @@ -1198,7 +1198,7 @@ fn drain_filter_consumed_panic() { struct Check { index: usize, drop_counts: Rc>>, - }; + } impl Drop for Check { fn drop(&mut self) { @@ -1250,7 +1250,7 @@ fn drain_filter_unconsumed_panic() { struct Check { index: usize, drop_counts: Rc>>, - }; + } impl Drop for Check { fn drop(&mut self) { diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 506d778068682..23e8d1d856a30 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -1182,7 +1182,7 @@ impl<'a> Formatter<'a> { /// ``` /// use std::fmt; /// - /// struct Foo { nb: i32 }; + /// struct Foo { nb: i32 } /// /// impl Foo { /// fn new(nb: i32) -> Foo { diff --git a/library/core/src/future/poll_fn.rs b/library/core/src/future/poll_fn.rs index f302cda09e721..af63e1bb097b8 100644 --- a/library/core/src/future/poll_fn.rs +++ b/library/core/src/future/poll_fn.rs @@ -21,7 +21,7 @@ use crate::task::{Context, Poll}; /// /// let read_future = poll_fn(read_line); /// assert_eq!(read_future.await, "Hello, World!".to_owned()); -/// # }; +/// # } /// ``` #[unstable(feature = "future_poll_fn", issue = "72302")] pub fn poll_fn(f: F) -> PollFn diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index 94ac16954a730..1924720b949f8 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -348,7 +348,7 @@ impl MaybeUninit { /// ```rust,no_run /// use std::mem::MaybeUninit; /// - /// enum NotZero { One = 1, Two = 2 }; + /// enum NotZero { One = 1, Two = 2 } /// /// let x = MaybeUninit::<(u8, NotZero)>::zeroed(); /// let x = unsafe { x.assume_init() }; diff --git a/library/core/tests/ptr.rs b/library/core/tests/ptr.rs index bf977c141cbf8..1970b17e26721 100644 --- a/library/core/tests/ptr.rs +++ b/library/core/tests/ptr.rs @@ -18,7 +18,7 @@ fn test() { struct Pair { fst: isize, snd: isize, - }; + } let mut p = Pair { fst: 10, snd: 20 }; let pptr: *mut Pair = &mut p; let iptr: *mut isize = pptr as *mut isize; diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs index c95404d094655..5c12a54eef120 100644 --- a/library/test/src/lib.rs +++ b/library/test/src/lib.rs @@ -265,14 +265,14 @@ where running_tests.remove(test); } timed_out - }; + } fn calc_timeout(running_tests: &TestMap) -> Option { running_tests.values().min().map(|next_timeout| { let now = Instant::now(); if *next_timeout >= now { *next_timeout - now } else { Duration::new(0, 0) } }) - }; + } if concurrency == 1 { while !remaining.is_empty() { diff --git a/src/test/ui/associated-type-bounds/dyn-impl-trait-type.rs b/src/test/ui/associated-type-bounds/dyn-impl-trait-type.rs index fd9e52a6ff2f9..a8d00803a534a 100644 --- a/src/test/ui/associated-type-bounds/dyn-impl-trait-type.rs +++ b/src/test/ui/associated-type-bounds/dyn-impl-trait-type.rs @@ -30,7 +30,7 @@ fn def_et3() -> Et3 { impl Tr1 for A { type As1 = core::ops::Range; fn mk(&self) -> Self::As1 { 0..10 } - }; + } Box::new(A) } pub fn use_et3() { diff --git a/src/test/ui/associated-type-bounds/dyn-lcsit.rs b/src/test/ui/associated-type-bounds/dyn-lcsit.rs index c936fe0550ac9..b7869e22b4a14 100644 --- a/src/test/ui/associated-type-bounds/dyn-lcsit.rs +++ b/src/test/ui/associated-type-bounds/dyn-lcsit.rs @@ -33,7 +33,7 @@ const cdef_et3: &dyn Tr1>>> impl Tr1 for A { type As1 = core::ops::Range; fn mk(&self) -> Self::As1 { 0..10 } - }; + } &A }; pub fn use_et3() { diff --git a/src/test/ui/associated-type-bounds/dyn-rpit-and-let.rs b/src/test/ui/associated-type-bounds/dyn-rpit-and-let.rs index f22a6c44cb84d..08f965452ef48 100644 --- a/src/test/ui/associated-type-bounds/dyn-rpit-and-let.rs +++ b/src/test/ui/associated-type-bounds/dyn-rpit-and-let.rs @@ -35,7 +35,7 @@ fn def_et3() -> Box impl Tr1 for A { type As1 = core::ops::Range; fn mk(&self) -> Self::As1 { 0..10 } - }; + } let x /* : Box>>>> */ = Box::new(A); x diff --git a/src/test/ui/associated-type-bounds/lcsit.rs b/src/test/ui/associated-type-bounds/lcsit.rs index 497205f9f189a..5364f25f89a11 100644 --- a/src/test/ui/associated-type-bounds/lcsit.rs +++ b/src/test/ui/associated-type-bounds/lcsit.rs @@ -39,7 +39,7 @@ const cdef_et3: impl Tr1>>> impl Tr1 for A { type As1 = core::ops::Range; fn mk(&self) -> Self::As1 { 0..10 } - }; + } let x: impl Tr1>>> = A; x }; diff --git a/src/test/ui/associated-type-bounds/rpit.rs b/src/test/ui/associated-type-bounds/rpit.rs index 7b640d5a457df..47cadf3310bd8 100644 --- a/src/test/ui/associated-type-bounds/rpit.rs +++ b/src/test/ui/associated-type-bounds/rpit.rs @@ -27,7 +27,7 @@ fn def_et3() -> impl Tr1>>> impl Tr1 for A { type As1 = core::ops::Range; fn mk(self) -> Self::As1 { 0..10 } - }; + } A } diff --git a/src/test/ui/associated-type-bounds/trait-alias-impl-trait.rs b/src/test/ui/associated-type-bounds/trait-alias-impl-trait.rs index 9ee33e4149aaf..025540ce20070 100644 --- a/src/test/ui/associated-type-bounds/trait-alias-impl-trait.rs +++ b/src/test/ui/associated-type-bounds/trait-alias-impl-trait.rs @@ -31,7 +31,7 @@ fn def_et3() -> Et3 { impl Tr1 for A { type As1 = core::ops::Range; fn mk(self) -> Self::As1 { 0..10 } - }; + } A } pub fn use_et3() { diff --git a/src/test/ui/const-generics/min_const_generics/macro.rs b/src/test/ui/const-generics/min_const_generics/macro.rs index 85ecce551d405..575fbd33572f0 100644 --- a/src/test/ui/const-generics/min_const_generics/macro.rs +++ b/src/test/ui/const-generics/min_const_generics/macro.rs @@ -15,14 +15,14 @@ impl Marker for Example {} fn make_marker() -> impl Marker<{ #[macro_export] - macro_rules! const_macro { () => {{ 3 }} }; inline!() + macro_rules! const_macro { () => {{ 3 }} } inline!() }> { Example::<{ const_macro!() }> } fn from_marker(_: impl Marker<{ #[macro_export] - macro_rules! inline { () => {{ 3 }} }; inline!() + macro_rules! inline { () => {{ 3 }} } inline!() }>) {} fn main() { @@ -30,7 +30,7 @@ fn main() { #[macro_export] macro_rules! gimme_a_const { ($rusty: ident) => {{ let $rusty = 3; *&$rusty }} - }; + } gimme_a_const!(run) }>; @@ -42,13 +42,13 @@ fn main() { let _ok: [u8; { #[macro_export] - macro_rules! const_two { () => {{ 2 }} }; + macro_rules! const_two { () => {{ 2 }} } const_two!() }]; let _ok = [0; { #[macro_export] - macro_rules! const_three { () => {{ 3 }} }; + macro_rules! const_three { () => {{ 3 }} } const_three!() }]; let _ok = [0; const_three!()]; diff --git a/src/test/ui/issues/issue-10767.rs b/src/test/ui/issues/issue-10767.rs index fa10f073b4576..f40815fdbdbc5 100644 --- a/src/test/ui/issues/issue-10767.rs +++ b/src/test/ui/issues/issue-10767.rs @@ -5,6 +5,6 @@ pub fn main() { fn f() { - }; + } let _: Box = box (f as fn()); } diff --git a/src/test/ui/issues/issue-2074.rs b/src/test/ui/issues/issue-2074.rs index bd5f015cca0dc..a6bea38580477 100644 --- a/src/test/ui/issues/issue-2074.rs +++ b/src/test/ui/issues/issue-2074.rs @@ -5,11 +5,11 @@ pub fn main() { let one = || { - enum r { a }; + enum r { a } r::a as usize }; let two = || { - enum r { a }; + enum r { a } r::a as usize }; one(); two(); diff --git a/src/test/ui/macros/macro-2.rs b/src/test/ui/macros/macro-2.rs index 4890c991dcd7b..a315981b6a69f 100644 --- a/src/test/ui/macros/macro-2.rs +++ b/src/test/ui/macros/macro-2.rs @@ -3,7 +3,7 @@ pub fn main() { macro_rules! mylambda_tt { ($x:ident, $body:expr) => ({ - fn f($x: isize) -> isize { return $body; }; + fn f($x: isize) -> isize { return $body; } f }) } diff --git a/src/test/ui/macros/macro-path.rs b/src/test/ui/macros/macro-path.rs index be59d8d139bb5..6c011c897da50 100644 --- a/src/test/ui/macros/macro-path.rs +++ b/src/test/ui/macros/macro-path.rs @@ -8,7 +8,7 @@ mod m { macro_rules! foo { ($p:path) => ({ - fn f() -> $p { 10 }; + fn f() -> $p { 10 } f() }) } diff --git a/src/test/ui/structs-enums/nested-enum-same-names.rs b/src/test/ui/structs-enums/nested-enum-same-names.rs index dece3dcd54b2f..111b9ba94773f 100644 --- a/src/test/ui/structs-enums/nested-enum-same-names.rs +++ b/src/test/ui/structs-enums/nested-enum-same-names.rs @@ -17,10 +17,10 @@ as it does not include the method name in the symbol name. pub struct Foo; impl Foo { pub fn foo() { - enum Panic { Common }; + enum Panic { Common } } pub fn bar() { - enum Panic { Common }; + enum Panic { Common } } } diff --git a/src/test/ui/try-is-identifier-edition2015.rs b/src/test/ui/try-is-identifier-edition2015.rs index dfb05599be6ba..90f56d5fa71d1 100644 --- a/src/test/ui/try-is-identifier-edition2015.rs +++ b/src/test/ui/try-is-identifier-edition2015.rs @@ -5,7 +5,7 @@ fn main() { let try = 2; - struct try { try: u32 }; + struct try { try: u32 } let try: try = try { try }; assert_eq!(try.try, 2); } diff --git a/src/test/ui/zero-sized/zero-size-type-destructors.rs b/src/test/ui/zero-sized/zero-size-type-destructors.rs index 98b5a439c82de..fb87d8ea0ba7f 100644 --- a/src/test/ui/zero-sized/zero-size-type-destructors.rs +++ b/src/test/ui/zero-sized/zero-size-type-destructors.rs @@ -10,7 +10,7 @@ pub fn foo() { fn drop(&mut self) { unsafe { destructions -= 1 }; } - }; + } let _x = [Foo, Foo, Foo]; } From e8564ad5898ad8358f5449e94ab7119fb92a9f80 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 26 Nov 2020 21:44:09 -0500 Subject: [PATCH 5/7] Use custom macro instead of println Loading a macro from libstd causes us to load serialized `SyntaxContext`s in a platform-dependent way, causing the printed spans to differ between platforms. --- .../ui/proc-macro/allowed-attr-stmt-expr.rs | 18 ++- .../proc-macro/allowed-attr-stmt-expr.stdout | 130 +++++++++--------- src/test/ui/proc-macro/attr-stmt-expr.rs | 17 ++- src/test/ui/proc-macro/attr-stmt-expr.stderr | 8 +- src/test/ui/proc-macro/attr-stmt-expr.stdout | 112 +++++++-------- .../ui/proc-macro/auxiliary/attr-stmt-expr.rs | 8 +- 6 files changed, 152 insertions(+), 141 deletions(-) diff --git a/src/test/ui/proc-macro/allowed-attr-stmt-expr.rs b/src/test/ui/proc-macro/allowed-attr-stmt-expr.rs index 9e82ccd9bed86..25243aeef3b44 100644 --- a/src/test/ui/proc-macro/allowed-attr-stmt-expr.rs +++ b/src/test/ui/proc-macro/allowed-attr-stmt-expr.rs @@ -13,14 +13,20 @@ extern crate std; extern crate attr_stmt_expr; extern crate test_macros; -use attr_stmt_expr::{expect_let, expect_print_stmt, expect_expr, expect_print_expr}; +use attr_stmt_expr::{expect_let, expect_my_macro_stmt, expect_expr, expect_my_macro_expr}; use test_macros::print_attr; -use std::println; + +// We don't use `std::println` so that we avoid loading hygiene +// information from libstd, which would affect the SyntaxContext ids +macro_rules! my_macro { + ($($tt:tt)*) => { () } +} + fn print_str(string: &'static str) { // macros are handled a bit differently - #[expect_print_expr] - println!("{}", string) + #[expect_my_macro_expr] + my_macro!("{}", string) } macro_rules! make_stmt { @@ -51,8 +57,8 @@ fn main() { let string = "Hello, world!"; #[print_attr] - #[expect_print_stmt] - println!("{}", string); + #[expect_my_macro_stmt] + my_macro!("{}", string); #[print_attr] second_make_stmt!(#[allow(dead_code)] struct Bar {}); diff --git a/src/test/ui/proc-macro/allowed-attr-stmt-expr.stdout b/src/test/ui/proc-macro/allowed-attr-stmt-expr.stdout index be14e368c046d..6cf864f359085 100644 --- a/src/test/ui/proc-macro/allowed-attr-stmt-expr.stdout +++ b/src/test/ui/proc-macro/allowed-attr-stmt-expr.stdout @@ -2,16 +2,16 @@ PRINT-ATTR INPUT (DISPLAY): struct ItemWithSemi ; PRINT-ATTR INPUT (DEBUG): TokenStream [ Ident { ident: "struct", - span: $DIR/allowed-attr-stmt-expr.rs:43:1: 43:7 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:49:1: 49:7 (#0), }, Ident { ident: "ItemWithSemi", - span: $DIR/allowed-attr-stmt-expr.rs:43:8: 43:20 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:49:8: 49:20 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:43:20: 43:21 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:49:20: 49:21 (#0), }, ] PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] struct Foo { } @@ -19,30 +19,30 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:29:9: 29:10 (#15), + span: $DIR/allowed-attr-stmt-expr.rs:35:9: 35:10 (#11), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "rustc_dummy", - span: $DIR/allowed-attr-stmt-expr.rs:29:11: 29:22 (#15), + span: $DIR/allowed-attr-stmt-expr.rs:35:11: 35:22 (#11), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:29:10: 29:23 (#15), + span: $DIR/allowed-attr-stmt-expr.rs:35:10: 35:23 (#11), }, Ident { ident: "struct", - span: $DIR/allowed-attr-stmt-expr.rs:47:16: 47:22 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:53:16: 53:22 (#0), }, Ident { ident: "Foo", - span: $DIR/allowed-attr-stmt-expr.rs:47:23: 47:26 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:53:23: 53:26 (#0), }, Group { delimiter: Brace, stream: TokenStream [], - span: $DIR/allowed-attr-stmt-expr.rs:47:27: 47:29 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:53:27: 53:29 (#0), }, ] PRINT-ATTR INPUT (DISPLAY): #[expect_let] let string = "Hello, world!" ; @@ -50,68 +50,68 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:50:5: 50:6 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:56:5: 56:6 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "expect_let", - span: $DIR/allowed-attr-stmt-expr.rs:50:7: 50:17 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:56:7: 56:17 (#0), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:50:6: 50:18 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:56:6: 56:18 (#0), }, Ident { ident: "let", - span: $DIR/allowed-attr-stmt-expr.rs:51:5: 51:8 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:57:5: 57:8 (#0), }, Ident { ident: "string", - span: $DIR/allowed-attr-stmt-expr.rs:51:9: 51:15 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:57:9: 57:15 (#0), }, Punct { ch: '=', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:51:16: 51:17 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:57:16: 57:17 (#0), }, Literal { kind: Str, symbol: "Hello, world!", suffix: None, - span: $DIR/allowed-attr-stmt-expr.rs:51:18: 51:33 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:57:18: 57:33 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:51:33: 51:34 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:57:33: 57:34 (#0), }, ] -PRINT-ATTR INPUT (DISPLAY): #[expect_print_stmt] println ! ("{}", string) ; +PRINT-ATTR INPUT (DISPLAY): #[expect_my_macro_stmt] my_macro ! ("{}", string) ; PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:54:5: 54:6 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:60:5: 60:6 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { - ident: "expect_print_stmt", - span: $DIR/allowed-attr-stmt-expr.rs:54:7: 54:24 (#0), + ident: "expect_my_macro_stmt", + span: $DIR/allowed-attr-stmt-expr.rs:60:7: 60:27 (#0), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:54:6: 54:25 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:60:6: 60:28 (#0), }, Ident { - ident: "println", - span: $DIR/allowed-attr-stmt-expr.rs:55:5: 55:12 (#0), + ident: "my_macro", + span: $DIR/allowed-attr-stmt-expr.rs:61:5: 61:13 (#0), }, Punct { ch: '!', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:55:12: 55:13 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:61:13: 61:14 (#0), }, Group { delimiter: Parenthesis, @@ -120,36 +120,36 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ kind: Str, symbol: "{}", suffix: None, - span: $DIR/allowed-attr-stmt-expr.rs:55:14: 55:18 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:61:15: 61:19 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:55:18: 55:19 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:61:19: 61:20 (#0), }, Ident { ident: "string", - span: $DIR/allowed-attr-stmt-expr.rs:55:20: 55:26 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:61:21: 61:27 (#0), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:55:13: 55:27 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:61:14: 61:28 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:55:27: 55:28 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:61:28: 61:29 (#0), }, ] PRINT-ATTR INPUT (DISPLAY): second_make_stmt ! (#[allow(dead_code)] struct Bar { }) ; PRINT-ATTR INPUT (DEBUG): TokenStream [ Ident { ident: "second_make_stmt", - span: $DIR/allowed-attr-stmt-expr.rs:58:5: 58:21 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:64:5: 64:21 (#0), }, Punct { ch: '!', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:58:21: 58:22 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:64:21: 64:22 (#0), }, Group { delimiter: Parenthesis, @@ -157,48 +157,48 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:58:23: 58:24 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:64:23: 64:24 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "allow", - span: $DIR/allowed-attr-stmt-expr.rs:58:25: 58:30 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:64:25: 64:30 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "dead_code", - span: $DIR/allowed-attr-stmt-expr.rs:58:31: 58:40 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:64:31: 64:40 (#0), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:58:30: 58:41 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:64:30: 64:41 (#0), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:58:24: 58:42 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:64:24: 64:42 (#0), }, Ident { ident: "struct", - span: $DIR/allowed-attr-stmt-expr.rs:58:43: 58:49 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:64:43: 64:49 (#0), }, Ident { ident: "Bar", - span: $DIR/allowed-attr-stmt-expr.rs:58:50: 58:53 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:64:50: 64:53 (#0), }, Group { delimiter: Brace, stream: TokenStream [], - span: $DIR/allowed-attr-stmt-expr.rs:58:54: 58:56 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:64:54: 64:56 (#0), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:58:22: 58:57 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:64:22: 64:57 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:58:57: 58:58 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:64:57: 64:58 (#0), }, ] PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] #[allow(dead_code)] struct Bar { } @@ -206,55 +206,55 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:29:9: 29:10 (#37), + span: $DIR/allowed-attr-stmt-expr.rs:35:9: 35:10 (#32), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "rustc_dummy", - span: $DIR/allowed-attr-stmt-expr.rs:29:11: 29:22 (#37), + span: $DIR/allowed-attr-stmt-expr.rs:35:11: 35:22 (#32), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:29:10: 29:23 (#37), + span: $DIR/allowed-attr-stmt-expr.rs:35:10: 35:23 (#32), }, Punct { ch: '#', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:58:23: 58:24 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:64:23: 64:24 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "allow", - span: $DIR/allowed-attr-stmt-expr.rs:58:25: 58:30 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:64:25: 64:30 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "dead_code", - span: $DIR/allowed-attr-stmt-expr.rs:58:31: 58:40 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:64:31: 64:40 (#0), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:58:30: 58:41 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:64:30: 64:41 (#0), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:58:24: 58:42 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:64:24: 64:42 (#0), }, Ident { ident: "struct", - span: $DIR/allowed-attr-stmt-expr.rs:58:43: 58:49 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:64:43: 64:49 (#0), }, Ident { ident: "Bar", - span: $DIR/allowed-attr-stmt-expr.rs:58:50: 58:53 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:64:50: 64:53 (#0), }, Group { delimiter: Brace, stream: TokenStream [], - span: $DIR/allowed-attr-stmt-expr.rs:58:54: 58:56 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:64:54: 64:56 (#0), }, ] PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] struct Other { } @@ -262,30 +262,30 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:61:5: 61:6 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:67:5: 67:6 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "rustc_dummy", - span: $DIR/allowed-attr-stmt-expr.rs:61:7: 61:18 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:67:7: 67:18 (#0), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:61:6: 61:19 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:67:6: 67:19 (#0), }, Ident { ident: "struct", - span: $DIR/allowed-attr-stmt-expr.rs:62:5: 62:11 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:68:5: 68:11 (#0), }, Ident { ident: "Other", - span: $DIR/allowed-attr-stmt-expr.rs:62:12: 62:17 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:68:12: 68:17 (#0), }, Group { delimiter: Brace, stream: TokenStream [], - span: $DIR/allowed-attr-stmt-expr.rs:62:18: 62:20 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:68:18: 68:20 (#0), }, ] PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] struct NonBracedStruct ; @@ -293,29 +293,29 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:67:5: 67:6 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:73:5: 73:6 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "rustc_dummy", - span: $DIR/allowed-attr-stmt-expr.rs:67:7: 67:18 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:73:7: 73:18 (#0), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:67:6: 67:19 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:73:6: 73:19 (#0), }, Ident { ident: "struct", - span: $DIR/allowed-attr-stmt-expr.rs:68:5: 68:11 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:74:5: 74:11 (#0), }, Ident { ident: "NonBracedStruct", - span: $DIR/allowed-attr-stmt-expr.rs:68:12: 68:27 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:74:12: 74:27 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:68:27: 68:28 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:74:27: 74:28 (#0), }, ] diff --git a/src/test/ui/proc-macro/attr-stmt-expr.rs b/src/test/ui/proc-macro/attr-stmt-expr.rs index 4f18ce9bf486d..0403684cda004 100644 --- a/src/test/ui/proc-macro/attr-stmt-expr.rs +++ b/src/test/ui/proc-macro/attr-stmt-expr.rs @@ -11,15 +11,20 @@ extern crate test_macros; extern crate attr_stmt_expr; use test_macros::print_attr; -use std::println; -use attr_stmt_expr::{expect_let, expect_print_stmt, expect_expr, expect_print_expr}; +use attr_stmt_expr::{expect_let, expect_my_macro_stmt, expect_expr, expect_my_macro_expr}; + +// We don't use `std::println` so that we avoid loading hygiene +// information from libstd, which would affect the SyntaxContext ids +macro_rules! my_macro { + ($($tt:tt)*) => { () } +} fn print_str(string: &'static str) { // macros are handled a bit differently - #[expect_print_expr] + #[expect_my_macro_expr] //~^ ERROR attributes on expressions are experimental //~| HELP add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable - println!("{}", string) + my_macro!("{}", string) } macro_rules! make_stmt { @@ -44,8 +49,8 @@ fn main() { let string = "Hello, world!"; #[print_attr] - #[expect_print_stmt] - println!("{}", string); + #[expect_my_macro_stmt] + my_macro!("{}", string); #[print_attr] second_make_stmt!(#[allow(dead_code)] struct Bar {}); diff --git a/src/test/ui/proc-macro/attr-stmt-expr.stderr b/src/test/ui/proc-macro/attr-stmt-expr.stderr index 1cc7d474fcf16..56178259d4352 100644 --- a/src/test/ui/proc-macro/attr-stmt-expr.stderr +++ b/src/test/ui/proc-macro/attr-stmt-expr.stderr @@ -1,14 +1,14 @@ error[E0658]: attributes on expressions are experimental - --> $DIR/attr-stmt-expr.rs:19:5 + --> $DIR/attr-stmt-expr.rs:24:5 | -LL | #[expect_print_expr] - | ^^^^^^^^^^^^^^^^^^^^ +LL | #[expect_my_macro_expr] + | ^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #15701 for more information = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable error[E0658]: attributes on expressions are experimental - --> $DIR/attr-stmt-expr.rs:57:5 + --> $DIR/attr-stmt-expr.rs:62:5 | LL | #[expect_expr] | ^^^^^^^^^^^^^^ diff --git a/src/test/ui/proc-macro/attr-stmt-expr.stdout b/src/test/ui/proc-macro/attr-stmt-expr.stdout index ed8af761a5571..f75309e6872f9 100644 --- a/src/test/ui/proc-macro/attr-stmt-expr.stdout +++ b/src/test/ui/proc-macro/attr-stmt-expr.stdout @@ -3,30 +3,30 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/attr-stmt-expr.rs:28:9: 28:10 (#12), + span: $DIR/attr-stmt-expr.rs:33:9: 33:10 (#8), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "rustc_dummy", - span: $DIR/attr-stmt-expr.rs:28:11: 28:22 (#12), + span: $DIR/attr-stmt-expr.rs:33:11: 33:22 (#8), }, ], - span: $DIR/attr-stmt-expr.rs:28:10: 28:23 (#12), + span: $DIR/attr-stmt-expr.rs:33:10: 33:23 (#8), }, Ident { ident: "struct", - span: $DIR/attr-stmt-expr.rs:40:16: 40:22 (#0), + span: $DIR/attr-stmt-expr.rs:45:16: 45:22 (#0), }, Ident { ident: "Foo", - span: $DIR/attr-stmt-expr.rs:40:23: 40:26 (#0), + span: $DIR/attr-stmt-expr.rs:45:23: 45:26 (#0), }, Group { delimiter: Brace, stream: TokenStream [], - span: $DIR/attr-stmt-expr.rs:40:27: 40:29 (#0), + span: $DIR/attr-stmt-expr.rs:45:27: 45:29 (#0), }, ] PRINT-ATTR INPUT (DISPLAY): #[expect_let] let string = "Hello, world!" ; @@ -34,68 +34,68 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/attr-stmt-expr.rs:43:5: 43:6 (#0), + span: $DIR/attr-stmt-expr.rs:48:5: 48:6 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "expect_let", - span: $DIR/attr-stmt-expr.rs:43:7: 43:17 (#0), + span: $DIR/attr-stmt-expr.rs:48:7: 48:17 (#0), }, ], - span: $DIR/attr-stmt-expr.rs:43:6: 43:18 (#0), + span: $DIR/attr-stmt-expr.rs:48:6: 48:18 (#0), }, Ident { ident: "let", - span: $DIR/attr-stmt-expr.rs:44:5: 44:8 (#0), + span: $DIR/attr-stmt-expr.rs:49:5: 49:8 (#0), }, Ident { ident: "string", - span: $DIR/attr-stmt-expr.rs:44:9: 44:15 (#0), + span: $DIR/attr-stmt-expr.rs:49:9: 49:15 (#0), }, Punct { ch: '=', spacing: Alone, - span: $DIR/attr-stmt-expr.rs:44:16: 44:17 (#0), + span: $DIR/attr-stmt-expr.rs:49:16: 49:17 (#0), }, Literal { kind: Str, symbol: "Hello, world!", suffix: None, - span: $DIR/attr-stmt-expr.rs:44:18: 44:33 (#0), + span: $DIR/attr-stmt-expr.rs:49:18: 49:33 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/attr-stmt-expr.rs:44:33: 44:34 (#0), + span: $DIR/attr-stmt-expr.rs:49:33: 49:34 (#0), }, ] -PRINT-ATTR INPUT (DISPLAY): #[expect_print_stmt] println ! ("{}", string) ; +PRINT-ATTR INPUT (DISPLAY): #[expect_my_macro_stmt] my_macro ! ("{}", string) ; PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/attr-stmt-expr.rs:47:5: 47:6 (#0), + span: $DIR/attr-stmt-expr.rs:52:5: 52:6 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { - ident: "expect_print_stmt", - span: $DIR/attr-stmt-expr.rs:47:7: 47:24 (#0), + ident: "expect_my_macro_stmt", + span: $DIR/attr-stmt-expr.rs:52:7: 52:27 (#0), }, ], - span: $DIR/attr-stmt-expr.rs:47:6: 47:25 (#0), + span: $DIR/attr-stmt-expr.rs:52:6: 52:28 (#0), }, Ident { - ident: "println", - span: $DIR/attr-stmt-expr.rs:48:5: 48:12 (#0), + ident: "my_macro", + span: $DIR/attr-stmt-expr.rs:53:5: 53:13 (#0), }, Punct { ch: '!', spacing: Alone, - span: $DIR/attr-stmt-expr.rs:48:12: 48:13 (#0), + span: $DIR/attr-stmt-expr.rs:53:13: 53:14 (#0), }, Group { delimiter: Parenthesis, @@ -104,36 +104,36 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ kind: Str, symbol: "{}", suffix: None, - span: $DIR/attr-stmt-expr.rs:48:14: 48:18 (#0), + span: $DIR/attr-stmt-expr.rs:53:15: 53:19 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/attr-stmt-expr.rs:48:18: 48:19 (#0), + span: $DIR/attr-stmt-expr.rs:53:19: 53:20 (#0), }, Ident { ident: "string", - span: $DIR/attr-stmt-expr.rs:48:20: 48:26 (#0), + span: $DIR/attr-stmt-expr.rs:53:21: 53:27 (#0), }, ], - span: $DIR/attr-stmt-expr.rs:48:13: 48:27 (#0), + span: $DIR/attr-stmt-expr.rs:53:14: 53:28 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/attr-stmt-expr.rs:48:27: 48:28 (#0), + span: $DIR/attr-stmt-expr.rs:53:28: 53:29 (#0), }, ] PRINT-ATTR INPUT (DISPLAY): second_make_stmt ! (#[allow(dead_code)] struct Bar { }) ; PRINT-ATTR INPUT (DEBUG): TokenStream [ Ident { ident: "second_make_stmt", - span: $DIR/attr-stmt-expr.rs:51:5: 51:21 (#0), + span: $DIR/attr-stmt-expr.rs:56:5: 56:21 (#0), }, Punct { ch: '!', spacing: Alone, - span: $DIR/attr-stmt-expr.rs:51:21: 51:22 (#0), + span: $DIR/attr-stmt-expr.rs:56:21: 56:22 (#0), }, Group { delimiter: Parenthesis, @@ -141,48 +141,48 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/attr-stmt-expr.rs:51:23: 51:24 (#0), + span: $DIR/attr-stmt-expr.rs:56:23: 56:24 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "allow", - span: $DIR/attr-stmt-expr.rs:51:25: 51:30 (#0), + span: $DIR/attr-stmt-expr.rs:56:25: 56:30 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "dead_code", - span: $DIR/attr-stmt-expr.rs:51:31: 51:40 (#0), + span: $DIR/attr-stmt-expr.rs:56:31: 56:40 (#0), }, ], - span: $DIR/attr-stmt-expr.rs:51:30: 51:41 (#0), + span: $DIR/attr-stmt-expr.rs:56:30: 56:41 (#0), }, ], - span: $DIR/attr-stmt-expr.rs:51:24: 51:42 (#0), + span: $DIR/attr-stmt-expr.rs:56:24: 56:42 (#0), }, Ident { ident: "struct", - span: $DIR/attr-stmt-expr.rs:51:43: 51:49 (#0), + span: $DIR/attr-stmt-expr.rs:56:43: 56:49 (#0), }, Ident { ident: "Bar", - span: $DIR/attr-stmt-expr.rs:51:50: 51:53 (#0), + span: $DIR/attr-stmt-expr.rs:56:50: 56:53 (#0), }, Group { delimiter: Brace, stream: TokenStream [], - span: $DIR/attr-stmt-expr.rs:51:54: 51:56 (#0), + span: $DIR/attr-stmt-expr.rs:56:54: 56:56 (#0), }, ], - span: $DIR/attr-stmt-expr.rs:51:22: 51:57 (#0), + span: $DIR/attr-stmt-expr.rs:56:22: 56:57 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/attr-stmt-expr.rs:51:57: 51:58 (#0), + span: $DIR/attr-stmt-expr.rs:56:57: 56:58 (#0), }, ] PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] #[allow(dead_code)] struct Bar { } @@ -190,55 +190,55 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/attr-stmt-expr.rs:28:9: 28:10 (#34), + span: $DIR/attr-stmt-expr.rs:33:9: 33:10 (#29), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "rustc_dummy", - span: $DIR/attr-stmt-expr.rs:28:11: 28:22 (#34), + span: $DIR/attr-stmt-expr.rs:33:11: 33:22 (#29), }, ], - span: $DIR/attr-stmt-expr.rs:28:10: 28:23 (#34), + span: $DIR/attr-stmt-expr.rs:33:10: 33:23 (#29), }, Punct { ch: '#', spacing: Alone, - span: $DIR/attr-stmt-expr.rs:51:23: 51:24 (#0), + span: $DIR/attr-stmt-expr.rs:56:23: 56:24 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "allow", - span: $DIR/attr-stmt-expr.rs:51:25: 51:30 (#0), + span: $DIR/attr-stmt-expr.rs:56:25: 56:30 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "dead_code", - span: $DIR/attr-stmt-expr.rs:51:31: 51:40 (#0), + span: $DIR/attr-stmt-expr.rs:56:31: 56:40 (#0), }, ], - span: $DIR/attr-stmt-expr.rs:51:30: 51:41 (#0), + span: $DIR/attr-stmt-expr.rs:56:30: 56:41 (#0), }, ], - span: $DIR/attr-stmt-expr.rs:51:24: 51:42 (#0), + span: $DIR/attr-stmt-expr.rs:56:24: 56:42 (#0), }, Ident { ident: "struct", - span: $DIR/attr-stmt-expr.rs:51:43: 51:49 (#0), + span: $DIR/attr-stmt-expr.rs:56:43: 56:49 (#0), }, Ident { ident: "Bar", - span: $DIR/attr-stmt-expr.rs:51:50: 51:53 (#0), + span: $DIR/attr-stmt-expr.rs:56:50: 56:53 (#0), }, Group { delimiter: Brace, stream: TokenStream [], - span: $DIR/attr-stmt-expr.rs:51:54: 51:56 (#0), + span: $DIR/attr-stmt-expr.rs:56:54: 56:56 (#0), }, ] PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] struct Other { } @@ -246,29 +246,29 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', spacing: Alone, - span: $DIR/attr-stmt-expr.rs:54:5: 54:6 (#0), + span: $DIR/attr-stmt-expr.rs:59:5: 59:6 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "rustc_dummy", - span: $DIR/attr-stmt-expr.rs:54:7: 54:18 (#0), + span: $DIR/attr-stmt-expr.rs:59:7: 59:18 (#0), }, ], - span: $DIR/attr-stmt-expr.rs:54:6: 54:19 (#0), + span: $DIR/attr-stmt-expr.rs:59:6: 59:19 (#0), }, Ident { ident: "struct", - span: $DIR/attr-stmt-expr.rs:55:5: 55:11 (#0), + span: $DIR/attr-stmt-expr.rs:60:5: 60:11 (#0), }, Ident { ident: "Other", - span: $DIR/attr-stmt-expr.rs:55:12: 55:17 (#0), + span: $DIR/attr-stmt-expr.rs:60:12: 60:17 (#0), }, Group { delimiter: Brace, stream: TokenStream [], - span: $DIR/attr-stmt-expr.rs:55:18: 55:20 (#0), + span: $DIR/attr-stmt-expr.rs:60:18: 60:20 (#0), }, ] diff --git a/src/test/ui/proc-macro/auxiliary/attr-stmt-expr.rs b/src/test/ui/proc-macro/auxiliary/attr-stmt-expr.rs index 213f999e9d0ea..19183c616516a 100644 --- a/src/test/ui/proc-macro/auxiliary/attr-stmt-expr.rs +++ b/src/test/ui/proc-macro/auxiliary/attr-stmt-expr.rs @@ -15,9 +15,9 @@ pub fn expect_let(attr: TokenStream, item: TokenStream) -> TokenStream { } #[proc_macro_attribute] -pub fn expect_print_stmt(attr: TokenStream, item: TokenStream) -> TokenStream { +pub fn expect_my_macro_stmt(attr: TokenStream, item: TokenStream) -> TokenStream { assert!(attr.to_string().is_empty()); - assert_eq!(item.to_string(), "println ! (\"{}\", string) ;"); + assert_eq!(item.to_string(), "my_macro ! (\"{}\", string) ;"); item } @@ -29,9 +29,9 @@ pub fn expect_expr(attr: TokenStream, item: TokenStream) -> TokenStream { } #[proc_macro_attribute] -pub fn expect_print_expr(attr: TokenStream, item: TokenStream) -> TokenStream { +pub fn expect_my_macro_expr(attr: TokenStream, item: TokenStream) -> TokenStream { assert!(attr.to_string().is_empty()); - assert_eq!(item.to_string(), "println ! (\"{}\", string)"); + assert_eq!(item.to_string(), "my_macro ! (\"{}\", string)"); item } From 772292fa5180516f34fdcbe704c16203f7f38202 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Fri, 27 Nov 2020 09:36:59 -0500 Subject: [PATCH 6/7] Don't lint on redundant semicolons after item statements This preserves the current lint behavior for now. Linting after item statements currently prevents the compiler from bootstrapping. Fixing this is blocked on fixing this upstream in Cargo, and bumping the Cargo submodule. --- .../rustc_lint/src/redundant_semicolon.rs | 21 ++++++++++++++++--- .../redundant-semicolon/item-stmt-semi.rs | 10 +++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/lint/redundant-semicolon/item-stmt-semi.rs diff --git a/compiler/rustc_lint/src/redundant_semicolon.rs b/compiler/rustc_lint/src/redundant_semicolon.rs index 84cc7b68d4ca9..428198cae8917 100644 --- a/compiler/rustc_lint/src/redundant_semicolon.rs +++ b/compiler/rustc_lint/src/redundant_semicolon.rs @@ -28,25 +28,40 @@ declare_lint_pass!(RedundantSemicolons => [REDUNDANT_SEMICOLONS]); impl EarlyLintPass for RedundantSemicolons { fn check_block(&mut self, cx: &EarlyContext<'_>, block: &Block) { + let mut after_item_stmt = false; let mut seq = None; for stmt in block.stmts.iter() { match (&stmt.kind, &mut seq) { (StmtKind::Empty, None) => seq = Some((stmt.span, false)), (StmtKind::Empty, Some(seq)) => *seq = (seq.0.to(stmt.span), true), - (_, seq) => maybe_lint_redundant_semis(cx, seq), + (_, seq) => { + maybe_lint_redundant_semis(cx, seq, after_item_stmt); + after_item_stmt = matches!(stmt.kind, StmtKind::Item(_)); + } } } - maybe_lint_redundant_semis(cx, &mut seq); + maybe_lint_redundant_semis(cx, &mut seq, after_item_stmt); } } -fn maybe_lint_redundant_semis(cx: &EarlyContext<'_>, seq: &mut Option<(Span, bool)>) { +fn maybe_lint_redundant_semis( + cx: &EarlyContext<'_>, + seq: &mut Option<(Span, bool)>, + after_item_stmt: bool, +) { if let Some((span, multiple)) = seq.take() { // FIXME: Find a better way of ignoring the trailing // semicolon from macro expansion if span == rustc_span::DUMMY_SP { return; } + + // FIXME: Lint on semicolons after item statements + // once doing so doesn't break bootstrapping + if after_item_stmt { + return; + } + cx.struct_span_lint(REDUNDANT_SEMICOLONS, span, |lint| { let (msg, rem) = if multiple { ("unnecessary trailing semicolons", "remove these semicolons") diff --git a/src/test/ui/lint/redundant-semicolon/item-stmt-semi.rs b/src/test/ui/lint/redundant-semicolon/item-stmt-semi.rs new file mode 100644 index 0000000000000..4592bc31a3976 --- /dev/null +++ b/src/test/ui/lint/redundant-semicolon/item-stmt-semi.rs @@ -0,0 +1,10 @@ +// check-pass +// This test should stop compiling +// we decide to enable this lint for item statements. + +#![deny(redundant_semicolons)] + +fn main() { + fn inner() {}; + struct Bar {}; +} From 92bfa05b07090be1b3bf32af0c8947a0f0b387e8 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Fri, 27 Nov 2020 15:46:19 -0500 Subject: [PATCH 7/7] Bump recursion_limit in rustc_ast_passes When cfg(parallel_compiler) is enabled, we end up trying to prove Send/Sync bounds for some deeply nested types (at least when rustdoc is run). --- compiler/rustc_ast_passes/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs index bfe304419801d..7487421e709a7 100644 --- a/compiler/rustc_ast_passes/src/lib.rs +++ b/compiler/rustc_ast_passes/src/lib.rs @@ -6,6 +6,7 @@ #![feature(bindings_after_at)] #![feature(iter_is_partitioned)] +#![recursion_limit = "256"] pub mod ast_validation; pub mod feature_gate;