From 176fe3f8ac79e58e35793e6a92c75eed3c8e5b91 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 27 Feb 2020 04:10:42 +0100 Subject: [PATCH] encode `;` stmt w/o expr as `StmtKind::Empty` --- src/librustc_ast/ast.rs | 2 + src/librustc_ast/attr/mod.rs | 7 +- src/librustc_ast/mut_visit.rs | 1 + src/librustc_ast/visit.rs | 5 +- src/librustc_ast_lowering/lib.rs | 1 + src/librustc_ast_pretty/pprust.rs | 20 ++---- src/librustc_lint/builtin.rs | 5 +- src/librustc_lint/lib.rs | 6 +- src/librustc_lint/redundant_semicolon.rs | 65 ++++++++----------- src/librustc_parse/parser/stmt.rs | 27 ++------ src/test/ui/block-expr-precedence.stderr | 2 +- src/test/ui/consts/const_let_eq.rs | 1 + src/test/ui/consts/const_let_eq_float.rs | 1 + .../redundant-semi-proc-macro.rs | 2 +- .../redundant-semi-proc-macro.stderr | 6 +- src/test/ui/parser/attr-dangling-in-fn.stderr | 6 +- .../ui/parser/attr-stmt-expr-attr-bad.stderr | 8 +-- src/test/ui/parser/doc-before-semi.rs | 2 - src/test/ui/parser/doc-before-semi.stderr | 8 --- 19 files changed, 73 insertions(+), 102 deletions(-) diff --git a/src/librustc_ast/ast.rs b/src/librustc_ast/ast.rs index 62ff4f5183a70..88564647d61f9 100644 --- a/src/librustc_ast/ast.rs +++ b/src/librustc_ast/ast.rs @@ -913,6 +913,8 @@ pub enum StmtKind { Expr(P), /// Expr with a trailing semi-colon. Semi(P), + /// Just a trailing semi-colon. + Empty, /// Macro. Mac(P<(Mac, MacStmtStyle, AttrVec)>), } diff --git a/src/librustc_ast/attr/mod.rs b/src/librustc_ast/attr/mod.rs index bc5c86b02b3c0..53515cee28119 100644 --- a/src/librustc_ast/attr/mod.rs +++ b/src/librustc_ast/attr/mod.rs @@ -674,8 +674,8 @@ impl HasAttrs for StmtKind { fn attrs(&self) -> &[Attribute] { match *self { StmtKind::Local(ref local) => local.attrs(), - StmtKind::Item(..) => &[], StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => expr.attrs(), + StmtKind::Empty | StmtKind::Item(..) => &[], StmtKind::Mac(ref mac) => { let (_, _, ref attrs) = **mac; attrs.attrs() @@ -686,9 +686,8 @@ impl HasAttrs for StmtKind { fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec)) { match self { StmtKind::Local(local) => local.visit_attrs(f), - StmtKind::Item(..) => {} - StmtKind::Expr(expr) => expr.visit_attrs(f), - StmtKind::Semi(expr) => expr.visit_attrs(f), + StmtKind::Expr(expr) | StmtKind::Semi(expr) => expr.visit_attrs(f), + StmtKind::Empty | StmtKind::Item(..) => {} StmtKind::Mac(mac) => { let (_mac, _style, attrs) = mac.deref_mut(); attrs.visit_attrs(f); diff --git a/src/librustc_ast/mut_visit.rs b/src/librustc_ast/mut_visit.rs index b3abd4fc755e4..a9b06f602f629 100644 --- a/src/librustc_ast/mut_visit.rs +++ b/src/librustc_ast/mut_visit.rs @@ -1265,6 +1265,7 @@ pub fn noop_flat_map_stmt_kind( StmtKind::Item(item) => vis.flat_map_item(item).into_iter().map(StmtKind::Item).collect(), StmtKind::Expr(expr) => vis.filter_map_expr(expr).into_iter().map(StmtKind::Expr).collect(), StmtKind::Semi(expr) => vis.filter_map_expr(expr).into_iter().map(StmtKind::Semi).collect(), + StmtKind::Empty => smallvec![StmtKind::Empty], StmtKind::Mac(mut mac) => { let (mac_, _semi, attrs) = mac.deref_mut(); vis.visit_mac(mac_); diff --git a/src/librustc_ast/visit.rs b/src/librustc_ast/visit.rs index 96149ad7947ce..c92a4db6dee0b 100644 --- a/src/librustc_ast/visit.rs +++ b/src/librustc_ast/visit.rs @@ -669,9 +669,8 @@ pub fn walk_stmt<'a, V: Visitor<'a>>(visitor: &mut V, statement: &'a Stmt) { match statement.kind { StmtKind::Local(ref local) => visitor.visit_local(local), StmtKind::Item(ref item) => visitor.visit_item(item), - StmtKind::Expr(ref expression) | StmtKind::Semi(ref expression) => { - visitor.visit_expr(expression) - } + StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => visitor.visit_expr(expr), + StmtKind::Empty => {} StmtKind::Mac(ref mac) => { let (ref mac, _, ref attrs) = **mac; visitor.visit_mac(mac); diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 0f7ed9f72f8f6..df71b05ac2c98 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -2281,6 +2281,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } StmtKind::Expr(ref e) => hir::StmtKind::Expr(self.lower_expr(e)), StmtKind::Semi(ref e) => hir::StmtKind::Semi(self.lower_expr(e)), + StmtKind::Empty => return smallvec![], StmtKind::Mac(..) => panic!("shouldn't exist here"), }; smallvec![hir::Stmt { hir_id: self.lower_node_id(s.id), kind, span: s.span }] diff --git a/src/librustc_ast_pretty/pprust.rs b/src/librustc_ast_pretty/pprust.rs index ea8535eabef3f..f95c154bb3b5a 100644 --- a/src/librustc_ast_pretty/pprust.rs +++ b/src/librustc_ast_pretty/pprust.rs @@ -1446,19 +1446,13 @@ impl<'a> State<'a> { } } ast::StmtKind::Semi(ref expr) => { - match expr.kind { - // Filter out empty `Tup` exprs created for the `redundant_semicolon` - // lint, as they shouldn't be visible and interact poorly - // with proc macros. - ast::ExprKind::Tup(ref exprs) if exprs.is_empty() && expr.attrs.is_empty() => { - () - } - _ => { - self.space_if_not_bol(); - self.print_expr_outer_attr_style(expr, false); - self.s.word(";"); - } - } + self.space_if_not_bol(); + self.print_expr_outer_attr_style(expr, false); + self.s.word(";"); + } + ast::StmtKind::Empty => { + self.space_if_not_bol(); + self.s.word(";"); } ast::StmtKind::Mac(ref mac) => { let (ref mac, style, ref attrs) = **mac; diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 3eecd2a54e33e..e1680015beadd 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -775,7 +775,10 @@ impl EarlyLintPass for UnusedDocComment { ast::StmtKind::Local(..) => "statements", ast::StmtKind::Item(..) => "inner items", // expressions will be reported by `check_expr`. - ast::StmtKind::Semi(..) | ast::StmtKind::Expr(..) | ast::StmtKind::Mac(..) => return, + ast::StmtKind::Empty + | ast::StmtKind::Semi(_) + | ast::StmtKind::Expr(_) + | ast::StmtKind::Mac(_) => return, }; warn_if_doc(cx, stmt.span, kind, stmt.kind.attrs()); diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 895c42a84d8e9..825ac04bc0920 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -113,7 +113,7 @@ macro_rules! early_lint_passes { WhileTrue: WhileTrue, NonAsciiIdents: NonAsciiIdents, IncompleteFeatures: IncompleteFeatures, - RedundantSemicolon: RedundantSemicolon, + RedundantSemicolons: RedundantSemicolons, UnusedDocComment: UnusedDocComment, ] ); @@ -274,7 +274,8 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) { UNUSED_EXTERN_CRATES, UNUSED_FEATURES, UNUSED_LABELS, - UNUSED_PARENS + UNUSED_PARENS, + REDUNDANT_SEMICOLONS ); add_lint_group!( @@ -307,6 +308,7 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) { store.register_renamed("unused_doc_comment", "unused_doc_comments"); store.register_renamed("async_idents", "keyword_idents"); store.register_renamed("exceeding_bitshifts", "arithmetic_overflow"); + store.register_renamed("redundant_semicolon", "redundant_semicolons"); store.register_removed("unknown_features", "replaced by an error"); store.register_removed("unsigned_negation", "replaced by negate_unsigned feature gate"); store.register_removed("negate_unsigned", "cast a signed value instead"); diff --git a/src/librustc_lint/redundant_semicolon.rs b/src/librustc_lint/redundant_semicolon.rs index 0b66fd92430ac..0f807cd497e56 100644 --- a/src/librustc_lint/redundant_semicolon.rs +++ b/src/librustc_lint/redundant_semicolon.rs @@ -1,50 +1,41 @@ use crate::{EarlyContext, EarlyLintPass, LintContext}; -use rustc_ast::ast::{ExprKind, Stmt, StmtKind}; +use rustc_ast::ast::{Block, StmtKind}; use rustc_errors::Applicability; +use rustc_span::Span; declare_lint! { - pub REDUNDANT_SEMICOLON, + pub REDUNDANT_SEMICOLONS, Warn, "detects unnecessary trailing semicolons" } -declare_lint_pass!(RedundantSemicolon => [REDUNDANT_SEMICOLON]); +declare_lint_pass!(RedundantSemicolons => [REDUNDANT_SEMICOLONS]); -impl EarlyLintPass for RedundantSemicolon { - fn check_stmt(&mut self, cx: &EarlyContext<'_>, stmt: &Stmt) { - if let StmtKind::Semi(expr) = &stmt.kind { - if let ExprKind::Tup(ref v) = &expr.kind { - if v.is_empty() { - // Strings of excess semicolons are encoded as empty tuple expressions - // during the parsing stage, so we check for empty tuple expressions - // which span only semicolons - if let Ok(source_str) = cx.sess().source_map().span_to_snippet(stmt.span) { - if source_str.chars().all(|c| c == ';') { - let multiple = (stmt.span.hi() - stmt.span.lo()).0 > 1; - let msg = if multiple { - "unnecessary trailing semicolons" - } else { - "unnecessary trailing semicolon" - }; - cx.struct_span_lint(REDUNDANT_SEMICOLON, stmt.span, |lint| { - let mut err = lint.build(&msg); - let suggest_msg = if multiple { - "remove these semicolons" - } else { - "remove this semicolon" - }; - err.span_suggestion( - stmt.span, - &suggest_msg, - String::new(), - Applicability::MaybeIncorrect, - ); - err.emit(); - }); - } - } - } +impl EarlyLintPass for RedundantSemicolons { + fn check_block(&mut self, cx: &EarlyContext<'_>, block: &Block) { + 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), } } + maybe_lint_redundant_semis(cx, &mut seq); + } +} + +fn maybe_lint_redundant_semis(cx: &EarlyContext<'_>, seq: &mut Option<(Span, bool)>) { + if let Some((span, multiple)) = seq.take() { + cx.struct_span_lint(REDUNDANT_SEMICOLONS, span, |lint| { + let (msg, rem) = if multiple { + ("unnecessary trailing semicolons", "remove these semicolons") + } else { + ("unnecessary trailing semicolon", "remove this semicolon") + }; + lint.build(msg) + .span_suggestion(span, rem, String::new(), Applicability::MaybeIncorrect) + .emit(); + }); } } diff --git a/src/librustc_parse/parser/stmt.rs b/src/librustc_parse/parser/stmt.rs index e38a7f2f1c2a2..3864ec3aaa163 100644 --- a/src/librustc_parse/parser/stmt.rs +++ b/src/librustc_parse/parser/stmt.rs @@ -59,23 +59,10 @@ impl<'a> Parser<'a> { } else if let Some(item) = self.parse_stmt_item(attrs.clone())? { // FIXME: Bad copy of attrs self.mk_stmt(lo.to(item.span), StmtKind::Item(P(item))) - } else if self.token == token::Semi { + } else if self.eat(&token::Semi) { // Do not attempt to parse an expression if we're done here. self.error_outer_attrs(&attrs); - self.bump(); - let mut last_semi = lo; - while self.token == token::Semi { - last_semi = self.token.span; - self.bump(); - } - // We are encoding a string of semicolons as an an empty tuple that spans - // the excess semicolons to preserve this info until the lint stage. - let kind = StmtKind::Semi(self.mk_expr( - lo.to(last_semi), - ExprKind::Tup(Vec::new()), - AttrVec::new(), - )); - self.mk_stmt(lo.to(last_semi), kind) + 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()))?; @@ -144,12 +131,11 @@ impl<'a> Parser<'a> { /// Error on outer attributes in this context. /// Also error if the previous token was a doc comment. fn error_outer_attrs(&self, attrs: &[Attribute]) { - if !attrs.is_empty() { - if matches!(self.prev_token.kind, TokenKind::DocComment(..)) { - self.span_fatal_err(self.prev_token.span, Error::UselessDocComment).emit(); + if let [.., last] = attrs { + if last.is_doc_comment() { + self.span_fatal_err(last.span, Error::UselessDocComment).emit(); } else if attrs.iter().any(|a| a.style == AttrStyle::Outer) { - self.struct_span_err(self.token.span, "expected statement after outer attribute") - .emit(); + self.struct_span_err(last.span, "expected statement after outer attribute").emit(); } } } @@ -401,6 +387,7 @@ impl<'a> Parser<'a> { self.expect_semi()?; eat_semi = false; } + StmtKind::Empty => eat_semi = false, _ => {} } diff --git a/src/test/ui/block-expr-precedence.stderr b/src/test/ui/block-expr-precedence.stderr index 1307b5d6ddd82..decee1f2f1629 100644 --- a/src/test/ui/block-expr-precedence.stderr +++ b/src/test/ui/block-expr-precedence.stderr @@ -4,5 +4,5 @@ warning: unnecessary trailing semicolons LL | if (true) { 12; };;; -num; | ^^ help: remove these semicolons | - = note: `#[warn(redundant_semicolon)]` on by default + = note: `#[warn(redundant_semicolons)]` on by default diff --git a/src/test/ui/consts/const_let_eq.rs b/src/test/ui/consts/const_let_eq.rs index a2364c392f26b..818819f9ff67a 100644 --- a/src/test/ui/consts/const_let_eq.rs +++ b/src/test/ui/consts/const_let_eq.rs @@ -5,6 +5,7 @@ struct Bar { x: T } struct W(u32); struct A { a: u32 } +#[allow(redundant_semicolons)] const fn basics((a,): (u32,)) -> u32 { // Deferred assignment: let b: u32; diff --git a/src/test/ui/consts/const_let_eq_float.rs b/src/test/ui/consts/const_let_eq_float.rs index 0c927a0484d9d..bc0ef26eb2fe5 100644 --- a/src/test/ui/consts/const_let_eq_float.rs +++ b/src/test/ui/consts/const_let_eq_float.rs @@ -7,6 +7,7 @@ struct Bar { x: T } struct W(f32); struct A { a: f32 } +#[allow(redundant_semicolons)] const fn basics((a,): (f32,)) -> f32 { // Deferred assignment: let b: f32; diff --git a/src/test/ui/lint/redundant-semicolon/redundant-semi-proc-macro.rs b/src/test/ui/lint/redundant-semicolon/redundant-semi-proc-macro.rs index f207b235735fe..08a5c6c2b634a 100644 --- a/src/test/ui/lint/redundant-semicolon/redundant-semi-proc-macro.rs +++ b/src/test/ui/lint/redundant-semicolon/redundant-semi-proc-macro.rs @@ -1,6 +1,6 @@ // aux-build:redundant-semi-proc-macro-def.rs -#![deny(redundant_semicolon)] +#![deny(redundant_semicolons)] extern crate redundant_semi_proc_macro; use redundant_semi_proc_macro::should_preserve_spans; diff --git a/src/test/ui/lint/redundant-semicolon/redundant-semi-proc-macro.stderr b/src/test/ui/lint/redundant-semicolon/redundant-semi-proc-macro.stderr index 8c5ee58dc121d..a79fba9bf3f00 100644 --- a/src/test/ui/lint/redundant-semicolon/redundant-semi-proc-macro.stderr +++ b/src/test/ui/lint/redundant-semicolon/redundant-semi-proc-macro.stderr @@ -1,4 +1,4 @@ -TokenStream [Ident { ident: "fn", span: #0 bytes(197..199) }, Ident { ident: "span_preservation", span: #0 bytes(200..217) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(217..219) }, Group { delimiter: Brace, stream: TokenStream [Ident { ident: "let", span: #0 bytes(227..230) }, Ident { ident: "tst", span: #0 bytes(231..234) }, Punct { ch: '=', spacing: Alone, span: #0 bytes(235..236) }, Literal { lit: Lit { kind: Integer, symbol: "123", suffix: None }, span: Span { lo: BytePos(237), hi: BytePos(240), ctxt: #0 } }, Punct { ch: ';', spacing: Joint, span: #0 bytes(240..241) }, Punct { ch: ';', spacing: Alone, span: #0 bytes(241..242) }, Ident { ident: "match", span: #0 bytes(288..293) }, Ident { ident: "tst", span: #0 bytes(294..297) }, Group { delimiter: Brace, stream: TokenStream [Literal { lit: Lit { kind: Integer, symbol: "123", suffix: None }, span: Span { lo: BytePos(482), hi: BytePos(485), ctxt: #0 } }, Punct { ch: '=', spacing: Joint, span: #0 bytes(486..488) }, Punct { ch: '>', spacing: Alone, span: #0 bytes(486..488) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(489..491) }, Punct { ch: ',', spacing: Alone, span: #0 bytes(491..492) }, Ident { ident: "_", span: #0 bytes(501..502) }, Punct { ch: '=', spacing: Joint, span: #0 bytes(503..505) }, Punct { ch: '>', spacing: Alone, span: #0 bytes(503..505) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(506..508) }], span: #0 bytes(298..514) }, Punct { ch: ';', spacing: Joint, span: #0 bytes(514..515) }, Punct { ch: ';', spacing: Joint, span: #0 bytes(515..516) }, Punct { ch: ';', spacing: Alone, span: #0 bytes(516..517) }], span: #0 bytes(221..561) }] +TokenStream [Ident { ident: "fn", span: #0 bytes(198..200) }, Ident { ident: "span_preservation", span: #0 bytes(201..218) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(218..220) }, Group { delimiter: Brace, stream: TokenStream [Ident { ident: "let", span: #0 bytes(228..231) }, Ident { ident: "tst", span: #0 bytes(232..235) }, Punct { ch: '=', spacing: Alone, span: #0 bytes(236..237) }, Literal { lit: Lit { kind: Integer, symbol: "123", suffix: None }, span: Span { lo: BytePos(238), hi: BytePos(241), ctxt: #0 } }, Punct { ch: ';', spacing: Joint, span: #0 bytes(241..242) }, Punct { ch: ';', spacing: Alone, span: #0 bytes(242..243) }, Ident { ident: "match", span: #0 bytes(289..294) }, Ident { ident: "tst", span: #0 bytes(295..298) }, Group { delimiter: Brace, stream: TokenStream [Literal { lit: Lit { kind: Integer, symbol: "123", suffix: None }, span: Span { lo: BytePos(483), hi: BytePos(486), ctxt: #0 } }, Punct { ch: '=', spacing: Joint, span: #0 bytes(487..489) }, Punct { ch: '>', spacing: Alone, span: #0 bytes(487..489) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(490..492) }, Punct { ch: ',', spacing: Alone, span: #0 bytes(492..493) }, Ident { ident: "_", span: #0 bytes(502..503) }, Punct { ch: '=', spacing: Joint, span: #0 bytes(504..506) }, Punct { ch: '>', spacing: Alone, span: #0 bytes(504..506) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(507..509) }], span: #0 bytes(299..515) }, Punct { ch: ';', spacing: Joint, span: #0 bytes(515..516) }, Punct { ch: ';', spacing: Joint, span: #0 bytes(516..517) }, Punct { ch: ';', spacing: Alone, span: #0 bytes(517..518) }], span: #0 bytes(222..562) }] error: unnecessary trailing semicolon --> $DIR/redundant-semi-proc-macro.rs:9:19 | @@ -8,8 +8,8 @@ LL | let tst = 123;; note: the lint level is defined here --> $DIR/redundant-semi-proc-macro.rs:3:9 | -LL | #![deny(redundant_semicolon)] - | ^^^^^^^^^^^^^^^^^^^ +LL | #![deny(redundant_semicolons)] + | ^^^^^^^^^^^^^^^^^^^^ error: unnecessary trailing semicolons --> $DIR/redundant-semi-proc-macro.rs:16:7 diff --git a/src/test/ui/parser/attr-dangling-in-fn.stderr b/src/test/ui/parser/attr-dangling-in-fn.stderr index 71488d2e5c369..b1bb3ab3b17ba 100644 --- a/src/test/ui/parser/attr-dangling-in-fn.stderr +++ b/src/test/ui/parser/attr-dangling-in-fn.stderr @@ -1,8 +1,8 @@ error: expected statement after outer attribute - --> $DIR/attr-dangling-in-fn.rs:5:1 + --> $DIR/attr-dangling-in-fn.rs:4:3 | -LL | } - | ^ +LL | #[foo = "bar"] + | ^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr b/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr index 4775b9b7bc003..b03db85422d0c 100644 --- a/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr +++ b/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr @@ -411,16 +411,16 @@ LL | #[cfg(FALSE)] fn e() { let _ = x.#[attr]foo(); } | ^ expected one of `.`, `;`, `?`, or an operator error: expected statement after outer attribute - --> $DIR/attr-stmt-expr-attr-bad.rs:114:44 + --> $DIR/attr-stmt-expr-attr-bad.rs:114:37 | LL | #[cfg(FALSE)] fn e() { { fn foo() { #[attr]; } } } - | ^ + | ^^^^^^^ error: expected statement after outer attribute - --> $DIR/attr-stmt-expr-attr-bad.rs:116:45 + --> $DIR/attr-stmt-expr-attr-bad.rs:116:37 | LL | #[cfg(FALSE)] fn e() { { fn foo() { #[attr] } } } - | ^ + | ^^^^^^^ error: aborting due to 57 previous errors diff --git a/src/test/ui/parser/doc-before-semi.rs b/src/test/ui/parser/doc-before-semi.rs index c3f478fe42077..405a7e1e2a33b 100644 --- a/src/test/ui/parser/doc-before-semi.rs +++ b/src/test/ui/parser/doc-before-semi.rs @@ -3,6 +3,4 @@ fn main() { //~^ ERROR found a documentation comment that doesn't document anything //~| HELP maybe a comment was intended ; - //~^ WARNING unnecessary trailing semicolon - //~| HELP remove this semicolon } diff --git a/src/test/ui/parser/doc-before-semi.stderr b/src/test/ui/parser/doc-before-semi.stderr index b9ac30b09b2f8..e6bade18d0a2d 100644 --- a/src/test/ui/parser/doc-before-semi.stderr +++ b/src/test/ui/parser/doc-before-semi.stderr @@ -6,14 +6,6 @@ LL | /// hi | = help: doc comments must come before what they document, maybe a comment was intended with `//`? -warning: unnecessary trailing semicolon - --> $DIR/doc-before-semi.rs:5:5 - | -LL | ; - | ^ help: remove this semicolon - | - = note: `#[warn(redundant_semicolon)]` on by default - error: aborting due to previous error For more information about this error, try `rustc --explain E0585`.