From 0a8ceaf8b0b343fb943fa18bbfa6a52a3ce93ec6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Thu, 6 Sep 2018 12:33:00 +0200 Subject: [PATCH 1/2] rustfmt clippy_lints/src/write.rs --- clippy_lints/src/write.rs | 54 ++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/clippy_lints/src/write.rs b/clippy_lints/src/write.rs index 5d3215723..06a4f6cb3 100644 --- a/clippy_lints/src/write.rs +++ b/clippy_lints/src/write.rs @@ -1,10 +1,10 @@ +use crate::utils::{snippet, span_lint, span_lint_and_sugg}; use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass}; use rustc::{declare_tool_lint, lint_array}; -use syntax::ast::*; -use syntax::tokenstream::{ThinTokenStream, TokenStream}; -use syntax::parse::{token, parser}; use std::borrow::Cow; -use crate::utils::{span_lint, span_lint_and_sugg, snippet}; +use syntax::ast::*; +use syntax::parse::{parser, token}; +use syntax::tokenstream::{ThinTokenStream, TokenStream}; /// **What it does:** This lint warns when you use `println!("")` to /// print a newline. @@ -196,24 +196,34 @@ impl EarlyLintPass for Pass { 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") && !fmtstr.ends_with("\\n\\n") { - span_lint(cx, PRINT_WITH_NEWLINE, mac.span, - "using `print!()` with a format string that ends in a \ - single newline, consider using `println!()` instead"); + span_lint( + cx, + PRINT_WITH_NEWLINE, + mac.span, + "using `print!()` with a format string that ends in a \ + single newline, consider using `println!()` instead", + ); } } } else if mac.node.path == "write" { if let Some(fmtstr) = check_tts(cx, &mac.node.tts, true).0 { if fmtstr.ends_with("\\n") && !fmtstr.ends_with("\\n\\n") { - span_lint(cx, WRITE_WITH_NEWLINE, mac.span, - "using `write!()` with a format string that ends in a \ - single newline, consider using `writeln!()` instead"); + span_lint( + cx, + WRITE_WITH_NEWLINE, + mac.span, + "using `write!()` with a format string that ends in a \ + single newline, consider using `writeln!()` instead", + ); } } } else if mac.node.path == "writeln" { let check_tts = check_tts(cx, &mac.node.tts, true); if let Some(fmtstr) = check_tts.0 { if fmtstr == "" { - let suggestion = check_tts.1.map_or(Cow::Borrowed("v"), |expr| snippet(cx, expr.span, "v")); + let suggestion = check_tts + .1 + .map_or(Cow::Borrowed("v"), |expr| snippet(cx, expr.span, "v")); span_lint_and_sugg( cx, @@ -231,13 +241,7 @@ impl EarlyLintPass for Pass { fn check_tts<'a>(cx: &EarlyContext<'a>, tts: &ThinTokenStream, is_write: bool) -> (Option, Option) { let tts = TokenStream::from(tts.clone()); - let mut parser = parser::Parser::new( - &cx.sess.parse_sess, - tts, - None, - false, - false, - ); + let mut parser = parser::Parser::new(&cx.sess.parse_sess, tts, None, false, false); let mut expr: Option = None; if is_write { expr = match parser.parse_expr().map_err(|mut err| err.cancel()) { @@ -270,11 +274,7 @@ fn check_tts<'a>(cx: &EarlyContext<'a>, tts: &ThinTokenStream, is_write: bool) - args.push(arg); } } - let lint = if is_write { - WRITE_LITERAL - } else { - PRINT_LITERAL - }; + let lint = if is_write { WRITE_LITERAL } else { PRINT_LITERAL }; let mut idx = 0; loop { if !parser.eat(&token::Comma) { @@ -299,9 +299,7 @@ fn check_tts<'a>(cx: &EarlyContext<'a>, tts: &ThinTokenStream, is_write: bool) - let mut seen = false; for arg in &args { match arg.position { - | ArgumentImplicitlyIs(n) - | ArgumentIs(n) - => if n == idx { + ArgumentImplicitlyIs(n) | ArgumentIs(n) => if n == idx { all_simple &= arg.format == SIMPLE; seen = true; }, @@ -320,9 +318,7 @@ fn check_tts<'a>(cx: &EarlyContext<'a>, tts: &ThinTokenStream, is_write: bool) - let mut seen = false; for arg in &args { match arg.position { - | ArgumentImplicitlyIs(_) - | ArgumentIs(_) - => {}, + ArgumentImplicitlyIs(_) | ArgumentIs(_) => {}, ArgumentNamed(name) => if *p == name { seen = true; all_simple &= arg.format == SIMPLE; From a0f56edfc316d642785efc5ccaf0d1c6c457b057 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Thu, 6 Sep 2018 12:55:04 +0200 Subject: [PATCH 2/2] print_with_newline / write_with_newline: don't warn about string with several `\n`s in them. Fixes #3126 --- clippy_lints/src/write.rs | 10 ++++++++-- tests/ui/print_with_newline.rs | 2 ++ tests/ui/write_with_newline.rs | 2 ++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/write.rs b/clippy_lints/src/write.rs index 06a4f6cb3..7ddae1c81 100644 --- a/clippy_lints/src/write.rs +++ b/clippy_lints/src/write.rs @@ -195,7 +195,10 @@ 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") && !fmtstr.ends_with("\\n\\n") { + if fmtstr.ends_with("\\n") && + // don't warn about strings with several `\n`s (#3126) + fmtstr.matches("\\n").count() == 1 + { span_lint( cx, PRINT_WITH_NEWLINE, @@ -207,7 +210,10 @@ 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") && !fmtstr.ends_with("\\n\\n") { + if fmtstr.ends_with("\\n") && + // don't warn about strings with several `\n`s (#3126) + fmtstr.matches("\\n").count() == 1 + { span_lint( cx, WRITE_WITH_NEWLINE, diff --git a/tests/ui/print_with_newline.rs b/tests/ui/print_with_newline.rs index 5efee5abf..c2c79c726 100644 --- a/tests/ui/print_with_newline.rs +++ b/tests/ui/print_with_newline.rs @@ -21,4 +21,6 @@ fn main() { print!("\n\n"); print!("like eof\n\n"); print!("Hello {} {}\n\n", "world", "#2"); + println!("\ndon't\nwarn\nfor\nmultiple\nnewlines\n"); // #3126 + println!("\nbla\n\n"); // #3126 } diff --git a/tests/ui/write_with_newline.rs b/tests/ui/write_with_newline.rs index e060459a4..58e6002fa 100644 --- a/tests/ui/write_with_newline.rs +++ b/tests/ui/write_with_newline.rs @@ -26,4 +26,6 @@ fn main() { write!(&mut v, "\n\n"); write!(&mut v, "like eof\n\n"); 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 }