Skip to content

Commit 144b4a5

Browse files
committed
Add explicit_write suggestions for write!s with format args
1 parent 4bae06d commit 144b4a5

6 files changed

+75
-51
lines changed

clippy_lints/src/explicit_write.rs

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};
1+
use clippy_utils::diagnostics::span_lint_and_sugg;
22
use clippy_utils::macros::FormatArgsExpn;
3+
use clippy_utils::source::snippet_with_applicability;
34
use clippy_utils::{is_expn_of, match_function_call, paths};
45
use if_chain::if_chain;
56
use rustc_errors::Applicability;
@@ -79,28 +80,22 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitWrite {
7980
"print".into(),
8081
)
8182
};
82-
let msg = format!("use of `{}.unwrap()`", used);
83-
if let [write_output] = *format_args.format_string_parts {
84-
let mut write_output = write_output.to_string();
85-
if write_output.ends_with('\n') {
86-
write_output.pop();
87-
}
88-
89-
let sugg = format!("{}{}!(\"{}\")", prefix, sugg_mac, write_output.escape_default());
90-
span_lint_and_sugg(
91-
cx,
92-
EXPLICIT_WRITE,
93-
expr.span,
94-
&msg,
95-
"try this",
96-
sugg,
97-
Applicability::MachineApplicable
98-
);
99-
} else {
100-
// We don't have a proper suggestion
101-
let help = format!("consider using `{}{}!` instead", prefix, sugg_mac);
102-
span_lint_and_help(cx, EXPLICIT_WRITE, expr.span, &msg, None, &help);
103-
}
83+
let mut applicability = Applicability::MachineApplicable;
84+
let inputs_snippet = snippet_with_applicability(
85+
cx,
86+
format_args.inputs_span(),
87+
"..",
88+
&mut applicability,
89+
);
90+
span_lint_and_sugg(
91+
cx,
92+
EXPLICIT_WRITE,
93+
expr.span,
94+
&format!("use of `{}.unwrap()`", used),
95+
"try this",
96+
format!("{}{}!({})", prefix, sugg_mac, inputs_snippet),
97+
applicability,
98+
)
10499
}
105100
}
106101
}

tests/ui/explicit_write.fixed

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ fn stderr() -> String {
1010
String::new()
1111
}
1212

