diff --git a/clippy_lints/src/dbg_macro.rs b/clippy_lints/src/dbg_macro.rs index f99d793c201..17deccf8c39 100644 --- a/clippy_lints/src/dbg_macro.rs +++ b/clippy_lints/src/dbg_macro.rs @@ -5,7 +5,7 @@ use clippy_utils::{is_in_cfg_test, is_in_test_function}; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::sym; declare_clippy_lint! { @@ -30,14 +30,27 @@ declare_clippy_lint! { "`dbg!` macro is intended as a debugging tool" } -declare_lint_pass!(DbgMacro => [DBG_MACRO]); +#[derive(Copy, Clone)] +pub struct DbgMacro { + allow_dbg_in_tests: bool, +} + +impl_lint_pass!(DbgMacro => [DBG_MACRO]); + +impl DbgMacro { + pub fn new(allow_dbg_in_tests: bool) -> Self { + DbgMacro { allow_dbg_in_tests } + } +} impl LateLintPass<'_> for DbgMacro { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { let Some(macro_call) = root_macro_call_first_node(cx, expr) else { return }; if cx.tcx.is_diagnostic_item(sym::dbg_macro, macro_call.def_id) { - // we make an exception for test code - if is_in_test_function(cx.tcx, expr.hir_id) || is_in_cfg_test(cx.tcx, expr.hir_id) { + // allows `dbg!` in test code if allow-dbg-in-test is set to true in clippy.toml + if self.allow_dbg_in_tests + && (is_in_test_function(cx.tcx, expr.hir_id) || is_in_cfg_test(cx.tcx, expr.hir_id)) + { return; } let mut applicability = Applicability::MachineApplicable; diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 09435b06d0a..ffbf9a65917 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -888,7 +888,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|| Box::new(default_union_representation::DefaultUnionRepresentation)); store.register_late_pass(|| Box::new(only_used_in_recursion::OnlyUsedInRecursion)); store.register_late_pass(|| Box::new(significant_drop_in_scrutinee::SignificantDropInScrutinee)); - store.register_late_pass(|| Box::new(dbg_macro::DbgMacro)); + let allow_dbg_in_tests = conf.allow_dbg_in_tests; + store.register_late_pass(move || Box::new(dbg_macro::DbgMacro::new(allow_dbg_in_tests))); let cargo_ignore_publish = conf.cargo_ignore_publish; store.register_late_pass(move || { Box::new(cargo::Cargo { diff --git a/clippy_lints/src/utils/conf.rs b/clippy_lints/src/utils/conf.rs index cd4d16fe95f..b5c5d35135f 100644 --- a/clippy_lints/src/utils/conf.rs +++ b/clippy_lints/src/utils/conf.rs @@ -340,6 +340,10 @@ define_Conf! { /// /// Whether `unwrap` should be allowed in test functions (allow_unwrap_in_tests: bool = false), + /// Lint: DBG_MACRO. + /// + /// Whether `dbg!` should be allowed in test functions + (allow_dbg_in_tests: bool = false), } /// Search for the configuration file. diff --git a/tests/ui-toml/dbg_macro/clippy.toml b/tests/ui-toml/dbg_macro/clippy.toml new file mode 100644 index 00000000000..4296655a040 --- /dev/null +++ b/tests/ui-toml/dbg_macro/clippy.toml @@ -0,0 +1 @@ +allow-dbg-in-tests = true diff --git a/tests/ui-toml/dbg_macro/dbg_macro.rs b/tests/ui-toml/dbg_macro/dbg_macro.rs new file mode 100644 index 00000000000..5d9ce18f631 --- /dev/null +++ b/tests/ui-toml/dbg_macro/dbg_macro.rs @@ -0,0 +1,39 @@ +// compile-flags: --test +#![warn(clippy::dbg_macro)] + +fn foo(n: u32) -> u32 { + if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n } +} + +fn factorial(n: u32) -> u32 { + if dbg!(n <= 1) { + dbg!(1) + } else { + dbg!(n * factorial(n - 1)) + } +} + +fn main() { + dbg!(42); + dbg!(dbg!(dbg!(42))); + foo(3) + dbg!(factorial(4)); + dbg!(1, 2, dbg!(3, 4)); + dbg!(1, 2, 3, 4, 5); +} + +#[test] +pub fn issue8481() { + dbg!(1); +} + +#[cfg(test)] +fn foo2() { + dbg!(1); +} + +#[cfg(test)] +mod mod1 { + fn func() { + dbg!(1); + } +} diff --git a/tests/ui-toml/dbg_macro/dbg_macro.stderr b/tests/ui-toml/dbg_macro/dbg_macro.stderr new file mode 100644 index 00000000000..46efb86dcfc --- /dev/null +++ b/tests/ui-toml/dbg_macro/dbg_macro.stderr @@ -0,0 +1,102 @@ +error: `dbg!` macro is intended as a debugging tool + --> $DIR/dbg_macro.rs:5:22 + | +LL | if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n } + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::dbg-macro` implied by `-D warnings` +help: ensure to avoid having uses of it in version control + | +LL | if let Some(n) = n.checked_sub(4) { n } else { n } + | ~~~~~~~~~~~~~~~~ + +error: `dbg!` macro is intended as a debugging tool + --> $DIR/dbg_macro.rs:9:8 + | +LL | if dbg!(n <= 1) { + | ^^^^^^^^^^^^ + | +help: ensure to avoid having uses of it in version control + | +LL | if n <= 1 { + | ~~~~~~ + +error: `dbg!` macro is intended as a debugging tool + --> $DIR/dbg_macro.rs:10:9 + | +LL | dbg!(1) + | ^^^^^^^ + | +help: ensure to avoid having uses of it in version control + | +LL | 1 + | + +error: `dbg!` macro is intended as a debugging tool + --> $DIR/dbg_macro.rs:12:9 + | +LL | dbg!(n * factorial(n - 1)) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: ensure to avoid having uses of it in version control + | +LL | n * factorial(n - 1) + | + +error: `dbg!` macro is intended as a debugging tool + --> $DIR/dbg_macro.rs:17:5 + | +LL | dbg!(42); + | ^^^^^^^^ + | +help: ensure to avoid having uses of it in version control + | +LL | 42; + | ~~ + +error: `dbg!` macro is intended as a debugging tool + --> $DIR/dbg_macro.rs:18:5 + | +LL | dbg!(dbg!(dbg!(42))); + | ^^^^^^^^^^^^^^^^^^^^ + | +help: ensure to avoid having uses of it in version control + | +LL | dbg!(dbg!(42)); + | ~~~~~~~~~~~~~~ + +error: `dbg!` macro is intended as a debugging tool + --> $DIR/dbg_macro.rs:19:14 + | +LL | foo(3) + dbg!(factorial(4)); + | ^^^^^^^^^^^^^^^^^^ + | +help: ensure to avoid having uses of it in version control + | +LL | foo(3) + factorial(4); + | ~~~~~~~~~~~~ + +error: `dbg!` macro is intended as a debugging tool + --> $DIR/dbg_macro.rs:20:5 + | +LL | dbg!(1, 2, dbg!(3, 4)); + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: ensure to avoid having uses of it in version control + | +LL | (1, 2, dbg!(3, 4)); + | ~~~~~~~~~~~~~~~~~~ + +error: `dbg!` macro is intended as a debugging tool + --> $DIR/dbg_macro.rs:21:5 + | +LL | dbg!(1, 2, 3, 4, 5); + | ^^^^^^^^^^^^^^^^^^^ + | +help: ensure to avoid having uses of it in version control + | +LL | (1, 2, 3, 4, 5); + | ~~~~~~~~~~~~~~~ + +error: aborting due to 9 previous errors + diff --git a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr index 92838aa57df..1d87fd91a25 100644 --- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr +++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr @@ -1,4 +1,5 @@ error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown field `foobar`, expected one of + allow-dbg-in-tests allow-expect-in-tests allow-unwrap-in-tests allowed-scripts diff --git a/tests/ui/dbg_macro.stderr b/tests/ui/dbg_macro.stderr index a3e7a7162e5..e6a65b46d97 100644 --- a/tests/ui/dbg_macro.stderr +++ b/tests/ui/dbg_macro.stderr @@ -109,5 +109,38 @@ help: ensure to avoid having uses of it in version control LL | 2; | ~ -error: aborting due to 10 previous errors +error: `dbg!` macro is intended as a debugging tool + --> $DIR/dbg_macro.rs:47:5 + | +LL | dbg!(1); + | ^^^^^^^ + | +help: ensure to avoid having uses of it in version control + | +LL | 1; + | ~ + +error: `dbg!` macro is intended as a debugging tool + --> $DIR/dbg_macro.rs:52:5 + | +LL | dbg!(1); + | ^^^^^^^ + | +help: ensure to avoid having uses of it in version control + | +LL | 1; + | ~ + +error: `dbg!` macro is intended as a debugging tool + --> $DIR/dbg_macro.rs:58:9 + | +LL | dbg!(1); + | ^^^^^^^ + | +help: ensure to avoid having uses of it in version control + | +LL | 1; + | ~ + +error: aborting due to 13 previous errors