about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTrevor Arjeski <tmarjeski@gmail.com>2022-11-04 20:33:04 +0300
committerTrevor Arjeski <tmarjeski@gmail.com>2022-11-04 20:33:04 +0300
commitddcfff6d9a33fd8ee95f715055e8ea3e691cc1f2 (patch)
tree740565d66145883c072f1dd2640679981c6fedd7
parent704e00cb75ef5be2080d21be0965afd938d6fbec (diff)
downloadrust-ddcfff6d9a33fd8ee95f715055e8ea3e691cc1f2.tar.gz
rust-ddcfff6d9a33fd8ee95f715055e8ea3e691cc1f2.zip
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
-rw-r--r--clippy_lints/src/lib.rs3
-rw-r--r--clippy_lints/src/utils/conf.rs4
-rw-r--r--clippy_lints/src/write.rs17
-rw-r--r--tests/ui-toml/print_macro/clippy.toml1
-rw-r--r--tests/ui-toml/print_macro/print_macro.rs20
-rw-r--r--tests/ui-toml/print_macro/print_macro.stderr18
-rw-r--r--tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr1
7 files changed, 61 insertions, 3 deletions
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::<only_used_in_recursion::OnlyUsedInRecursion>::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::<write::Write>::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