Skip to content

Commit 54c0edc

Browse files
author
Michael Recachinas
committed
Add smaller check_unformatted to write.rs and fix precision,width,align false positive
1 parent 8ccaa83 commit 54c0edc

File tree

1 file changed

+54
-7
lines changed

1 file changed

+54
-7
lines changed

clippy_lints/src/write.rs

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use syntax::ptr;
77
use syntax::symbol::InternedString;
88
use syntax_pos::Span;
99
use utils::{is_expn_of, match_def_path, match_path, resolve_node, span_lint, span_lint_and_sugg};
10-
use utils::{opt_def_id, paths};
10+
use utils::{opt_def_id, paths, last_path_segment};
1111

1212
/// **What it does:** This lint warns when you use `println!("")` to
1313
/// print a newline.
@@ -266,7 +266,6 @@ fn check_print_variants<'a, 'tcx>(
266266
};
267267

268268
span_lint(cx, PRINT_STDOUT, span, &format!("use of `{}!`", name));
269-
270269
if_chain! {
271270
// ensure we're calling Arguments::new_v1
272271
if args.len() == 1;
@@ -339,7 +338,9 @@ where
339338
F: Fn(Span),
340339
{
341340
if_chain! {
342-
if args.len() > 1;
341+
if args.len() >= 2;
342+
343+
// the match statement
343344
if let ExprAddrOf(_, ref match_expr) = args[1].node;
344345
if let ExprMatch(ref matchee, ref arms, _) = match_expr.node;
345346
if let ExprTup(ref tup) = matchee.node;
@@ -355,15 +356,31 @@ where
355356
if let ExprLit(_) = tup_val.node;
356357

357358
// next, check the corresponding match arm body to ensure
358-
// this is "{}", or DISPLAY_FMT_METHOD
359+
// this is DISPLAY_FMT_METHOD
359360
if let ExprCall(_, ref body_args) = arm_body_exprs[idx].node;
360361
if body_args.len() == 2;
361362
if let ExprPath(ref body_qpath) = body_args[1].node;
362363
if let Some(fun_def_id) = opt_def_id(resolve_node(cx, body_qpath, body_args[1].hir_id));
363-
if match_def_path(cx.tcx, fun_def_id, &paths::DISPLAY_FMT_METHOD) ||
364-
match_def_path(cx.tcx, fun_def_id, &paths::DEBUG_FMT_METHOD);
364+
if match_def_path(cx.tcx, fun_def_id, &paths::DISPLAY_FMT_METHOD);
365365
then {
366-
lint_fn(tup_val.span);
366+
if args.len() == 2 {
367+
lint_fn(tup_val.span);
368+
}
369+
370+
// ensure the format str has no options (e.g., width, precision, alignment, etc.)
371+
// and is just "{}"
372+
if_chain! {
373+
if args.len() == 3;
374+
if let ExprAddrOf(_, ref format_expr) = args[2].node;
375+
if let ExprArray(ref format_exprs) = format_expr.node;
376+
if format_exprs.len() >= 1;
377+
if let ExprStruct(_, ref fields, _) = format_exprs[idx].node;
378+
if let Some(format_field) = fields.iter().find(|f| f.name.node == "format");
379+
if check_unformatted(&format_field.expr);
380+
then {
381+
lint_fn(tup_val.span);
382+
}
383+
}
367384
}
368385
}
369386
}
@@ -438,3 +455,33 @@ fn is_in_debug_impl(cx: &LateContext, expr: &Expr) -> bool {
438455
}
439456
false
440457
}
458+
459+
/// Checks if the expression matches
460+
/// ```rust,ignore
461+
/// &[_ {
462+
/// format: _ {
463+
/// width: _::Implied,
464+
/// ...
465+
/// },
466+
/// ...,
467+
/// }]
468+
/// ```
469+
pub fn check_unformatted(format_field: &Expr) -> bool {
470+
if_chain! {
471+
if let ExprStruct(_, ref fields, _) = format_field.node;
472+
if let Some(width_field) = fields.iter().find(|f| f.name.node == "width");
473+
if let ExprPath(ref qpath) = width_field.expr.node;
474+
if last_path_segment(qpath).name == "Implied";
475+
if let Some(align_field) = fields.iter().find(|f| f.name.node == "align");
476+
if let ExprPath(ref qpath) = align_field.expr.node;
477+
if last_path_segment(qpath).name == "Unknown";
478+
if let Some(precision_field) = fields.iter().find(|f| f.name.node == "precision");
479+
if let ExprPath(ref qpath_precision) = precision_field.expr.node;
480+
if last_path_segment(qpath_precision).name == "Implied";
481+
then {
482+
return true;
483+
}
484+
}
485+
486+
false
487+
}

0 commit comments

Comments
 (0)