From ddcfff6d9a33fd8ee95f715055e8ea3e691cc1f2 Mon Sep 17 00:00:00 2001 From: Trevor Arjeski Date: Fri, 4 Nov 2022 20:33:04 +0300 Subject: [PATCH] Add allow-print-in-tests config Add a config, allow-print-in-tests, that can be set in clippy.toml which allows the usage of `[e]print[ln]!` macros in tests. Closes #9795 --- clippy_lints/src/lib.rs | 3 ++- clippy_lints/src/utils/conf.rs | 4 ++++ clippy_lints/src/write.rs | 17 ++++++++++++++-- tests/ui-toml/print_macro/clippy.toml | 1 + tests/ui-toml/print_macro/print_macro.rs | 20 +++++++++++++++++++ tests/ui-toml/print_macro/print_macro.stderr | 18 +++++++++++++++++ .../toml_unknown_key/conf_unknown_key.stderr | 1 + 7 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 tests/ui-toml/print_macro/clippy.toml create mode 100644 tests/ui-toml/print_macro/print_macro.rs create mode 100644 tests/ui-toml/print_macro/print_macro.stderr diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 197d8f2dc08..4949a1b778f 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -876,13 +876,14 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|_| Box::::default()); 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 allow_print_in_tests = conf.allow_print_in_tests; + store.register_late_pass(move |_| Box::new(write::Write::new(allow_print_in_tests))); let cargo_ignore_publish = conf.cargo_ignore_publish; store.register_late_pass(move |_| { Box::new(cargo::Cargo { ignore_publish: cargo_ignore_publish, }) }); - store.register_late_pass(|_| Box::::default()); store.register_early_pass(|| Box::new(crate_in_macro_def::CrateInMacroDef)); store.register_early_pass(|| Box::new(empty_structs_with_brackets::EmptyStructsWithBrackets)); store.register_late_pass(|_| Box::new(unnecessary_owned_empty_strings::UnnecessaryOwnedEmptyStrings)); diff --git a/clippy_lints/src/utils/conf.rs b/clippy_lints/src/utils/conf.rs index 2771c26255a..0cf49ca6d42 100644 --- a/clippy_lints/src/utils/conf.rs +++ b/clippy_lints/src/utils/conf.rs @@ -389,6 +389,10 @@ define_Conf! { /// /// Whether `dbg!` should be allowed in test functions (allow_dbg_in_tests: bool = false), + /// Lint: PRINT_STDOUT, PRINT_STDERR. + /// + /// Whether print macros (ex. `println!`) should be allowed in test functions + (allow_print_in_tests: bool = false), /// Lint: RESULT_LARGE_ERR. /// /// The maximum size of the `Err`-variant in a `Result` returned from a function diff --git a/clippy_lints/src/write.rs b/clippy_lints/src/write.rs index 36574198f91..6b321765bc0 100644 --- a/clippy_lints/src/write.rs +++ b/clippy_lints/src/write.rs @@ -1,6 +1,7 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_then}; use clippy_utils::macros::{root_macro_call_first_node, FormatArgsExpn, MacroCall}; use clippy_utils::source::{expand_past_previous_comma, snippet_opt}; +use clippy_utils::{is_in_cfg_test, is_in_test_function}; use rustc_ast::LitKind; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, HirIdMap, Impl, Item, ItemKind}; @@ -232,6 +233,16 @@ declare_clippy_lint! { #[derive(Default)] pub struct Write { in_debug_impl: bool, + allow_print_in_tests: bool, +} + +impl Write { + pub fn new(allow_print_in_tests: bool) -> Self { + Self { + allow_print_in_tests, + ..Default::default() + } + } } impl_lint_pass!(Write => [ @@ -271,13 +282,15 @@ impl<'tcx> LateLintPass<'tcx> for Write { .as_ref() .map_or(false, |crate_name| crate_name == "build_script_build"); + let allowed_in_tests = self.allow_print_in_tests + && (is_in_test_function(cx.tcx, expr.hir_id) || is_in_cfg_test(cx.tcx, expr.hir_id)); match diag_name { - sym::print_macro | sym::println_macro => { + sym::print_macro | sym::println_macro if !allowed_in_tests => { if !is_build_script { span_lint(cx, PRINT_STDOUT, macro_call.span, &format!("use of `{name}!`")); } }, - sym::eprint_macro | sym::eprintln_macro => { + sym::eprint_macro | sym::eprintln_macro if !allowed_in_tests => { span_lint(cx, PRINT_STDERR, macro_call.span, &format!("use of `{name}!`")); }, sym::write_macro | sym::writeln_macro => {}, diff --git a/tests/ui-toml/print_macro/clippy.toml b/tests/ui-toml/print_macro/clippy.toml new file mode 100644 index 00000000000..40b1dda5b2e --- /dev/null +++ b/tests/ui-toml/print_macro/clippy.toml @@ -0,0 +1 @@ +allow-print-in-tests = true diff --git a/tests/ui-toml/print_macro/print_macro.rs b/tests/ui-toml/print_macro/print_macro.rs new file mode 100644 index 00000000000..5aefb6a6b4d --- /dev/null +++ b/tests/ui-toml/print_macro/print_macro.rs @@ -0,0 +1,20 @@ +// compile-flags: --test +#![warn(clippy::print_stdout)] +#![warn(clippy::print_stderr)] + +fn foo(n: u32) { + print!("{n}"); + eprint!("{n}"); +} + +#[test] +pub fn foo1() { + print!("{}", 1); + eprint!("{}", 1); +} + +#[cfg(test)] +fn foo3() { + print!("{}", 1); + eprint!("{}", 1); +} diff --git a/tests/ui-toml/print_macro/print_macro.stderr b/tests/ui-toml/print_macro/print_macro.stderr new file mode 100644 index 00000000000..d4b1ae84fd7 --- /dev/null +++ b/tests/ui-toml/print_macro/print_macro.stderr @@ -0,0 +1,18 @@ +error: use of `print!` + --> $DIR/print_macro.rs:6:5 + | +LL | print!("{n}"); + | ^^^^^^^^^^^^^ + | + = note: `-D clippy::print-stdout` implied by `-D warnings` + +error: use of `eprint!` + --> $DIR/print_macro.rs:7:5 + | +LL | eprint!("{n}"); + | ^^^^^^^^^^^^^^ + | + = note: `-D clippy::print-stderr` implied by `-D warnings` + +error: aborting due to 2 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 b7842c36240..f91d285c2e0 100644 --- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr +++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr @@ -1,6 +1,7 @@ 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-print-in-tests allow-unwrap-in-tests allowed-scripts arithmetic-side-effects-allowed