diff --git a/clippy_lints/src/assert_checks.rs b/clippy_lints/src/assert_checks.rs new file mode 100644 index 00000000000..ecd71952b93 --- /dev/null +++ b/clippy_lints/src/assert_checks.rs @@ -0,0 +1,78 @@ +// Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use crate::rustc::hir::{Expr, ExprKind}; +use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; +use crate::rustc::{declare_tool_lint, lint_array}; +use crate::syntax::ast::LitKind; +use crate::utils::{is_direct_expn_of, span_lint}; +use if_chain::if_chain; + +/// **What it does:** Check explicit call assert!(true) +/// +/// **Why is this bad?** Will be optimized out by the compiler +/// +/// **Known problems:** None +/// +/// **Example:** +/// ```rust +/// assert!(true) +/// ``` +declare_clippy_lint! { + pub EXPLICIT_TRUE, + correctness, + "assert!(true) will be optimized out by the compiler" +} + +/// **What it does:** Check explicit call assert!(false) +/// +/// **Why is this bad?** Should probably be replaced by a panic!() +/// +/// **Known problems:** None +/// +/// **Example:** +/// ```rust +/// assert!(false) +/// ``` +declare_clippy_lint! { + pub EXPLICIT_FALSE, + correctness, + "assert!(false) should probably be replaced by a panic!()r" +} + +pub struct AssertChecks; + +impl LintPass for AssertChecks { + fn get_lints(&self) -> LintArray { + lint_array![EXPLICIT_TRUE, EXPLICIT_FALSE] + } +} + +impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssertChecks { + fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) { + if_chain! { + if is_direct_expn_of(e.span, "assert").is_some(); + if let ExprKind::Unary(_, ref lit) = e.node; + if let ExprKind::Lit(ref inner) = lit.node; + then { + match inner.node { + LitKind::Bool(true) => { + span_lint(cx, EXPLICIT_TRUE, e.span, + "assert!(true) will be optimized out by the compiler"); + }, + LitKind::Bool(false) => { + span_lint(cx, EXPLICIT_FALSE, e.span, + "assert!(false) should probably be replaced by a panic!()"); + }, + _ => (), + } + } + } + } +} diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 2e515cc8aea..1f4cb27891b 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -88,6 +88,7 @@ mod utils; // begin lints modules, do not remove this comment, it’s used in `update_lints` pub mod approx_const; pub mod arithmetic; +pub mod assert_checks; pub mod assign_ops; pub mod attrs; pub mod bit_mask; @@ -486,6 +487,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) { reg.register_late_lint_pass(box ptr_offset_with_cast::Pass); reg.register_late_lint_pass(box redundant_clone::RedundantClone); reg.register_late_lint_pass(box slow_vector_initialization::Pass); + reg.register_late_lint_pass(box assert_checks::AssertChecks); reg.register_lint_group("clippy::restriction", Some("clippy_restriction"), vec![ arithmetic::FLOAT_ARITHMETIC, @@ -563,6 +565,8 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) { reg.register_lint_group("clippy::all", Some("clippy"), vec![ approx_const::APPROX_CONSTANT, + assert_checks::EXPLICIT_TRUE, + assert_checks::EXPLICIT_FALSE, assign_ops::ASSIGN_OP_PATTERN, assign_ops::MISREFACTORED_ASSIGN_OP, attrs::DEPRECATED_CFG_ATTR, @@ -940,6 +944,8 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) { reg.register_lint_group("clippy::correctness", Some("clippy_correctness"), vec![ approx_const::APPROX_CONSTANT, + assert_checks::EXPLICIT_TRUE, + assert_checks::EXPLICIT_FALSE, attrs::DEPRECATED_SEMVER, attrs::USELESS_ATTRIBUTE, bit_mask::BAD_BIT_MASK, diff --git a/tests/ui/assert_checks.rs b/tests/ui/assert_checks.rs new file mode 100644 index 00000000000..811046d060a --- /dev/null +++ b/tests/ui/assert_checks.rs @@ -0,0 +1,13 @@ +// Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + assert!(true); + assert!(false); +} diff --git a/tests/ui/assert_checks.stderr b/tests/ui/assert_checks.stderr new file mode 100644 index 00000000000..fd7e4e01420 --- /dev/null +++ b/tests/ui/assert_checks.stderr @@ -0,0 +1,18 @@ +error: assert!(true) will be optimized out by the compiler + --> $DIR/assert_checks.rs:11:5 + | +11 | assert!(true); + | ^^^^^^^^^^^^^^ + | + = note: #[deny(clippy::explicit_true)] on by default + +error: assert!(false) should probably be replaced by a panic!() + --> $DIR/assert_checks.rs:12:5 + | +12 | assert!(false); + | ^^^^^^^^^^^^^^^ + | + = note: #[deny(clippy::explicit_false)] on by default + +error: aborting due to 2 previous errors + diff --git a/tests/ui/attrs.rs b/tests/ui/attrs.rs index 413c30a1945..c0ea7329718 100644 --- a/tests/ui/attrs.rs +++ b/tests/ui/attrs.rs @@ -8,7 +8,7 @@ // except according to those terms. #![warn(clippy::inline_always, clippy::deprecated_semver)] - +#![allow(clippy::assert_checks::explicit_true)] #[inline(always)] fn test_attr_lint() { assert!(true) diff --git a/tests/ui/empty_line_after_outer_attribute.rs b/tests/ui/empty_line_after_outer_attribute.rs index ede1244df7e..a6e6adcac5c 100644 --- a/tests/ui/empty_line_after_outer_attribute.rs +++ b/tests/ui/empty_line_after_outer_attribute.rs @@ -8,7 +8,7 @@ // except according to those terms. #![warn(clippy::empty_line_after_outer_attr)] - +#![allow(clippy::assert_checks::explicit_true)] // This should produce a warning #[crate_type = "lib"] diff --git a/tests/ui/panic_unimplemented.rs b/tests/ui/panic_unimplemented.rs index 93dec197ff5..3c568658a6c 100644 --- a/tests/ui/panic_unimplemented.rs +++ b/tests/ui/panic_unimplemented.rs @@ -8,7 +8,7 @@ // except according to those terms. #![warn(clippy::panic_params, clippy::unimplemented)] - +#![allow(clippy::assert_checks::explicit_true)] fn missing() { if true { panic!("{}");