]> git.lizzy.rs Git - rust.git/commitdiff
Add lint for excess trailing semicolons
authorNathan <nathan.whitaker01@gmail.com>
Tue, 30 Jul 2019 17:48:39 +0000 (13:48 -0400)
committernathanwhit <nathan.whitaker01@gmail.com>
Mon, 12 Aug 2019 14:14:07 +0000 (10:14 -0400)
src/librustc_lint/lib.rs
src/librustc_lint/redundant_semicolon.rs [new file with mode: 0644]

index 3a540fdf4b91f80c292478e22f03ccfa80cfba6f..fc416be8eeb504a6a7a582e15f9fe1d0c28d46e6 100644 (file)
@@ -24,6 +24,7 @@
 
 mod error_codes;
 mod nonstandard_style;
+mod redundant_semicolon;
 pub mod builtin;
 mod types;
 mod unused;
@@ -55,6 +56,7 @@
 use lint::LintId;
 use lint::FutureIncompatibleInfo;
 
+use redundant_semicolon::*;
 use nonstandard_style::*;
 use builtin::*;
 use types::*;
@@ -98,6 +100,7 @@ macro_rules! early_lint_passes {
             WhileTrue: WhileTrue,
             NonAsciiIdents: NonAsciiIdents,
             IncompleteFeatures: IncompleteFeatures,
+            RedundantSemicolon: RedundantSemicolon,
         ]);
     )
 }
diff --git a/src/librustc_lint/redundant_semicolon.rs b/src/librustc_lint/redundant_semicolon.rs
new file mode 100644 (file)
index 0000000..7c9df35
--- /dev/null
@@ -0,0 +1,52 @@
+use crate::lint::{EarlyLintPass, LintPass, EarlyContext, LintArray, LintContext};
+use syntax::ast::{Stmt, StmtKind, ExprKind};
+use syntax::errors::Applicability;
+
+declare_lint! {
+    pub REDUNDANT_SEMICOLON,
+    Warn,
+    "detects unnecessary trailing semicolons"
+}
+
+declare_lint_pass!(RedundantSemicolon => [REDUNDANT_SEMICOLON]);
+
+impl EarlyLintPass for RedundantSemicolon {
+    fn check_stmt(&mut self, cx: &EarlyContext<'_>, stmt: &Stmt) {
+        if let StmtKind::Semi(expr) = &stmt.node {
+            if let ExprKind::Tup(ref v) = &expr.node {
+                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"
+                            };
+                            let mut err = cx.struct_span_lint(
+                                REDUNDANT_SEMICOLON,
+                                stmt.span,
+                                &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();
+                        }
+                    }
+                }
+            }
+        }
+    }
+}