@@ -279,8 +279,15 @@ impl EarlyLintPass for Write {
279279 span_lint ( cx, PRINT_STDERR , mac. span ( ) , "use of `eprintln!`" ) ;
280280 self . lint_println_empty_string ( cx, mac) ;
281281 } else if mac. path == sym ! ( write) {
282- if let ( Some ( fmt_str) , _ ) = self . check_tts ( cx, mac. args . inner_tokens ( ) , true ) {
282+ if let ( Some ( fmt_str) , dest ) = self . check_tts ( cx, mac. args . inner_tokens ( ) , true ) {
283283 if check_newlines ( & fmt_str) {
284+ let ( nl_span, only_nl) = newline_span ( & fmt_str) ;
285+ let nl_span = match ( dest, only_nl) {
286+ // Special case of `write!(buf, "\n")`: Mark everything from the end of
287+ // `buf` for removal so no trailing comma [`writeln!(buf, )`] remains.
288+ ( Some ( dest_expr) , true ) => Span :: new ( dest_expr. span . hi ( ) , nl_span. hi ( ) , nl_span. ctxt ( ) ) ,
289+ _ => nl_span,
290+ } ;
284291 span_lint_and_then (
285292 cx,
286293 WRITE_WITH_NEWLINE ,
@@ -289,10 +296,7 @@ impl EarlyLintPass for Write {
289296 |err| {
290297 err. multipart_suggestion (
291298 "use `writeln!()` instead" ,
292- vec ! [
293- ( mac. path. span, String :: from( "writeln" ) ) ,
294- ( newline_span( & fmt_str) , String :: new( ) ) ,
295- ] ,
299+ vec ! [ ( mac. path. span, String :: from( "writeln" ) ) , ( nl_span, String :: new( ) ) ] ,
296300 Applicability :: MachineApplicable ,
297301 ) ;
298302 } ,
@@ -329,12 +333,13 @@ impl EarlyLintPass for Write {
329333
330334/// Given a format string that ends in a newline and its span, calculates the span of the
331335/// newline, or the format string itself if the format string consists solely of a newline.
332- fn newline_span ( fmtstr : & StrLit ) -> Span {
336+ /// Return this and a boolean indicating whether it only consisted of a newline.
337+ fn newline_span ( fmtstr : & StrLit ) -> ( Span , bool ) {
333338 let sp = fmtstr. span ;
334339 let contents = & fmtstr. symbol . as_str ( ) ;
335340
336341 if * contents == r"\n" {
337- return sp ;
342+ return ( sp , true ) ;
338343 }
339344
340345 let newline_sp_hi = sp. hi ( )
@@ -351,7 +356,7 @@ fn newline_span(fmtstr: &StrLit) -> Span {
351356 panic ! ( "expected format string to contain a newline" ) ;
352357 } ;
353358
354- sp. with_lo ( newline_sp_hi - newline_sp_len) . with_hi ( newline_sp_hi)
359+ ( sp. with_lo ( newline_sp_hi - newline_sp_len) . with_hi ( newline_sp_hi) , false )
355360}
356361
357362/// Stores a list of replacement spans for each argument, but only if all the replacements used an
@@ -613,7 +618,7 @@ impl Write {
613618 |err| {
614619 err. multipart_suggestion (
615620 & format ! ( "use `{}!` instead" , suggested) ,
616- vec ! [ ( mac. path. span, suggested) , ( newline_span( & fmt_str) , String :: new( ) ) ] ,
621+ vec ! [ ( mac. path. span, suggested) , ( newline_span( & fmt_str) . 0 , String :: new( ) ) ] ,
617622 Applicability :: MachineApplicable ,
618623 ) ;
619624 } ,
0 commit comments