#3016 Add feedback and implement test for fixed hardcoded suggestion
This commit is contained in:
parent
3015987f27
commit
c292b80783
3 changed files with 26 additions and 17 deletions
|
@ -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,
|
||||||
|
|
|
@ -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, " ");
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue