]> git.lizzy.rs Git - rust.git/blobdiff - clippy_lints/src/panic.rs
Create lint for unimplemented!()
[rust.git] / clippy_lints / src / panic.rs
index 97ad9173ef15fbe2724c96caa5959971495222fa..7f1b6775bab92f6db5ae9c5eb45d3d3bd7e48040 100644 (file)
@@ -1,7 +1,8 @@
 use rustc::hir::*;
 use rustc::lint::*;
 use syntax::ast::LitKind;
-use utils::{is_direct_expn_of, match_def_path, resolve_node, paths, span_lint};
+use syntax::ptr::P;
+use utils::{is_direct_expn_of, is_expn_of, match_def_path, opt_def_id, paths, resolve_node, span_lint};
 
 /// **What it does:** Checks for missing parameters in `panic!`.
 ///
 /// is not a format string and used literally. So while `format!("{}")` will
 /// fail to compile, `panic!("{}")` will not.
 ///
-/// **Known problems:** Should you want to use curly brackets in `panic!`
-/// without any parameter, this lint will warn.
+/// **Known problems:** None.
 ///
 /// **Example:**
 /// ```rust
 /// panic!("This `panic!` is probably missing a parameter there: {}");
 /// ```
-declare_lint! {
+declare_clippy_lint! {
     pub PANIC_PARAMS,
-    Warn,
+    style,
     "missing parameters in `panic!` calls"
 }
 
+/// **What it does:** Checks for usage of `unimplemented!`.
+///
+/// **Why is this bad?** This macro should not be present in production code
+///
+/// **Known problems:** None.
+///
+/// **Example:**
+/// ```rust
+/// unimplemented!();
+/// ```
+declare_clippy_lint! {
+    pub UNIMPLEMENTED,
+    style,
+    "`unimplemented!` should not be present in production code"
+}
+
 #[allow(missing_copy_implementations)]
 pub struct Pass;
 
 impl LintPass for Pass {
     fn get_lints(&self) -> LintArray {
-        lint_array!(PANIC_PARAMS)
+        lint_array!(PANIC_PARAMS, UNIMPLEMENTED)
+    }
+}
+
+impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
+    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
+        if_chain! {
+            if let ExprBlock(ref block, _) = expr.node;
+            if let Some(ref ex) = block.expr;
+            if let ExprCall(ref fun, ref params) = ex.node;
+            if let ExprPath(ref qpath) = fun.node;
+            if let Some(fun_def_id) = opt_def_id(resolve_node(cx, qpath, fun.hir_id));
+            if match_def_path(cx.tcx, fun_def_id, &paths::BEGIN_PANIC);
+            if params.len() == 2;
+            then {
+                if is_expn_of(expr.span, "unimplemented").is_some() {
+                    span_lint(cx, UNIMPLEMENTED, expr.span,
+                              "`unimplemented` should not be present in production code");
+                } else {
+                    match_panic(params, expr, cx);
+                }
+            }
+        }
     }
 }
 
-impl LateLintPass for Pass {
-    fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
-        if_let_chain! {[
-            let ExprBlock(ref block) = expr.node,
-            let Some(ref ex) = block.expr,
-            let ExprCall(ref fun, ref params) = ex.node,
-            params.len() == 2,
-            let ExprPath(None, _) = fun.node,
-            let Some(fun) = resolve_node(cx, fun.id),
-            match_def_path(cx, fun.def_id(), &paths::BEGIN_PANIC),
-            let ExprLit(ref lit) = params[0].node,
-            is_direct_expn_of(cx, params[0].span, "panic").is_some(),
-            let LitKind::Str(ref string, _) = lit.node,
-            let Some(par) = string.as_str().find('{'),
-            string.as_str()[par..].contains('}')
-        ], {
+fn match_panic(params: &P<[Expr]>, expr: &Expr, cx: &LateContext) {
+    if_chain! {
+        if let ExprLit(ref lit) = params[0].node;
+        if is_direct_expn_of(expr.span, "panic").is_some();
+        if let LitKind::Str(ref string, _) = lit.node;
+        let string = string.as_str().replace("{{", "").replace("}}", "");
+        if let Some(par) = string.find('{');
+        if string[par..].contains('}');
+        if params[0].span.source_callee().is_none();
+        if params[0].span.lo() != params[0].span.hi();
+        then {
             span_lint(cx, PANIC_PARAMS, params[0].span,
                       "you probably are missing some parameter in your format string");
-        }}
+        }
     }
 }