13+
macro_rules! one {
14+
() => {
15+
1
16+
};
17+
}
18+
1319
fn main() {
1420
// these should warn
1521
{
@@ -24,6 +30,12 @@ fn main() {
2430
// including newlines
2531
println!("test\ntest");
2632
eprintln!("test\ntest");
33+
34+
let value = 1;
35+
eprintln!("with {}", value);
36+
eprintln!("with {} {}", 2, value);
37+
eprintln!("with {value}");
38+
eprintln!("macro arg {}", one!());
2739
}
2840
// these should not warn, different destination
2941
{

tests/ui/explicit_write.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ fn stderr() -> String {
1010
String::new()
1111
}
1212

13+
macro_rules! one {
14+
() => {
15+
1
16+
};
17+
}
18+
1319
fn main() {
1420
// these should warn
1521
{
@@ -24,6 +30,12 @@ fn main() {
2430
// including newlines
2531
writeln!(std::io::stdout(), "test\ntest").unwrap();
2632
writeln!(std::io::stderr(), "test\ntest").unwrap();
33+
34+
let value = 1;
35+
writeln!(std::io::stderr(), "with {}", value).unwrap();
36+
writeln!(std::io::stderr(), "with {} {}", 2, value).unwrap();
37+
writeln!(std::io::stderr(), "with {value}").unwrap();
38+
writeln!(std::io::stderr(), "macro arg {}", one!()).unwrap();
2739
}
2840
// these should not warn, different destination
2941
{

tests/ui/explicit_write.stderr

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,76 @@
11
error: use of `write!(stdout(), ...).unwrap()`
2-
--> $DIR/explicit_write.rs:17:9
2+
--> $DIR/explicit_write.rs:23:9
33
|
44
LL | write!(std::io::stdout(), "test").unwrap();
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `print!("test")`
66
|
77
= note: `-D clippy::explicit-write` implied by `-D warnings`
88

99
error: use of `write!(stderr(), ...).unwrap()`
10-
--> $DIR/explicit_write.rs:18:9
10+
--> $DIR/explicit_write.rs:24:9
1111
|
1212
LL | write!(std::io::stderr(), "test").unwrap();
1313
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `eprint!("test")`
1414

1515
error: use of `writeln!(stdout(), ...).unwrap()`
16-
--> $DIR/explicit_write.rs:19:9
16+
--> $DIR/explicit_write.rs:25:9
1717
|
1818
LL | writeln!(std::io::stdout(), "test").unwrap();
1919
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `println!("test")`
2020

2121
error: use of `writeln!(stderr(), ...).unwrap()`
22-
--> $DIR/explicit_write.rs:20:9
22+
--> $DIR/explicit_write.rs:26:9
2323
|
2424
LL | writeln!(std::io::stderr(), "test").unwrap();
2525
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `eprintln!("test")`
2626

2727
error: use of `stdout().write_fmt(...).unwrap()`
28-
--> $DIR/explicit_write.rs:21:9
28+
--> $DIR/explicit_write.rs:27:9
2929
|
3030
LL | std::io::stdout().write_fmt(format_args!("test")).unwrap();
3131
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `print!("test")`
3232

3333
error: use of `stderr().write_fmt(...).unwrap()`
34-
--> $DIR/explicit_write.rs:22:9
34+
--> $DIR/explicit_write.rs:28:9
3535
|
3636
LL | std::io::stderr().write_fmt(format_args!("test")).unwrap();
3737
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `eprint!("test")`
3838

3939
error: use of `writeln!(stdout(), ...).unwrap()`
40-
--> $DIR/explicit_write.rs:25:9
40+
--> $DIR/explicit_write.rs:31:9
4141
|
4242
LL | writeln!(std::io::stdout(), "test/ntest").unwrap();
4343
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `println!("test/ntest")`
4444

4545
error: use of `writeln!(stderr(), ...).unwrap()`
46-
--> $DIR/explicit_write.rs:26:9
46+
--> $DIR/explicit_write.rs:32:9
4747
|
4848
LL | writeln!(std::io::stderr(), "test/ntest").unwrap();
4949
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `eprintln!("test/ntest")`
5050

51-
error: aborting due to 8 previous errors
51+
error: use of `writeln!(stderr(), ...).unwrap()`
52+
--> $DIR/explicit_write.rs:35:9
53+
|
54+
LL | writeln!(std::io::stderr(), "with {}", value).unwrap();
55+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `eprintln!("with {}", value)`
56+
57+
error: use of `writeln!(stderr(), ...).unwrap()`
58+
--> $DIR/explicit_write.rs:36:9
59+
|
60+
LL | writeln!(std::io::stderr(), "with {} {}", 2, value).unwrap();
61+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `eprintln!("with {} {}", 2, value)`
62+
63+
error: use of `writeln!(stderr(), ...).unwrap()`
64+
--> $DIR/explicit_write.rs:37:9
65+
|
66+
LL | writeln!(std::io::stderr(), "with {value}").unwrap();
67+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `eprintln!("with {value}")`
68+
69+
error: use of `writeln!(stderr(), ...).unwrap()`
70+
--> $DIR/explicit_write.rs:38:9
71+
|
72+
LL | writeln!(std::io::stderr(), "macro arg {}", one!()).unwrap();
73+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `eprintln!("macro arg {}", one!())`
74+
75+
error: aborting due to 12 previous errors
5276

tests/ui/explicit_write_non_rustfix.rs

Lines changed: 0 additions & 8 deletions
This file was deleted.

tests/ui/explicit_write_non_rustfix.stderr

Lines changed: 0 additions & 11 deletions
This file was deleted.

0 commit comments

Comments
 (0)