]> git.lizzy.rs Git - rust.git/commitdiff
Create lint for unimplemented!()
authorMichael A. Plikk <michael@aptoma.com>
Wed, 23 May 2018 14:43:05 +0000 (16:43 +0200)
committerMichael A. Plikk <michael@aptoma.com>
Thu, 24 May 2018 08:04:18 +0000 (10:04 +0200)
CHANGELOG.md
README.md
clippy_lints/src/lib.rs
clippy_lints/src/panic.rs
tests/ui/panic.rs
tests/ui/panic.stderr

index 3deece4229b1171d1dd567fabe6a103f9d58828d..9e233837be4345b0ef263a3167353cdd9e4c94d0 100644 (file)
@@ -815,6 +815,7 @@ All notable changes to this project will be documented in this file.
 [`trivial_regex`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#trivial_regex
 [`type_complexity`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#type_complexity
 [`unicode_not_nfc`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#unicode_not_nfc
+[`unimplemented`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#unimplemented
 [`unit_arg`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#unit_arg
 [`unit_cmp`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#unit_cmp
 [`unnecessary_cast`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#unnecessary_cast
index 9472156ec987f1d116546847734cddd802ad76cd..506615014778c6e88a36343fbe0d4c2d96350619 100644 (file)
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@
 
 A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code.
 
-[There are 258 lints included in this crate!](https://rust-lang-nursery.github.io/rust-clippy/master/index.html)
+[There are 259 lints included in this crate!](https://rust-lang-nursery.github.io/rust-clippy/master/index.html)
 
 We have a bunch of lint categories to allow you to choose how much clippy is supposed to ~~annoy~~ help you:
 
index 7864e90c1961d11c7d446e1ba9c57e3f0e3987c3..9dd9a364be7c0bd7542ade66311f88c5de6c7ea4 100644 (file)
@@ -627,6 +627,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
         open_options::NONSENSICAL_OPEN_OPTIONS,
         overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL,
         panic::PANIC_PARAMS,
+        panic::UNIMPLEMENTED,
         partialeq_ne_impl::PARTIALEQ_NE_IMPL,
         precedence::PRECEDENCE,
         ptr::CMP_NULL,
@@ -749,6 +750,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
         non_expressive_names::MANY_SINGLE_CHAR_NAMES,
         ok_if_let::IF_LET_SOME_RESULT,
         panic::PANIC_PARAMS,
+        panic::UNIMPLEMENTED,
         ptr::CMP_NULL,
         ptr::PTR_ARG,
         question_mark::QUESTION_MARK,
index bd44b8d9b03302a89d5863fc1d8e456a038f5d1e..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, opt_def_id, paths, resolve_node, 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!`.
 ///
     "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)
     }
 }
 
@@ -37,22 +54,35 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
             if let ExprBlock(ref block, _) = expr.node;
             if let Some(ref ex) = block.expr;
             if let ExprCall(ref fun, ref params) = ex.node;
-            if params.len() == 2;
             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 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();
+            if params.len() == 2;
             then {
-                span_lint(cx, PANIC_PARAMS, params[0].span,
-                          "you probably are missing some parameter in your format string");
+                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);
+                }
             }
         }
     }
 }
+
+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");
+        }
+    }
+}
index d833d2651a5975bc5c7713924eeaf7504ef698d8..56d06f23904b52dc41719ca106eba8781205cf62 100644 (file)
@@ -1,7 +1,7 @@
 
 
 
-#![warn(panic_params)]
+#![warn(panic_params, unimplemented)]
 
 fn missing() {
     if true {
@@ -53,6 +53,10 @@ fn ok_escaped() {
     panic!("{case }}");
 }
 
+fn unimplemented() {
+    unimplemented!();
+}
+
 fn main() {
     missing();
     ok_single();
@@ -61,4 +65,5 @@ fn main() {
     ok_inner();
     ok_nomsg();
     ok_escaped();
+    unimplemented();
 }
index 165c33cacb7da49a6301905f2ba73d4ae8b44887..786a20c031b318492072bc6c5d993e82706e426a 100644 (file)
@@ -24,5 +24,14 @@ error: you probably are missing some parameter in your format string
 15 |     panic!("{{{this}}}");
    |            ^^^^^^^^^^^^
 
-error: aborting due to 4 previous errors
+error: `unimplemented` should not be present in production code
+  --> $DIR/panic.rs:57:5
+   |
+57 |     unimplemented!();
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D unimplemented` implied by `-D warnings`
+   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error: aborting due to 5 previous errors