1 use crate::{EarlyContext, EarlyLintPass, LintContext}
;
2 use rustc_ast
::{Block, StmtKind}
;
3 use rustc_errors
::Applicability
;
7 /// The `redundant_semicolons` lint detects unnecessary trailing
20 /// Extra semicolons are not needed, and may be removed to avoid confusion
21 /// and visual clutter.
22 pub REDUNDANT_SEMICOLONS
,
24 "detects unnecessary trailing semicolons"
27 declare_lint_pass
!(RedundantSemicolons
=> [REDUNDANT_SEMICOLONS
]);
29 impl EarlyLintPass
for RedundantSemicolons
{
30 fn check_block(&mut self, cx
: &EarlyContext
<'_
>, block
: &Block
) {
31 let mut after_item_stmt
= false;
33 for stmt
in block
.stmts
.iter() {
34 match (&stmt
.kind
, &mut seq
) {
35 (StmtKind
::Empty
, None
) => seq
= Some((stmt
.span
, false)),
36 (StmtKind
::Empty
, Some(seq
)) => *seq
= (seq
.0.to(stmt
.span
), true),
38 maybe_lint_redundant_semis(cx
, seq
, after_item_stmt
);
39 after_item_stmt
= matches
!(stmt
.kind
, StmtKind
::Item(_
));
43 maybe_lint_redundant_semis(cx
, &mut seq
, after_item_stmt
);
47 fn maybe_lint_redundant_semis(
48 cx
: &EarlyContext
<'_
>,
49 seq
: &mut Option
<(Span
, bool
)>,
50 after_item_stmt
: bool
,
52 if let Some((span
, multiple
)) = seq
.take() {
53 // FIXME: Find a better way of ignoring the trailing
54 // semicolon from macro expansion
55 if span
== rustc_span
::DUMMY_SP
{
59 // FIXME: Lint on semicolons after item statements
60 // once doing so doesn't break bootstrapping
65 cx
.struct_span_lint(REDUNDANT_SEMICOLONS
, span
, |lint
| {
66 let (msg
, rem
) = if multiple
{
67 ("unnecessary trailing semicolons", "remove these semicolons")
69 ("unnecessary trailing semicolon", "remove this semicolon")
72 .span_suggestion(span
, rem
, String
::new(), Applicability
::MaybeIncorrect
)