@@ -279,8 +279,15 @@ impl EarlyLintPass for Write {
279
279
span_lint ( cx, PRINT_STDERR , mac. span ( ) , "use of `eprintln!`" ) ;
280
280
self . lint_println_empty_string ( cx, mac) ;
281
281
} 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 ) {
283
283
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
+ } ;
284
291
span_lint_and_then (
285
292
cx,
286
293
WRITE_WITH_NEWLINE ,
@@ -289,10 +296,7 @@ impl EarlyLintPass for Write {
289
296
|err| {
290
297
err. multipart_suggestion (
291
298
"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( ) ) ] ,
296
300
Applicability :: MachineApplicable ,
297
301
) ;
298
302
} ,
@@ -329,12 +333,13 @@ impl EarlyLintPass for Write {
329
333
330
334
/// Given a format string that ends in a newline and its span, calculates the span of the
331
335
/// 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 ) {
333
338
let sp = fmtstr. span ;
334
339
let contents = & fmtstr. symbol . as_str ( ) ;
335
340
336
341
if * contents == r"\n" {
337
- return sp ;
342
+ return ( sp , true ) ;
338
343
}
339
344
340
345
let newline_sp_hi = sp. hi ( )
@@ -351,7 +356,7 @@ fn newline_span(fmtstr: &StrLit) -> Span {
351
356
panic ! ( "expected format string to contain a newline" ) ;
352
357
} ;
353
358
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 )
355
360
}
356
361
357
362
/// Stores a list of replacement spans for each argument, but only if all the replacements used an
@@ -613,7 +618,7 @@ impl Write {
613
618
|err| {
614
619
err. multipart_suggestion (
615
620
& 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( ) ) ] ,
617
622
Applicability :: MachineApplicable ,
618
623
) ;
619
624
} ,
0 commit comments