diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 92b58782465bf..9d6ee65049ab2 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 878196a693381..c4e92a9f6d17f 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -579,13 +579,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) { @@ -1328,16 +1329,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( @@ -1354,9 +1351,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 60ff956bd9624..61426a838deec 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -689,7 +689,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_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; 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_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_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_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/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/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_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index 9953d3255b776..44999c9b63ab6 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; @@ -251,29 +252,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..e974556f43a49 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,13 +469,18 @@ 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, - _ => {} + StmtKind::Empty | StmtKind::Item(_) | StmtKind::Semi(_) => eat_semi = false, } 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 +491,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/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 19957e7d303cf..55c815b21ad20 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/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 {}; +} 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/proc-macro/allowed-attr-stmt-expr.rs b/src/test/ui/proc-macro/allowed-attr-stmt-expr.rs index 03c10a4324898..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,19 +13,28 @@ 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 { ($stmt:stmt) => { - $stmt + #[print_attr] + #[rustc_dummy] + $stmt; // This semicolon is *not* passed to the macro, + // since `$stmt` is already a statement. } } @@ -35,6 +44,10 @@ macro_rules! second_make_stmt { } } +// The macro will see a semicolon here +#[print_attr] +struct ItemWithSemi; + fn main() { make_stmt!(struct Foo {}); @@ -44,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 {}); @@ -54,6 +67,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 0c7ac4fb682ae..6cf864f359085 100644 --- a/src/test/ui/proc-macro/allowed-attr-stmt-expr.stdout +++ b/src/test/ui/proc-macro/allowed-attr-stmt-expr.stdout @@ -1,70 +1,117 @@ +PRINT-ATTR INPUT (DISPLAY): struct ItemWithSemi ; +PRINT-ATTR INPUT (DEBUG): TokenStream [ + Ident { + ident: "struct", + span: $DIR/allowed-attr-stmt-expr.rs:49:1: 49:7 (#0), + }, + Ident { + ident: "ItemWithSemi", + span: $DIR/allowed-attr-stmt-expr.rs:49:8: 49:20 (#0), + }, + Punct { + ch: ';', + spacing: Alone, + span: $DIR/allowed-attr-stmt-expr.rs:49:20: 49: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:35:9: 35:10 (#11), + }, + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + ident: "rustc_dummy", + span: $DIR/allowed-attr-stmt-expr.rs:35:11: 35:22 (#11), + }, + ], + span: $DIR/allowed-attr-stmt-expr.rs:35:10: 35:23 (#11), + }, + Ident { + ident: "struct", + span: $DIR/allowed-attr-stmt-expr.rs:53:16: 53:22 (#0), + }, + Ident { + ident: "Foo", + span: $DIR/allowed-attr-stmt-expr.rs:53:23: 53:26 (#0), + }, + Group { + delimiter: Brace, + stream: TokenStream [], + span: $DIR/allowed-attr-stmt-expr.rs:53:27: 53: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:56:5: 56: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:56:7: 56:17 (#0), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:56:6: 56:18 (#0), }, Ident { ident: "let", - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:57:5: 57:8 (#0), }, Ident { ident: "string", - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:57:9: 57: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:57:16: 57: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:57:18: 57: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: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:1:1: 1:1 (#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:1:1: 1:1 (#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:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:60:6: 60:28 (#0), }, Ident { - ident: "println", - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#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:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:61:13: 61:14 (#0), }, Group { delimiter: Parenthesis, @@ -73,36 +120,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:61:15: 61:19 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:61:19: 61:20 (#0), }, Ident { ident: "string", - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:61:21: 61:27 (#0), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:61:14: 61:28 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#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:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:64:5: 64: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:64:21: 64:22 (#0), }, Group { delimiter: Parenthesis, @@ -110,48 +157,104 @@ 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:64:23: 64: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:64:25: 64: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:64:31: 64:40 (#0), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:64:30: 64:41 (#0), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:64:24: 64:42 (#0), }, Ident { ident: "struct", - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:64:43: 64:49 (#0), }, Ident { ident: "Bar", - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#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:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:64:54: 64:56 (#0), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:64:22: 64: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:64:57: 64:58 (#0), + }, +] +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:35:9: 35:10 (#32), + }, + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + ident: "rustc_dummy", + span: $DIR/allowed-attr-stmt-expr.rs:35:11: 35:22 (#32), + }, + ], + span: $DIR/allowed-attr-stmt-expr.rs:35:10: 35:23 (#32), + }, + Punct { + ch: '#', + spacing: Alone, + 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:64:25: 64:30 (#0), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "dead_code", + span: $DIR/allowed-attr-stmt-expr.rs:64:31: 64:40 (#0), + }, + ], + span: $DIR/allowed-attr-stmt-expr.rs:64:30: 64:41 (#0), + }, + ], + span: $DIR/allowed-attr-stmt-expr.rs:64:24: 64:42 (#0), + }, + Ident { + ident: "struct", + span: $DIR/allowed-attr-stmt-expr.rs:64:43: 64:49 (#0), + }, + Ident { + ident: "Bar", + span: $DIR/allowed-attr-stmt-expr.rs:64:50: 64:53 (#0), + }, + Group { + delimiter: Brace, + stream: TokenStream [], + span: $DIR/allowed-attr-stmt-expr.rs:64:54: 64:56 (#0), }, ] PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] struct Other { } @@ -159,29 +262,60 @@ 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:67:5: 67: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:67:7: 67:18 (#0), }, ], - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:67:6: 67:19 (#0), }, Ident { ident: "struct", - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:68:5: 68:11 (#0), }, Ident { ident: "Other", - span: $DIR/allowed-attr-stmt-expr.rs:1:1: 1:1 (#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:1:1: 1:1 (#0), + span: $DIR/allowed-attr-stmt-expr.rs:68:18: 68: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:73:5: 73:6 (#0), + }, + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + ident: "rustc_dummy", + span: $DIR/allowed-attr-stmt-expr.rs:73:7: 73:18 (#0), + }, + ], + span: $DIR/allowed-attr-stmt-expr.rs:73:6: 73:19 (#0), + }, + Ident { + ident: "struct", + span: $DIR/allowed-attr-stmt-expr.rs:74:5: 74:11 (#0), + }, + Ident { + ident: "NonBracedStruct", + span: $DIR/allowed-attr-stmt-expr.rs:74:12: 74:27 (#0), + }, + Punct { + ch: ';', + spacing: Alone, + 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 ca1b163c986e0..0403684cda004 100644 --- a/src/test/ui/proc-macro/attr-stmt-expr.rs +++ b/src/test/ui/proc-macro/attr-stmt-expr.rs @@ -11,19 +11,26 @@ 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 { ($stmt:stmt) => { + #[print_attr] + #[rustc_dummy] $stmt } } @@ -42,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 7bd60e8ee77f9..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:55: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 5c1b586725b24..f75309e6872f9 100644 --- a/src/test/ui/proc-macro/attr-stmt-expr.stdout +++ b/src/test/ui/proc-macro/attr-stmt-expr.stdout @@ -1,70 +1,101 @@ +PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] struct Foo { } +PRINT-ATTR INPUT (DEBUG): TokenStream [ + Punct { + ch: '#', + spacing: Alone, + 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:33:11: 33:22 (#8), + }, + ], + span: $DIR/attr-stmt-expr.rs:33:10: 33:23 (#8), + }, + Ident { + ident: "struct", + span: $DIR/attr-stmt-expr.rs:45:16: 45:22 (#0), + }, + Ident { + ident: "Foo", + span: $DIR/attr-stmt-expr.rs:45:23: 45:26 (#0), + }, + Group { + delimiter: Brace, + stream: TokenStream [], + span: $DIR/attr-stmt-expr.rs:45:27: 45: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:48:5: 48: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:48:7: 48:17 (#0), }, ], - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:48:6: 48:18 (#0), }, Ident { ident: "let", - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:49:5: 49:8 (#0), }, Ident { ident: "string", - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:49:9: 49:15 (#0), }, Punct { ch: '=', spacing: Alone, - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#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:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:49:18: 49:33 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#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:1:1: 1:1 (#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:1:1: 1:1 (#0), + ident: "expect_my_macro_stmt", + span: $DIR/attr-stmt-expr.rs:52:7: 52:27 (#0), }, ], - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:52:6: 52:28 (#0), }, Ident { - ident: "println", - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#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:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:53:13: 53:14 (#0), }, Group { delimiter: Parenthesis, @@ -73,36 +104,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:53:15: 53:19 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:53:19: 53:20 (#0), }, Ident { ident: "string", - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:53:21: 53:27 (#0), }, ], - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:53:14: 53:28 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#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:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:56:5: 56:21 (#0), }, Punct { ch: '!', spacing: Alone, - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:56:21: 56:22 (#0), }, Group { delimiter: Parenthesis, @@ -110,48 +141,104 @@ 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:56:23: 56: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:56:25: 56: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:56:31: 56:40 (#0), }, ], - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:56:30: 56:41 (#0), }, ], - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:56:24: 56:42 (#0), }, Ident { ident: "struct", - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:56:43: 56:49 (#0), }, Ident { ident: "Bar", - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:56:50: 56:53 (#0), }, Group { delimiter: Brace, stream: TokenStream [], - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:56:54: 56:56 (#0), }, ], - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:56:22: 56:57 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:56:57: 56:58 (#0), + }, +] +PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] #[allow(dead_code)] struct Bar { } +PRINT-ATTR INPUT (DEBUG): TokenStream [ + Punct { + ch: '#', + spacing: Alone, + 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:33:11: 33:22 (#29), + }, + ], + span: $DIR/attr-stmt-expr.rs:33:10: 33:23 (#29), + }, + Punct { + ch: '#', + spacing: Alone, + 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:56:25: 56:30 (#0), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "dead_code", + span: $DIR/attr-stmt-expr.rs:56:31: 56:40 (#0), + }, + ], + span: $DIR/attr-stmt-expr.rs:56:30: 56:41 (#0), + }, + ], + span: $DIR/attr-stmt-expr.rs:56:24: 56:42 (#0), + }, + Ident { + ident: "struct", + span: $DIR/attr-stmt-expr.rs:56:43: 56:49 (#0), + }, + Ident { + ident: "Bar", + span: $DIR/attr-stmt-expr.rs:56:50: 56:53 (#0), + }, + Group { + delimiter: Brace, + stream: TokenStream [], + span: $DIR/attr-stmt-expr.rs:56:54: 56:56 (#0), }, ] PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] struct Other { } @@ -159,29 +246,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:59:5: 59: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:59:7: 59:18 (#0), }, ], - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:59:6: 59:19 (#0), }, Ident { ident: "struct", - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:60:5: 60:11 (#0), }, Ident { ident: "Other", - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#0), + span: $DIR/attr-stmt-expr.rs:60:12: 60:17 (#0), }, Group { delimiter: Brace, stream: TokenStream [], - span: $DIR/attr-stmt-expr.rs:1:1: 1:1 (#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 } 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]; }