Skip to content

Commit ef72b2c

Browse files
committed
Check {print,write}_with_newline for literal newline
Both regular strings and raw strings can contain literal newlines. This commit extends the lint to also warn about terminating strings with these. Behaviour handling for raw strings is also moved into `check_newlines` by passing in the `is_raw` boolean from `check_tts` as [suggested](#3781 (review))
1 parent 3fa3bd8 commit ef72b2c

File tree

5 files changed

+72
-5
lines changed

5 files changed

+72
-5
lines changed

clippy_lints/src/write.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ impl EarlyLintPass for Pass {
201201
} else if mac.node.path == "print" {
202202
span_lint(cx, PRINT_STDOUT, mac.span, "use of `print!`");
203203
if let (Some(fmtstr), _, is_raw) = check_tts(cx, &mac.node.tts, false) {
204-
if !is_raw && check_newlines(&fmtstr) {
204+
if check_newlines(&fmtstr, is_raw) {
205205
span_lint(
206206
cx,
207207
PRINT_WITH_NEWLINE,
@@ -213,7 +213,7 @@ impl EarlyLintPass for Pass {
213213
}
214214
} else if mac.node.path == "write" {
215215
if let (Some(fmtstr), _, is_raw) = check_tts(cx, &mac.node.tts, true) {
216-
if !is_raw && check_newlines(&fmtstr) {
216+
if check_newlines(&fmtstr, is_raw) {
217217
span_lint(
218218
cx,
219219
WRITE_WITH_NEWLINE,
@@ -382,7 +382,14 @@ fn check_tts<'a>(cx: &EarlyContext<'a>, tts: &TokenStream, is_write: bool) -> (O
382382
}
383383

384384
// Checks if `s` constains a single newline that terminates it
385-
fn check_newlines(s: &str) -> bool {
385+
// Literal and escaped newlines are both checked (only literal for raw strings)
386+
fn check_newlines(s: &str, is_raw: bool) -> bool {
387+
if s.ends_with('\n') {
388+
return true;
389+
} else if is_raw {
390+
return false;
391+
}
392+
386393
if s.len() < 2 {
387394
return false;
388395
}

tests/ui/print_with_newline.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,14 @@ fn main() {
2929

3030
// Raw strings
3131
print!(r"\n"); // #3778
32+
33+
// Literal newlines should also fail
34+
print!(
35+
"
36+
"
37+
);
38+
print!(
39+
r"
40+
"
41+
);
3242
}

tests/ui/print_with_newline.stderr

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,23 @@ error: using `print!()` with a format string that ends in a single newline, cons
3030
LL | print!("//n"); // should fail
3131
| ^^^^^^^^^^^^^^
3232

33-
error: aborting due to 5 previous errors
33+
error: using `print!()` with a format string that ends in a single newline, consider using `println!()` instead
34+
--> $DIR/print_with_newline.rs:34:5
35+
|
36+
LL | / print!(
37+
LL | | "
38+
LL | | "
39+
LL | | );
40+
| |_____^
41+
42+
error: using `print!()` with a format string that ends in a single newline, consider using `println!()` instead
43+
--> $DIR/print_with_newline.rs:38:5
44+
|
45+
LL | / print!(
46+
LL | | r"
47+
LL | | "
48+
LL | | );
49+
| |_____^
50+
51+
error: aborting due to 7 previous errors
3452

tests/ui/write_with_newline.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,16 @@ fn main() {
3434

3535
// Raw strings
3636
write!(&mut v, r"\n"); // #3778
37+
38+
// Literal newlines should also fail
39+
write!(
40+
&mut v,
41+
"
42+
"
43+
);
44+
write!(
45+
&mut v,
46+
r"
47+
"
48+
);
3749
}

tests/ui/write_with_newline.stderr

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,25 @@ error: using `write!()` with a format string that ends in a single newline, cons
3030
LL | write!(&mut v, "//n"); // should fail
3131
| ^^^^^^^^^^^^^^^^^^^^^^
3232

33-
error: aborting due to 5 previous errors
33+
error: using `write!()` with a format string that ends in a single newline, consider using `writeln!()` instead
34+
--> $DIR/write_with_newline.rs:39:5
35+
|
36+
LL | / write!(
37+
LL | | &mut v,
38+
LL | | "
39+
LL | | "
40+
LL | | );
41+
| |_____^
42+
43+
error: using `write!()` with a format string that ends in a single newline, consider using `writeln!()` instead
44+
--> $DIR/write_with_newline.rs:44:5
45+
|
46+
LL | / write!(
47+
LL | | &mut v,
48+
LL | | r"
49+
LL | | "
50+
LL | | );
51+
| |_____^
52+
53+
error: aborting due to 7 previous errors
3454

0 commit comments

Comments
 (0)