Skip to content

Commit

Permalink
Auto merge of #3531 - mikerite:fix-3514, r=phansch
Browse files Browse the repository at this point in the history
Fix write_with_newline escaping false positive

Fixes #3514
  • Loading branch information
bors committed Dec 14, 2018
2 parents 379c934 + be40d82 commit 17a9aff
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 9 deletions.
36 changes: 28 additions & 8 deletions clippy_lints/src/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,10 +206,7 @@ impl EarlyLintPass for Pass {
} else if mac.node.path == "print" {
span_lint(cx, PRINT_STDOUT, mac.span, "use of `print!`");
if let Some(fmtstr) = check_tts(cx, &mac.node.tts, false).0 {
if fmtstr.ends_with("\\n") &&
// don't warn about strings with several `\n`s (#3126)
fmtstr.matches("\\n").count() == 1
{
if check_newlines(&fmtstr) {
span_lint(
cx,
PRINT_WITH_NEWLINE,
Expand All @@ -221,10 +218,7 @@ impl EarlyLintPass for Pass {
}
} else if mac.node.path == "write" {
if let Some(fmtstr) = check_tts(cx, &mac.node.tts, true).0 {
if fmtstr.ends_with("\\n") &&
// don't warn about strings with several `\n`s (#3126)
fmtstr.matches("\\n").count() == 1
{
if check_newlines(&fmtstr) {
span_lint(
cx,
WRITE_WITH_NEWLINE,
Expand Down Expand Up @@ -375,3 +369,29 @@ fn check_tts<'a>(cx: &EarlyContext<'a>, tts: &ThinTokenStream, is_write: bool) -
}
}
}

// Checks if `s` constains a single newline that terminates it
fn check_newlines(s: &str) -> bool {
if s.len() < 2 {
return false;
}

let bytes = s.as_bytes();
if bytes[bytes.len() - 2] != b'\\' || bytes[bytes.len() - 1] != b'n' {
return false;
}

let mut escaping = false;
for (index, &byte) in bytes.iter().enumerate() {
if escaping {
if byte == b'n' {
return index == bytes.len() - 1;
}
escaping = false;
} else if byte == b'\\' {
escaping = true;
}
}

false
}
5 changes: 5 additions & 0 deletions tests/ui/write_with_newline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,9 @@ fn main() {
write!(&mut v, "Hello {} {}\n\n", "world", "#2");
writeln!(&mut v, "\ndon't\nwarn\nfor\nmultiple\nnewlines\n"); // #3126
writeln!(&mut v, "\nbla\n\n"); // #3126

// Escaping
write!(&mut v, "\\n"); // #3514
write!(&mut v, "\\\n");
write!(&mut v, "\\\\n");
}
8 changes: 7 additions & 1 deletion tests/ui/write_with_newline.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,11 @@ error: using `write!()` with a format string that ends in a single newline, cons
22 | write!(&mut v, "{}/n", 1265);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 4 previous errors
error: using `write!()` with a format string that ends in a single newline, consider using `writeln!()` instead
--> $DIR/write_with_newline.rs:41:5
|
41 | write!(&mut v, "//n");
| ^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 5 previous errors

0 comments on commit 17a9aff

Please sign in to comment.