]> git.lizzy.rs Git - rust.git/commitdiff
matches: new module, move single_match lint there
authorGeorg Brandl <georg@python.org>
Fri, 21 Aug 2015 17:32:21 +0000 (19:32 +0200)
committerGeorg Brandl <georg@python.org>
Sat, 22 Aug 2015 12:34:39 +0000 (14:34 +0200)
src/lib.rs
src/matches.rs [new file with mode: 0644]
src/misc.rs

index b0f46ae45abbf7be906ba133534ef1e51b29df0b..fbeebb210fe725caa78e12af8766c5c90a46003f 100755 (executable)
 pub mod lifetimes;
 pub mod loops;
 pub mod ranges;
+pub mod matches;
 
 #[plugin_registrar]
 pub fn plugin_registrar(reg: &mut Registry) {
     reg.register_lint_pass(box types::TypePass as LintPassObject);
-    reg.register_lint_pass(box misc::MiscPass as LintPassObject);
     reg.register_lint_pass(box misc::TopLevelRefPass as LintPassObject);
     reg.register_lint_pass(box misc::CmpNan as LintPassObject);
     reg.register_lint_pass(box eq_op::EqOp as LintPassObject);
@@ -71,6 +71,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
     reg.register_lint_pass(box ranges::StepByZero as LintPassObject);
     reg.register_lint_pass(box types::CastPass as LintPassObject);
     reg.register_lint_pass(box types::TypeComplexityPass as LintPassObject);
+    reg.register_lint_pass(box matches::MatchPass as LintPassObject);
 
     reg.register_lint_group("clippy", vec![
         approx_const::APPROX_CONSTANT,
@@ -87,6 +88,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
         loops::EXPLICIT_ITER_LOOP,
         loops::ITER_NEXT_LOOP,
         loops::NEEDLESS_RANGE_LOOP,
+        matches::SINGLE_MATCH,
         methods::OPTION_UNWRAP_USED,
         methods::RESULT_UNWRAP_USED,
         methods::STR_TO_STRING,
@@ -96,7 +98,6 @@ pub fn plugin_registrar(reg: &mut Registry) {
         misc::FLOAT_CMP,
         misc::MODULO_ONE,
         misc::PRECEDENCE,
-        misc::SINGLE_MATCH,
         misc::TOPLEVEL_REF_ARG,
         mut_mut::MUT_MUT,
         needless_bool::NEEDLESS_BOOL,
diff --git a/src/matches.rs b/src/matches.rs
new file mode 100644 (file)
index 0000000..b9f6cbc
--- /dev/null
@@ -0,0 +1,61 @@
+use rustc::lint::*;
+use syntax::ast;
+use syntax::ast::*;
+use std::borrow::Cow;
+
+use utils::{snippet, snippet_block, span_help_and_lint};
+
+declare_lint!(pub SINGLE_MATCH, Warn,
+              "a match statement with a single nontrivial arm (i.e, where the other arm \
+               is `_ => {}`) is used; recommends `if let` instead");
+
+#[allow(missing_copy_implementations)]
+pub struct MatchPass;
+
+impl LintPass for MatchPass {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(SINGLE_MATCH)
+    }
+
+    fn check_expr(&mut self, cx: &Context, expr: &Expr) {
+        if let ExprMatch(ref ex, ref arms, ast::MatchSource::Normal) = expr.node {
+            // check preconditions: only two arms
+            if arms.len() == 2 &&
+                // both of the arms have a single pattern and no guard
+                arms[0].pats.len() == 1 && arms[0].guard.is_none() &&
+                arms[1].pats.len() == 1 && arms[1].guard.is_none() &&
+                // and the second pattern is a `_` wildcard: this is not strictly necessary,
+                // since the exhaustiveness check will ensure the last one is a catch-all,
+                // but in some cases, an explicit match is preferred to catch situations
+                // when an enum is extended, so we don't consider these cases
+                arms[1].pats[0].node == PatWild(PatWildSingle) &&
+                // finally, we don't want any content in the second arm (unit or empty block)
+                is_unit_expr(&*arms[1].body)
+            {
+                let body_code = snippet_block(cx, arms[0].body.span, "..");
+                let body_code = if let ExprBlock(_) = arms[0].body.node {
+                    body_code
+                } else {
+                    Cow::Owned(format!("{{ {} }}", body_code))
+                };
+                span_help_and_lint(cx, SINGLE_MATCH, expr.span,
+                      "you seem to be trying to use match for \
+                      destructuring a single pattern. Did you mean to \
+                      use `if let`?",
+                      &*format!("try\nif let {} = {} {}",
+                                snippet(cx, arms[0].pats[0].span, ".."),
+                                snippet(cx, ex.span, ".."),
+                                body_code)
+                );
+            }
+        }
+    }
+}
+
+fn is_unit_expr(expr: &Expr) -> bool {
+    match expr.node {
+        ExprTup(ref v) if v.is_empty() => true,
+        ExprBlock(ref b) if b.stmts.is_empty() && b.expr.is_none() => true,
+        _ => false,
+    }
+}
index aca849931bb2dec4144aea43f78fa094038ccfde..49324de8de91c781f46ad7cda29c4cf23cf0ac37 100644 (file)
@@ -1,75 +1,14 @@
 use rustc::lint::*;
 use syntax::ptr::P;
-use syntax::ast;
 use syntax::ast::*;
 use syntax::ast_util::{is_comparison_binop, binop_to_string};
 use syntax::codemap::{Span, Spanned};
 use syntax::visit::FnKind;
 use rustc::middle::ty;
-use std::borrow::Cow;
 
-use utils::{match_path, snippet, snippet_block, span_lint, span_help_and_lint, walk_ptrs_ty};
+use utils::{match_path, snippet, span_lint, walk_ptrs_ty};
 use consts::constant;
 
-/// Handles uncategorized lints
-/// Currently handles linting of if-let-able matches
-#[allow(missing_copy_implementations)]
-pub struct MiscPass;
-
-
-declare_lint!(pub SINGLE_MATCH, Warn,
-              "a match statement with a single nontrivial arm (i.e, where the other arm \
-               is `_ => {}`) is used; recommends `if let` instead");
-
-impl LintPass for MiscPass {
-    fn get_lints(&self) -> LintArray {
-        lint_array!(SINGLE_MATCH)
-    }
-
-    fn check_expr(&mut self, cx: &Context, expr: &Expr) {
-        if let ExprMatch(ref ex, ref arms, ast::MatchSource::Normal) = expr.node {
-            // check preconditions: only two arms
-            if arms.len() == 2 &&
-                // both of the arms have a single pattern and no guard
-                arms[0].pats.len() == 1 && arms[0].guard.is_none() &&
-                arms[1].pats.len() == 1 && arms[1].guard.is_none() &&
-                // and the second pattern is a `_` wildcard: this is not strictly necessary,
-                // since the exhaustiveness check will ensure the last one is a catch-all,
-                // but in some cases, an explicit match is preferred to catch situations
-                // when an enum is extended, so we don't consider these cases
-                arms[1].pats[0].node == PatWild(PatWildSingle) &&
-                // finally, we don't want any content in the second arm (unit or empty block)
-                is_unit_expr(&*arms[1].body)
-            {
-                let body_code = snippet_block(cx, arms[0].body.span, "..");
-                let body_code = if let ExprBlock(_) = arms[0].body.node {
-                    body_code
-                } else {
-                    Cow::Owned(format!("{{ {} }}", body_code))
-                };
-                span_help_and_lint(cx, SINGLE_MATCH, expr.span,
-                      "you seem to be trying to use match for \
-                      destructuring a single pattern. Did you mean to \
-                      use `if let`?",
-                      &*format!("try\nif let {} = {} {}",
-                                snippet(cx, arms[0].pats[0].span, ".."),
-                                snippet(cx, ex.span, ".."),
-                                body_code)
-                );
-            }
-        }
-    }
-}
-
-fn is_unit_expr(expr: &Expr) -> bool {
-    match expr.node {
-        ExprTup(ref v) if v.is_empty() => true,
-        ExprBlock(ref b) if b.stmts.is_empty() && b.expr.is_none() => true,
-        _ => false,
-    }
-}
-
-
 declare_lint!(pub TOPLEVEL_REF_ARG, Warn,
               "a function argument is declared `ref` (i.e. `fn foo(ref x: u8)`, but not \
                `fn foo((ref x, ref y): (u8, u8))`)");