Add explicit_write suggestions for write!s with format args

This commit is contained in:
Alex Macleod 2022-01-28 14:58:14 +00:00
parent 4bae06d73c
commit 144b4a59c7
6 changed files with 75 additions and 51 deletions

View File

@ -1,5 +1,6 @@
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::macros::FormatArgsExpn;
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::{is_expn_of, match_function_call, paths};
use if_chain::if_chain;
use rustc_errors::Applicability;
@ -79,28 +80,22 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitWrite {
"print".into(),
)
};
let msg = format!("use of `{}.unwrap()`", used);
if let [write_output] = *format_args.format_string_parts {
let mut write_output = write_output.to_string();
if write_output.ends_with('\n') {
write_output.pop();
}
let sugg = format!("{}{}!(\"{}\")", prefix, sugg_mac, write_output.escape_default());
span_lint_and_sugg(
cx,
EXPLICIT_WRITE,
expr.span,
&msg,
"try this",
sugg,
Applicability::MachineApplicable
);
} else {
// We don't have a proper suggestion
let help = format!("consider using `{}{}!` instead", prefix, sugg_mac);
span_lint_and_help(cx, EXPLICIT_WRITE, expr.span, &msg, None, &help);
}
let mut applicability = Applicability::MachineApplicable;
let inputs_snippet = snippet_with_applicability(
cx,
format_args.inputs_span(),
"..",
&mut applicability,
);
span_lint_and_sugg(
cx,
EXPLICIT_WRITE,
expr.span,
&format!("use of `{}.unwrap()`", used),
"try this",
format!("{}{}!({})", prefix, sugg_mac, inputs_snippet),
applicability,
)
}
}
}

View File

@ -10,6 +10,12 @@ fn stderr() -> String {
String::new()
}
macro_rules! one {
() => {
1
};
}
fn main() {
// these should warn
{
@ -24,6 +30,12 @@ fn main() {
// including newlines
println!("test\ntest");
eprintln!("test\ntest");
let value = 1;
eprintln!("with {}", value);
eprintln!("with {} {}", 2, value);
eprintln!("with {value}");
eprintln!("macro arg {}", one!());
}
// these should not warn, different destination
{

View File

@ -10,6 +10,12 @@ fn stderr() -> String {
String::new()
}
macro_rules! one {
() => {
1
};
}
fn main() {
// these should warn
{
@ -24,6 +30,12 @@ fn main() {
// including newlines
writeln!(std::io::stdout(), "test\ntest").unwrap();
writeln!(std::io::stderr(), "test\ntest").unwrap();
let value = 1;
writeln!(std::io::stderr(), "with {}", value).unwrap();
writeln!(std::io::stderr(), "with {} {}", 2, value).unwrap();
writeln!(std::io::stderr(), "with {value}").unwrap();
writeln!(std::io::stderr(), "macro arg {}", one!()).unwrap();
}
// these should not warn, different destination
{

View File

@ -1,5 +1,5 @@
error: use of `write!(stdout(), ...).unwrap()`
--> $DIR/explicit_write.rs:17:9
--> $DIR/explicit_write.rs:23:9
|
LL | write!(std::io::stdout(), "test").unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `print!("test")`
@ -7,46 +7,70 @@ LL | write!(std::io::stdout(), "test").unwrap();
= note: `-D clippy::explicit-write` implied by `-D warnings`
error: use of `write!(stderr(), ...).unwrap()`
--> $DIR/explicit_write.rs:18:9
--> $DIR/explicit_write.rs:24:9
|
LL | write!(std::io::stderr(), "test").unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `eprint!("test")`
error: use of `writeln!(stdout(), ...).unwrap()`
--> $DIR/explicit_write.rs:19:9
--> $DIR/explicit_write.rs:25:9
|
LL | writeln!(std::io::stdout(), "test").unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `println!("test")`
error: use of `writeln!(stderr(), ...).unwrap()`
--> $DIR/explicit_write.rs:20:9
--> $DIR/explicit_write.rs:26:9
|
LL | writeln!(std::io::stderr(), "test").unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `eprintln!("test")`
error: use of `stdout().write_fmt(...).unwrap()`
--> $DIR/explicit_write.rs:21:9
--> $DIR/explicit_write.rs:27:9
|
LL | std::io::stdout().write_fmt(format_args!("test")).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `print!("test")`
error: use of `stderr().write_fmt(...).unwrap()`
--> $DIR/explicit_write.rs:22:9
--> $DIR/explicit_write.rs:28:9
|
LL | std::io::stderr().write_fmt(format_args!("test")).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `eprint!("test")`
error: use of `writeln!(stdout(), ...).unwrap()`
--> $DIR/explicit_write.rs:25:9
--> $DIR/explicit_write.rs:31:9
|
LL | writeln!(std::io::stdout(), "test/ntest").unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `println!("test/ntest")`
error: use of `writeln!(stderr(), ...).unwrap()`
--> $DIR/explicit_write.rs:26:9
--> $DIR/explicit_write.rs:32:9
|
LL | writeln!(std::io::stderr(), "test/ntest").unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `eprintln!("test/ntest")`
error: aborting due to 8 previous errors
error: use of `writeln!(stderr(), ...).unwrap()`
--> $DIR/explicit_write.rs:35:9
|
LL | writeln!(std::io::stderr(), "with {}", value).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `eprintln!("with {}", value)`
error: use of `writeln!(stderr(), ...).unwrap()`
--> $DIR/explicit_write.rs:36:9
|
LL | writeln!(std::io::stderr(), "with {} {}", 2, value).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `eprintln!("with {} {}", 2, value)`
error: use of `writeln!(stderr(), ...).unwrap()`
--> $DIR/explicit_write.rs:37:9
|
LL | writeln!(std::io::stderr(), "with {value}").unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `eprintln!("with {value}")`
error: use of `writeln!(stderr(), ...).unwrap()`
--> $DIR/explicit_write.rs:38:9
|
LL | writeln!(std::io::stderr(), "macro arg {}", one!()).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `eprintln!("macro arg {}", one!())`
error: aborting due to 12 previous errors

View File

@ -1,8 +0,0 @@
#![allow(unused_imports, clippy::blacklisted_name)]
#![warn(clippy::explicit_write)]
fn main() {
use std::io::Write;
let bar = "bar";
writeln!(std::io::stderr(), "foo {}", bar).unwrap();
}

View File

@ -1,11 +0,0 @@
error: use of `writeln!(stderr(), ...).unwrap()`
--> $DIR/explicit_write_non_rustfix.rs:7:5
|
LL | writeln!(std::io::stderr(), "foo {}", bar).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::explicit-write` implied by `-D warnings`
= help: consider using `eprintln!` instead
error: aborting due to previous error