1
Fork 0

#3016 Add feedback and implement test for fixed hardcoded suggestion

This commit is contained in:
Lachezar Lechev 2018-08-20 15:33:43 +02:00
parent 3015987f27
commit c292b80783
3 changed files with 26 additions and 17 deletions

View file

@ -3,6 +3,7 @@ use rustc::{declare_lint, lint_array};
use syntax::ast::*; use syntax::ast::*;
use syntax::tokenstream::{ThinTokenStream, TokenStream}; use syntax::tokenstream::{ThinTokenStream, TokenStream};
use syntax::parse::{token, parser}; use syntax::parse::{token, parser};
use std::borrow::Cow;
use crate::utils::{span_lint, span_lint_and_sugg, snippet}; use crate::utils::{span_lint, span_lint_and_sugg, snippet};
/// **What it does:** This lint warns when you use `println!("")` to /// **What it does:** This lint warns when you use `println!("")` to
@ -212,7 +213,7 @@ impl EarlyLintPass for Pass {
let check_tts = check_tts(cx, &mac.node.tts, true); let check_tts = check_tts(cx, &mac.node.tts, true);
if let Some(fmtstr) = check_tts.0 { if let Some(fmtstr) = check_tts.0 {
if fmtstr == "" { if fmtstr == "" {
let suggestion = check_tts.1.map_or("v", |expr| snippet(cx, expr.span, "v").into_owned().as_str()); let suggestion = check_tts.1.map_or(Cow::Borrowed("v"), |expr| snippet(cx, expr.span, "v"));
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
@ -220,7 +221,7 @@ impl EarlyLintPass for Pass {
mac.span, mac.span,
format!("using writeln!({}, \"\")", suggestion).as_str(), format!("using writeln!({}, \"\")", suggestion).as_str(),
"replace it with", "replace it with",
format!("writeln!({})", "v"), format!("writeln!({})", suggestion),
); );
} }
} }
@ -239,20 +240,19 @@ fn check_tts<'a>(cx: &EarlyContext<'a>, tts: &ThinTokenStream, is_write: bool) -
); );
let mut expr: Option<Expr> = None; let mut expr: Option<Expr> = None;
if is_write { if is_write {
// skip the initial write target expr = match parser.parse_expr().map_err(|mut err| err.cancel()) {
expr = match parser.parse_expr().map_err(|mut err| err.cancel()).ok() { Ok(p) => Some(p.into_inner()),
Some(p) => Some(p.and_then(|expr| expr)), Err(_) => return (None, None),
None => return (None, None),
}; };
// might be `writeln!(foo)` // might be `writeln!(foo)`
if let None = parser.expect(&token::Comma).map_err(|mut err| err.cancel()).ok() { if parser.expect(&token::Comma).map_err(|mut err| err.cancel()).is_err() {
return (None, expr); return (None, expr);
} }
} }
let fmtstr = match parser.parse_str().map_err(|mut err| err.cancel()).ok() { let fmtstr = match parser.parse_str().map_err(|mut err| err.cancel()) {
Some(token) => token.0.to_string(), Ok(token) => token.0.to_string(),
None => return (None, expr), Err(_) => return (None, expr),
}; };
use fmt_macros::*; use fmt_macros::*;
let tmp = fmtstr.clone(); let tmp = fmtstr.clone();
@ -281,9 +281,9 @@ fn check_tts<'a>(cx: &EarlyContext<'a>, tts: &ThinTokenStream, is_write: bool) -
assert!(parser.eat(&token::Eof)); assert!(parser.eat(&token::Eof));
return (Some(fmtstr), expr); return (Some(fmtstr), expr);
} }
let token_expr = match parser.parse_expr().map_err(|mut err| err.cancel()).ok() { let token_expr = match parser.parse_expr().map_err(|mut err| err.cancel()) {
Some(expr) => expr, Ok(expr) => expr,
None => return (Some(fmtstr), None), Err(_) => return (Some(fmtstr), None),
}; };
const SIMPLE: FormatSpec<'_> = FormatSpec { const SIMPLE: FormatSpec<'_> = FormatSpec {
fill: None, fill: None,

View file

@ -5,9 +5,12 @@ use std::io::Write;
fn main() { fn main() {
let mut v = Vec::new(); let mut v = Vec::new();
// This should fail // These should fail
writeln!(&mut v, ""); writeln!(&mut v, "");
let mut suggestion = Vec::new();
writeln!(&mut suggestion, "");
// These should be fine // These should be fine
writeln!(&mut v); writeln!(&mut v);
writeln!(&mut v, " "); writeln!(&mut v, " ");

View file

@ -1,10 +1,16 @@
error: using `writeln!(v, "")` error: using writeln!(&mut v, "")
--> $DIR/writeln_empty_string.rs:9:5 --> $DIR/writeln_empty_string.rs:9:5
| |
9 | writeln!(&mut v, ""); 9 | writeln!(&mut v, "");
| ^^^^^^^^^^^^^^^^^^^^ help: replace it with: `writeln!(v)` | ^^^^^^^^^^^^^^^^^^^^ help: replace it with: `writeln!(&mut v)`
| |
= note: `-D writeln-empty-string` implied by `-D warnings` = note: `-D writeln-empty-string` implied by `-D warnings`
error: aborting due to previous error error: using writeln!(&mut suggestion, "")
--> $DIR/writeln_empty_string.rs:12:5
|
12 | writeln!(&mut suggestion, "");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `writeln!(&mut suggestion)`
error: aborting due to 2 previous errors