From b25b6b3355efa33c797f4a37afb2f516531ad581 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Wed, 9 Aug 2017 09:30:56 +0200 Subject: [PATCH] Rustfmt --- clippy_lints/src/approx_const.rs | 58 +-- clippy_lints/src/array_indexing.rs | 58 ++- clippy_lints/src/assign_ops.rs | 81 ++-- clippy_lints/src/attrs.rs | 62 ++- clippy_lints/src/bit_mask.rs | 137 +++--- clippy_lints/src/blacklisted_name.rs | 10 +- clippy_lints/src/block_in_if_condition.rs | 35 +- clippy_lints/src/booleans.rs | 75 ++-- clippy_lints/src/collapsible_if.rs | 5 +- clippy_lints/src/consts.rs | 3 +- clippy_lints/src/copies.rs | 93 ++-- clippy_lints/src/cyclomatic_complexity.rs | 75 ++-- clippy_lints/src/derive.rs | 2 +- clippy_lints/src/doc.rs | 52 ++- clippy_lints/src/drop_forget_ref.rs | 18 +- clippy_lints/src/empty_enum.rs | 9 +- clippy_lints/src/entry.rs | 14 +- clippy_lints/src/enum_clike.rs | 17 +- clippy_lints/src/enum_glob_use.rs | 9 +- clippy_lints/src/enum_variants.rs | 48 +- clippy_lints/src/eq_op.rs | 59 +-- clippy_lints/src/escape.rs | 12 +- clippy_lints/src/eta_reduction.rs | 15 +- clippy_lints/src/eval_order_dependence.rs | 17 +- clippy_lints/src/format.rs | 6 +- clippy_lints/src/formatting.rs | 88 ++-- clippy_lints/src/functions.rs | 32 +- clippy_lints/src/identity_op.rs | 19 +- .../src/if_let_redundant_pattern_matching.rs | 6 +- clippy_lints/src/if_not_else.rs | 27 +- clippy_lints/src/items_after_statements.rs | 19 +- clippy_lints/src/large_enum_variant.rs | 64 +-- clippy_lints/src/len_zero.rs | 84 ++-- clippy_lints/src/let_if_seq.rs | 4 +- clippy_lints/src/lifetimes.rs | 27 +- clippy_lints/src/literal_digit_grouping.rs | 45 +- clippy_lints/src/loops.rs | 337 ++++++++------ clippy_lints/src/map_clone.rs | 30 +- clippy_lints/src/matches.rs | 211 +++++---- clippy_lints/src/mem_forget.rs | 6 +- clippy_lints/src/methods.rs | 401 ++++++++++------- clippy_lints/src/misc.rs | 174 +++++--- clippy_lints/src/misc_early.rs | 112 +++-- clippy_lints/src/missing_doc.rs | 45 +- clippy_lints/src/mut_mut.rs | 39 +- clippy_lints/src/mut_reference.rs | 22 +- clippy_lints/src/mutex_atomic.rs | 12 +- clippy_lints/src/needless_bool.rs | 97 ++-- clippy_lints/src/needless_borrow.rs | 2 +- clippy_lints/src/needless_borrowed_ref.rs | 6 +- clippy_lints/src/needless_continue.rs | 125 +++--- clippy_lints/src/needless_pass_by_value.rs | 29 +- clippy_lints/src/needless_update.rs | 10 +- clippy_lints/src/new_without_default.rs | 12 +- clippy_lints/src/no_effect.rs | 41 +- clippy_lints/src/non_expressive_names.rs | 101 +++-- clippy_lints/src/ok_if_let.rs | 3 +- clippy_lints/src/open_options.rs | 65 +-- clippy_lints/src/precedence.rs | 66 +-- clippy_lints/src/print.rs | 6 +- clippy_lints/src/ptr.rs | 78 ++-- clippy_lints/src/ranges.rs | 15 +- clippy_lints/src/reference.rs | 14 +- clippy_lints/src/regex.rs | 47 +- clippy_lints/src/returns.rs | 15 +- clippy_lints/src/serde_api.rs | 13 +- clippy_lints/src/shadow.rs | 92 ++-- clippy_lints/src/should_assert_eq.rs | 9 +- clippy_lints/src/strings.rs | 42 +- clippy_lints/src/swap.rs | 2 +- clippy_lints/src/transmute.rs | 147 ++++--- clippy_lints/src/types.rs | 415 ++++++++++-------- clippy_lints/src/unicode.rs | 55 ++- clippy_lints/src/unsafe_removed_from_name.rs | 26 +- clippy_lints/src/unused_io_amount.rs | 29 +- clippy_lints/src/unused_label.rs | 2 +- clippy_lints/src/utils/author.rs | 46 +- clippy_lints/src/utils/comparisons.rs | 3 +- clippy_lints/src/utils/conf.rs | 39 +- clippy_lints/src/utils/constants.rs | 19 +- clippy_lints/src/utils/higher.rs | 15 +- clippy_lints/src/utils/hir_utils.rs | 59 +-- clippy_lints/src/utils/inspector.rs | 43 +- clippy_lints/src/utils/internal_lints.rs | 46 +- clippy_lints/src/utils/mod.rs | 212 +++++---- clippy_lints/src/utils/paths.rs | 3 +- clippy_lints/src/utils/sugg.rs | 62 ++- clippy_lints/src/vec.rs | 19 +- clippy_lints/src/zero_div_zero.rs | 3 +- src/main.rs | 153 ++++--- tests/compile-test.rs | 6 +- tests/dogfood.rs | 4 +- tests/issue-825.rs | 7 +- tests/matches.rs | 34 +- tests/needless_continue_helpers.rs | 1 - 95 files changed, 3090 insertions(+), 2022 deletions(-) diff --git a/clippy_lints/src/approx_const.rs b/clippy_lints/src/approx_const.rs index 7093e18454f..cbe12e58119 100644 --- a/clippy_lints/src/approx_const.rs +++ b/clippy_lints/src/approx_const.rs @@ -7,9 +7,11 @@ use utils::span_lint; /// **What it does:** Checks for floating point literals that approximate /// constants which are defined in -/// [`std::f32::consts`](https://doc.rust-lang.org/stable/std/f32/consts/#constants) +/// [`std::f32::consts`](https://doc.rust-lang. +/// org/stable/std/f32/consts/#constants) /// or -/// [`std::f64::consts`](https://doc.rust-lang.org/stable/std/f64/consts/#constants), +/// [`std::f64::consts`](https://doc.rust-lang. +/// org/stable/std/f64/consts/#constants), /// respectively, suggesting to use the predefined constant. /// /// **Why is this bad?** Usually, the definition in the standard library is more @@ -33,24 +35,26 @@ declare_lint! { } // Tuples are of the form (constant, name, min_digits) -const KNOWN_CONSTS: &'static [(f64, &'static str, usize)] = &[(f64::E, "E", 4), - (f64::FRAC_1_PI, "FRAC_1_PI", 4), - (f64::FRAC_1_SQRT_2, "FRAC_1_SQRT_2", 5), - (f64::FRAC_2_PI, "FRAC_2_PI", 5), - (f64::FRAC_2_SQRT_PI, "FRAC_2_SQRT_PI", 5), - (f64::FRAC_PI_2, "FRAC_PI_2", 5), - (f64::FRAC_PI_3, "FRAC_PI_3", 5), - (f64::FRAC_PI_4, "FRAC_PI_4", 5), - (f64::FRAC_PI_6, "FRAC_PI_6", 5), - (f64::FRAC_PI_8, "FRAC_PI_8", 5), - (f64::LN_10, "LN_10", 5), - (f64::LN_2, "LN_2", 5), - (f64::LOG10_E, "LOG10_E", 5), - (f64::LOG2_E, "LOG2_E", 5), - (f64::PI, "PI", 3), - (f64::SQRT_2, "SQRT_2", 5)]; +const KNOWN_CONSTS: &'static [(f64, &'static str, usize)] = &[ + (f64::E, "E", 4), + (f64::FRAC_1_PI, "FRAC_1_PI", 4), + (f64::FRAC_1_SQRT_2, "FRAC_1_SQRT_2", 5), + (f64::FRAC_2_PI, "FRAC_2_PI", 5), + (f64::FRAC_2_SQRT_PI, "FRAC_2_SQRT_PI", 5), + (f64::FRAC_PI_2, "FRAC_PI_2", 5), + (f64::FRAC_PI_3, "FRAC_PI_3", 5), + (f64::FRAC_PI_4, "FRAC_PI_4", 5), + (f64::FRAC_PI_6, "FRAC_PI_6", 5), + (f64::FRAC_PI_8, "FRAC_PI_8", 5), + (f64::LN_10, "LN_10", 5), + (f64::LN_2, "LN_2", 5), + (f64::LOG10_E, "LOG10_E", 5), + (f64::LOG2_E, "LOG2_E", 5), + (f64::PI, "PI", 3), + (f64::SQRT_2, "SQRT_2", 5), +]; -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] pub struct Pass; impl LintPass for Pass { @@ -81,13 +85,17 @@ fn check_known_consts(cx: &LateContext, e: &Expr, s: &symbol::Symbol, module: &s if s.parse::().is_ok() { for &(constant, name, min_digits) in KNOWN_CONSTS { if is_approx_const(constant, &s, min_digits) { - span_lint(cx, - APPROX_CONSTANT, - e.span, - &format!("approximate value of `{}::consts::{}` found. \ + span_lint( + cx, + APPROX_CONSTANT, + e.span, + &format!( + "approximate value of `{}::consts::{}` found. \ Consider using it directly", - module, - &name)); + module, + &name + ), + ); return; } } diff --git a/clippy_lints/src/array_indexing.rs b/clippy_lints/src/array_indexing.rs index baac8d790ba..422935fa067 100644 --- a/clippy_lints/src/array_indexing.rs +++ b/clippy_lints/src/array_indexing.rs @@ -8,7 +8,8 @@ use rustc::hir; use syntax::ast::RangeLimits; use utils::{self, higher}; -/// **What it does:** Checks for out of bounds array indexing with a constant index. +/// **What it does:** Checks for out of bounds array indexing with a constant +/// index. /// /// **Why is this bad?** This will always panic at runtime. /// @@ -46,7 +47,7 @@ declare_restriction_lint! { "indexing/slicing usage" } -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] pub struct ArrayIndexing; impl LintPass for ArrayIndexing { @@ -61,8 +62,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ArrayIndexing { // Array with known size can be checked statically let ty = cx.tables.expr_ty(array); if let ty::TyArray(_, size) = ty.sty { - let size = ConstInt::Usize(ConstUsize::new(size as u64, cx.sess().target.uint_type) - .expect("array size is invalid")); + let size = ConstInt::Usize( + ConstUsize::new(size as u64, cx.sess().target.uint_type).expect("array size is invalid"), + ); let parent_item = cx.tcx.hir.get_parent(e.id); let parent_def_id = cx.tcx.hir.local_def_id(parent_item); let substs = Substs::identity_for_item(cx.tcx, parent_def_id); @@ -80,12 +82,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ArrayIndexing { // Index is a constant range if let Some(range) = higher::range(index) { - let start = range.start - .map(|start| constcx.eval(start)) - .map(|v| v.ok()); - let end = range.end - .map(|end| constcx.eval(end)) - .map(|v| v.ok()); + let start = range.start.map(|start| constcx.eval(start)).map(|v| v.ok()); + let end = range.end.map(|end| constcx.eval(end)).map(|v| v.ok()); if let Some((start, end)) = to_const_range(&start, &end, range.limits, size) { if start > size || end > size { @@ -111,12 +109,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ArrayIndexing { } } -/// Returns an option containing a tuple with the start and end (exclusive) of the range. +/// Returns an option containing a tuple with the start and end (exclusive) of +/// the range. fn to_const_range( start: &Option>, end: &Option>, limits: RangeLimits, - array_size: ConstInt + array_size: ConstInt, ) -> Option<(ConstInt, ConstInt)> { let start = match *start { Some(Some(ConstVal::Integral(x))) => x, @@ -128,24 +127,23 @@ fn to_const_range( Some(Some(ConstVal::Integral(x))) => { if limits == RangeLimits::Closed { match x { - ConstInt::U8(_) => (x + ConstInt::U8(1)), - ConstInt::U16(_) => (x + ConstInt::U16(1)), - ConstInt::U32(_) => (x + ConstInt::U32(1)), - ConstInt::U64(_) => (x + ConstInt::U64(1)), - ConstInt::U128(_) => (x + ConstInt::U128(1)), - ConstInt::Usize(ConstUsize::Us16(_)) => (x + ConstInt::Usize(ConstUsize::Us16(1))), - ConstInt::Usize(ConstUsize::Us32(_)) => (x + ConstInt::Usize(ConstUsize::Us32(1))), - ConstInt::Usize(ConstUsize::Us64(_)) => (x + ConstInt::Usize(ConstUsize::Us64(1))), - ConstInt::I8(_) => (x + ConstInt::I8(1)), - ConstInt::I16(_) => (x + ConstInt::I16(1)), - ConstInt::I32(_) => (x + ConstInt::I32(1)), - ConstInt::I64(_) => (x + ConstInt::I64(1)), - ConstInt::I128(_) => (x + ConstInt::I128(1)), - ConstInt::Isize(ConstIsize::Is16(_)) => (x + ConstInt::Isize(ConstIsize::Is16(1))), - ConstInt::Isize(ConstIsize::Is32(_)) => (x + ConstInt::Isize(ConstIsize::Is32(1))), - ConstInt::Isize(ConstIsize::Is64(_)) => (x + ConstInt::Isize(ConstIsize::Is64(1))), - } - .expect("such a big array is not realistic") + ConstInt::U8(_) => (x + ConstInt::U8(1)), + ConstInt::U16(_) => (x + ConstInt::U16(1)), + ConstInt::U32(_) => (x + ConstInt::U32(1)), + ConstInt::U64(_) => (x + ConstInt::U64(1)), + ConstInt::U128(_) => (x + ConstInt::U128(1)), + ConstInt::Usize(ConstUsize::Us16(_)) => (x + ConstInt::Usize(ConstUsize::Us16(1))), + ConstInt::Usize(ConstUsize::Us32(_)) => (x + ConstInt::Usize(ConstUsize::Us32(1))), + ConstInt::Usize(ConstUsize::Us64(_)) => (x + ConstInt::Usize(ConstUsize::Us64(1))), + ConstInt::I8(_) => (x + ConstInt::I8(1)), + ConstInt::I16(_) => (x + ConstInt::I16(1)), + ConstInt::I32(_) => (x + ConstInt::I32(1)), + ConstInt::I64(_) => (x + ConstInt::I64(1)), + ConstInt::I128(_) => (x + ConstInt::I128(1)), + ConstInt::Isize(ConstIsize::Is16(_)) => (x + ConstInt::Isize(ConstIsize::Is16(1))), + ConstInt::Isize(ConstIsize::Is32(_)) => (x + ConstInt::Isize(ConstIsize::Is32(1))), + ConstInt::Isize(ConstIsize::Is64(_)) => (x + ConstInt::Isize(ConstIsize::Is64(1))), + }.expect("such a big array is not realistic") } else { x } diff --git a/clippy_lints/src/assign_ops.rs b/clippy_lints/src/assign_ops.rs index 07d838bef2e..759bb9f12ec 100644 --- a/clippy_lints/src/assign_ops.rs +++ b/clippy_lints/src/assign_ops.rs @@ -4,12 +4,14 @@ use syntax::ast; use utils::{span_lint_and_then, snippet_opt, SpanlessEq, get_trait_def_id, implements_trait}; use utils::{higher, sugg}; -/// **What it does:** Checks for compound assignment operations (`+=` and similar). +/// **What it does:** Checks for compound assignment operations (`+=` and +/// similar). /// /// **Why is this bad?** Projects with many developers from languages without /// those operations may find them unreadable and not worth their weight. /// -/// **Known problems:** Types implementing `OpAssign` don't necessarily implement `Op`. +/// **Known problems:** Types implementing `OpAssign` don't necessarily +/// implement `Op`. /// /// **Example:** /// ```rust @@ -20,7 +22,8 @@ declare_restriction_lint! { "any compound assignment operation" } -/// **What it does:** Checks for `a = a op b` or `a = b commutative_op a` patterns. +/// **What it does:** Checks for `a = a op b` or `a = b commutative_op a` +/// patterns. /// /// **Why is this bad?** These can be written as the shorter `a op= b`. /// @@ -41,7 +44,8 @@ declare_lint! { /// **What it does:** Checks for `a op= a op b` or `a op= b op a` patterns. /// -/// **Why is this bad?** Most likely these are bugs where one meant to write `a op= b`. +/// **Why is this bad?** Most likely these are bugs where one meant to write `a +/// op= b`. /// /// **Known problems:** Someone might actually mean `a op= a op b`, but that /// should rather be written as `a = (2 * a) op b` where applicable. @@ -75,9 +79,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps { let lhs = &sugg::Sugg::hir(cx, lhs, ".."); let rhs = &sugg::Sugg::hir(cx, rhs, ".."); - db.span_suggestion(expr.span, - "replace it with", - format!("{} = {}", lhs, sugg::make_binop(higher::binop(op.node), lhs, rhs))); + db.span_suggestion( + expr.span, + "replace it with", + format!("{} = {}", lhs, sugg::make_binop(higher::binop(op.node), lhs, rhs)), + ); }); if let hir::ExprBinary(binop, ref l, ref r) = rhs.node { if op.node == binop.node { @@ -144,35 +150,40 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps { } } } - if ops!(op.node, + if ops!( + op.node, + cx, + ty, + rty, + Add: BiAdd, + Sub: BiSub, + Mul: BiMul, + Div: BiDiv, + Rem: BiRem, + And: BiAnd, + Or: BiOr, + BitAnd: BiBitAnd, + BitOr: BiBitOr, + BitXor: BiBitXor, + Shr: BiShr, + Shl: BiShl + ) + { + span_lint_and_then( cx, - ty, - rty, - Add: BiAdd, - Sub: BiSub, - Mul: BiMul, - Div: BiDiv, - Rem: BiRem, - And: BiAnd, - Or: BiOr, - BitAnd: BiBitAnd, - BitOr: BiBitOr, - BitXor: BiBitXor, - Shr: BiShr, - Shl: BiShl) { - span_lint_and_then(cx, - ASSIGN_OP_PATTERN, - expr.span, - "manual implementation of an assign operation", - |db| if let (Some(snip_a), Some(snip_r)) = - (snippet_opt(cx, assignee.span), snippet_opt(cx, rhs.span)) { - db.span_suggestion(expr.span, - "replace it with", - format!("{} {}= {}", - snip_a, - op.node.as_str(), - snip_r)); - }); + ASSIGN_OP_PATTERN, + expr.span, + "manual implementation of an assign operation", + |db| if let (Some(snip_a), Some(snip_r)) = + (snippet_opt(cx, assignee.span), snippet_opt(cx, rhs.span)) + { + db.span_suggestion( + expr.span, + "replace it with", + format!("{} {}= {}", snip_a, op.node.as_str(), snip_r), + ); + }, + ); } }; // a = a op b diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs index 88f0ef0955c..a52c4d90aab 100644 --- a/clippy_lints/src/attrs.rs +++ b/clippy_lints/src/attrs.rs @@ -35,12 +35,15 @@ declare_lint! { "use of `#[inline(always)]`" } -/// **What it does:** Checks for `extern crate` and `use` items annotated with lint attributes +/// **What it does:** Checks for `extern crate` and `use` items annotated with +/// lint attributes /// -/// **Why is this bad?** Lint attributes have no effect on crate imports. Most likely a `!` was +/// **Why is this bad?** Lint attributes have no effect on crate imports. Most +/// likely a `!` was /// forgotten /// -/// **Known problems:** Technically one might allow `unused_import` on a `use` item, +/// **Known problems:** Technically one might allow `unused_import` on a `use` +/// item, /// but it's easier to remove the unused item. /// /// **Example:** @@ -75,7 +78,7 @@ declare_lint! { "use of `#[deprecated(since = \"x\")]` where x is not semver" } -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] pub struct AttrPass; impl LintPass for AttrPass { @@ -124,14 +127,20 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AttrPass { } if let Some(mut sugg) = snippet_opt(cx, attr.span) { if sugg.len() > 1 { - span_lint_and_then(cx, - USELESS_ATTRIBUTE, - attr.span, - "useless lint attribute", - |db| { - sugg.insert(1, '!'); - db.span_suggestion(attr.span, "if you just forgot a `!`, use", sugg); - }); + span_lint_and_then( + cx, + USELESS_ATTRIBUTE, + attr.span, + "useless lint attribute", + |db| { + sugg.insert(1, '!'); + db.span_suggestion( + attr.span, + "if you just forgot a `!`, use", + sugg, + ); + }, + ); } } }, @@ -191,7 +200,10 @@ fn is_relevant_block(tcx: TyCtxt, tables: &ty::TypeckTables, block: &Block) -> b StmtSemi(ref expr, _) => is_relevant_expr(tcx, tables, expr), } } else { - block.expr.as_ref().map_or(false, |e| is_relevant_expr(tcx, tables, e)) + block.expr.as_ref().map_or( + false, + |e| is_relevant_expr(tcx, tables, e), + ) } } @@ -224,11 +236,15 @@ fn check_attrs(cx: &LateContext, span: Span, name: &Name, attrs: &[Attribute]) { continue; } if is_word(&values[0], "always") { - span_lint(cx, - INLINE_ALWAYS, - attr.span, - &format!("you have declared `#[inline(always)]` on `{}`. This is usually a bad idea", - name)); + span_lint( + cx, + INLINE_ALWAYS, + attr.span, + &format!( + "you have declared `#[inline(always)]` on `{}`. This is usually a bad idea", + name + ), + ); } } } @@ -240,10 +256,12 @@ fn check_semver(cx: &LateContext, span: Span, lit: &Lit) { return; } } - span_lint(cx, - DEPRECATED_SEMVER, - span, - "the since field must contain a semver-compliant version"); + span_lint( + cx, + DEPRECATED_SEMVER, + span, + "the since field must contain a semver-compliant version", + ); } fn is_word(nmi: &NestedMetaItem, expected: &str) -> bool { diff --git a/clippy_lints/src/bit_mask.rs b/clippy_lints/src/bit_mask.rs index f56c0b2aeb3..64f007bf521 100644 --- a/clippy_lints/src/bit_mask.rs +++ b/clippy_lints/src/bit_mask.rs @@ -74,7 +74,8 @@ declare_lint! { /// **What it does:** Checks for bit masks that can be replaced by a call /// to `trailing_zeros` /// -/// **Why is this bad?** `x.trailing_zeros() > 4` is much clearer than `x & 15 == 0` +/// **Why is this bad?** `x.trailing_zeros() > 4` is much clearer than `x & 15 +/// == 0` /// /// **Known problems:** llvm generates better code for `x & 15 == 0` on x86 /// @@ -88,7 +89,7 @@ declare_lint! { "expressions where a bit mask is less readable than the corresponding method call" } -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] pub struct BitMask; impl LintPass for BitMask { @@ -162,12 +163,16 @@ fn check_bit_mask(cx: &LateContext, bit_op: BinOp_, cmp_op: BinOp_, mask_value: BiBitAnd => { if mask_value & cmp_value != cmp_value { if cmp_value != 0 { - span_lint(cx, - BAD_BIT_MASK, - *span, - &format!("incompatible bit mask: `_ & {}` can never be equal to `{}`", - mask_value, - cmp_value)); + span_lint( + cx, + BAD_BIT_MASK, + *span, + &format!( + "incompatible bit mask: `_ & {}` can never be equal to `{}`", + mask_value, + cmp_value + ), + ); } } else if mask_value == 0 { span_lint(cx, BAD_BIT_MASK, *span, "&-masking with zero"); @@ -175,12 +180,16 @@ fn check_bit_mask(cx: &LateContext, bit_op: BinOp_, cmp_op: BinOp_, mask_value: }, BiBitOr => { if mask_value | cmp_value != cmp_value { - span_lint(cx, - BAD_BIT_MASK, - *span, - &format!("incompatible bit mask: `_ | {}` can never be equal to `{}`", - mask_value, - cmp_value)); + span_lint( + cx, + BAD_BIT_MASK, + *span, + &format!( + "incompatible bit mask: `_ | {}` can never be equal to `{}`", + mask_value, + cmp_value + ), + ); } }, _ => (), @@ -190,24 +199,32 @@ fn check_bit_mask(cx: &LateContext, bit_op: BinOp_, cmp_op: BinOp_, mask_value: match bit_op { BiBitAnd => { if mask_value < cmp_value { - span_lint(cx, - BAD_BIT_MASK, - *span, - &format!("incompatible bit mask: `_ & {}` will always be lower than `{}`", - mask_value, - cmp_value)); + span_lint( + cx, + BAD_BIT_MASK, + *span, + &format!( + "incompatible bit mask: `_ & {}` will always be lower than `{}`", + mask_value, + cmp_value + ), + ); } else if mask_value == 0 { span_lint(cx, BAD_BIT_MASK, *span, "&-masking with zero"); } }, BiBitOr => { if mask_value >= cmp_value { - span_lint(cx, - BAD_BIT_MASK, - *span, - &format!("incompatible bit mask: `_ | {}` will never be lower than `{}`", - mask_value, - cmp_value)); + span_lint( + cx, + BAD_BIT_MASK, + *span, + &format!( + "incompatible bit mask: `_ | {}` will never be lower than `{}`", + mask_value, + cmp_value + ), + ); } else { check_ineffective_lt(cx, *span, mask_value, cmp_value, "|"); } @@ -220,24 +237,32 @@ fn check_bit_mask(cx: &LateContext, bit_op: BinOp_, cmp_op: BinOp_, mask_value: match bit_op { BiBitAnd => { if mask_value <= cmp_value { - span_lint(cx, - BAD_BIT_MASK, - *span, - &format!("incompatible bit mask: `_ & {}` will never be higher than `{}`", - mask_value, - cmp_value)); + span_lint( + cx, + BAD_BIT_MASK, + *span, + &format!( + "incompatible bit mask: `_ & {}` will never be higher than `{}`", + mask_value, + cmp_value + ), + ); } else if mask_value == 0 { span_lint(cx, BAD_BIT_MASK, *span, "&-masking with zero"); } }, BiBitOr => { if mask_value > cmp_value { - span_lint(cx, - BAD_BIT_MASK, - *span, - &format!("incompatible bit mask: `_ | {}` will always be higher than `{}`", - mask_value, - cmp_value)); + span_lint( + cx, + BAD_BIT_MASK, + *span, + &format!( + "incompatible bit mask: `_ | {}` will always be higher than `{}`", + mask_value, + cmp_value + ), + ); } else { check_ineffective_gt(cx, *span, mask_value, cmp_value, "|"); } @@ -252,25 +277,33 @@ fn check_bit_mask(cx: &LateContext, bit_op: BinOp_, cmp_op: BinOp_, mask_value: fn check_ineffective_lt(cx: &LateContext, span: Span, m: u128, c: u128, op: &str) { if c.is_power_of_two() && m < c { - span_lint(cx, - INEFFECTIVE_BIT_MASK, - span, - &format!("ineffective bit mask: `x {} {}` compared to `{}`, is the same as x compared directly", - op, - m, - c)); + span_lint( + cx, + INEFFECTIVE_BIT_MASK, + span, + &format!( + "ineffective bit mask: `x {} {}` compared to `{}`, is the same as x compared directly", + op, + m, + c + ), + ); } } fn check_ineffective_gt(cx: &LateContext, span: Span, m: u128, c: u128, op: &str) { if (c + 1).is_power_of_two() && m <= c { - span_lint(cx, - INEFFECTIVE_BIT_MASK, - span, - &format!("ineffective bit mask: `x {} {}` compared to `{}`, is the same as x compared directly", - op, - m, - c)); + span_lint( + cx, + INEFFECTIVE_BIT_MASK, + span, + &format!( + "ineffective bit mask: `x {} {}` compared to `{}`, is the same as x compared directly", + op, + m, + c + ), + ); } } diff --git a/clippy_lints/src/blacklisted_name.rs b/clippy_lints/src/blacklisted_name.rs index f8f0ea998bc..e88e4108d3d 100644 --- a/clippy_lints/src/blacklisted_name.rs +++ b/clippy_lints/src/blacklisted_name.rs @@ -41,10 +41,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BlackListedName { fn check_pat(&mut self, cx: &LateContext<'a, 'tcx>, pat: &'tcx Pat) { if let PatKind::Binding(_, _, ref ident, _) = pat.node { if self.blacklist.iter().any(|s| ident.node == *s) { - span_lint(cx, - BLACKLISTED_NAME, - ident.span, - &format!("use of a blacklisted/placeholder name `{}`", ident.node)); + span_lint( + cx, + BLACKLISTED_NAME, + ident.span, + &format!("use of a blacklisted/placeholder name `{}`", ident.node), + ); } } } diff --git a/clippy_lints/src/block_in_if_condition.rs b/clippy_lints/src/block_in_if_condition.rs index 6c0523dc198..eea44393e3d 100644 --- a/clippy_lints/src/block_in_if_condition.rs +++ b/clippy_lints/src/block_in_if_condition.rs @@ -40,7 +40,7 @@ declare_lint! { "complex blocks in conditions, e.g. `if { let x = true; x } ...`" } -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] pub struct BlockInIfCondition; impl LintPass for BlockInIfCondition { @@ -87,27 +87,34 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BlockInIfCondition { if in_macro(expr.span) || differing_macro_contexts(expr.span, ex.span) { return; } - span_help_and_lint(cx, - BLOCK_IN_IF_CONDITION_EXPR, - check.span, - BRACED_EXPR_MESSAGE, - &format!("try\nif {} {} ... ", + span_help_and_lint( + cx, + BLOCK_IN_IF_CONDITION_EXPR, + check.span, + BRACED_EXPR_MESSAGE, + &format!("try\nif {} {} ... ", snippet_block(cx, ex.span, ".."), - snippet_block(cx, then.span, ".."))); + snippet_block(cx, then.span, "..")), + ); } } else { - let span = block.expr.as_ref().map_or_else(|| block.stmts[0].span, |e| e.span); + let span = block.expr.as_ref().map_or_else( + || block.stmts[0].span, + |e| e.span, + ); if in_macro(span) || differing_macro_contexts(expr.span, span) { return; } // move block higher - span_help_and_lint(cx, - BLOCK_IN_IF_CONDITION_STMT, - check.span, - COMPLEX_BLOCK_MESSAGE, - &format!("try\nlet res = {};\nif res {} ... ", + span_help_and_lint( + cx, + BLOCK_IN_IF_CONDITION_STMT, + check.span, + COMPLEX_BLOCK_MESSAGE, + &format!("try\nlet res = {};\nif res {} ... ", snippet_block(cx, block.span, ".."), - snippet_block(cx, then.span, ".."))); + snippet_block(cx, then.span, "..")), + ); } } } else { diff --git a/clippy_lints/src/booleans.rs b/clippy_lints/src/booleans.rs index c338189cefe..4c67b260046 100644 --- a/clippy_lints/src/booleans.rs +++ b/clippy_lints/src/booleans.rs @@ -44,7 +44,7 @@ declare_lint! { "boolean expressions that contain terminals which can be eliminated" } -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] pub struct NonminimalBool; impl LintPass for NonminimalBool { @@ -61,7 +61,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonminimalBool { _: &'tcx FnDecl, body: &'tcx Body, _: Span, - _: NodeId + _: NodeId, ) { NonminimalBoolVisitor { cx: cx }.visit_body(body) } @@ -115,8 +115,7 @@ impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> { } for (n, expr) in self.terminals.iter().enumerate() { if SpanlessEq::new(self.cx).ignore_fn().eq_expr(e, expr) { - #[allow(cast_possible_truncation)] - return Ok(Bool::Term(n as u8)); + #[allow(cast_possible_truncation)] return Ok(Bool::Term(n as u8)); } let negated = match e.node { ExprBinary(binop, ref lhs, ref rhs) => { @@ -141,15 +140,13 @@ impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> { _ => continue, }; if SpanlessEq::new(self.cx).ignore_fn().eq_expr(&negated, expr) { - #[allow(cast_possible_truncation)] - return Ok(Bool::Not(Box::new(Bool::Term(n as u8)))); + #[allow(cast_possible_truncation)] return Ok(Bool::Not(Box::new(Bool::Term(n as u8)))); } } let n = self.terminals.len(); self.terminals.push(e); if n < 32 { - #[allow(cast_possible_truncation)] - Ok(Bool::Term(n as u8)) + #[allow(cast_possible_truncation)] Ok(Bool::Term(n as u8)) } else { Err("too many literals".to_owned()) } @@ -353,44 +350,54 @@ impl<'a, 'tcx> NonminimalBoolVisitor<'a, 'tcx> { continue 'simplified; } if stats.terminals[i] != 0 && simplified_stats.terminals[i] == 0 { - span_lint_and_then(self.cx, - LOGIC_BUG, - e.span, - "this boolean expression contains a logic bug", - |db| { - db.span_help(h2q.terminals[i].span, - "this expression can be optimized out by applying boolean operations to the \ - outer expression"); - db.span_suggestion(e.span, - "it would look like the following", - suggest(self.cx, suggestion, &h2q.terminals)); - }); + span_lint_and_then( + self.cx, + LOGIC_BUG, + e.span, + "this boolean expression contains a logic bug", + |db| { + db.span_help( + h2q.terminals[i].span, + "this expression can be optimized out by applying boolean operations to the \ + outer expression", + ); + db.span_suggestion( + e.span, + "it would look like the following", + suggest(self.cx, suggestion, &h2q.terminals), + ); + }, + ); // don't also lint `NONMINIMAL_BOOL` return; } // if the number of occurrences of a terminal decreases or any of the stats // decreases while none increases improvement |= (stats.terminals[i] > simplified_stats.terminals[i]) || - (stats.negations > simplified_stats.negations && - stats.ops == simplified_stats.ops) || - (stats.ops > simplified_stats.ops && stats.negations == simplified_stats.negations); + (stats.negations > simplified_stats.negations && stats.ops == simplified_stats.ops) || + (stats.ops > simplified_stats.ops && stats.negations == simplified_stats.negations); } if improvement { improvements.push(suggestion); } } if !improvements.is_empty() { - span_lint_and_then(self.cx, - NONMINIMAL_BOOL, - e.span, - "this boolean expression can be simplified", - |db| { - db.span_suggestions(e.span, - "try", - improvements.into_iter() - .map(|suggestion| suggest(self.cx, suggestion, &h2q.terminals)) - .collect()); - }); + span_lint_and_then( + self.cx, + NONMINIMAL_BOOL, + e.span, + "this boolean expression can be simplified", + |db| { + db.span_suggestions( + e.span, + "try", + improvements + .into_iter() + .map(|suggestion| suggest(self.cx, suggestion, &h2q.terminals)) + .collect(), + ); + }, + ); } } } diff --git a/clippy_lints/src/collapsible_if.rs b/clippy_lints/src/collapsible_if.rs index 1178f98db59..54b6490a183 100644 --- a/clippy_lints/src/collapsible_if.rs +++ b/clippy_lints/src/collapsible_if.rs @@ -19,7 +19,8 @@ use utils::{in_macro, snippet_block, span_lint_and_then, span_lint_and_sugg}; use utils::sugg::Sugg; /// **What it does:** Checks for nested `if` statements which can be collapsed -/// by `&&`-combining their conditions and for `else { if ... }` expressions that +/// by `&&`-combining their conditions and for `else { if ... }` expressions +/// that /// can be collapsed to `else if ...`. /// /// **Why is this bad?** Each `if`-statement adds one level of nesting, which @@ -67,7 +68,7 @@ declare_lint! { "`if`s that can be collapsed (e.g. `if x { if y { ... } }` and `else { if x { ... } }`)" } -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] pub struct CollapsibleIf; impl LintPass for CollapsibleIf { diff --git a/clippy_lints/src/consts.rs b/clippy_lints/src/consts.rs index 54b297d588d..095fcf06e09 100644 --- a/clippy_lints/src/consts.rs +++ b/clippy_lints/src/consts.rs @@ -83,7 +83,8 @@ impl PartialEq for Constant { impl Hash for Constant { fn hash(&self, state: &mut H) - where H: Hasher + where + H: Hasher, { match *self { Constant::Str(ref s, ref k) => { diff --git a/clippy_lints/src/copies.rs b/clippy_lints/src/copies.rs index 8f8bdf472a5..8a37c7a846d 100644 --- a/clippy_lints/src/copies.rs +++ b/clippy_lints/src/copies.rs @@ -138,12 +138,14 @@ fn lint_same_then_else(cx: &LateContext, blocks: &[&Block]) { let eq: &Fn(&&Block, &&Block) -> bool = &|&lhs, &rhs| -> bool { SpanlessEq::new(cx).eq_block(lhs, rhs) }; if let Some((i, j)) = search_same(blocks, hash, eq) { - span_note_and_lint(cx, - IF_SAME_THEN_ELSE, - j.span, - "this `if` has identical blocks", - i.span, - "same as this"); + span_note_and_lint( + cx, + IF_SAME_THEN_ELSE, + j.span, + "this `if` has identical blocks", + i.span, + "same as this", + ); } } @@ -158,12 +160,14 @@ fn lint_same_cond(cx: &LateContext, conds: &[&Expr]) { let eq: &Fn(&&Expr, &&Expr) -> bool = &|&lhs, &rhs| -> bool { SpanlessEq::new(cx).ignore_fn().eq_expr(lhs, rhs) }; if let Some((i, j)) = search_same(conds, hash, eq) { - span_note_and_lint(cx, - IFS_SAME_COND, - j.span, - "this `if` has the same condition as a previous if", - i.span, - "same as this"); + span_note_and_lint( + cx, + IFS_SAME_COND, + j.span, + "this `if` has the same condition as a previous if", + i.span, + "same as this", + ); } } @@ -185,40 +189,48 @@ fn lint_match_arms(cx: &LateContext, expr: &Expr) { if let ExprMatch(_, ref arms, MatchSource::Normal) = expr.node { if let Some((i, j)) = search_same(arms, hash, eq) { - span_lint_and_then(cx, - MATCH_SAME_ARMS, - j.body.span, - "this `match` has identical arm bodies", - |db| { - db.span_note(i.body.span, "same as this"); + span_lint_and_then( + cx, + MATCH_SAME_ARMS, + j.body.span, + "this `match` has identical arm bodies", + |db| { + db.span_note(i.body.span, "same as this"); - // Note: this does not use `span_suggestion` on purpose: there is no clean way to - // remove the other arm. Building a span and suggest to replace it to "" makes an - // even more confusing error message. Also in order not to make up a span for the - // whole pattern, the suggestion is only shown when there is only one pattern. The - // user should know about `|` if they are already using it… + // Note: this does not use `span_suggestion` on purpose: there is no clean way + // to + // remove the other arm. Building a span and suggest to replace it to "" makes + // an + // even more confusing error message. Also in order not to make up a span for + // the + // whole pattern, the suggestion is only shown when there is only one pattern. + // The + // user should know about `|` if they are already using it… - if i.pats.len() == 1 && j.pats.len() == 1 { - let lhs = snippet(cx, i.pats[0].span, ""); - let rhs = snippet(cx, j.pats[0].span, ""); + if i.pats.len() == 1 && j.pats.len() == 1 { + let lhs = snippet(cx, i.pats[0].span, ""); + let rhs = snippet(cx, j.pats[0].span, ""); - if let PatKind::Wild = j.pats[0].node { - // if the last arm is _, then i could be integrated into _ - // note that i.pats[0] cannot be _, because that would mean that we're - // hiding all the subsequent arms, and rust won't compile - db.span_note(i.body.span, - &format!("`{}` has the same arm body as the `_` wildcard, consider removing it`", - lhs)); - } else { - db.span_note(i.body.span, &format!("consider refactoring into `{} | {}`", lhs, rhs)); + if let PatKind::Wild = j.pats[0].node { + // if the last arm is _, then i could be integrated into _ + // note that i.pats[0] cannot be _, because that would mean that we're + // hiding all the subsequent arms, and rust won't compile + db.span_note( + i.body.span, + &format!("`{}` has the same arm body as the `_` wildcard, consider removing it`", lhs), + ); + } else { + db.span_note(i.body.span, &format!("consider refactoring into `{} | {}`", lhs, rhs)); + } } - } - }); + }, + ); } } } -/// Return the list of condition expressions and the list of blocks in a sequence of `if/else`. +/// Return the list of condition expressions and the list of blocks in a +/// sequence of `if/else`. /// Eg. would return `([a, b], [c, d, e])` for the expression /// `if a { c } else if b { d } else { e }`. fn if_sequence(mut expr: &Expr) -> (SmallVector<&Expr>, SmallVector<&Block>) { @@ -303,8 +315,9 @@ fn bindings<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, pat: &Pat) -> HashMap(exprs: &[T], hash: Hash, eq: Eq) -> Option<(&T, &T)> - where Hash: Fn(&T) -> u64, - Eq: Fn(&T, &T) -> bool +where + Hash: Fn(&T) -> u64, + Eq: Fn(&T, &T) -> bool, { // common cases if exprs.len() < 2 { diff --git a/clippy_lints/src/cyclomatic_complexity.rs b/clippy_lints/src/cyclomatic_complexity.rs index ffb240d3ab4..e87e60f9d23 100644 --- a/clippy_lints/src/cyclomatic_complexity.rs +++ b/clippy_lints/src/cyclomatic_complexity.rs @@ -15,7 +15,8 @@ use utils::{in_macro, LimitStack, span_help_and_lint, paths, match_type}; /// **Why is this bad?** Methods of high cyclomatic complexity tend to be badly /// readable. Also LLVM will usually optimize small methods better. /// -/// **Known problems:** Sometimes it's hard to find a way to reduce the complexity. +/// **Known problems:** Sometimes it's hard to find a way to reduce the +/// complexity. /// /// **Example:** No. You'll see it when you get the warning. declare_lint! { @@ -63,7 +64,13 @@ impl CyclomaticComplexity { cx: cx, }; helper.visit_expr(expr); - let CCHelper { match_arms, divergence, short_circuits, returns, .. } = helper; + let CCHelper { + match_arms, + divergence, + short_circuits, + returns, + .. + } = helper; let ret_ty = cx.tables.node_id_to_type(expr.id); let ret_adjust = if match_type(cx, ret_ty, &paths::RESULT) { returns @@ -80,11 +87,13 @@ impl CyclomaticComplexity { rust_cc -= ret_adjust; } if rust_cc > self.limit.limit() { - span_help_and_lint(cx, - CYCLOMATIC_COMPLEXITY, - span, - &format!("the function has a cyclomatic complexity of {}", rust_cc), - "you could split it up into multiple smaller functions"); + span_help_and_lint( + cx, + CYCLOMATIC_COMPLEXITY, + span, + &format!("the function has a cyclomatic complexity of {}", rust_cc), + "you could split it up into multiple smaller functions", + ); } } } @@ -98,7 +107,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CyclomaticComplexity { _: &'tcx FnDecl, body: &'tcx Body, span: Span, - node_id: NodeId + node_id: NodeId, ) { let def_id = cx.tcx.hir.local_def_id(node_id); if !cx.tcx.has_attr(def_id, "test") { @@ -107,10 +116,18 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CyclomaticComplexity { } fn enter_lint_attrs(&mut self, cx: &LateContext<'a, 'tcx>, attrs: &'tcx [Attribute]) { - self.limit.push_attrs(cx.sess(), attrs, "cyclomatic_complexity"); + self.limit.push_attrs( + cx.sess(), + attrs, + "cyclomatic_complexity", + ); } fn exit_lint_attrs(&mut self, cx: &LateContext<'a, 'tcx>, attrs: &'tcx [Attribute]) { - self.limit.pop_attrs(cx.sess(), attrs, "cyclomatic_complexity"); + self.limit.pop_attrs( + cx.sess(), + attrs, + "cyclomatic_complexity", + ); } } @@ -162,29 +179,35 @@ impl<'a, 'tcx> Visitor<'tcx> for CCHelper<'a, 'tcx> { } } -#[cfg(feature="debugging")] +#[cfg(feature = "debugging")] fn report_cc_bug(_: &LateContext, cc: u64, narms: u64, div: u64, shorts: u64, returns: u64, span: Span) { - span_bug!(span, - "Clippy encountered a bug calculating cyclomatic complexity: cc = {}, arms = {}, \ + span_bug!( + span, + "Clippy encountered a bug calculating cyclomatic complexity: cc = {}, arms = {}, \ div = {}, shorts = {}, returns = {}. Please file a bug report.", - cc, - narms, - div, - shorts, - returns); + cc, + narms, + div, + shorts, + returns + ); } -#[cfg(not(feature="debugging"))] +#[cfg(not(feature = "debugging"))] fn report_cc_bug(cx: &LateContext, cc: u64, narms: u64, div: u64, shorts: u64, returns: u64, span: Span) { if cx.current_level(CYCLOMATIC_COMPLEXITY) != Level::Allow { - cx.sess().span_note_without_error(span, - &format!("Clippy encountered a bug calculating cyclomatic complexity \ + cx.sess().span_note_without_error( + span, + &format!( + "Clippy encountered a bug calculating cyclomatic complexity \ (hide this message with `#[allow(cyclomatic_complexity)]`): \ cc = {}, arms = {}, div = {}, shorts = {}, returns = {}. \ Please file a bug report.", - cc, - narms, - div, - shorts, - returns)); + cc, + narms, + div, + shorts, + returns + ), + ); } } diff --git a/clippy_lints/src/derive.rs b/clippy_lints/src/derive.rs index 5ac4a342274..e186dd5e4db 100644 --- a/clippy_lints/src/derive.rs +++ b/clippy_lints/src/derive.rs @@ -89,7 +89,7 @@ fn check_hash_peq<'a, 'tcx>( span: Span, trait_ref: &TraitRef, ty: Ty<'tcx>, - hash_is_automatically_derived: bool + hash_is_automatically_derived: bool, ) { if_let_chain! {[ match_path_old(&trait_ref.path, &paths::HASH), diff --git a/clippy_lints/src/doc.rs b/clippy_lints/src/doc.rs index 46c3bd51068..3ca71694bbd 100644 --- a/clippy_lints/src/doc.rs +++ b/clippy_lints/src/doc.rs @@ -19,7 +19,8 @@ use utils::span_lint; /// /// **Examples:** /// ```rust -/// /// Do something with the foo_bar parameter. See also that::other::module::foo. +/// /// Do something with the foo_bar parameter. See also +/// that::other::module::foo. /// // ^ `foo_bar` and `that::other::module::foo` should be ticked. /// fn doit(foo_bar) { .. } /// ``` @@ -78,7 +79,8 @@ impl<'a> Iterator for Parser<'a> { /// Cleanup documentation decoration (`///` and such). /// /// We can't use `syntax::attr::AttributeMethods::with_desugared_doc` or -/// `syntax::parse::lexer::comments::strip_doc_comment_decoration` because we need to keep track of +/// `syntax::parse::lexer::comments::strip_doc_comment_decoration` because we +/// need to keep track of /// the spans but this function is inspired from the later. #[allow(cast_possible_truncation)] pub fn strip_doc_comment_decoration(comment: &str, span: Span) -> (String, Vec<(usize, Span)>) { @@ -89,7 +91,18 @@ pub fn strip_doc_comment_decoration(comment: &str, span: Span) -> (String, Vec<( let doc = &comment[prefix.len()..]; let mut doc = doc.to_owned(); doc.push('\n'); - return (doc.to_owned(), vec![(doc.len(), Span { lo: span.lo + BytePos(prefix.len() as u32), ..span })]); + return ( + doc.to_owned(), + vec![ + ( + doc.len(), + Span { + lo: span.lo + BytePos(prefix.len() as u32), + ..span + } + ), + ], + ); } } @@ -102,7 +115,13 @@ pub fn strip_doc_comment_decoration(comment: &str, span: Span) -> (String, Vec<( debug_assert_eq!(offset as u32 as usize, offset); // +1 for the newline - sizes.push((line.len() + 1, Span { lo: span.lo + BytePos(offset as u32), ..span })); + sizes.push(( + line.len() + 1, + Span { + lo: span.lo + BytePos(offset as u32), + ..span + }, + )); } return (doc.to_string(), sizes); @@ -163,7 +182,7 @@ fn check_doc<'a, Events: Iterator)>>( cx: &EarlyContext, valid_idents: &[String], docs: Events, - spans: &[(usize, Span)] + spans: &[(usize, Span)], ) { use pulldown_cmark::Event::*; use pulldown_cmark::Tag::*; @@ -192,7 +211,10 @@ fn check_doc<'a, Events: Iterator)>>( let (begin, span) = spans[index]; // Adjust for the begining of the current `Event` - let span = Span { lo: span.lo + BytePos::from_usize(offset - begin), ..span }; + let span = Span { + lo: span.lo + BytePos::from_usize(offset - begin), + ..span + }; check_text(cx, valid_idents, &text, span); } @@ -225,8 +247,10 @@ fn check_text(cx: &EarlyContext, valid_idents: &[String], text: &str, span: Span } fn check_word(cx: &EarlyContext, word: &str, span: Span) { - /// Checks if a string is camel-case, ie. contains at least two uppercase letter (`Clippy` is - /// ok) and one lower-case letter (`NASA` is ok). Plural are also excluded (`IDs` is ok). + /// Checks if a string is camel-case, ie. contains at least two uppercase + /// letter (`Clippy` is + /// ok) and one lower-case letter (`NASA` is ok). Plural are also excluded + /// (`IDs` is ok). fn is_camel_case(s: &str) -> bool { if s.starts_with(|c: char| c.is_digit(10)) { return false; @@ -239,7 +263,7 @@ fn check_word(cx: &EarlyContext, word: &str, span: Span) { }; s.chars().all(char::is_alphanumeric) && s.chars().filter(|&c| c.is_uppercase()).take(2).count() > 1 && - s.chars().filter(|&c| c.is_lowercase()).take(1).count() > 0 + s.chars().filter(|&c| c.is_lowercase()).take(1).count() > 0 } fn has_underscore(s: &str) -> bool { @@ -247,9 +271,11 @@ fn check_word(cx: &EarlyContext, word: &str, span: Span) { } if has_underscore(word) || word.contains("::") || is_camel_case(word) { - span_lint(cx, - DOC_MARKDOWN, - span, - &format!("you should put `{}` between ticks in the documentation", word)); + span_lint( + cx, + DOC_MARKDOWN, + span, + &format!("you should put `{}` between ticks in the documentation", word), + ); } } diff --git a/clippy_lints/src/drop_forget_ref.rs b/clippy_lints/src/drop_forget_ref.rs index 6112aec7cb6..b02333b89a0 100644 --- a/clippy_lints/src/drop_forget_ref.rs +++ b/clippy_lints/src/drop_forget_ref.rs @@ -16,7 +16,8 @@ use utils::{match_def_path, paths, span_note_and_lint, is_copy}; /// **Example:** /// ```rust /// let mut lock_guard = mutex.lock(); -/// std::mem::drop(&lock_guard) // Should have been drop(lock_guard), mutex still locked +/// std::mem::drop(&lock_guard) // Should have been drop(lock_guard), mutex +/// still locked /// operation_that_requires_mutex_to_be_unlocked(); /// ``` declare_lint! { @@ -29,7 +30,8 @@ declare_lint! { /// instead of an owned value. /// /// **Why is this bad?** Calling `forget` on a reference will only forget the -/// reference itself, which is a no-op. It will not forget the underlying referenced +/// reference itself, which is a no-op. It will not forget the underlying +/// referenced /// value, which is likely what was intended. /// /// **Known problems:** None. @@ -57,7 +59,8 @@ declare_lint! { /// **Example:** /// ```rust /// let x:i32 = 42; // i32 implements Copy -/// std::mem::drop(x) // A copy of x is passed to the function, leaving the original unaffected +/// std::mem::drop(x) // A copy of x is passed to the function, leaving the +/// original unaffected /// ``` declare_lint! { pub DROP_COPY, @@ -72,8 +75,10 @@ declare_lint! { /// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html) since the /// value will be copied and moved into the function on invocation. /// -/// An alternative, but also valid, explanation is that Copy types do not implement -/// the Drop trait, which means they have no destructors. Without a destructor, there +/// An alternative, but also valid, explanation is that Copy types do not +/// implement +/// the Drop trait, which means they have no destructors. Without a destructor, +/// there /// is nothing for `std::mem::forget` to ignore. /// /// **Known problems:** None. @@ -81,7 +86,8 @@ declare_lint! { /// **Example:** /// ```rust /// let x:i32 = 42; // i32 implements Copy -/// std::mem::forget(x) // A copy of x is passed to the function, leaving the original unaffected +/// std::mem::forget(x) // A copy of x is passed to the function, leaving the +/// original unaffected /// ``` declare_lint! { pub FORGET_COPY, diff --git a/clippy_lints/src/empty_enum.rs b/clippy_lints/src/empty_enum.rs index 431e8779842..7845c85b687 100644 --- a/clippy_lints/src/empty_enum.rs +++ b/clippy_lints/src/empty_enum.rs @@ -6,7 +6,8 @@ use utils::span_lint_and_then; /// **What it does:** Checks for `enum`s with no variants. /// -/// **Why is this bad?** Enum's with no variants should be replaced with `!`, the uninhabited type, +/// **Why is this bad?** Enum's with no variants should be replaced with `!`, +/// the uninhabited type, /// or a wrapper around it. /// /// **Known problems:** None. @@ -21,7 +22,7 @@ declare_lint! { "enum with no variants" } -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] pub struct EmptyEnum; impl LintPass for EmptyEnum { @@ -35,7 +36,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EmptyEnum { let did = cx.tcx.hir.local_def_id(item.id); if let ItemEnum(..) = item.node { let ty = cx.tcx.type_of(did); - let adt = ty.ty_adt_def().expect("already checked whether this is an enum"); + let adt = ty.ty_adt_def().expect( + "already checked whether this is an enum", + ); if adt.variants.is_empty() { span_lint_and_then(cx, EMPTY_ENUM, item.span, "enum with no variants", |db| { db.span_help(item.span, "consider using the uninhabited type `!` or a wrapper around it"); diff --git a/clippy_lints/src/entry.rs b/clippy_lints/src/entry.rs index 43d8357e335..80288ff2268 100644 --- a/clippy_lints/src/entry.rs +++ b/clippy_lints/src/entry.rs @@ -30,7 +30,7 @@ declare_lint! { "use of `contains_key` followed by `insert` on a `HashMap` or `BTreeMap`" } -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] pub struct HashMapLint; impl LintPass for HashMapLint { @@ -48,11 +48,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for HashMapLint { // we can give a better error message let sole_expr = { else_block.is_none() && - if let ExprBlock(ref then_block) = then_block.node { - (then_block.expr.is_some() as usize) + then_block.stmts.len() == 1 - } else { - true - } + if let ExprBlock(ref then_block) = then_block.node { + (then_block.expr.is_some() as usize) + then_block.stmts.len() == 1 + } else { + true + } }; let mut visitor = InsertVisitor { @@ -86,7 +86,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for HashMapLint { fn check_cond<'a, 'tcx, 'b>( cx: &'a LateContext<'a, 'tcx>, - check: &'b Expr + check: &'b Expr, ) -> Option<(&'static str, &'b Expr, &'b Expr)> { if_let_chain! {[ let ExprMethodCall(ref path, _, ref params) = check.node, diff --git a/clippy_lints/src/enum_clike.rs b/clippy_lints/src/enum_clike.rs index 3741b3934bd..bf2ba847ec8 100644 --- a/clippy_lints/src/enum_clike.rs +++ b/clippy_lints/src/enum_clike.rs @@ -1,4 +1,5 @@ -//! lint on C-like enums that are `repr(isize/usize)` and have values that don't fit into an `i32` +//! lint on C-like enums that are `repr(isize/usize)` and have values that +//! don't fit into an `i32` use rustc::lint::*; use rustc::middle::const_val::ConstVal; @@ -50,16 +51,20 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnportableVariant { let did = cx.tcx.hir.body_owner_def_id(body_id); let param_env = ty::ParamEnv::empty(Reveal::UserFacing); let substs = Substs::identity_for_item(cx.tcx.global_tcx(), did); - let bad = match cx.tcx.at(expr.span).const_eval(param_env.and((did, substs))) { + let bad = match cx.tcx.at(expr.span).const_eval( + param_env.and((did, substs)), + ) { Ok(ConstVal::Integral(Usize(Us64(i)))) => i as u32 as u64 != i, Ok(ConstVal::Integral(Isize(Is64(i)))) => i as i32 as i64 != i, _ => false, }; if bad { - span_lint(cx, - ENUM_CLIKE_UNPORTABLE_VARIANT, - var.span, - "Clike enum variant discriminant is not portable to 32-bit targets"); + span_lint( + cx, + ENUM_CLIKE_UNPORTABLE_VARIANT, + var.span, + "Clike enum variant discriminant is not portable to 32-bit targets", + ); } } } diff --git a/clippy_lints/src/enum_glob_use.rs b/clippy_lints/src/enum_glob_use.rs index 12b588967f8..6738f5bb63b 100644 --- a/clippy_lints/src/enum_glob_use.rs +++ b/clippy_lints/src/enum_glob_use.rs @@ -48,9 +48,14 @@ impl EnumGlobUse { } if let ItemUse(ref path, UseKind::Glob) = item.node { // FIXME: ask jseyfried why the qpath.def for `use std::cmp::Ordering::*;` - // extracted through `ItemUse(ref qpath, UseKind::Glob)` is a `Mod` and not an `Enum` + // extracted through `ItemUse(ref qpath, UseKind::Glob)` is a `Mod` and not an + // `Enum` // if let Def::Enum(_) = path.def { - if path.segments.last().and_then(|seg| seg.name.as_str().chars().next()).map_or(false, char::is_uppercase) { + if path.segments + .last() + .and_then(|seg| seg.name.as_str().chars().next()) + .map_or(false, char::is_uppercase) + { span_lint(cx, ENUM_GLOB_USE, item.span, "don't use glob imports for enum variants"); } } diff --git a/clippy_lints/src/enum_variants.rs b/clippy_lints/src/enum_variants.rs index 16a2e021723..1227de69db2 100644 --- a/clippy_lints/src/enum_variants.rs +++ b/clippy_lints/src/enum_variants.rs @@ -68,13 +68,16 @@ declare_lint! { "type names prefixed/postfixed with their containing module's name" } -/// **What it does:** Checks for modules that have the same name as their parent module +/// **What it does:** Checks for modules that have the same name as their +/// parent module /// -/// **Why is this bad?** A typical beginner mistake is to have `mod foo;` and again `mod foo { .. +/// **Why is this bad?** A typical beginner mistake is to have `mod foo;` and +/// again `mod foo { .. /// }` in `foo.rs`. /// The expectation is that items inside the inner `mod foo { .. }` are then /// available -/// through `foo::x`, but they are only available through `foo::foo::x`. +/// through `foo::x`, but they are only available through +/// `foo::foo::x`. /// If this is done on purpose, it would be better to choose a more /// representative module name. /// @@ -123,14 +126,21 @@ fn var2str(var: &Variant) -> InternedString { fn partial_match(pre: &str, name: &str) -> usize { let mut name_iter = name.chars(); let _ = name_iter.next_back(); // make sure the name is never fully matched - pre.chars().zip(name_iter).take_while(|&(l, r)| l == r).count() + pre.chars() + .zip(name_iter) + .take_while(|&(l, r)| l == r) + .count() } /// Returns the number of chars that match from the end fn partial_rmatch(post: &str, name: &str) -> usize { let mut name_iter = name.chars(); let _ = name_iter.next(); // make sure the name is never fully matched - post.chars().rev().zip(name_iter.rev()).take_while(|&(l, r)| l == r).count() + post.chars() + .rev() + .zip(name_iter.rev()) + .take_while(|&(l, r)| l == r) + .count() } // FIXME: #600 @@ -142,7 +152,7 @@ fn check_variant( item_name: &str, item_name_chars: usize, span: Span, - lint: &'static Lint + lint: &'static Lint, ) { if (def.variants.len() as u64) < threshold { return; @@ -187,13 +197,17 @@ fn check_variant( (false, _) => ("pre", pre), (true, false) => ("post", post), }; - span_help_and_lint(cx, - lint, - span, - &format!("All variants have the same {}fix: `{}`", what, value), - &format!("remove the {}fixes and use full paths to \ + span_help_and_lint( + cx, + lint, + span, + &format!("All variants have the same {}fix: `{}`", what, value), + &format!( + "remove the {}fixes and use full paths to \ the variants instead of glob imports", - what)); + what + ), + ); } fn to_camel_case(item_name: &str) -> String { @@ -234,10 +248,12 @@ impl EarlyLintPass for EnumVariantNames { if !mod_camel.is_empty() { if *mod_name == item_name { if let ItemKind::Mod(..) = item.node { - span_lint(cx, - MODULE_INCEPTION, - item.span, - "module has the same name as its containing module"); + span_lint( + cx, + MODULE_INCEPTION, + item.span, + "module has the same name as its containing module", + ); } } if item.vis == Visibility::Public { diff --git a/clippy_lints/src/eq_op.rs b/clippy_lints/src/eq_op.rs index 10e5f2ba7c0..84a54dd215b 100644 --- a/clippy_lints/src/eq_op.rs +++ b/clippy_lints/src/eq_op.rs @@ -23,7 +23,8 @@ declare_lint! { "equal operands on both sides of a comparison or bitwise combination (e.g. `x == x`)" } -/// **What it does:** Checks for arguments to `==` which have their address taken to satisfy a bound +/// **What it does:** Checks for arguments to `==` which have their address +/// taken to satisfy a bound /// and suggests to dereference the other argument instead /// /// **Why is this bad?** It is more idiomatic to dereference the other argument. @@ -40,7 +41,7 @@ declare_lint! { "taking a reference to satisfy the type constraints on `==`" } -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] pub struct EqOp; impl LintPass for EqOp { @@ -53,10 +54,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) { if let ExprBinary(ref op, ref left, ref right) = e.node { if is_valid_operator(op) && SpanlessEq::new(cx).ignore_fn().eq_expr(left, right) { - span_lint(cx, - EQ_OP, - e.span, - &format!("equal expressions as operands to `{}`", op.node.as_str())); + span_lint( + cx, + EQ_OP, + e.span, + &format!("equal expressions as operands to `{}`", op.node.as_str()), + ); return; } let (trait_id, requires_ref) = match op.node { @@ -89,31 +92,37 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp { let rcpy = is_copy(cx, rty); // either operator autorefs or both args are copyable if (requires_ref || (lcpy && rcpy)) && implements_trait(cx, lty, trait_id, &[rty]) { - span_lint_and_then(cx, - OP_REF, - e.span, - "needlessly taken reference of both operands", - |db| { - let lsnip = snippet(cx, l.span, "...").to_string(); - let rsnip = snippet(cx, r.span, "...").to_string(); - multispan_sugg(db, - "use the values directly".to_string(), - vec![(left.span, lsnip), (right.span, rsnip)]); - }) + span_lint_and_then( + cx, + OP_REF, + e.span, + "needlessly taken reference of both operands", + |db| { + let lsnip = snippet(cx, l.span, "...").to_string(); + let rsnip = snippet(cx, r.span, "...").to_string(); + multispan_sugg( + db, + "use the values directly".to_string(), + vec![(left.span, lsnip), (right.span, rsnip)], + ); + }, + ) } else if lcpy && !rcpy && implements_trait(cx, lty, trait_id, &[cx.tables.expr_ty(right)]) { span_lint_and_then(cx, OP_REF, e.span, "needlessly taken reference of left operand", |db| { let lsnip = snippet(cx, l.span, "...").to_string(); db.span_suggestion(left.span, "use the left value directly", lsnip); }) } else if !lcpy && rcpy && implements_trait(cx, cx.tables.expr_ty(left), trait_id, &[rty]) { - span_lint_and_then(cx, - OP_REF, - e.span, - "needlessly taken reference of right operand", - |db| { - let rsnip = snippet(cx, r.span, "...").to_string(); - db.span_suggestion(right.span, "use the right value directly", rsnip); - }) + span_lint_and_then( + cx, + OP_REF, + e.span, + "needlessly taken reference of right operand", + |db| { + let rsnip = snippet(cx, r.span, "...").to_string(); + db.span_suggestion(right.span, "use the right value directly", rsnip); + }, + ) } }, // &foo == bar diff --git a/clippy_lints/src/escape.rs b/clippy_lints/src/escape.rs index c3a3f37fab5..68f0ede8a6c 100644 --- a/clippy_lints/src/escape.rs +++ b/clippy_lints/src/escape.rs @@ -61,7 +61,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { _: &'tcx FnDecl, body: &'tcx Body, _: Span, - node_id: NodeId + node_id: NodeId, ) { let fn_def_id = cx.tcx.hir.local_def_id(node_id); let mut v = EscapeDelegate { @@ -74,10 +74,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { ExprUseVisitor::new(&mut v, cx.tcx, cx.param_env, region_maps, cx.tables).consume_body(body); for node in v.set { - span_lint(cx, - BOXED_LOCAL, - cx.tcx.hir.span(node), - "local variable doesn't need to be boxed here"); + span_lint( + cx, + BOXED_LOCAL, + cx.tcx.hir.span(node), + "local variable doesn't need to be boxed here", + ); } } } diff --git a/clippy_lints/src/eta_reduction.rs b/clippy_lints/src/eta_reduction.rs index 7ec528b90f4..b5667db920c 100644 --- a/clippy_lints/src/eta_reduction.rs +++ b/clippy_lints/src/eta_reduction.rs @@ -20,7 +20,8 @@ pub struct EtaPass; /// ```rust /// xs.map(|x| foo(x)) /// ``` -/// where `foo(_)` is a plain function that takes the exact argument type of `x`. +/// where `foo(_)` is a plain function that takes the exact argument type of +/// `x`. declare_lint! { pub REDUNDANT_CLOSURE, Warn, @@ -91,13 +92,11 @@ fn check_closure(cx: &LateContext, expr: &Expr) { return; } } - span_lint_and_then(cx, - REDUNDANT_CLOSURE, - expr.span, - "redundant closure found", - |db| if let Some(snippet) = snippet_opt(cx, caller.span) { - db.span_suggestion(expr.span, "remove closure as shown", snippet); - }); + span_lint_and_then(cx, REDUNDANT_CLOSURE, expr.span, "redundant closure found", |db| { + if let Some(snippet) = snippet_opt(cx, caller.span) { + db.span_suggestion(expr.span, "remove closure as shown", snippet); + } + }); } } } diff --git a/clippy_lints/src/eval_order_dependence.rs b/clippy_lints/src/eval_order_dependence.rs index 765da9ea877..81109761ca7 100644 --- a/clippy_lints/src/eval_order_dependence.rs +++ b/clippy_lints/src/eval_order_dependence.rs @@ -27,12 +27,14 @@ declare_lint! { "whether a variable read occurs before a write depends on sub-expression evaluation order" } -/// **What it does:** Checks for diverging calls that are not match arms or statements. +/// **What it does:** Checks for diverging calls that are not match arms or +/// statements. /// /// **Why is this bad?** It is often confusing to read. In addition, the /// sub-expression evaluation order for Rust is not well documented. /// -/// **Known problems:** Someone might want to use `some_bool || panic!()` as a shorthand. +/// **Known problems:** Someone might want to use `some_bool || panic!()` as a +/// shorthand. /// /// **Example:** /// ```rust @@ -47,7 +49,7 @@ declare_lint! { "whether an expression contains a diverging sub expression" } -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] pub struct EvalOrderDependence; impl LintPass for EvalOrderDependence { @@ -144,7 +146,8 @@ impl<'a, 'tcx> Visitor<'tcx> for DivergenceVisitor<'a, 'tcx> { } }, _ => { - // do not lint expressions referencing objects of type `!`, as that required a diverging expression + // do not lint expressions referencing objects of type `!`, as that required a + // diverging expression // to begin with }, } @@ -271,8 +274,10 @@ fn check_stmt<'a, 'tcx>(vis: &mut ReadVisitor<'a, 'tcx>, stmt: &'tcx Stmt) -> St DeclLocal(ref local) => Some(local), _ => None, }; - local.and_then(|local| local.init.as_ref()) - .map_or(StopEarly::KeepGoing, |expr| check_expr(vis, expr)) + local.and_then(|local| local.init.as_ref()).map_or( + StopEarly::KeepGoing, + |expr| check_expr(vis, expr), + ) }, } } diff --git a/clippy_lints/src/format.rs b/clippy_lints/src/format.rs index e7dbc3250f7..16dced95760 100644 --- a/clippy_lints/src/format.rs +++ b/clippy_lints/src/format.rs @@ -99,7 +99,8 @@ pub fn get_argument_fmtstr_parts<'a, 'b>(cx: &LateContext<'a, 'b>, expr: &'a Exp /// Checks if the expressions matches /// ```rust, ignore -/// { static __STATIC_FMTSTR: &'static[&'static str] = &["a", "b", c]; __STATIC_FMTSTR } +/// { static __STATIC_FMTSTR: &'static[&'static str] = &["a", "b", c]; +/// __STATIC_FMTSTR } /// ``` fn check_static_str(cx: &LateContext, expr: &Expr) -> bool { if let Some(expr) = get_argument_fmtstr_parts(cx, expr) { @@ -112,7 +113,8 @@ fn check_static_str(cx: &LateContext, expr: &Expr) -> bool { /// Checks if the expressions matches /// ```rust,ignore /// &match (&42,) { -/// (__arg0,) => [::std::fmt::ArgumentV1::new(__arg0, ::std::fmt::Display::fmt)], +/// (__arg0,) => [::std::fmt::ArgumentV1::new(__arg0, +/// ::std::fmt::Display::fmt)], /// } /// ``` fn check_arg_is_display(cx: &LateContext, expr: &Expr) -> bool { diff --git a/clippy_lints/src/formatting.rs b/clippy_lints/src/formatting.rs index 8f8c7db64cf..c478974a5bd 100644 --- a/clippy_lints/src/formatting.rs +++ b/clippy_lints/src/formatting.rs @@ -4,9 +4,11 @@ use syntax_pos::{Span, NO_EXPANSION}; use utils::{differing_macro_contexts, in_macro, snippet_opt, span_note_and_lint}; use syntax::ptr::P; -/// **What it does:** Checks for use of the non-existent `=*`, `=!` and `=-` operators. +/// **What it does:** Checks for use of the non-existent `=*`, `=!` and `=-` +/// operators. /// -/// **Why is this bad?** This is either a typo of `*=`, `!=` or `-=` or confusing. +/// **Why is this bad?** This is either a typo of `*=`, `!=` or `-=` or +/// confusing. /// /// **Known problems:** None. /// @@ -67,12 +69,16 @@ declare_lint! { } -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] pub struct Formatting; impl LintPass for Formatting { fn get_lints(&self) -> LintArray { - lint_array![SUSPICIOUS_ASSIGNMENT_FORMATTING, SUSPICIOUS_ELSE_FORMATTING, POSSIBLE_MISSING_COMMA] + lint_array!( + SUSPICIOUS_ASSIGNMENT_FORMATTING, + SUSPICIOUS_ELSE_FORMATTING, + POSSIBLE_MISSING_COMMA + ) } } @@ -114,14 +120,18 @@ fn check_assign(cx: &EarlyContext, expr: &ast::Expr) { ctxt: NO_EXPANSION, }; if eq_snippet.ends_with('=') { - span_note_and_lint(cx, - SUSPICIOUS_ASSIGNMENT_FORMATTING, - eqop_span, - &format!("this looks like you are trying to use `.. {op}= ..`, but you \ + span_note_and_lint( + cx, + SUSPICIOUS_ASSIGNMENT_FORMATTING, + eqop_span, + &format!( + "this looks like you are trying to use `.. {op}= ..`, but you \ really are doing `.. = ({op} ..)`", - op = op), - eqop_span, - &format!("to remove this lint, use either `{op}=` or `= {op}`", op = op)); + op = op + ), + eqop_span, + &format!("to remove this lint, use either `{op}=` or `= {op}`", op = op), + ); } } } @@ -133,7 +143,8 @@ fn check_assign(cx: &EarlyContext, expr: &ast::Expr) { fn check_else_if(cx: &EarlyContext, expr: &ast::Expr) { if let Some((then, &Some(ref else_))) = unsugar_if(expr) { if unsugar_if(else_).is_some() && !differing_macro_contexts(then.span, else_.span) && !in_macro(then.span) { - // this will be a span from the closing ‘}’ of the “then” block (excluding) to the + // this will be a span from the closing ‘}’ of the “then” block (excluding) to + // the // “if” of the “else if” block (excluding) let else_span = Span { lo: then.span.hi, @@ -144,16 +155,20 @@ fn check_else_if(cx: &EarlyContext, expr: &ast::Expr) { // the snippet should look like " else \n " with maybe comments anywhere // it’s bad when there is a ‘\n’ after the “else” if let Some(else_snippet) = snippet_opt(cx, else_span) { - let else_pos = else_snippet.find("else").expect("there must be a `else` here"); + let else_pos = else_snippet.find("else").expect( + "there must be a `else` here", + ); if else_snippet[else_pos..].contains('\n') { - span_note_and_lint(cx, - SUSPICIOUS_ELSE_FORMATTING, - else_span, - "this is an `else if` but the formatting might hide it", - else_span, - "to remove this lint, remove the `else` or remove the new line between `else` \ - and `if`"); + span_note_and_lint( + cx, + SUSPICIOUS_ELSE_FORMATTING, + else_span, + "this is an `else if` but the formatting might hide it", + else_span, + "to remove this lint, remove the `else` or remove the new line between `else` \ + and `if`", + ); } } } @@ -178,12 +193,14 @@ fn check_array(cx: &EarlyContext, expr: &ast::Expr) { ctxt: NO_EXPANSION, }; if space_snippet.contains('\n') { - span_note_and_lint(cx, - POSSIBLE_MISSING_COMMA, - lint_span, - "possibly missing a comma here", - lint_span, - "to remove this lint, add a comma or write the expr in a single line"); + span_note_and_lint( + cx, + POSSIBLE_MISSING_COMMA, + lint_span, + "possibly missing a comma here", + lint_span, + "to remove this lint, add a comma or write the expr in a single line", + ); } } } @@ -195,7 +212,8 @@ fn check_array(cx: &EarlyContext, expr: &ast::Expr) { /// Implementation of the `SUSPICIOUS_ELSE_FORMATTING` lint for consecutive ifs. fn check_consecutive_ifs(cx: &EarlyContext, first: &ast::Expr, second: &ast::Expr) { if !differing_macro_contexts(first.span, second.span) && !in_macro(first.span) && unsugar_if(first).is_some() && - unsugar_if(second).is_some() { + unsugar_if(second).is_some() + { // where the else would be let else_span = Span { lo: first.span.hi, @@ -205,13 +223,15 @@ fn check_consecutive_ifs(cx: &EarlyContext, first: &ast::Expr, second: &ast::Exp if let Some(else_snippet) = snippet_opt(cx, else_span) { if !else_snippet.contains('\n') { - span_note_and_lint(cx, - SUSPICIOUS_ELSE_FORMATTING, - else_span, - "this looks like an `else if` but the `else` is missing", - else_span, - "to remove this lint, add the missing `else` or add a new line before the second \ - `if`"); + span_note_and_lint( + cx, + SUSPICIOUS_ELSE_FORMATTING, + else_span, + "this looks like an `else if` but the `else` is missing", + else_span, + "to remove this lint, add the missing `else` or add a new line before the second \ + `if`", + ); } } } diff --git a/clippy_lints/src/functions.rs b/clippy_lints/src/functions.rs index 79d47b1e7da..e45ab558089 100644 --- a/clippy_lints/src/functions.rs +++ b/clippy_lints/src/functions.rs @@ -17,7 +17,8 @@ use utils::{span_lint, type_is_unsafe_function, iter_input_pats}; /// /// **Example:** /// ```rust -/// fn foo(x: u32, y: u32, name: &str, c: Color, w: f32, h: f32, a: f32, b: f32) { .. } +/// fn foo(x: u32, y: u32, name: &str, c: Color, w: f32, h: f32, a: f32, b: +/// f32) { .. } /// ``` declare_lint! { pub TOO_MANY_ARGUMENTS, @@ -35,7 +36,8 @@ declare_lint! { /// **Known problems:** /// /// * It does not check functions recursively so if the pointer is passed to a -/// private non-`unsafe` function which does the dereferencing, the lint won't trigger. +/// private non-`unsafe` function which does the dereferencing, the lint won't +/// trigger. /// * It only checks for arguments whose type are raw pointers, not raw pointers /// got from an argument in some other way (`fn foo(bar: &[*const u8])` or /// `some_argument.get_raw_ptr()`). @@ -50,7 +52,7 @@ declare_lint! { "public functions dereferencing raw pointer arguments but not marked `unsafe`" } -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] pub struct Functions { threshold: u64, } @@ -75,7 +77,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Functions { decl: &'tcx hir::FnDecl, body: &'tcx hir::Body, span: Span, - nodeid: ast::NodeId + nodeid: ast::NodeId, ) { use rustc::hir::map::Node::*; @@ -123,10 +125,12 @@ impl<'a, 'tcx> Functions { fn check_arg_number(&self, cx: &LateContext, decl: &hir::FnDecl, span: Span) { let args = decl.inputs.len() as u64; if args > self.threshold { - span_lint(cx, - TOO_MANY_ARGUMENTS, - span, - &format!("this function has too many arguments ({}/{})", args, self.threshold)); + span_lint( + cx, + TOO_MANY_ARGUMENTS, + span, + &format!("this function has too many arguments ({}/{})", args, self.threshold), + ); } } @@ -136,7 +140,7 @@ impl<'a, 'tcx> Functions { unsafety: hir::Unsafety, decl: &'tcx hir::FnDecl, body: &'tcx hir::Body, - nodeid: ast::NodeId + nodeid: ast::NodeId, ) { let expr = &body.value; if unsafety == hir::Unsafety::Normal && cx.access_levels.is_exported(nodeid) { @@ -208,10 +212,12 @@ impl<'a, 'tcx: 'a> DerefVisitor<'a, 'tcx> { if let hir::ExprPath(ref qpath) = ptr.node { let def = self.cx.tables.qpath_def(qpath, ptr.id); if self.ptrs.contains(&def.def_id()) { - span_lint(self.cx, - NOT_UNSAFE_PTR_ARG_DEREF, - ptr.span, - "this public function dereferences a raw pointer but is not marked `unsafe`"); + span_lint( + self.cx, + NOT_UNSAFE_PTR_ARG_DEREF, + ptr.span, + "this public function dereferences a raw pointer but is not marked `unsafe`", + ); } } } diff --git a/clippy_lints/src/identity_op.rs b/clippy_lints/src/identity_op.rs index 7bac29f6808..a7c254e1e46 100644 --- a/clippy_lints/src/identity_op.rs +++ b/clippy_lints/src/identity_op.rs @@ -22,7 +22,7 @@ declare_lint! { "using identity operations, e.g. `x + 0` or `y / 1`" } -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] pub struct IdentityOp; impl LintPass for IdentityOp { @@ -71,12 +71,17 @@ fn check(cx: &LateContext, e: &Expr, m: i8, span: Span, arg: Span) { }, 1 => v.to_u128_unchecked() == 1, _ => unreachable!(), - } { - span_lint(cx, - IDENTITY_OP, - span, - &format!("the operation is ineffective. Consider reducing it to `{}`", - snippet(cx, arg, ".."))); + } + { + span_lint( + cx, + IDENTITY_OP, + span, + &format!( + "the operation is ineffective. Consider reducing it to `{}`", + snippet(cx, arg, "..") + ), + ); } } } diff --git a/clippy_lints/src/if_let_redundant_pattern_matching.rs b/clippy_lints/src/if_let_redundant_pattern_matching.rs index 8d6a28e62db..058052769ef 100644 --- a/clippy_lints/src/if_let_redundant_pattern_matching.rs +++ b/clippy_lints/src/if_let_redundant_pattern_matching.rs @@ -3,9 +3,11 @@ use rustc::hir::*; use syntax::codemap::Span; use utils::{paths, span_lint_and_then, match_path, snippet}; -/// **What it does:*** Lint for redundant pattern matching over `Result` or `Option` +/// **What it does:*** Lint for redundant pattern matching over `Result` or +/// `Option` /// -/// **Why is this bad?** It's more concise and clear to just use the proper utility function +/// **Why is this bad?** It's more concise and clear to just use the proper +/// utility function /// /// **Known problems:** None. /// diff --git a/clippy_lints/src/if_not_else.rs b/clippy_lints/src/if_not_else.rs index 72a3d485bd0..66f2778f215 100644 --- a/clippy_lints/src/if_not_else.rs +++ b/clippy_lints/src/if_not_else.rs @@ -1,4 +1,5 @@ -//! lint on if branches that could be swapped so no `!` operation is necessary on the condition +//! lint on if branches that could be swapped so no `!` operation is necessary +//! on the condition use rustc::lint::*; use syntax::ast::*; @@ -50,18 +51,22 @@ impl EarlyLintPass for IfNotElse { if let ExprKind::Block(..) = els.node { match cond.node { ExprKind::Unary(UnOp::Not, _) => { - span_help_and_lint(cx, - IF_NOT_ELSE, - item.span, - "Unnecessary boolean `not` operation", - "remove the `!` and swap the blocks of the if/else"); + span_help_and_lint( + cx, + IF_NOT_ELSE, + item.span, + "Unnecessary boolean `not` operation", + "remove the `!` and swap the blocks of the if/else", + ); }, ExprKind::Binary(ref kind, _, _) if kind.node == BinOpKind::Ne => { - span_help_and_lint(cx, - IF_NOT_ELSE, - item.span, - "Unnecessary `!=` operation", - "change to `==` and swap the blocks of the if/else"); + span_help_and_lint( + cx, + IF_NOT_ELSE, + item.span, + "Unnecessary `!=` operation", + "change to `==` and swap the blocks of the if/else", + ); }, _ => (), } diff --git a/clippy_lints/src/items_after_statements.rs b/clippy_lints/src/items_after_statements.rs index b3561720cc7..f14c70dc4dd 100644 --- a/clippy_lints/src/items_after_statements.rs +++ b/clippy_lints/src/items_after_statements.rs @@ -47,10 +47,9 @@ impl EarlyLintPass for ItemsAfterStatements { } // skip initial items - let stmts = item.stmts - .iter() - .map(|stmt| &stmt.node) - .skip_while(|s| matches!(**s, StmtKind::Item(..))); + let stmts = item.stmts.iter().map(|stmt| &stmt.node).skip_while(|s| { + matches!(**s, StmtKind::Item(..)) + }); // lint on all further items for stmt in stmts { @@ -62,11 +61,13 @@ impl EarlyLintPass for ItemsAfterStatements { // do not lint `macro_rules`, but continue processing further statements continue; } - span_lint(cx, - ITEMS_AFTER_STATEMENTS, - it.span, - "adding items after statements is confusing, since items exist from the \ - start of the scope"); + span_lint( + cx, + ITEMS_AFTER_STATEMENTS, + it.span, + "adding items after statements is confusing, since items exist from the \ + start of the scope", + ); } } } diff --git a/clippy_lints/src/large_enum_variant.rs b/clippy_lints/src/large_enum_variant.rs index 4e9c792c42a..73a62c97bc8 100644 --- a/clippy_lints/src/large_enum_variant.rs +++ b/clippy_lints/src/large_enum_variant.rs @@ -5,9 +5,11 @@ use rustc::hir::*; use utils::{span_lint_and_then, snippet_opt, type_size}; use rustc::ty::TypeFoldable; -/// **What it does:** Checks for large size differences between variants on `enum`s. +/// **What it does:** Checks for large size differences between variants on +/// `enum`s. /// -/// **Why is this bad?** Enum size is bounded by the largest variant. Having a large variant +/// **Why is this bad?** Enum size is bounded by the largest variant. Having a +/// large variant /// can penalize the memory layout of that enum. /// /// **Known problems:** None. @@ -25,7 +27,7 @@ declare_lint! { "large size difference between variants on an enum" } -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] pub struct LargeEnumVariant { maximum_size_difference_allowed: u64, } @@ -47,13 +49,16 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LargeEnumVariant { let did = cx.tcx.hir.local_def_id(item.id); if let ItemEnum(ref def, _) = item.node { let ty = cx.tcx.type_of(did); - let adt = ty.ty_adt_def().expect("already checked whether this is an enum"); + let adt = ty.ty_adt_def().expect( + "already checked whether this is an enum", + ); let mut smallest_variant: Option<(_, _)> = None; let mut largest_variant: Option<(_, _)> = None; for (i, variant) in adt.variants.iter().enumerate() { - let size: u64 = variant.fields + let size: u64 = variant + .fields .iter() .map(|f| { let ty = cx.tcx.type_of(f.did); @@ -77,28 +82,34 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LargeEnumVariant { if difference > self.maximum_size_difference_allowed { let (i, variant) = largest.1; - span_lint_and_then(cx, - LARGE_ENUM_VARIANT, - def.variants[i].span, - "large size difference between variants", - |db| { - if variant.fields.len() == 1 { - let span = match def.variants[i].node.data { - VariantData::Struct(ref fields, _) | - VariantData::Tuple(ref fields, _) => fields[0].ty.span, - VariantData::Unit(_) => unreachable!(), - }; - if let Some(snip) = snippet_opt(cx, span) { - db.span_suggestion(span, - "consider boxing the large fields to reduce the total size of the \ + span_lint_and_then( + cx, + LARGE_ENUM_VARIANT, + def.variants[i].span, + "large size difference between variants", + |db| { + if variant.fields.len() == 1 { + let span = match def.variants[i].node.data { + VariantData::Struct(ref fields, _) | + VariantData::Tuple(ref fields, _) => fields[0].ty.span, + VariantData::Unit(_) => unreachable!(), + }; + if let Some(snip) = snippet_opt(cx, span) { + db.span_suggestion( + span, + "consider boxing the large fields to reduce the total size of the \ enum", - format!("Box<{}>", snip)); - return; + format!("Box<{}>", snip), + ); + return; + } } - } - db.span_help(def.variants[i].span, - "consider boxing the large fields to reduce the total size of the enum"); - }); + db.span_help( + def.variants[i].span, + "consider boxing the large fields to reduce the total size of the enum", + ); + }, + ); } } @@ -107,7 +118,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LargeEnumVariant { } fn update_if(old: &mut Option, new: T, f: F) - where F: Fn(&T, &T) -> bool +where + F: Fn(&T, &T) -> bool, { if let Some(ref mut val) = *old { if f(val, &new) { diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs index 9b76986dbcc..4e40348facf 100644 --- a/clippy_lints/src/len_zero.rs +++ b/clippy_lints/src/len_zero.rs @@ -51,7 +51,7 @@ declare_lint! { "traits or impls with a public `len` method but no corresponding `is_empty` method" } -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] pub struct LenZero; impl LintPass for LenZero { @@ -91,24 +91,26 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LenZero { fn check_trait_items(cx: &LateContext, item: &Item, trait_items: &[TraitItemRef]) { fn is_named_self(cx: &LateContext, item: &TraitItemRef, name: &str) -> bool { item.name == name && - if let AssociatedItemKind::Method { has_self } = item.kind { - has_self && - { - let did = cx.tcx.hir.local_def_id(item.id.node_id); - cx.tcx.fn_sig(did).inputs().skip_binder().len() == 1 + if let AssociatedItemKind::Method { has_self } = item.kind { + has_self && + { + let did = cx.tcx.hir.local_def_id(item.id.node_id); + cx.tcx.fn_sig(did).inputs().skip_binder().len() == 1 + } + } else { + false } - } else { - false - } } if !trait_items.iter().any(|i| is_named_self(cx, i, "is_empty")) { if let Some(i) = trait_items.iter().find(|i| is_named_self(cx, i, "len")) { if cx.access_levels.is_exported(i.id.node_id) { - span_lint(cx, - LEN_WITHOUT_IS_EMPTY, - item.span, - &format!("trait `{}` has a `len` method but no `is_empty` method", item.name)); + span_lint( + cx, + LEN_WITHOUT_IS_EMPTY, + item.span, + &format!("trait `{}` has a `len` method but no `is_empty` method", item.name), + ); } } } @@ -117,15 +119,15 @@ fn check_trait_items(cx: &LateContext, item: &Item, trait_items: &[TraitItemRef] fn check_impl_items(cx: &LateContext, item: &Item, impl_items: &[ImplItemRef]) { fn is_named_self(cx: &LateContext, item: &ImplItemRef, name: &str) -> bool { item.name == name && - if let AssociatedItemKind::Method { has_self } = item.kind { - has_self && - { - let did = cx.tcx.hir.local_def_id(item.id.node_id); - cx.tcx.fn_sig(did).inputs().skip_binder().len() == 1 + if let AssociatedItemKind::Method { has_self } = item.kind { + has_self && + { + let did = cx.tcx.hir.local_def_id(item.id.node_id); + cx.tcx.fn_sig(did).inputs().skip_binder().len() == 1 + } + } else { + false } - } else { - false - } } let is_empty = if let Some(is_empty) = impl_items.iter().find(|i| is_named_self(cx, i, "is_empty")) { @@ -143,10 +145,12 @@ fn check_impl_items(cx: &LateContext, item: &Item, impl_items: &[ImplItemRef]) { let def_id = cx.tcx.hir.local_def_id(item.id); let ty = cx.tcx.type_of(def_id); - span_lint(cx, - LEN_WITHOUT_IS_EMPTY, - item.span, - &format!("item `{}` has a public `len` method but {} `is_empty` method", ty, is_empty)); + span_lint( + cx, + LEN_WITHOUT_IS_EMPTY, + item.span, + &format!("item `{}` has a public `len` method but {} `is_empty` method", ty, is_empty), + ); } } } @@ -170,12 +174,14 @@ fn check_cmp(cx: &LateContext, span: Span, left: &Expr, right: &Expr, op: &str) fn check_len_zero(cx: &LateContext, span: Span, name: Name, args: &[Expr], lit: &Lit, op: &str) { if let Spanned { node: LitKind::Int(0, _), .. } = *lit { if name == "len" && args.len() == 1 && has_is_empty(cx, &args[0]) { - span_lint_and_sugg(cx, - LEN_ZERO, - span, - "length comparison to zero", - "using `is_empty` is more concise", - format!("{}{}.is_empty()", op, snippet(cx, args[0].span, "_"))); + span_lint_and_sugg( + cx, + LEN_ZERO, + span, + "length comparison to zero", + "using `is_empty` is more concise", + format!("{}{}.is_empty()", op, snippet(cx, args[0].span, "_")), + ); } } } @@ -199,10 +205,11 @@ fn has_is_empty(cx: &LateContext, expr: &Expr) -> bool { /// Check the inherent impl's items for an `is_empty(self)` method. fn has_is_empty_impl(cx: &LateContext, id: DefId) -> bool { - cx.tcx - .inherent_impls(id) - .iter() - .any(|imp| cx.tcx.associated_items(*imp).any(|item| is_is_empty(cx, &item))) + cx.tcx.inherent_impls(id).iter().any(|imp| { + cx.tcx.associated_items(*imp).any( + |item| is_is_empty(cx, &item), + ) + }) } let ty = &walk_ptrs_ty(cx.tables.expr_ty(expr)); @@ -212,7 +219,12 @@ fn has_is_empty(cx: &LateContext, expr: &Expr) -> bool { .associated_items(ty.ty_to_def_id().expect("trait impl not found")) .any(|item| is_is_empty(cx, &item)) }, - ty::TyProjection(_) => ty.ty_to_def_id().map_or(false, |id| has_is_empty_impl(cx, id)), + ty::TyProjection(_) => { + ty.ty_to_def_id().map_or( + false, + |id| has_is_empty_impl(cx, id), + ) + }, ty::TyAdt(id, _) => has_is_empty_impl(cx, id.did), ty::TyArray(..) | ty::TySlice(..) | ty::TyStr => true, _ => false, diff --git a/clippy_lints/src/let_if_seq.rs b/clippy_lints/src/let_if_seq.rs index 93b981a2b4a..ecd18424bd8 100644 --- a/clippy_lints/src/let_if_seq.rs +++ b/clippy_lints/src/let_if_seq.rs @@ -49,7 +49,7 @@ declare_lint! { "unidiomatic `let mut` declaration followed by initialization in `if`" } -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] pub struct LetIfSeq; impl LintPass for LetIfSeq { @@ -154,7 +154,7 @@ impl<'a, 'tcx> hir::intravisit::Visitor<'tcx> for UsedVisitor<'a, 'tcx> { fn check_assign<'a, 'tcx>( cx: &LateContext<'a, 'tcx>, decl: hir::def_id::DefId, - block: &'tcx hir::Block + block: &'tcx hir::Block, ) -> Option<&'tcx hir::Expr> { if_let_chain! {[ block.expr.is_none(), diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs index d29ef8200ec..dd721db0f09 100644 --- a/clippy_lints/src/lifetimes.rs +++ b/clippy_lints/src/lifetimes.rs @@ -48,7 +48,7 @@ declare_lint! { "unused lifetimes in function definitions" } -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] pub struct LifetimePass; impl LintPass for LifetimePass { @@ -94,7 +94,7 @@ fn check_fn_inner<'a, 'tcx>( decl: &'tcx FnDecl, body: Option, generics: &'tcx Generics, - span: Span + span: Span, ) { if in_external_macro(cx, span) || has_where_lifetimes(cx, &generics.where_clause) { return; @@ -104,7 +104,8 @@ fn check_fn_inner<'a, 'tcx>( for typ in &generics.ty_params { for bound in &typ.bounds { if let TraitTyParamBound(ref trait_ref, _) = *bound { - let bounds = trait_ref.trait_ref + let bounds = trait_ref + .trait_ref .path .segments .last() @@ -121,10 +122,12 @@ fn check_fn_inner<'a, 'tcx>( } } if could_use_elision(cx, decl, body, &generics.lifetimes, bounds_lts) { - span_lint(cx, - NEEDLESS_LIFETIMES, - span, - "explicit lifetimes given in parameter types where they could be elided"); + span_lint( + cx, + NEEDLESS_LIFETIMES, + span, + "explicit lifetimes given in parameter types where they could be elided", + ); } report_extra_lifetimes(cx, decl, generics); } @@ -134,7 +137,7 @@ fn could_use_elision<'a, 'tcx: 'a>( func: &'tcx FnDecl, body: Option, named_lts: &'tcx [LifetimeDef], - bounds_lts: Vec<&'tcx Lifetime> + bounds_lts: Vec<&'tcx Lifetime>, ) -> bool { // There are two scenarios where elision works: // * no output references, all input references have different LT @@ -189,7 +192,10 @@ fn could_use_elision<'a, 'tcx: 'a>( // no output lifetimes, check distinctness of input lifetimes // only unnamed and static, ok - if input_lts.iter().all(|lt| *lt == RefLt::Unnamed || *lt == RefLt::Static) { + if input_lts.iter().all(|lt| { + *lt == RefLt::Unnamed || *lt == RefLt::Static + }) + { return false; } // we have no output reference, so we only need all distinct lifetimes @@ -406,7 +412,8 @@ impl<'tcx> Visitor<'tcx> for LifetimeChecker { } fn report_extra_lifetimes<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, func: &'tcx FnDecl, generics: &'tcx Generics) { - let hs = generics.lifetimes + let hs = generics + .lifetimes .iter() .map(|lt| (lt.lifetime.name, lt.lifetime.span)) .collect(); diff --git a/clippy_lints/src/literal_digit_grouping.rs b/clippy_lints/src/literal_digit_grouping.rs index 2b1599d79f3..0da8ffd0a30 100644 --- a/clippy_lints/src/literal_digit_grouping.rs +++ b/clippy_lints/src/literal_digit_grouping.rs @@ -146,7 +146,8 @@ impl<'a> DigitInfo<'a> { let group_size = self.radix.suggest_grouping(); if self.digits.contains('.') { let mut parts = self.digits.split('.'); - let int_part_hint = parts.next() + let int_part_hint = parts + .next() .expect("split always returns at least one element") .chars() .rev() @@ -157,7 +158,8 @@ impl<'a> DigitInfo<'a> { .rev() .collect::>() .join("_"); - let frac_part_hint = parts.next() + let frac_part_hint = parts + .next() .expect("already checked that there is a `.`") .chars() .filter(|&c| c != '_') @@ -194,25 +196,31 @@ impl WarningType { pub fn display(&self, grouping_hint: &str, cx: &EarlyContext, span: &syntax_pos::Span) { match *self { WarningType::UnreadableLiteral => { - span_help_and_lint(cx, - UNREADABLE_LITERAL, - *span, - "long literal lacking separators", - &format!("consider: {}", grouping_hint)) + span_help_and_lint( + cx, + UNREADABLE_LITERAL, + *span, + "long literal lacking separators", + &format!("consider: {}", grouping_hint), + ) }, WarningType::LargeDigitGroups => { - span_help_and_lint(cx, - LARGE_DIGIT_GROUPS, - *span, - "digit groups should be smaller", - &format!("consider: {}", grouping_hint)) + span_help_and_lint( + cx, + LARGE_DIGIT_GROUPS, + *span, + "digit groups should be smaller", + &format!("consider: {}", grouping_hint), + ) }, WarningType::InconsistentDigitGrouping => { - span_help_and_lint(cx, - INCONSISTENT_DIGIT_GROUPING, - *span, - "digits grouped inconsistently by underscores", - &format!("consider: {}", grouping_hint)) + span_help_and_lint( + cx, + INCONSISTENT_DIGIT_GROUPING, + *span, + "digits grouped inconsistently by underscores", + &format!("consider: {}", grouping_hint), + ) }, }; } @@ -309,7 +317,8 @@ impl LiteralDigitGrouping { /// size on success or `WarningType` when emitting a warning. fn do_lint(digits: &str) -> Result { // Grab underscore indices with respect to the units digit. - let underscore_positions: Vec = digits.chars() + let underscore_positions: Vec = digits + .chars() .rev() .enumerate() .filter_map(|(idx, digit)| if digit == '_' { Some(idx) } else { None }) diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs index fc28918ff16..25015cb26bb 100644 --- a/clippy_lints/src/loops.rs +++ b/clippy_lints/src/loops.rs @@ -83,7 +83,8 @@ declare_lint! { /// implements `IntoIterator`, so that possibly one value will be iterated, /// leading to some hard to find bugs. No one will want to write such code /// [except to win an Underhanded Rust -/// Contest](https://www.reddit.com/r/rust/comments/3hb0wm/underhanded_rust_contest/cu5yuhr). +/// Contest](https://www.reddit. +/// com/r/rust/comments/3hb0wm/underhanded_rust_contest/cu5yuhr). /// /// **Known problems:** None. /// @@ -99,7 +100,8 @@ declare_lint! { /// **What it does:** Checks for `for` loops over `Option` values. /// -/// **Why is this bad?** Readability. This is more clearly expressed as an `if let`. +/// **Why is this bad?** Readability. This is more clearly expressed as an `if +/// let`. /// /// **Known problems:** None. /// @@ -120,7 +122,8 @@ declare_lint! { /// **What it does:** Checks for `for` loops over `Result` values. /// -/// **Why is this bad?** Readability. This is more clearly expressed as an `if let`. +/// **Why is this bad?** Readability. This is more clearly expressed as an `if +/// let`. /// /// **Known problems:** None. /// @@ -142,7 +145,8 @@ declare_lint! { /// **What it does:** Detects `loop + match` combinations that are easier /// written as a `while let` loop. /// -/// **Why is this bad?** The `while let` loop is usually shorter and more readable. +/// **Why is this bad?** The `while let` loop is usually shorter and more +/// readable. /// /// **Known problems:** Sometimes the wrong binding is displayed (#383). /// @@ -309,20 +313,22 @@ pub struct Pass; impl LintPass for Pass { fn get_lints(&self) -> LintArray { - lint_array!(NEEDLESS_RANGE_LOOP, - EXPLICIT_ITER_LOOP, - EXPLICIT_INTO_ITER_LOOP, - ITER_NEXT_LOOP, - FOR_LOOP_OVER_RESULT, - FOR_LOOP_OVER_OPTION, - WHILE_LET_LOOP, - UNUSED_COLLECT, - REVERSE_RANGE_LOOP, - EXPLICIT_COUNTER_LOOP, - EMPTY_LOOP, - WHILE_LET_ON_ITERATOR, - FOR_KV_MAP, - NEVER_LOOP) + lint_array!( + NEEDLESS_RANGE_LOOP, + EXPLICIT_ITER_LOOP, + EXPLICIT_INTO_ITER_LOOP, + ITER_NEXT_LOOP, + FOR_LOOP_OVER_RESULT, + FOR_LOOP_OVER_OPTION, + WHILE_LET_LOOP, + UNUSED_COLLECT, + REVERSE_RANGE_LOOP, + EXPLICIT_COUNTER_LOOP, + EMPTY_LOOP, + WHILE_LET_ON_ITERATOR, + FOR_KV_MAP, + NEVER_LOOP + ) } } @@ -349,11 +355,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { if let ExprLoop(ref block, _, LoopSource::Loop) = expr.node { // also check for empty `loop {}` statements if block.stmts.is_empty() && block.expr.is_none() { - span_lint(cx, - EMPTY_LOOP, - expr.span, - "empty `loop {}` detected. You may want to either use `panic!()` or add \ - `std::thread::sleep(..);` to the loop body."); + span_lint( + cx, + EMPTY_LOOP, + expr.span, + "empty `loop {}` detected. You may want to either use `panic!()` or add \ + `std::thread::sleep(..);` to the loop body.", + ); } // extract the expression from the first statement (if any) in a block @@ -366,8 +374,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { MatchSource::Normal | MatchSource::IfLetDesugar { .. } => { if arms.len() == 2 && arms[0].pats.len() == 1 && arms[0].guard.is_none() && - arms[1].pats.len() == 1 && arms[1].guard.is_none() && - is_break_expr(&arms[1].body) { + arms[1].pats.len() == 1 && arms[1].guard.is_none() && + is_break_expr(&arms[1].body) + { if in_external_macro(cx, expr.span) { return; } @@ -377,14 +386,18 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { // 1) it was ugly with big bodies; // 2) it was not indented properly; // 3) it wasn’t very smart (see #675). - span_lint_and_sugg(cx, - WHILE_LET_LOOP, - expr.span, - "this loop could be written as a `while let` loop", - "try", - format!("while let {} = {} {{ .. }}", - snippet(cx, arms[0].pats[0].span, ".."), - snippet(cx, matchexpr.span, ".."))); + span_lint_and_sugg( + cx, + WHILE_LET_LOOP, + expr.span, + "this loop could be written as a `while let` loop", + "try", + format!( + "while let {} = {} {{ .. }}", + snippet(cx, arms[0].pats[0].span, ".."), + snippet(cx, matchexpr.span, "..") + ), + ); } }, _ => (), @@ -395,20 +408,25 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { if let ExprMatch(ref match_expr, ref arms, MatchSource::WhileLetDesugar) = expr.node { let pat = &arms[0].pats[0].node; if let (&PatKind::TupleStruct(ref qpath, ref pat_args, _), - &ExprMethodCall(ref method_path, _, ref method_args)) = (pat, &match_expr.node) { + &ExprMethodCall(ref method_path, _, ref method_args)) = (pat, &match_expr.node) + { let iter_expr = &method_args[0]; let lhs_constructor = last_path_segment(qpath); if method_path.name == "next" && match_trait_method(cx, match_expr, &paths::ITERATOR) && - lhs_constructor.name == "Some" && !is_refutable(cx, &pat_args[0]) && - !is_iterator_used_after_while_let(cx, iter_expr) && !is_nested(cx, expr, &method_args[0]) { + lhs_constructor.name == "Some" && !is_refutable(cx, &pat_args[0]) && + !is_iterator_used_after_while_let(cx, iter_expr) && + !is_nested(cx, expr, &method_args[0]) + { let iterator = snippet(cx, method_args[0].span, "_"); let loop_var = snippet(cx, pat_args[0].span, "_"); - span_lint_and_sugg(cx, - WHILE_LET_ON_ITERATOR, - expr.span, - "this loop could be written as a `for` loop", - "try", - format!("for {} in {} {{ .. }}", loop_var, iterator)); + span_lint_and_sugg( + cx, + WHILE_LET_ON_ITERATOR, + expr.span, + "this loop could be written as a `for` loop", + "try", + format!("for {} in {} {{ .. }}", loop_var, iterator), + ); } } } @@ -418,11 +436,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { if let StmtSemi(ref expr, _) = stmt.node { if let ExprMethodCall(ref method, _, ref args) = expr.node { if args.len() == 1 && method.name == "collect" && match_trait_method(cx, expr, &paths::ITERATOR) { - span_lint(cx, - UNUSED_COLLECT, - expr.span, - "you are collect()ing an iterator and throwing away the result. \ - Consider using an explicit for loop to exhaust the iterator"); + span_lint( + cx, + UNUSED_COLLECT, + expr.span, + "you are collect()ing an iterator and throwing away the result. \ + Consider using an explicit for loop to exhaust the iterator", + ); } } } @@ -435,7 +455,10 @@ fn never_loop(block: &Block, id: &NodeId) -> bool { fn contains_continue_block(block: &Block, dest: &NodeId) -> bool { block.stmts.iter().any(|e| contains_continue_stmt(e, dest)) || - block.expr.as_ref().map_or(false, |e| contains_continue_expr(e, dest)) + block.expr.as_ref().map_or( + false, + |e| contains_continue_expr(e, dest), + ) } fn contains_continue_stmt(stmt: &Stmt, dest: &NodeId) -> bool { @@ -448,7 +471,12 @@ fn contains_continue_stmt(stmt: &Stmt, dest: &NodeId) -> bool { fn contains_continue_decl(decl: &Decl, dest: &NodeId) -> bool { match decl.node { - DeclLocal(ref local) => local.init.as_ref().map_or(false, |e| contains_continue_expr(e, dest)), + DeclLocal(ref local) => { + local.init.as_ref().map_or( + false, + |e| contains_continue_expr(e, dest), + ) + }, _ => false, } } @@ -475,14 +503,21 @@ fn contains_continue_expr(expr: &Expr, dest: &NodeId) -> bool { ExprAssignOp(_, ref e1, ref e2) | ExprIndex(ref e1, ref e2) => [e1, e2].iter().any(|e| contains_continue_expr(e, dest)), ExprIf(ref e, ref e2, ref e3) => { - [e, e2].iter().chain(e3.as_ref().iter()).any(|e| contains_continue_expr(e, dest)) + [e, e2].iter().chain(e3.as_ref().iter()).any(|e| { + contains_continue_expr(e, dest) + }) }, ExprWhile(ref e, ref b, _) => contains_continue_expr(e, dest) || contains_continue_block(b, dest), ExprMatch(ref e, ref arms, _) => { contains_continue_expr(e, dest) || arms.iter().any(|a| contains_continue_expr(&a.body, dest)) }, ExprBlock(ref block) => contains_continue_block(block, dest), - ExprStruct(_, _, ref base) => base.as_ref().map_or(false, |e| contains_continue_expr(e, dest)), + ExprStruct(_, _, ref base) => { + base.as_ref().map_or( + false, + |e| contains_continue_expr(e, dest), + ) + }, ExprAgain(d) => d.target_id.opt_id().map_or(false, |id| id == *dest), _ => false, } @@ -541,7 +576,7 @@ fn check_for_loop<'a, 'tcx>( pat: &'tcx Pat, arg: &'tcx Expr, body: &'tcx Expr, - expr: &'tcx Expr + expr: &'tcx Expr, ) { check_for_loop_range(cx, pat, arg, body, expr); check_for_loop_reverse_range(cx, arg, expr); @@ -557,9 +592,14 @@ fn check_for_loop_range<'a, 'tcx>( pat: &'tcx Pat, arg: &'tcx Expr, body: &'tcx Expr, - expr: &'tcx Expr + expr: &'tcx Expr, ) { - if let Some(higher::Range { start: Some(start), ref end, limits }) = higher::range(arg) { + if let Some(higher::Range { + start: Some(start), + ref end, + limits, + }) = higher::range(arg) + { // the var must be a single name if let PatKind::Binding(_, def_id, ref ident, _) = pat.node { let mut visitor = VarVisitor { @@ -573,10 +613,9 @@ fn check_for_loop_range<'a, 'tcx>( // linting condition: we only indexed one variable if visitor.indexed.len() == 1 { - let (indexed, indexed_extent) = visitor.indexed - .into_iter() - .next() - .expect("already checked that we have exactly 1 element"); + let (indexed, indexed_extent) = visitor.indexed.into_iter().next().expect( + "already checked that we have exactly 1 element", + ); // ensure that the indexed variable was declared before the loop, see #601 if let Some(indexed_extent) = indexed_extent { @@ -589,7 +628,8 @@ fn check_for_loop_range<'a, 'tcx>( } } - // don't lint if the container that is indexed into is also used without indexing + // don't lint if the container that is indexed into is also used without + // indexing if visitor.referenced.contains(&indexed) { return; } @@ -670,7 +710,12 @@ fn is_len_call(expr: &Expr, var: &Name) -> bool { fn check_for_loop_reverse_range(cx: &LateContext, arg: &Expr, expr: &Expr) { // if this for loop is iterating over a two-sided range... - if let Some(higher::Range { start: Some(start), end: Some(end), limits }) = higher::range(arg) { + if let Some(higher::Range { + start: Some(start), + end: Some(end), + limits, + }) = higher::range(arg) + { // ...and both sides are compile-time constant integers... let parent_item = cx.tcx.hir.get_parent(arg.id); let parent_def_id = cx.tcx.hir.local_def_id(parent_item); @@ -714,10 +759,12 @@ fn check_for_loop_reverse_range(cx: &LateContext, arg: &Expr, expr: &Expr) { } else if eq && limits != ast::RangeLimits::Closed { // if they are equal, it's also problematic - this loop // will never run. - span_lint(cx, - REVERSE_RANGE_LOOP, - expr.span, - "this range is empty so this for loop will never run"); + span_lint( + cx, + REVERSE_RANGE_LOOP, + expr.span, + "this range is empty so this for loop will never run", + ); } } } @@ -731,13 +778,15 @@ fn lint_iter_method(cx: &LateContext, args: &[Expr], arg: &Expr, method_name: &s } else { "" }; - span_lint_and_sugg(cx, - EXPLICIT_ITER_LOOP, - arg.span, - "it is more idiomatic to loop over references to containers instead of using explicit \ + span_lint_and_sugg( + cx, + EXPLICIT_ITER_LOOP, + arg.span, + "it is more idiomatic to loop over references to containers instead of using explicit \ iteration methods", - "to write this more concisely, try", - format!("&{}{}", muta, object)) + "to write this more concisely, try", + format!("&{}{}", muta, object), + ) } fn check_for_loop_arg(cx: &LateContext, pat: &Pat, arg: &Expr, expr: &Expr) { @@ -762,20 +811,24 @@ fn check_for_loop_arg(cx: &LateContext, pat: &Pat, arg: &Expr, expr: &Expr) { lint_iter_method(cx, args, arg, method_name); } else { let object = snippet(cx, args[0].span, "_"); - span_lint_and_sugg(cx, - EXPLICIT_INTO_ITER_LOOP, - arg.span, - "it is more idiomatic to loop over containers instead of using explicit \ + span_lint_and_sugg( + cx, + EXPLICIT_INTO_ITER_LOOP, + arg.span, + "it is more idiomatic to loop over containers instead of using explicit \ iteration methods`", - "to write this more concisely, try", - object.to_string()); + "to write this more concisely, try", + object.to_string(), + ); } } else if method_name == "next" && match_trait_method(cx, arg, &paths::ITERATOR) { - span_lint(cx, - ITER_NEXT_LOOP, - expr.span, - "you are iterating over `Iterator::next()` which is an Option; this will compile but is \ - probably not what you want"); + span_lint( + cx, + ITER_NEXT_LOOP, + expr.span, + "you are iterating over `Iterator::next()` which is an Option; this will compile but is \ + probably not what you want", + ); next_loop_linted = true; } } @@ -789,25 +842,37 @@ fn check_for_loop_arg(cx: &LateContext, pat: &Pat, arg: &Expr, expr: &Expr) { fn check_arg_type(cx: &LateContext, pat: &Pat, arg: &Expr) { let ty = cx.tables.expr_ty(arg); if match_type(cx, ty, &paths::OPTION) { - span_help_and_lint(cx, - FOR_LOOP_OVER_OPTION, - arg.span, - &format!("for loop over `{0}`, which is an `Option`. This is more readably written as an \ + span_help_and_lint( + cx, + FOR_LOOP_OVER_OPTION, + arg.span, + &format!( + "for loop over `{0}`, which is an `Option`. This is more readably written as an \ `if let` statement.", - snippet(cx, arg.span, "_")), - &format!("consider replacing `for {0} in {1}` with `if let Some({0}) = {1}`", - snippet(cx, pat.span, "_"), - snippet(cx, arg.span, "_"))); + snippet(cx, arg.span, "_") + ), + &format!( + "consider replacing `for {0} in {1}` with `if let Some({0}) = {1}`", + snippet(cx, pat.span, "_"), + snippet(cx, arg.span, "_") + ), + ); } else if match_type(cx, ty, &paths::RESULT) { - span_help_and_lint(cx, - FOR_LOOP_OVER_RESULT, - arg.span, - &format!("for loop over `{0}`, which is a `Result`. This is more readably written as an \ + span_help_and_lint( + cx, + FOR_LOOP_OVER_RESULT, + arg.span, + &format!( + "for loop over `{0}`, which is a `Result`. This is more readably written as an \ `if let` statement.", - snippet(cx, arg.span, "_")), - &format!("consider replacing `for {0} in {1}` with `if let Ok({0}) = {1}`", - snippet(cx, pat.span, "_"), - snippet(cx, arg.span, "_"))); + snippet(cx, arg.span, "_") + ), + &format!( + "consider replacing `for {0} in {1}` with `if let Ok({0}) = {1}`", + snippet(cx, pat.span, "_"), + snippet(cx, arg.span, "_") + ), + ); } } @@ -815,7 +880,7 @@ fn check_for_loop_explicit_counter<'a, 'tcx>( cx: &LateContext<'a, 'tcx>, arg: &'tcx Expr, body: &'tcx Expr, - expr: &'tcx Expr + expr: &'tcx Expr, ) { // Look for variables that are incremented once per loop iteration. let mut visitor = IncrementVisitor { @@ -829,10 +894,15 @@ fn check_for_loop_explicit_counter<'a, 'tcx>( // For each candidate, check the parent block to see if // it's initialized to zero at the start of the loop. let map = &cx.tcx.hir; - let parent_scope = map.get_enclosing_scope(expr.id).and_then(|id| map.get_enclosing_scope(id)); + let parent_scope = map.get_enclosing_scope(expr.id).and_then(|id| { + map.get_enclosing_scope(id) + }); if let Some(parent_id) = parent_scope { if let NodeBlock(block) = map.get(parent_id) { - for (id, _) in visitor.states.iter().filter(|&(_, v)| *v == VarState::IncrOnce) { + for (id, _) in visitor.states.iter().filter( + |&(_, v)| *v == VarState::IncrOnce, + ) + { let mut visitor2 = InitializeVisitor { cx: cx, end_expr: expr, @@ -846,13 +916,17 @@ fn check_for_loop_explicit_counter<'a, 'tcx>( if visitor2.state == VarState::Warn { if let Some(name) = visitor2.name { - span_lint(cx, - EXPLICIT_COUNTER_LOOP, - expr.span, - &format!("the variable `{0}` is used as a loop counter. Consider using `for ({0}, \ + span_lint( + cx, + EXPLICIT_COUNTER_LOOP, + expr.span, + &format!( + "the variable `{0}` is used as a loop counter. Consider using `for ({0}, \ item) in {1}.enumerate()` or similar iterators", - name, - snippet(cx, arg.span, "_"))); + name, + snippet(cx, arg.span, "_") + ), + ); } } } @@ -866,7 +940,7 @@ fn check_for_loop_over_map_kv<'a, 'tcx>( pat: &'tcx Pat, arg: &'tcx Expr, body: &'tcx Expr, - expr: &'tcx Expr + expr: &'tcx Expr, ) { let pat_span = pat.span; @@ -929,7 +1003,7 @@ fn pat_is_wild<'tcx>(pat: &'tcx PatKind, body: &'tcx Expr) -> bool { fn match_var(expr: &Expr, var: Name) -> bool { if let ExprPath(QPath::Resolved(None, ref path)) = expr.node { if path.segments.len() == 1 && path.segments[0].name == var { - return true + return true; } } false @@ -964,7 +1038,8 @@ struct VarVisitor<'a, 'tcx: 'a> { /// Any names that are used outside an index operation. /// Used to detect things like `&mut vec` used together with `vec[i]` referenced: HashSet, - /// has the loop variable been used in expressions other than the index of an index op? + /// has the loop variable been used in expressions other than the index of + /// an index op? nonindex: bool, } @@ -1095,7 +1170,8 @@ fn is_iterable_array(ty: Ty) -> bool { } } -/// If a block begins with a statement (possibly a `let` binding) and has an expression, return it. +/// If a block begins with a statement (possibly a `let` binding) and has an +/// expression, return it. fn extract_expr_from_first_stmt(block: &Block) -> Option<&Expr> { if block.stmts.is_empty() { return None; @@ -1302,7 +1378,9 @@ fn var_def_id(cx: &LateContext, expr: &Expr) -> Option { if let ExprPath(ref qpath) = expr.node { let path_res = cx.tables.qpath_def(qpath, expr.id); if let Def::Local(def_id) = path_res { - let node_id = cx.tcx.hir.as_local_node_id(def_id).expect("That DefId should be valid"); + let node_id = cx.tcx.hir.as_local_node_id(def_id).expect( + "That DefId should be valid", + ); return Some(node_id); } } @@ -1348,17 +1426,18 @@ fn is_loop_nested(cx: &LateContext, loop_expr: &Expr, iter_expr: &Expr) -> bool match cx.tcx.hir.find(parent) { Some(NodeExpr(expr)) => { match expr.node { - ExprLoop(..) | - ExprWhile(..) => { return true; }, - _ => () + ExprLoop(..) | ExprWhile(..) => { + return true; + }, + _ => (), } }, Some(NodeBlock(block)) => { let mut block_visitor = LoopNestVisitor { - id: id, - iterator: iter_name, - nesting: Unknown - }; + id: id, + iterator: iter_name, + nesting: Unknown, + }; walk_block(&mut block_visitor, block); if block_visitor.nesting == RuledOut { return false; @@ -1367,7 +1446,7 @@ fn is_loop_nested(cx: &LateContext, loop_expr: &Expr, iter_expr: &Expr) -> bool Some(NodeStmt(_)) => (), _ => { return false; - } + }, } id = parent; } @@ -1377,7 +1456,7 @@ fn is_loop_nested(cx: &LateContext, loop_expr: &Expr, iter_expr: &Expr) -> bool enum Nesting { Unknown, // no nesting detected yet RuledOut, // the iterator is initialized or assigned within scope - LookFurther // no nesting detected, no further walk required + LookFurther, // no nesting detected, no further walk required } use self::Nesting::{Unknown, RuledOut, LookFurther}; @@ -1385,7 +1464,7 @@ use self::Nesting::{Unknown, RuledOut, LookFurther}; struct LoopNestVisitor { id: NodeId, iterator: Name, - nesting: Nesting + nesting: Nesting, } impl<'tcx> Visitor<'tcx> for LoopNestVisitor { @@ -1398,22 +1477,28 @@ impl<'tcx> Visitor<'tcx> for LoopNestVisitor { } fn visit_expr(&mut self, expr: &'tcx Expr) { - if self.nesting != Unknown { return; } + if self.nesting != Unknown { + return; + } if expr.id == self.id { self.nesting = LookFurther; return; } match expr.node { ExprAssign(ref path, _) | - ExprAssignOp(_, ref path, _) => if match_var(path, self.iterator) { - self.nesting = RuledOut; + ExprAssignOp(_, ref path, _) => { + if match_var(path, self.iterator) { + self.nesting = RuledOut; + } }, - _ => walk_expr(self, expr) + _ => walk_expr(self, expr), } } fn visit_pat(&mut self, pat: &'tcx Pat) { - if self.nesting != Unknown { return; } + if self.nesting != Unknown { + return; + } if let PatKind::Binding(_, _, span_name, _) = pat.node { if self.iterator == span_name.node { self.nesting = RuledOut; diff --git a/clippy_lints/src/map_clone.rs b/clippy_lints/src/map_clone.rs index 1661c71167e..457c6cc8d65 100644 --- a/clippy_lints/src/map_clone.rs +++ b/clippy_lints/src/map_clone.rs @@ -2,8 +2,8 @@ use rustc::lint::*; use rustc::hir::*; use rustc::ty; use syntax::ast; -use utils::{is_adjusted, match_path, match_trait_method, match_type, remove_blocks, paths, snippet, span_help_and_lint, - walk_ptrs_ty, walk_ptrs_ty_depth, iter_input_pats}; +use utils::{is_adjusted, match_path, match_trait_method, match_type, remove_blocks, paths, snippet, + span_help_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth, iter_input_pats}; /// **What it does:** Checks for mapping `clone()` over an iterator. /// @@ -76,13 +76,17 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { ExprPath(ref path) => { if match_path(path, &paths::CLONE) { let type_name = get_type_name(cx, expr, &args[0]).unwrap_or("_"); - span_help_and_lint(cx, - MAP_CLONE, - expr.span, - &format!("you seem to be using .map() to clone the contents of an \ + span_help_and_lint( + cx, + MAP_CLONE, + expr.span, + &format!( + "you seem to be using .map() to clone the contents of an \ {}, consider using `.cloned()`", - type_name), - &format!("try\n{}.cloned()", snippet(cx, args[0].span, ".."))); + type_name + ), + &format!("try\n{}.cloned()", snippet(cx, args[0].span, "..")), + ); } }, _ => (), @@ -95,10 +99,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { fn expr_eq_name(expr: &Expr, id: ast::Name) -> bool { match expr.node { ExprPath(QPath::Resolved(None, ref path)) => { - let arg_segment = [PathSegment { - name: id, - parameters: PathParameters::none(), - }]; + let arg_segment = [ + PathSegment { + name: id, + parameters: PathParameters::none(), + }, + ]; !path.is_global() && path.segments[..] == arg_segment }, _ => false, diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs index ec06e72749e..5dba102f6a4 100644 --- a/clippy_lints/src/matches.rs +++ b/clippy_lints/src/matches.rs @@ -150,12 +150,14 @@ pub struct MatchPass; impl LintPass for MatchPass { fn get_lints(&self) -> LintArray { - lint_array!(SINGLE_MATCH, - MATCH_REF_PATS, - MATCH_BOOL, - SINGLE_MATCH_ELSE, - MATCH_OVERLAPPING_ARM, - MATCH_WILD_ERR_ARM) + lint_array!( + SINGLE_MATCH, + MATCH_REF_PATS, + MATCH_BOOL, + SINGLE_MATCH_ELSE, + MATCH_OVERLAPPING_ARM, + MATCH_WILD_ERR_ARM + ) } } @@ -212,28 +214,34 @@ fn report_single_match_single_pattern(cx: &LateContext, ex: &Expr, arms: &[Arm], SINGLE_MATCH }; let els_str = els.map_or(String::new(), |els| format!(" else {}", expr_block(cx, els, None, ".."))); - span_lint_and_sugg(cx, - lint, - expr.span, - "you seem to be trying to use match for destructuring a single pattern. Consider using `if \ + span_lint_and_sugg( + cx, + lint, + expr.span, + "you seem to be trying to use match for destructuring a single pattern. Consider using `if \ let`", - "try this", - format!("if let {} = {} {}{}", - snippet(cx, arms[0].pats[0].span, ".."), - snippet(cx, ex.span, ".."), - expr_block(cx, &arms[0].body, None, ".."), - els_str)); + "try this", + format!( + "if let {} = {} {}{}", + snippet(cx, arms[0].pats[0].span, ".."), + snippet(cx, ex.span, ".."), + expr_block(cx, &arms[0].body, None, ".."), + els_str + ), + ); } fn check_single_match_opt_like(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr, ty: Ty, els: Option<&Expr>) { // list of candidate Enums we know will never get any more members - let candidates = &[(&paths::COW, "Borrowed"), - (&paths::COW, "Cow::Borrowed"), - (&paths::COW, "Cow::Owned"), - (&paths::COW, "Owned"), - (&paths::OPTION, "None"), - (&paths::RESULT, "Err"), - (&paths::RESULT, "Ok")]; + let candidates = &[ + (&paths::COW, "Borrowed"), + (&paths::COW, "Cow::Borrowed"), + (&paths::COW, "Cow::Owned"), + (&paths::COW, "Owned"), + (&paths::OPTION, "None"), + (&paths::RESULT, "Err"), + (&paths::RESULT, "Ok"), + ]; let path = match arms[1].pats[0].node { PatKind::TupleStruct(ref path, ref inner, _) => { @@ -258,52 +266,60 @@ fn check_single_match_opt_like(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: fn check_match_bool(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr) { // type of expression == bool if cx.tables.expr_ty(ex).sty == ty::TyBool { - span_lint_and_then(cx, - MATCH_BOOL, - expr.span, - "you seem to be trying to match on a boolean expression", - move |db| { - if arms.len() == 2 && arms[0].pats.len() == 1 { - // no guards - let exprs = if let PatKind::Lit(ref arm_bool) = arms[0].pats[0].node { - if let ExprLit(ref lit) = arm_bool.node { - match lit.node { - LitKind::Bool(true) => Some((&*arms[0].body, &*arms[1].body)), - LitKind::Bool(false) => Some((&*arms[1].body, &*arms[0].body)), - _ => None, + span_lint_and_then( + cx, + MATCH_BOOL, + expr.span, + "you seem to be trying to match on a boolean expression", + move |db| { + if arms.len() == 2 && arms[0].pats.len() == 1 { + // no guards + let exprs = if let PatKind::Lit(ref arm_bool) = arms[0].pats[0].node { + if let ExprLit(ref lit) = arm_bool.node { + match lit.node { + LitKind::Bool(true) => Some((&*arms[0].body, &*arms[1].body)), + LitKind::Bool(false) => Some((&*arms[1].body, &*arms[0].body)), + _ => None, + } + } else { + None } } else { None - } - } else { - None - }; - - if let Some((true_expr, false_expr)) = exprs { - let sugg = match (is_unit_expr(true_expr), is_unit_expr(false_expr)) { - (false, false) => { - Some(format!("if {} {} else {}", - snippet(cx, ex.span, "b"), - expr_block(cx, true_expr, None, ".."), - expr_block(cx, false_expr, None, ".."))) - }, - (false, true) => { - Some(format!("if {} {}", snippet(cx, ex.span, "b"), expr_block(cx, true_expr, None, ".."))) - }, - (true, false) => { - let test = Sugg::hir(cx, ex, ".."); - Some(format!("if {} {}", !test, expr_block(cx, false_expr, None, ".."))) - }, - (true, true) => None, }; - if let Some(sugg) = sugg { - db.span_suggestion(expr.span, "consider using an if/else expression", sugg); + if let Some((true_expr, false_expr)) = exprs { + let sugg = match (is_unit_expr(true_expr), is_unit_expr(false_expr)) { + (false, false) => { + Some(format!( + "if {} {} else {}", + snippet(cx, ex.span, "b"), + expr_block(cx, true_expr, None, ".."), + expr_block(cx, false_expr, None, "..") + )) + }, + (false, true) => { + Some(format!( + "if {} {}", + snippet(cx, ex.span, "b"), + expr_block(cx, true_expr, None, "..") + )) + }, + (true, false) => { + let test = Sugg::hir(cx, ex, ".."); + Some(format!("if {} {}", !test, expr_block(cx, false_expr, None, ".."))) + }, + (true, true) => None, + }; + + if let Some(sugg) = sugg { + db.span_suggestion(expr.span, "consider using an if/else expression", sugg); + } } } - } - }); + }, + ); } } @@ -313,12 +329,14 @@ fn check_overlapping_arms(cx: &LateContext, ex: &Expr, arms: &[Arm]) { let type_ranges = type_ranges(&ranges); if !type_ranges.is_empty() { if let Some((start, end)) = overlapping(&type_ranges) { - span_note_and_lint(cx, - MATCH_OVERLAPPING_ARM, - start.span, - "some ranges overlap", - end.span, - "overlaps with this"); + span_note_and_lint( + cx, + MATCH_OVERLAPPING_ARM, + start.span, + "some ranges overlap", + end.span, + "overlaps with this", + ); } } } @@ -376,17 +394,21 @@ fn check_match_ref_pats(cx: &LateContext, ex: &Expr, arms: &[Arm], source: Match db.span_suggestion(expr.span, "try", template); }); } else { - span_lint_and_then(cx, - MATCH_REF_PATS, - expr.span, - "you don't need to add `&` to all patterns", - |db| { - let ex = Sugg::hir(cx, ex, ".."); - let template = match_template(expr.span, source, &ex.deref()); - db.span_suggestion(expr.span, - "instead of prefixing all patterns with `&`, you can dereference the expression", - template); - }); + span_lint_and_then( + cx, + MATCH_REF_PATS, + expr.span, + "you don't need to add `&` to all patterns", + |db| { + let ex = Sugg::hir(cx, ex, ".."); + let template = match_template(expr.span, source, &ex.deref()); + db.span_suggestion( + expr.span, + "instead of prefixing all patterns with `&`, you can dereference the expression", + template, + ); + }, + ); } } } @@ -399,13 +421,17 @@ fn all_ranges<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, arms: &[Arm], id: NodeId) -> let constcx = ConstContext::new(cx.tcx, cx.param_env.and(substs), cx.tables); arms.iter() .flat_map(|arm| { - if let Arm { ref pats, guard: None, .. } = *arm { - pats.iter() - } else { - [].iter() - } - .filter_map(|pat| { - if_let_chain! {[ + if let Arm { + ref pats, + guard: None, + .. + } = *arm + { + pats.iter() + } else { + [].iter() + }.filter_map(|pat| { + if_let_chain! {[ let PatKind::Range(ref lhs, ref rhs, ref range_end) = pat.node, let Ok(lhs) = constcx.eval(lhs), let Ok(rhs) = constcx.eval(rhs) @@ -417,15 +443,15 @@ fn all_ranges<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, arms: &[Arm], id: NodeId) -> return Some(SpannedRange { span: pat.span, node: (lhs, rhs) }); }} - if_let_chain! {[ + if_let_chain! {[ let PatKind::Lit(ref value) = pat.node, let Ok(value) = constcx.eval(value) ], { return Some(SpannedRange { span: pat.span, node: (value.clone(), Bound::Included(value)) }); }} - None - }) + None + }) }) .collect() } @@ -438,10 +464,12 @@ pub struct SpannedRange { type TypedRanges = Vec>; -/// Get all `Int` ranges or all `Uint` ranges. Mixed types are an error anyway and other types than +/// Get all `Int` ranges or all `Uint` ranges. Mixed types are an error anyway +/// and other types than /// `Uint` and `Int` probably don't make sense. fn type_ranges(ranges: &[SpannedRange]) -> TypedRanges { - ranges.iter() + ranges + .iter() .filter_map(|range| match range.node { (ConstVal::Integral(start), Bound::Included(ConstVal::Integral(end))) => { Some(SpannedRange { @@ -500,7 +528,8 @@ fn match_template(span: Span, source: MatchSource, expr: &Sugg) -> String { } pub fn overlapping(ranges: &[SpannedRange]) -> Option<(&SpannedRange, &SpannedRange)> - where T: Copy + Ord +where + T: Copy + Ord, { #[derive(Copy, Clone, Debug, Eq, PartialEq)] enum Kind<'a, T: 'a> { diff --git a/clippy_lints/src/mem_forget.rs b/clippy_lints/src/mem_forget.rs index b43a2473f0d..280b51b2312 100644 --- a/clippy_lints/src/mem_forget.rs +++ b/clippy_lints/src/mem_forget.rs @@ -2,7 +2,8 @@ use rustc::lint::*; use rustc::hir::{Expr, ExprCall, ExprPath}; use utils::{match_def_path, paths, span_lint}; -/// **What it does:** Checks for usage of `std::mem::forget(t)` where `t` is `Drop`. +/// **What it does:** Checks for usage of `std::mem::forget(t)` where `t` is +/// `Drop`. /// /// **Why is this bad?** `std::mem::forget(t)` prevents `t` from running its /// destructor, possibly causing leaks. @@ -38,7 +39,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MemForget { if match forgot_ty.ty_adt_def() { Some(def) => def.has_dtor(cx.tcx), _ => false, - } { + } + { span_lint(cx, MEM_FORGET, e.span, "usage of mem::forget on Drop type"); } } diff --git a/clippy_lints/src/methods.rs b/clippy_lints/src/methods.rs index 1c6f7dd214e..c04fdde772f 100644 --- a/clippy_lints/src/methods.rs +++ b/clippy_lints/src/methods.rs @@ -65,7 +65,8 @@ declare_lint! { /// information) instead of an inherent implementation. /// /// **Why is this bad?** Implementing the traits improve ergonomics for users of -/// the code, often with very little cost. Also people seeing a `mul(...)` method +/// the code, often with very little cost. Also people seeing a `mul(...)` +/// method /// may expect `*` to work equally, so you should have good reason to disappoint /// them. /// @@ -368,7 +369,8 @@ declare_lint! { `_.split(\"x\")`" } -/// **What it does:** Checks for getting the inner pointer of a temporary `CString`. +/// **What it does:** Checks for getting the inner pointer of a temporary +/// `CString`. /// /// **Why is this bad?** The inner pointer of a `CString` is only valid as long /// as the `CString` is alive. @@ -500,7 +502,8 @@ declare_lint! { "using `x.extend(s.chars())` where s is a `&str` or `String`" } -/// **What it does:** Checks for the use of `.cloned().collect()` on slice to create a `Vec`. +/// **What it does:** Checks for the use of `.cloned().collect()` on slice to +/// create a `Vec`. /// /// **Why is this bad?** `.to_vec()` is clearer /// @@ -524,29 +527,31 @@ declare_lint! { impl LintPass for Pass { fn get_lints(&self) -> LintArray { - lint_array!(OPTION_UNWRAP_USED, - RESULT_UNWRAP_USED, - SHOULD_IMPLEMENT_TRAIT, - WRONG_SELF_CONVENTION, - WRONG_PUB_SELF_CONVENTION, - OK_EXPECT, - OPTION_MAP_UNWRAP_OR, - OPTION_MAP_UNWRAP_OR_ELSE, - OR_FUN_CALL, - CHARS_NEXT_CMP, - CLONE_ON_COPY, - CLONE_DOUBLE_REF, - NEW_RET_NO_SELF, - SINGLE_CHAR_PATTERN, - SEARCH_IS_SOME, - TEMPORARY_CSTRING_AS_PTR, - FILTER_NEXT, - FILTER_MAP, - ITER_NTH, - ITER_SKIP_NEXT, - GET_UNWRAP, - STRING_EXTEND_CHARS, - ITER_CLONED_COLLECT) + lint_array!( + OPTION_UNWRAP_USED, + RESULT_UNWRAP_USED, + SHOULD_IMPLEMENT_TRAIT, + WRONG_SELF_CONVENTION, + WRONG_PUB_SELF_CONVENTION, + OK_EXPECT, + OPTION_MAP_UNWRAP_OR, + OPTION_MAP_UNWRAP_OR_ELSE, + OR_FUN_CALL, + CHARS_NEXT_CMP, + CLONE_ON_COPY, + CLONE_DOUBLE_REF, + NEW_RET_NO_SELF, + SINGLE_CHAR_PATTERN, + SEARCH_IS_SOME, + TEMPORARY_CSTRING_AS_PTR, + FILTER_NEXT, + FILTER_MAP, + ITER_NTH, + ITER_SKIP_NEXT, + GET_UNWRAP, + STRING_EXTEND_CHARS, + ITER_CLONED_COLLECT + ) } } @@ -706,7 +711,7 @@ fn lint_or_fun_call(cx: &LateContext, expr: &hir::Expr, name: &str, args: &[hir: self_expr: &hir::Expr, arg: &hir::Expr, or_has_args: bool, - span: Span + span: Span, ) -> bool { if or_has_args { return false; @@ -718,20 +723,22 @@ fn lint_or_fun_call(cx: &LateContext, expr: &hir::Expr, name: &str, args: &[hir: if ["default", "new"].contains(&path) { let arg_ty = cx.tables.expr_ty(arg); - let default_trait_id = if let Some(default_trait_id) = - get_trait_def_id(cx, &paths::DEFAULT_TRAIT) { - default_trait_id - } else { - return false; - }; + let default_trait_id = + if let Some(default_trait_id) = get_trait_def_id(cx, &paths::DEFAULT_TRAIT) { + default_trait_id + } else { + return false; + }; if implements_trait(cx, arg_ty, default_trait_id, &[]) { - span_lint_and_sugg(cx, - OR_FUN_CALL, - span, - &format!("use of `{}` followed by a call to `{}`", name, path), - "try this", - format!("{}.unwrap_or_default()", snippet(cx, self_expr.span, "_"))); + span_lint_and_sugg( + cx, + OR_FUN_CALL, + span, + &format!("use of `{}` followed by a call to `{}`", name, path), + "try this", + format!("{}.unwrap_or_default()", snippet(cx, self_expr.span, "_")), + ); return true; } } @@ -749,7 +756,7 @@ fn lint_or_fun_call(cx: &LateContext, expr: &hir::Expr, name: &str, args: &[hir: self_expr: &hir::Expr, arg: &hir::Expr, or_has_args: bool, - span: Span + span: Span, ) { // don't lint for constant values // FIXME: can we `expect` here instead of match? @@ -765,15 +772,18 @@ fn lint_or_fun_call(cx: &LateContext, expr: &hir::Expr, name: &str, args: &[hir: // (path, fn_has_argument, methods, suffix) let know_types: &[(&[_], _, &[_], _)] = - &[(&paths::BTREEMAP_ENTRY, false, &["or_insert"], "with"), - (&paths::HASHMAP_ENTRY, false, &["or_insert"], "with"), - (&paths::OPTION, false, &["map_or", "ok_or", "or", "unwrap_or"], "else"), - (&paths::RESULT, true, &["or", "unwrap_or"], "else")]; + &[ + (&paths::BTREEMAP_ENTRY, false, &["or_insert"], "with"), + (&paths::HASHMAP_ENTRY, false, &["or_insert"], "with"), + (&paths::OPTION, false, &["map_or", "ok_or", "or", "unwrap_or"], "else"), + (&paths::RESULT, true, &["or", "unwrap_or"], "else"), + ]; let self_ty = cx.tables.expr_ty(self_expr); let (fn_has_arguments, poss, suffix) = if let Some(&(_, fn_has_arguments, poss, suffix)) = - know_types.iter().find(|&&i| match_type(cx, self_ty, i.0)) { + know_types.iter().find(|&&i| match_type(cx, self_ty, i.0)) + { (fn_has_arguments, poss, suffix) } else { return; @@ -789,12 +799,14 @@ fn lint_or_fun_call(cx: &LateContext, expr: &hir::Expr, name: &str, args: &[hir: (false, true) => snippet(cx, fun_span, ".."), }; - span_lint_and_sugg(cx, - OR_FUN_CALL, - span, - &format!("use of `{}` followed by a function call", name), - "try this", - format!("{}.{}_{}({})", snippet(cx, self_expr.span, "_"), name, suffix, sugg)); + span_lint_and_sugg( + cx, + OR_FUN_CALL, + span, + &format!("use of `{}` followed by a function call", name), + "try this", + format!("{}.{}_{}({})", snippet(cx, self_expr.span, "_"), name, suffix, sugg), + ); } if args.len() == 2 { @@ -818,32 +830,30 @@ fn lint_clone_on_copy(cx: &LateContext, expr: &hir::Expr, arg: &hir::Expr, arg_t let ty = cx.tables.expr_ty(expr); if let ty::TyRef(_, ty::TypeAndMut { ty: inner, .. }) = arg_ty.sty { if let ty::TyRef(..) = inner.sty { - span_lint_and_then(cx, - CLONE_DOUBLE_REF, - expr.span, - "using `clone` on a double-reference; \ + span_lint_and_then( + cx, + CLONE_DOUBLE_REF, + expr.span, + "using `clone` on a double-reference; \ this will copy the reference instead of cloning the inner type", - |db| if let Some(snip) = sugg::Sugg::hir_opt(cx, arg) { - db.span_suggestion(expr.span, - "try dereferencing it", - format!("({}).clone()", snip.deref())); - }); + |db| if let Some(snip) = sugg::Sugg::hir_opt(cx, arg) { + db.span_suggestion(expr.span, "try dereferencing it", format!("({}).clone()", snip.deref())); + }, + ); return; // don't report clone_on_copy } } if is_copy(cx, ty) { - span_lint_and_then(cx, - CLONE_ON_COPY, - expr.span, - "using `clone` on a `Copy` type", - |db| if let Some(snip) = sugg::Sugg::hir_opt(cx, arg) { - if let ty::TyRef(..) = cx.tables.expr_ty(arg).sty { - db.span_suggestion(expr.span, "try dereferencing it", format!("{}", snip.deref())); - } else { - db.span_suggestion(expr.span, "try removing the `clone` call", format!("{}", snip)); - } - }); + span_lint_and_then(cx, CLONE_ON_COPY, expr.span, "using `clone` on a `Copy` type", |db| { + if let Some(snip) = sugg::Sugg::hir_opt(cx, arg) { + if let ty::TyRef(..) = cx.tables.expr_ty(arg).sty { + db.span_suggestion(expr.span, "try dereferencing it", format!("{}", snip.deref())); + } else { + db.span_suggestion(expr.span, "try removing the `clone` call", format!("{}", snip)); + } + } + }); } } @@ -860,15 +870,19 @@ fn lint_string_extend(cx: &LateContext, expr: &hir::Expr, args: &[hir::Expr]) { return; }; - span_lint_and_sugg(cx, - STRING_EXTEND_CHARS, - expr.span, - "calling `.extend(_.chars())`", - "try this", - format!("{}.push_str({}{})", - snippet(cx, args[0].span, "_"), - ref_str, - snippet(cx, target.span, "_"))); + span_lint_and_sugg( + cx, + STRING_EXTEND_CHARS, + expr.span, + "calling `.extend(_.chars())`", + "try this", + format!( + "{}.push_str({}{})", + snippet(cx, args[0].span, "_"), + ref_str, + snippet(cx, target.span, "_") + ), + ); } } @@ -898,12 +912,15 @@ fn lint_cstring_as_ptr(cx: &LateContext, expr: &hir::Expr, new: &hir::Expr, unwr fn lint_iter_cloned_collect(cx: &LateContext, expr: &hir::Expr, iter_args: &[hir::Expr]) { if match_type(cx, cx.tables.expr_ty(expr), &paths::VEC) && - derefs_to_slice(cx, &iter_args[0], cx.tables.expr_ty(&iter_args[0])).is_some() { - span_lint(cx, - ITER_CLONED_COLLECT, - expr.span, - "called `cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and \ - more readable"); + derefs_to_slice(cx, &iter_args[0], cx.tables.expr_ty(&iter_args[0])).is_some() + { + span_lint( + cx, + ITER_CLONED_COLLECT, + expr.span, + "called `cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and \ + more readable", + ); } } @@ -919,12 +936,16 @@ fn lint_iter_nth(cx: &LateContext, expr: &hir::Expr, iter_args: &[hir::Expr], is return; // caller is not a type that we want to lint }; - span_lint(cx, - ITER_NTH, - expr.span, - &format!("called `.iter{0}().nth()` on a {1}. Calling `.get{0}()` is both faster and more readable", - mut_str, - caller_type)); + span_lint( + cx, + ITER_NTH, + expr.span, + &format!( + "called `.iter{0}().nth()` on a {1}. Calling `.get{0}()` is both faster and more readable", + mut_str, + caller_type + ), + ); } fn lint_get_unwrap(cx: &LateContext, expr: &hir::Expr, get_args: &[hir::Expr], is_mut: bool) { @@ -947,26 +968,34 @@ fn lint_get_unwrap(cx: &LateContext, expr: &hir::Expr, get_args: &[hir::Expr], i let mut_str = if is_mut { "_mut" } else { "" }; let borrow_str = if is_mut { "&mut " } else { "&" }; - span_lint_and_sugg(cx, - GET_UNWRAP, - expr.span, - &format!("called `.get{0}().unwrap()` on a {1}. Using `[]` is more clear and more concise", - mut_str, - caller_type), - "try this", - format!("{}{}[{}]", - borrow_str, - snippet(cx, get_args[0].span, "_"), - snippet(cx, get_args[1].span, "_"))); + span_lint_and_sugg( + cx, + GET_UNWRAP, + expr.span, + &format!( + "called `.get{0}().unwrap()` on a {1}. Using `[]` is more clear and more concise", + mut_str, + caller_type + ), + "try this", + format!( + "{}{}[{}]", + borrow_str, + snippet(cx, get_args[0].span, "_"), + snippet(cx, get_args[1].span, "_") + ), + ); } fn lint_iter_skip_next(cx: &LateContext, expr: &hir::Expr) { // lint if caller of skip is an Iterator if match_trait_method(cx, expr, &paths::ITERATOR) { - span_lint(cx, - ITER_SKIP_NEXT, - expr.span, - "called `skip(x).next()` on an iterator. This is more succinctly expressed by calling `nth(x)`"); + span_lint( + cx, + ITER_SKIP_NEXT, + expr.span, + "called `skip(x).next()` on an iterator. This is more succinctly expressed by calling `nth(x)`", + ); } } @@ -1017,14 +1046,18 @@ fn lint_unwrap(cx: &LateContext, expr: &hir::Expr, unwrap_args: &[hir::Expr]) { }; if let Some((lint, kind, none_value)) = mess { - span_lint(cx, - lint, - expr.span, - &format!("used unwrap() on {} value. If you don't want to handle the {} case gracefully, consider \ + span_lint( + cx, + lint, + expr.span, + &format!( + "used unwrap() on {} value. If you don't want to handle the {} case gracefully, consider \ using expect() to provide a better panic \ message", - kind, - none_value)); + kind, + none_value + ), + ); } } @@ -1035,10 +1068,12 @@ fn lint_ok_expect(cx: &LateContext, expr: &hir::Expr, ok_args: &[hir::Expr]) { let result_type = cx.tables.expr_ty(&ok_args[0]); if let Some(error_type) = get_error_type(cx, result_type) { if has_debug_impl(error_type, cx) { - span_lint(cx, - OK_EXPECT, - expr.span, - "called `ok().expect()` on a Result value. You can call `expect` directly on the `Result`"); + span_lint( + cx, + OK_EXPECT, + expr.span, + "called `ok().expect()` on a Result value. You can call `expect` directly on the `Result`", + ); } } } @@ -1059,14 +1094,18 @@ fn lint_map_unwrap_or(cx: &LateContext, expr: &hir::Expr, map_args: &[hir::Expr] let multiline = map_snippet.lines().count() > 1 || unwrap_snippet.lines().count() > 1; let same_span = map_args[1].span.ctxt == unwrap_args[1].span.ctxt; if same_span && !multiline { - span_note_and_lint(cx, - OPTION_MAP_UNWRAP_OR, - expr.span, - msg, - expr.span, - &format!("replace `map({0}).unwrap_or({1})` with `map_or({1}, {0})`", - map_snippet, - unwrap_snippet)); + span_note_and_lint( + cx, + OPTION_MAP_UNWRAP_OR, + expr.span, + msg, + expr.span, + &format!( + "replace `map({0}).unwrap_or({1})` with `map_or({1}, {0})`", + map_snippet, + unwrap_snippet + ), + ); } else if same_span && multiline { span_lint(cx, OPTION_MAP_UNWRAP_OR, expr.span, msg); }; @@ -1088,14 +1127,18 @@ fn lint_map_unwrap_or_else(cx: &LateContext, expr: &hir::Expr, map_args: &[hir:: let multiline = map_snippet.lines().count() > 1 || unwrap_snippet.lines().count() > 1; let same_span = map_args[1].span.ctxt == unwrap_args[1].span.ctxt; if same_span && !multiline { - span_note_and_lint(cx, - OPTION_MAP_UNWRAP_OR_ELSE, - expr.span, - msg, - expr.span, - &format!("replace `map({0}).unwrap_or_else({1})` with `map_or_else({1}, {0})`", - map_snippet, - unwrap_snippet)); + span_note_and_lint( + cx, + OPTION_MAP_UNWRAP_OR_ELSE, + expr.span, + msg, + expr.span, + &format!( + "replace `map({0}).unwrap_or_else({1})` with `map_or_else({1}, {0})`", + map_snippet, + unwrap_snippet + ), + ); } else if same_span && multiline { span_lint(cx, OPTION_MAP_UNWRAP_OR_ELSE, expr.span, msg); }; @@ -1111,12 +1154,14 @@ fn lint_filter_next(cx: &LateContext, expr: &hir::Expr, filter_args: &[hir::Expr let filter_snippet = snippet(cx, filter_args[1].span, ".."); if filter_snippet.lines().count() <= 1 { // add note if not multi-line - span_note_and_lint(cx, - FILTER_NEXT, - expr.span, - msg, - expr.span, - &format!("replace `filter({0}).next()` with `find({0})`", filter_snippet)); + span_note_and_lint( + cx, + FILTER_NEXT, + expr.span, + msg, + expr.span, + &format!("replace `filter({0}).next()` with `find({0})`", filter_snippet), + ); } else { span_lint(cx, FILTER_NEXT, expr.span, msg); } @@ -1171,22 +1216,26 @@ fn lint_search_is_some( expr: &hir::Expr, search_method: &str, search_args: &[hir::Expr], - is_some_args: &[hir::Expr] + is_some_args: &[hir::Expr], ) { // lint if caller of search is an Iterator if match_trait_method(cx, &is_some_args[0], &paths::ITERATOR) { - let msg = format!("called `is_some()` after searching an `Iterator` with {}. This is more succinctly \ + let msg = format!( + "called `is_some()` after searching an `Iterator` with {}. This is more succinctly \ expressed by calling `any()`.", - search_method); + search_method + ); let search_snippet = snippet(cx, search_args[1].span, ".."); if search_snippet.lines().count() <= 1 { // add note if not multi-line - span_note_and_lint(cx, - SEARCH_IS_SOME, - expr.span, - &msg, - expr.span, - &format!("replace `{0}({1}).is_some()` with `any({1})`", search_method, search_snippet)); + span_note_and_lint( + cx, + SEARCH_IS_SOME, + expr.span, + &msg, + expr.span, + &format!("replace `{0}({1}).is_some()` with `any({1})`", search_method, search_snippet), + ); } else { span_lint(cx, SEARCH_IS_SOME, expr.span, &msg); } @@ -1233,11 +1282,13 @@ fn lint_single_char_pattern(cx: &LateContext, expr: &hir::Expr, arg: &hir::Expr) if let Ok(ConstVal::Str(r)) = ConstContext::new(cx.tcx, cx.param_env.and(substs), cx.tables).eval(arg) { if r.len() == 1 { let hint = snippet(cx, expr.span, "..").replace(&format!("\"{}\"", r), &format!("'{}'", r)); - span_lint_and_then(cx, - SINGLE_CHAR_PATTERN, - arg.span, - "single-character string constant used as pattern", - |db| { db.span_suggestion(expr.span, "try using a char instead", hint); }); + span_lint_and_then( + cx, + SINGLE_CHAR_PATTERN, + arg.span, + "single-character string constant used as pattern", + |db| { db.span_suggestion(expr.span, "try using a char instead", hint); }, + ); } } } @@ -1349,13 +1400,17 @@ impl SelfKind { arg: &hir::Arg, self_ty: &hir::Ty, allow_value_for_ref: bool, - generics: &hir::Generics + generics: &hir::Generics, ) -> bool { - // Self types in the HIR are desugared to explicit self types. So it will always be `self: + // Self types in the HIR are desugared to explicit self types. So it will + // always be `self: // SomeType`, - // where SomeType can be `Self` or an explicit impl self type (e.g. `Foo` if the impl is on `Foo`) - // Thus, we only need to test equality against the impl self type or if it is an explicit - // `Self`. Furthermore, the only possible types for `self: ` are `&Self`, `Self`, `&mut Self`, + // where SomeType can be `Self` or an explicit impl self type (e.g. `Foo` if + // the impl is on `Foo`) + // Thus, we only need to test equality against the impl self type or if it is + // an explicit + // `Self`. Furthermore, the only possible types for `self: ` are `&Self`, + // `Self`, `&mut Self`, // and `Box`, including the equivalent types with `Foo`. let is_actually_self = |ty| is_self_ty(ty) || ty == self_ty; @@ -1404,18 +1459,22 @@ fn is_as_ref_or_mut_trait(ty: &hir::Ty, self_ty: &hir::Ty, generics: &hir::Gener single_segment_ty(ty).map_or(false, |seg| { generics.ty_params.iter().any(|param| { param.name == seg.name && - param.bounds.iter().any(|bound| if let hir::TyParamBound::TraitTyParamBound(ref ptr, ..) = *bound { - let path = &ptr.trait_ref.path; - match_path_old(path, name) && - path.segments.last().map_or(false, |s| if let hir::PathParameters::AngleBracketedParameters(ref data) = - s.parameters { - data.types.len() == 1 && (is_self_ty(&data.types[0]) || is_ty(&*data.types[0], self_ty)) - } else { - false + param.bounds.iter().any(|bound| { + if let hir::TyParamBound::TraitTyParamBound(ref ptr, ..) = *bound { + let path = &ptr.trait_ref.path; + match_path_old(path, name) && + path.segments.last().map_or(false, |s| { + if let hir::PathParameters::AngleBracketedParameters(ref data) = s.parameters { + data.types.len() == 1 && + (is_self_ty(&data.types[0]) || is_ty(&*data.types[0], self_ty)) + } else { + false + } + }) + } else { + false + } }) - } else { - false - }) }) }) } @@ -1424,7 +1483,9 @@ fn is_ty(ty: &hir::Ty, self_ty: &hir::Ty) -> bool { match (&ty.node, &self_ty.node) { (&hir::TyPath(hir::QPath::Resolved(_, ref ty_path)), &hir::TyPath(hir::QPath::Resolved(_, ref self_ty_path))) => { - ty_path.segments.iter().map(|seg| seg.name).eq(self_ty_path.segments.iter().map(|seg| seg.name)) + ty_path.segments.iter().map(|seg| seg.name).eq( + self_ty_path.segments.iter().map(|seg| seg.name), + ) }, _ => false, } diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs index 70f25e7dff0..67b0b1e167d 100644 --- a/clippy_lints/src/misc.rs +++ b/clippy_lints/src/misc.rs @@ -14,7 +14,8 @@ use utils::{get_item_name, get_parent_expr, implements_trait, in_macro, is_integ use utils::sugg::Sugg; use syntax::ast::{LitKind, CRATE_NODE_ID, FloatTy}; -/// **What it does:** Checks for function arguments and let bindings denoted as `ref`. +/// **What it does:** Checks for function arguments and let bindings denoted as +/// `ref`. /// /// **Why is this bad?** The `ref` declaration makes the function take an owned /// value, but turns the argument into a reference (which means that the value @@ -118,7 +119,8 @@ declare_lint! { /// **What it does:** Checks for patterns in the form `name @ _`. /// -/// **Why is this bad?** It's almost always more readable to just use direct bindings. +/// **Why is this bad?** It's almost always more readable to just use direct +/// bindings. /// /// **Known problems:** None. /// @@ -135,7 +137,8 @@ declare_lint! { "using `name @ _` in a pattern" } -/// **What it does:** Checks for the use of bindings with a single leading underscore. +/// **What it does:** Checks for the use of bindings with a single leading +/// underscore. /// /// **Why is this bad?** A single leading underscore is usually used to indicate /// that a binding will not be used. Using such a binding breaks this @@ -147,7 +150,8 @@ declare_lint! { /// **Example:** /// ```rust /// let _x = 0; -/// let y = _x + 1; // Here we are using `_x`, even though it has a leading underscore. +/// let y = _x + 1; // Here we are using `_x`, even though it has a leading +/// underscore. /// // We should rename `_x` to `x` /// ``` declare_lint! { @@ -156,11 +160,14 @@ declare_lint! { "using a binding which is prefixed with an underscore" } -/// **What it does:** Checks for the use of short circuit boolean conditions as a +/// **What it does:** Checks for the use of short circuit boolean conditions as +/// a /// statement. /// -/// **Why is this bad?** Using a short circuit boolean condition as a statement may -/// hide the fact that the second part is executed or not depending on the outcome of +/// **Why is this bad?** Using a short circuit boolean condition as a statement +/// may +/// hide the fact that the second part is executed or not depending on the +/// outcome of /// the first part. /// /// **Known problems:** None. @@ -198,15 +205,17 @@ pub struct Pass; impl LintPass for Pass { fn get_lints(&self) -> LintArray { - lint_array!(TOPLEVEL_REF_ARG, - CMP_NAN, - FLOAT_CMP, - CMP_OWNED, - MODULO_ONE, - REDUNDANT_PATTERN, - USED_UNDERSCORE_BINDING, - SHORT_CIRCUIT_STATEMENT, - ZERO_PTR) + lint_array!( + TOPLEVEL_REF_ARG, + CMP_NAN, + FLOAT_CMP, + CMP_OWNED, + MODULO_ONE, + REDUNDANT_PATTERN, + USED_UNDERSCORE_BINDING, + SHORT_CIRCUIT_STATEMENT, + ZERO_PTR + ) } } @@ -218,7 +227,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { decl: &'tcx FnDecl, body: &'tcx Body, _: Span, - _: NodeId + _: NodeId, ) { if let FnKind::Closure(_) = k { // Does not apply to closures @@ -228,11 +237,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { match arg.pat.node { PatKind::Binding(BindingAnnotation::Ref, _, _, _) | PatKind::Binding(BindingAnnotation::RefMut, _, _, _) => { - span_lint(cx, - TOPLEVEL_REF_ARG, - arg.pat.span, - "`ref` directly on a function argument is ignored. Consider using a reference type \ - instead."); + span_lint( + cx, + TOPLEVEL_REF_ARG, + arg.pat.span, + "`ref` directly on a function argument is ignored. Consider using a reference type \ + instead.", + ); }, _ => {}, } @@ -316,7 +327,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { if let Some(name) = get_item_name(cx, expr) { let name = name.as_str(); if name == "eq" || name == "ne" || name == "is_nan" || name.starts_with("eq_") || - name.ends_with("_eq") { + name.ends_with("_eq") + { return; } } @@ -324,9 +336,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { let lhs = Sugg::hir(cx, left, ".."); let rhs = Sugg::hir(cx, right, ".."); - db.span_suggestion(expr.span, - "consider comparing them within some error", - format!("({}).abs() < error", lhs - rhs)); + db.span_suggestion( + expr.span, + "consider comparing them within some error", + format!("({}).abs() < error", lhs - rhs), + ); db.span_note(expr.span, "std::f32::EPSILON and std::f64::EPSILON are available."); }); } else if op == BiRem && is_integer_literal(right, 1) { @@ -347,7 +361,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { binding != "_result" && // FIXME: #944 is_used(cx, expr) && // don't lint if the declaration is in a macro - non_macro_local(cx, &cx.tables.qpath_def(qpath, expr.id)) { + non_macro_local(cx, &cx.tables.qpath_def(qpath, expr.id)) + { Some(binding) } else { None @@ -364,22 +379,28 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { _ => None, }; if let Some(binding) = binding { - span_lint(cx, - USED_UNDERSCORE_BINDING, - expr.span, - &format!("used binding `{}` which is prefixed with an underscore. A leading \ + span_lint( + cx, + USED_UNDERSCORE_BINDING, + expr.span, + &format!( + "used binding `{}` which is prefixed with an underscore. A leading \ underscore signals that a binding will not be used.", - binding)); + binding + ), + ); } } fn check_pat(&mut self, cx: &LateContext<'a, 'tcx>, pat: &'tcx Pat) { if let PatKind::Binding(_, _, ref ident, Some(ref right)) = pat.node { if right.node == PatKind::Wild { - span_lint(cx, - REDUNDANT_PATTERN, - pat.span, - &format!("the `{} @ _` pattern can be written as just `{}`", ident.node, ident.node)); + span_lint( + cx, + REDUNDANT_PATTERN, + pat.span, + &format!("the `{} @ _` pattern can be written as just `{}`", ident.node, ident.node), + ); } } } @@ -388,10 +409,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { fn check_nan(cx: &LateContext, path: &Path, expr: &Expr) { if !in_constant(cx, expr.id) { path.segments.last().map(|seg| if seg.name == "NAN" { - span_lint(cx, - CMP_NAN, - expr.span, - "doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead"); + span_lint( + cx, + CMP_NAN, + expr.span, + "doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead", + ); }); } } @@ -421,7 +444,7 @@ fn is_allowed(cx: &LateContext, expr: &Expr) -> bool { }; val.try_cmp(zero) == Ok(Ordering::Equal) || val.try_cmp(infinity) == Ok(Ordering::Equal) || - val.try_cmp(neg_infinity) == Ok(Ordering::Equal) + val.try_cmp(neg_infinity) == Ok(Ordering::Equal) }, FloatTy::F64 => { let zero = ConstFloat { @@ -440,7 +463,7 @@ fn is_allowed(cx: &LateContext, expr: &Expr) -> bool { }; val.try_cmp(zero) == Ok(Ordering::Equal) || val.try_cmp(infinity) == Ok(Ordering::Equal) || - val.try_cmp(neg_infinity) == Ok(Ordering::Equal) + val.try_cmp(neg_infinity) == Ok(Ordering::Equal) }, } } else { @@ -490,37 +513,43 @@ fn check_to_owned(cx: &LateContext, expr: &Expr, other: &Expr) { .builtin_deref(true, ty::LvaluePreference::NoPreference) .map_or(false, |tam| implements_trait(cx, arg_ty, partial_eq_trait_id, &[tam.ty])) // arg impls PartialEq - && !implements_trait(cx, arg_ty, partial_eq_trait_id, &[other_ty]) { + && !implements_trait(cx, arg_ty, partial_eq_trait_id, &[other_ty]) + { return; } - span_lint_and_then(cx, - CMP_OWNED, - expr.span, - "this creates an owned instance just for comparison", - |db| { - // this is as good as our recursion check can get, we can't prove that the current function is - // called by - // PartialEq::eq, but we can at least ensure that this code is not part of it - let parent_fn = cx.tcx.hir.get_parent(expr.id); - let parent_impl = cx.tcx.hir.get_parent(parent_fn); - if parent_impl != CRATE_NODE_ID { - if let map::NodeItem(item) = cx.tcx.hir.get(parent_impl) { - if let ItemImpl(.., Some(ref trait_ref), _, _) = item.node { - if trait_ref.path.def.def_id() == partial_eq_trait_id { - // we are implementing PartialEq, don't suggest not doing `to_owned`, otherwise we go into - // recursion - db.span_label(expr.span, "try calling implementing the comparison without allocating"); - return; + span_lint_and_then( + cx, + CMP_OWNED, + expr.span, + "this creates an owned instance just for comparison", + |db| { + // this is as good as our recursion check can get, we can't prove that the + // current function is + // called by + // PartialEq::eq, but we can at least ensure that this code is not part of it + let parent_fn = cx.tcx.hir.get_parent(expr.id); + let parent_impl = cx.tcx.hir.get_parent(parent_fn); + if parent_impl != CRATE_NODE_ID { + if let map::NodeItem(item) = cx.tcx.hir.get(parent_impl) { + if let ItemImpl(.., Some(ref trait_ref), _, _) = item.node { + if trait_ref.path.def.def_id() == partial_eq_trait_id { + // we are implementing PartialEq, don't suggest not doing `to_owned`, otherwise + // we go into + // recursion + db.span_label(expr.span, "try calling implementing the comparison without allocating"); + return; + } } } } - } - db.span_suggestion(expr.span, "try", snip.to_string()); - }); + db.span_suggestion(expr.span, "try", snip.to_string()); + }, + ); } -/// Heuristic to see if an expression is used. Should be compatible with `unused_variables`'s idea +/// Heuristic to see if an expression is used. Should be compatible with +/// `unused_variables`'s idea /// of what it means for an expression to be "used". fn is_used(cx: &LateContext, expr: &Expr) -> bool { if let Some(parent) = get_parent_expr(cx, expr) { @@ -534,10 +563,14 @@ fn is_used(cx: &LateContext, expr: &Expr) -> bool { } } -/// Test whether an expression is in a macro expansion (e.g. something generated by +/// Test whether an expression is in a macro expansion (e.g. something +/// generated by /// `#[derive(...)`] or the like). fn in_attributes_expansion(expr: &Expr) -> bool { - expr.span.ctxt.outer().expn_info().map_or(false, |info| matches!(info.callee.format, ExpnFormat::MacroAttribute(_))) + expr.span.ctxt.outer().expn_info().map_or( + false, + |info| matches!(info.callee.format, ExpnFormat::MacroAttribute(_)), + ) } /// Test whether `def` is a variable defined outside a macro. @@ -545,10 +578,9 @@ fn non_macro_local(cx: &LateContext, def: &def::Def) -> bool { match *def { def::Def::Local(def_id) | def::Def::Upvar(def_id, _, _) => { - let id = cx.tcx - .hir - .as_local_node_id(def_id) - .expect("local variables should be found in the same crate"); + let id = cx.tcx.hir.as_local_node_id(def_id).expect( + "local variables should be found in the same crate", + ); !in_macro(cx.tcx.hir.span(id)) }, _ => false, diff --git a/clippy_lints/src/misc_early.rs b/clippy_lints/src/misc_early.rs index c63dff52ae9..52a97024e44 100644 --- a/clippy_lints/src/misc_early.rs +++ b/clippy_lints/src/misc_early.rs @@ -40,9 +40,11 @@ declare_lint! { "function arguments having names which only differ by an underscore" } -/// **What it does:** Detects closures called in the same expression where they are defined. +/// **What it does:** Detects closures called in the same expression where they +/// are defined. /// -/// **Why is this bad?** It is unnecessarily adding to the expression's complexity. +/// **Why is this bad?** It is unnecessarily adding to the expression's +/// complexity. /// /// **Known problems:** None. /// @@ -73,7 +75,8 @@ declare_lint! { "`--x`, which is a double negation of `x` and not a pre-decrement as in C/C++" } -/// **What it does:** Warns on hexadecimal literals with mixed-case letter digits. +/// **What it does:** Warns on hexadecimal literals with mixed-case letter +/// digits. /// /// **Why is this bad?** It looks confusing. /// @@ -89,7 +92,8 @@ declare_lint! { "hex literals whose letter digits are not consistently upper- or lowercased" } -/// **What it does:** Warns if literal suffixes are not separated by an underscore. +/// **What it does:** Warns if literal suffixes are not separated by an +/// underscore. /// /// **Why is this bad?** It is much less readable. /// @@ -107,8 +111,10 @@ declare_lint! { /// **What it does:** Warns if an integral constant literal starts with `0`. /// -/// **Why is this bad?** In some languages (including the infamous C language and most of its -/// family), this marks an octal constant. In Rust however, this is a decimal constant. This could +/// **Why is this bad?** In some languages (including the infamous C language +/// and most of its +/// family), this marks an octal constant. In Rust however, this is a decimal +/// constant. This could /// be confusing for both the writer and a reader of the constant. /// /// **Known problems:** None. @@ -167,14 +173,16 @@ pub struct MiscEarly; impl LintPass for MiscEarly { fn get_lints(&self) -> LintArray { - lint_array!(UNNEEDED_FIELD_PATTERN, - DUPLICATE_UNDERSCORE_ARGUMENT, - REDUNDANT_CLOSURE_CALL, - DOUBLE_NEG, - MIXED_CASE_HEX_LITERALS, - UNSEPARATED_LITERAL_SUFFIX, - ZERO_PREFIXED_LITERAL, - BUILTIN_TYPE_SHADOW) + lint_array!( + UNNEEDED_FIELD_PATTERN, + DUPLICATE_UNDERSCORE_ARGUMENT, + REDUNDANT_CLOSURE_CALL, + DOUBLE_NEG, + MIXED_CASE_HEX_LITERALS, + UNSEPARATED_LITERAL_SUFFIX, + ZERO_PREFIXED_LITERAL, + BUILTIN_TYPE_SHADOW + ) } } @@ -183,10 +191,12 @@ impl EarlyLintPass for MiscEarly { for ty in &gen.ty_params { let name = ty.ident.name.as_str(); if constants::BUILTIN_TYPES.contains(&&*name) { - span_lint(cx, - BUILTIN_TYPE_SHADOW, - ty.span, - &format!("This generic shadows the built-in type `{}`", name)); + span_lint( + cx, + BUILTIN_TYPE_SHADOW, + ty.span, + &format!("This generic shadows the built-in type `{}`", name), + ); } } } @@ -194,7 +204,11 @@ impl EarlyLintPass for MiscEarly { fn check_pat(&mut self, cx: &EarlyContext, pat: &Pat) { if let PatKind::Struct(ref npat, ref pfields, _) = pat.node { let mut wilds = 0; - let type_name = npat.segments.last().expect("A path must have at least one segment").identifier.name; + let type_name = npat.segments + .last() + .expect("A path must have at least one segment") + .identifier + .name; for field in pfields { if field.node.pat.node == PatKind::Wild { @@ -202,11 +216,13 @@ impl EarlyLintPass for MiscEarly { } } if !pfields.is_empty() && wilds == pfields.len() { - span_help_and_lint(cx, - UNNEEDED_FIELD_PATTERN, - pat.span, - "All the struct fields are matched to a wildcard pattern, consider using `..`.", - &format!("Try with `{} {{ .. }}` instead", type_name)); + span_help_and_lint( + cx, + UNNEEDED_FIELD_PATTERN, + pat.span, + "All the struct fields are matched to a wildcard pattern, consider using `..`.", + &format!("Try with `{} {{ .. }}` instead", type_name), + ); return; } if wilds > 0 { @@ -223,19 +239,21 @@ impl EarlyLintPass for MiscEarly { if field.node.pat.node == PatKind::Wild { wilds -= 1; if wilds > 0 { - span_lint(cx, - UNNEEDED_FIELD_PATTERN, - field.span, - "You matched a field with a wildcard pattern. Consider using `..` instead"); + span_lint( + cx, + UNNEEDED_FIELD_PATTERN, + field.span, + "You matched a field with a wildcard pattern. Consider using `..` instead", + ); } else { - span_help_and_lint(cx, - UNNEEDED_FIELD_PATTERN, - field.span, - "You matched a field with a wildcard pattern. Consider using `..` \ + span_help_and_lint( + cx, + UNNEEDED_FIELD_PATTERN, + field.span, + "You matched a field with a wildcard pattern. Consider using `..` \ instead", - &format!("Try with `{} {{ {}, .. }}`", - type_name, - normal[..].join(", "))); + &format!("Try with `{} {{ {}, .. }}`", type_name, normal[..].join(", ")), + ); } } } @@ -252,12 +270,16 @@ impl EarlyLintPass for MiscEarly { if arg_name.starts_with('_') { if let Some(correspondence) = registered_names.get(&arg_name[1..]) { - span_lint(cx, - DUPLICATE_UNDERSCORE_ARGUMENT, - *correspondence, - &format!("`{}` already exists, having another argument having almost the same \ + span_lint( + cx, + DUPLICATE_UNDERSCORE_ARGUMENT, + *correspondence, + &format!( + "`{}` already exists, having another argument having almost the same \ name makes code comprehension and documentation more difficult", - arg_name[1..].to_owned()));; + arg_name[1..].to_owned() + ), + );; } } else { registered_names.insert(arg_name, arg.pat.span); @@ -287,10 +309,12 @@ impl EarlyLintPass for MiscEarly { }, ExprKind::Unary(UnOp::Neg, ref inner) => { if let ExprKind::Unary(UnOp::Neg, _) = inner.node { - span_lint(cx, - DOUBLE_NEG, - expr.span, - "`--x` could be misinterpreted as pre-decrement by C programmers, is usually a no-op"); + span_lint( + cx, + DOUBLE_NEG, + expr.span, + "`--x` could be misinterpreted as pre-decrement by C programmers, is usually a no-op", + ); } }, ExprKind::Lit(ref lit) => self.check_lit(cx, lit), diff --git a/clippy_lints/src/missing_doc.rs b/clippy_lints/src/missing_doc.rs index c38402ad29c..17b3ad4d9e2 100644 --- a/clippy_lints/src/missing_doc.rs +++ b/clippy_lints/src/missing_doc.rs @@ -11,12 +11,16 @@ // except according to those terms. // -// Note: More specifically this lint is largely inspired (aka copied) from *rustc*'s +// Note: More specifically this lint is largely inspired (aka copied) from +// *rustc*'s // [`missing_doc`]. // // [`missing_doc`]: // https://github. // com/rust-lang/rust/blob/d6d05904697d89099b55da3331155392f1db9c00/src/librustc_lint/builtin. +// +// +// // rs#L246 // @@ -28,10 +32,13 @@ use syntax::attr; use syntax::codemap::Span; use utils::in_macro; -/// **What it does:** Warns if there is missing doc for any documentable item (public or private). +/// **What it does:** Warns if there is missing doc for any documentable item +/// (public or private). /// -/// **Why is this bad?** Doc is good. *rustc* has a `MISSING_DOCS` allowed-by-default lint for -/// public members, but has no way to enforce documentation of private items. This lint fixes that. +/// **Why is this bad?** Doc is good. *rustc* has a `MISSING_DOCS` +/// allowed-by-default lint for +/// public members, but has no way to enforce documentation of private items. +/// This lint fixes that. /// /// **Known problems:** None. declare_lint! { @@ -58,7 +65,9 @@ impl MissingDoc { } fn doc_hidden(&self) -> bool { - *self.doc_hidden_stack.last().expect("empty doc_hidden_stack") + *self.doc_hidden_stack.last().expect( + "empty doc_hidden_stack", + ) } fn check_missing_docs_attrs(&self, cx: &LateContext, attrs: &[ast::Attribute], sp: Span, desc: &'static str) { @@ -77,11 +86,15 @@ impl MissingDoc { return; } - let has_doc = attrs.iter().any(|a| a.is_value_str() && a.name().map_or(false, |n| n == "doc")); + let has_doc = attrs.iter().any(|a| { + a.is_value_str() && a.name().map_or(false, |n| n == "doc") + }); if !has_doc { - cx.span_lint(MISSING_DOCS_IN_PRIVATE_ITEMS, - sp, - &format!("missing documentation for {}", desc)); + cx.span_lint( + MISSING_DOCS_IN_PRIVATE_ITEMS, + sp, + &format!("missing documentation for {}", desc), + ); } } } @@ -95,13 +108,13 @@ impl LintPass for MissingDoc { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { fn enter_lint_attrs(&mut self, _: &LateContext<'a, 'tcx>, attrs: &'tcx [ast::Attribute]) { let doc_hidden = self.doc_hidden() || - attrs.iter().any(|attr| { - attr.check_name("doc") && - match attr.meta_item_list() { - None => false, - Some(l) => attr::list_contains_name(&l[..], "hidden"), - } - }); + attrs.iter().any(|attr| { + attr.check_name("doc") && + match attr.meta_item_list() { + None => false, + Some(l) => attr::list_contains_name(&l[..], "hidden"), + } + }); self.doc_hidden_stack.push(doc_hidden); } diff --git a/clippy_lints/src/mut_mut.rs b/clippy_lints/src/mut_mut.rs index fc3107c3068..e8133050475 100644 --- a/clippy_lints/src/mut_mut.rs +++ b/clippy_lints/src/mut_mut.rs @@ -22,7 +22,7 @@ declare_lint! { "usage of double-mut refs, e.g. `&mut &mut ...`" } -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] pub struct MutMut; impl LintPass for MutMut { @@ -64,26 +64,37 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for MutVisitor<'a, 'tcx> { intravisit::walk_expr(self, body); } else if let hir::ExprAddrOf(hir::MutMutable, ref e) = expr.node { if let hir::ExprAddrOf(hir::MutMutable, _) = e.node { - span_lint(self.cx, - MUT_MUT, - expr.span, - "generally you want to avoid `&mut &mut _` if possible"); + span_lint( + self.cx, + MUT_MUT, + expr.span, + "generally you want to avoid `&mut &mut _` if possible", + ); } else if let ty::TyRef(_, ty::TypeAndMut { mutbl: hir::MutMutable, .. }) = self.cx.tables.expr_ty(e).sty { - span_lint(self.cx, - MUT_MUT, - expr.span, - "this expression mutably borrows a mutable reference. Consider reborrowing"); + span_lint( + self.cx, + MUT_MUT, + expr.span, + "this expression mutably borrows a mutable reference. Consider reborrowing", + ); } } } fn visit_ty(&mut self, ty: &'tcx hir::Ty) { - if let hir::TyRptr(_, hir::MutTy { ty: ref pty, mutbl: hir::MutMutable }) = ty.node { + if let hir::TyRptr(_, + hir::MutTy { + ty: ref pty, + mutbl: hir::MutMutable, + }) = ty.node + { if let hir::TyRptr(_, hir::MutTy { mutbl: hir::MutMutable, .. }) = pty.node { - span_lint(self.cx, - MUT_MUT, - ty.span, - "generally you want to avoid `&mut &mut _` if possible"); + span_lint( + self.cx, + MUT_MUT, + ty.span, + "generally you want to avoid `&mut &mut _` if possible", + ); } } diff --git a/clippy_lints/src/mut_reference.rs b/clippy_lints/src/mut_reference.rs index 0e2c0412702..0c0c8f4061f 100644 --- a/clippy_lints/src/mut_reference.rs +++ b/clippy_lints/src/mut_reference.rs @@ -24,7 +24,7 @@ declare_lint! { } -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] pub struct UnnecessaryMutPassed; impl LintPass for UnnecessaryMutPassed { @@ -38,10 +38,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnecessaryMutPassed { match e.node { ExprCall(ref fn_expr, ref arguments) => { if let ExprPath(ref path) = fn_expr.node { - check_arguments(cx, - arguments, - cx.tables.expr_ty(fn_expr), - &print::to_string(print::NO_ANN, |s| s.print_qpath(path, false))); + check_arguments( + cx, + arguments, + cx.tables.expr_ty(fn_expr), + &print::to_string(print::NO_ANN, |s| s.print_qpath(path, false)), + ); } }, ExprMethodCall(ref path, _, ref arguments) => { @@ -64,10 +66,12 @@ fn check_arguments<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, arguments: &[Expr], typ ty::TyRef(_, ty::TypeAndMut { mutbl: MutImmutable, .. }) | ty::TyRawPtr(ty::TypeAndMut { mutbl: MutImmutable, .. }) => { if let ExprAddrOf(MutMutable, _) = argument.node { - span_lint(cx, - UNNECESSARY_MUT_PASSED, - argument.span, - &format!("The function/method `{}` doesn't need a mutable reference", name)); + span_lint( + cx, + UNNECESSARY_MUT_PASSED, + argument.span, + &format!("The function/method `{}` doesn't need a mutable reference", name), + ); } }, _ => (), diff --git a/clippy_lints/src/mutex_atomic.rs b/clippy_lints/src/mutex_atomic.rs index 085067935a0..25a7118ceda 100644 --- a/clippy_lints/src/mutex_atomic.rs +++ b/clippy_lints/src/mutex_atomic.rs @@ -28,9 +28,11 @@ declare_lint! { "using a mutex where an atomic value could be used instead" } -/// **What it does:** Checks for usages of `Mutex` where `X` is an integral type. +/// **What it does:** Checks for usages of `Mutex` where `X` is an integral +/// type. /// -/// **Why is this bad?** Using a mutex just to make access to a plain integer sequential is +/// **Why is this bad?** Using a mutex just to make access to a plain integer +/// sequential is /// shooting flies with cannons. `std::atomic::usize` is leaner and faster. /// /// **Known problems:** This lint cannot detect if the mutex is actually used @@ -61,9 +63,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutexAtomic { if match_type(cx, ty, &paths::MUTEX) { let mutex_param = subst.type_at(0); if let Some(atomic_name) = get_atomic_name(mutex_param) { - let msg = format!("Consider using an {} instead of a Mutex here. If you just want the locking \ + let msg = format!( + "Consider using an {} instead of a Mutex here. If you just want the locking \ behaviour and not the internal type, consider using Mutex<()>.", - atomic_name); + atomic_name + ); match mutex_param.sty { ty::TyUint(t) if t != ast::UintTy::Us => span_lint(cx, MUTEX_INTEGER, expr.span, &msg), ty::TyInt(t) if t != ast::IntTy::Is => span_lint(cx, MUTEX_INTEGER, expr.span, &msg), diff --git a/clippy_lints/src/needless_bool.rs b/clippy_lints/src/needless_bool.rs index 4456547c777..52f0df12bcd 100644 --- a/clippy_lints/src/needless_bool.rs +++ b/clippy_lints/src/needless_bool.rs @@ -9,7 +9,8 @@ use syntax::codemap::Spanned; use utils::{span_lint, span_lint_and_sugg, snippet}; use utils::sugg::Sugg; -/// **What it does:** Checks for expressions of the form `if c { true } else { false }` +/// **What it does:** Checks for expressions of the form `if c { true } else { +/// false }` /// (or vice versa) and suggest using the condition directly. /// /// **Why is this bad?** Redundant code. @@ -47,7 +48,7 @@ declare_lint! { "comparing a variable to a boolean, e.g. `if x == true`" } -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] pub struct NeedlessBool; impl LintPass for NeedlessBool { @@ -70,28 +71,34 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBool { snip.to_string() }; - span_lint_and_sugg(cx, - NEEDLESS_BOOL, - e.span, - "this if-then-else expression returns a bool literal", - "you can reduce it to", - hint); + span_lint_and_sugg( + cx, + NEEDLESS_BOOL, + e.span, + "this if-then-else expression returns a bool literal", + "you can reduce it to", + hint, + ); }; if let ExprBlock(ref then_block) = then_block.node { match (fetch_bool_block(then_block), fetch_bool_expr(else_expr)) { (RetBool(true), RetBool(true)) | (Bool(true), Bool(true)) => { - span_lint(cx, - NEEDLESS_BOOL, - e.span, - "this if-then-else expression will always return true"); + span_lint( + cx, + NEEDLESS_BOOL, + e.span, + "this if-then-else expression will always return true", + ); }, (RetBool(false), RetBool(false)) | (Bool(false), Bool(false)) => { - span_lint(cx, - NEEDLESS_BOOL, - e.span, - "this if-then-else expression will always return false"); + span_lint( + cx, + NEEDLESS_BOOL, + e.span, + "this if-then-else expression will always return false", + ); }, (RetBool(true), RetBool(false)) => reduce(true, false), (Bool(true), Bool(false)) => reduce(false, false), @@ -106,7 +113,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBool { } } -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] pub struct BoolComparison; impl LintPass for BoolComparison { @@ -122,39 +129,47 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoolComparison { match (fetch_bool_expr(left_side), fetch_bool_expr(right_side)) { (Bool(true), Other) => { let hint = snippet(cx, right_side.span, "..").into_owned(); - span_lint_and_sugg(cx, - BOOL_COMPARISON, - e.span, - "equality checks against true are unnecessary", - "try simplifying it as shown", - hint); + span_lint_and_sugg( + cx, + BOOL_COMPARISON, + e.span, + "equality checks against true are unnecessary", + "try simplifying it as shown", + hint, + ); }, (Other, Bool(true)) => { let hint = snippet(cx, left_side.span, "..").into_owned(); - span_lint_and_sugg(cx, - BOOL_COMPARISON, - e.span, - "equality checks against true are unnecessary", - "try simplifying it as shown", - hint); + span_lint_and_sugg( + cx, + BOOL_COMPARISON, + e.span, + "equality checks against true are unnecessary", + "try simplifying it as shown", + hint, + ); }, (Bool(false), Other) => { let hint = Sugg::hir(cx, right_side, ".."); - span_lint_and_sugg(cx, - BOOL_COMPARISON, - e.span, - "equality checks against false can be replaced by a negation", - "try simplifying it as shown", - (!hint).to_string()); + span_lint_and_sugg( + cx, + BOOL_COMPARISON, + e.span, + "equality checks against false can be replaced by a negation", + "try simplifying it as shown", + (!hint).to_string(), + ); }, (Other, Bool(false)) => { let hint = Sugg::hir(cx, left_side, ".."); - span_lint_and_sugg(cx, - BOOL_COMPARISON, - e.span, - "equality checks against false can be replaced by a negation", - "try simplifying it as shown", - (!hint).to_string()); + span_lint_and_sugg( + cx, + BOOL_COMPARISON, + e.span, + "equality checks against false can be replaced by a negation", + "try simplifying it as shown", + (!hint).to_string(), + ); }, _ => (), } diff --git a/clippy_lints/src/needless_borrow.rs b/clippy_lints/src/needless_borrow.rs index 385fcc86adb..b331d6910a3 100644 --- a/clippy_lints/src/needless_borrow.rs +++ b/clippy_lints/src/needless_borrow.rs @@ -26,7 +26,7 @@ declare_lint! { "taking a reference that is going to be automatically dereferenced" } -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] pub struct NeedlessBorrow; impl LintPass for NeedlessBorrow { diff --git a/clippy_lints/src/needless_borrowed_ref.rs b/clippy_lints/src/needless_borrowed_ref.rs index bfe52a41214..6f81c811414 100644 --- a/clippy_lints/src/needless_borrowed_ref.rs +++ b/clippy_lints/src/needless_borrowed_ref.rs @@ -9,7 +9,8 @@ use utils::{span_lint, in_macro}; /// **What it does:** Checks for useless borrowed references. /// -/// **Why is this bad?** It is completely useless and make the code look more complex than it +/// **Why is this bad?** It is completely useless and make the code look more +/// complex than it /// actually is. /// /// **Known problems:** None. @@ -19,7 +20,8 @@ use utils::{span_lint, in_macro}; /// let mut v = Vec::::new(); /// let _ = v.iter_mut().filter(|&ref a| a.is_empty()); /// ``` -/// This clojure takes a reference on something that has been matched as a reference and +/// This clojure takes a reference on something that has been matched as a +/// reference and /// de-referenced. /// As such, it could just be |a| a.is_empty() declare_lint! { diff --git a/clippy_lints/src/needless_continue.rs b/clippy_lints/src/needless_continue.rs index 076bf82b687..692fa19f3ba 100644 --- a/clippy_lints/src/needless_continue.rs +++ b/clippy_lints/src/needless_continue.rs @@ -99,7 +99,7 @@ declare_lint! { "`continue` statements that can be replaced by a rearrangement of code" } -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] pub struct NeedlessContinue; impl LintPass for NeedlessContinue { @@ -116,59 +116,60 @@ impl EarlyLintPass for NeedlessContinue { } } -/* This lint has to mainly deal with two cases of needless continue statements. - * - * Case 1 [Continue inside else block]: - * - * loop { - * // region A - * if cond { - * // region B - * } else { - * continue; - * } - * // region C - * } - * - * This code can better be written as follows: - * - * loop { - * // region A - * if cond { - * // region B - * // region C - * } - * } - * - * Case 2 [Continue inside then block]: - * - * loop { - * // region A - * if cond { - * continue; - * // potentially more code here. - * } else { - * // region B - * } - * // region C - * } - * - * - * This snippet can be refactored to: - * - * loop { - * // region A - * if !cond { - * // region B - * // region C - * } - * } - * */ +/* This lint has to mainly deal with two cases of needless continue + * statements. */ +// Case 1 [Continue inside else block]: +// +// loop { +// // region A +// if cond { +// // region B +// } else { +// continue; +// } +// // region C +// } +// +// This code can better be written as follows: +// +// loop { +// // region A +// if cond { +// // region B +// // region C +// } +// } +// +// Case 2 [Continue inside then block]: +// +// loop { +// // region A +// if cond { +// continue; +// // potentially more code here. +// } else { +// // region B +// } +// // region C +// } +// +// +// This snippet can be refactored to: +// +// loop { +// // region A +// if !cond { +// // region B +// // region C +// } +// } +// /// Given an expression, returns true if either of the following is true /// /// - The expression is a `continue` node. -/// - The expression node is a block with the first statement being a `continue`. +/// - The expression node is a block with the first statement being a +/// `continue`. /// fn needless_continue_in_else(else_expr: &ast::Expr) -> bool { match else_expr.node { @@ -195,7 +196,8 @@ fn is_first_block_stmt_continue(block: &ast::Block) -> bool { /// If `expr` is a loop expression (while/while let/for/loop), calls `func` with /// the AST object representing the loop block of `expr`. fn with_loop_block(expr: &ast::Expr, mut func: F) - where F: FnMut(&ast::Block) +where + F: FnMut(&ast::Block), { match expr.node { ast::ExprKind::While(_, ref loop_block, _) | @@ -206,7 +208,8 @@ fn with_loop_block(expr: &ast::Expr, mut func: F) } } -/// If `stmt` is an if expression node with an `else` branch, calls func with the +/// If `stmt` is an if expression node with an `else` branch, calls func with +/// the /// following: /// /// - The `if` expression itself, @@ -215,7 +218,8 @@ fn with_loop_block(expr: &ast::Expr, mut func: F) /// - The `else` expression. /// fn with_if_expr(stmt: &ast::Stmt, mut func: F) - where F: FnMut(&ast::Expr, &ast::Expr, &ast::Block, &ast::Expr) +where + F: FnMut(&ast::Expr, &ast::Expr, &ast::Block, &ast::Expr), { match stmt.node { ast::StmtKind::Semi(ref e) | @@ -271,10 +275,18 @@ fn emit_warning<'a>(ctx: &EarlyContext, data: &'a LintData, header: &str, typ: L // expr is the expression which the lint warning message refers to. let (snip, message, expr) = match typ { LintType::ContinueInsideElseBlock => { - (suggestion_snippet_for_continue_inside_else(ctx, data, header), MSG_REDUNDANT_ELSE_BLOCK, data.else_expr) + ( + suggestion_snippet_for_continue_inside_else(ctx, data, header), + MSG_REDUNDANT_ELSE_BLOCK, + data.else_expr, + ) }, LintType::ContinueInsideThenBlock => { - (suggestion_snippet_for_continue_inside_if(ctx, data, header), MSG_ELSE_BLOCK_NOT_NEEDED, data.if_expr) + ( + suggestion_snippet_for_continue_inside_if(ctx, data, header), + MSG_ELSE_BLOCK_NOT_NEEDED, + data.if_expr, + ) }, }; span_help_and_lint(ctx, NEEDLESS_CONTINUE, expr.span, message, &snip); @@ -407,7 +419,8 @@ pub fn erode_from_front(s: &str) -> String { } /// If `s` contains the code for a block, delimited by braces, this function -/// tries to get the contents of the block. If there is no closing brace present, +/// tries to get the contents of the block. If there is no closing brace +/// present, /// an empty string is returned. pub fn erode_block(s: &str) -> String { erode_from_back(&erode_from_front(s)) diff --git a/clippy_lints/src/needless_pass_by_value.rs b/clippy_lints/src/needless_pass_by_value.rs index 0740ca483f7..e4efaf495a8 100644 --- a/clippy_lints/src/needless_pass_by_value.rs +++ b/clippy_lints/src/needless_pass_by_value.rs @@ -13,10 +13,12 @@ use utils::{in_macro, is_self, is_copy, implements_trait, get_trait_def_id, matc multispan_sugg, paths}; use std::collections::{HashSet, HashMap}; -/// **What it does:** Checks for functions taking arguments by value, but not consuming them in its +/// **What it does:** Checks for functions taking arguments by value, but not +/// consuming them in its /// body. /// -/// **Why is this bad?** Taking arguments by reference is more flexible and can sometimes avoid +/// **Why is this bad?** Taking arguments by reference is more flexible and can +/// sometimes avoid /// unnecessary allocations. /// /// **Known problems:** Hopefully none. @@ -53,7 +55,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue { decl: &'tcx FnDecl, body: &'tcx Body, span: Span, - node_id: NodeId + node_id: NodeId, ) { if in_macro(span) { return; @@ -87,8 +89,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue { .collect() }; - // Collect moved variables and spans which will need dereferencings from the function body. - let MovedVariablesCtxt { moved_vars, spans_need_deref, .. } = { + // Collect moved variables and spans which will need dereferencings from the + // function body. + let MovedVariablesCtxt { + moved_vars, + spans_need_deref, + .. + } = { let mut ctx = MovedVariablesCtxt::new(cx); let region_maps = &cx.tcx.region_maps(fn_def_id); euv::ExprUseVisitor::new(&mut ctx, cx.tcx, cx.param_env, region_maps, cx.tables).consume_body(body); @@ -102,14 +109,19 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue { // Determines whether `ty` implements `Borrow` (U != ty) specifically. // This is needed due to the `Borrow for T` blanket impl. - let implements_borrow_trait = preds.iter() + let implements_borrow_trait = preds + .iter() .filter_map(|pred| if let ty::Predicate::Trait(ref poly_trait_ref) = *pred { Some(poly_trait_ref.skip_binder()) } else { None }) .filter(|tpred| tpred.def_id() == borrow_trait && tpred.self_ty() == ty) - .any(|tpred| tpred.input_types().nth(1).expect("Borrow trait must have an parameter") != ty); + .any(|tpred| { + tpred.input_types().nth(1).expect( + "Borrow trait must have an parameter", + ) != ty + }); if_let_chain! {[ !is_self(arg), @@ -177,7 +189,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue { struct MovedVariablesCtxt<'a, 'tcx: 'a> { cx: &'a LateContext<'a, 'tcx>, moved_vars: HashSet, - /// Spans which need to be prefixed with `*` for dereferencing the suggested additional + /// Spans which need to be prefixed with `*` for dereferencing the + /// suggested additional /// reference. spans_need_deref: HashMap>, } diff --git a/clippy_lints/src/needless_update.rs b/clippy_lints/src/needless_update.rs index da6f635e34e..d6624411e2f 100644 --- a/clippy_lints/src/needless_update.rs +++ b/clippy_lints/src/needless_update.rs @@ -36,10 +36,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { let ty = cx.tables.expr_ty(expr); if let ty::TyAdt(def, _) = ty.sty { if fields.len() == def.struct_variant().fields.len() { - span_lint(cx, - NEEDLESS_UPDATE, - base.span, - "struct update has no effect, all the fields in the struct have already been specified"); + span_lint( + cx, + NEEDLESS_UPDATE, + base.span, + "struct update has no effect, all the fields in the struct have already been specified", + ); } } } diff --git a/clippy_lints/src/new_without_default.rs b/clippy_lints/src/new_without_default.rs index e5644b606f5..c6bd91919f5 100644 --- a/clippy_lints/src/new_without_default.rs +++ b/clippy_lints/src/new_without_default.rs @@ -80,7 +80,7 @@ declare_lint! { "`fn new() -> Self` without `#[derive]`able `Default` implementation" } -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] pub struct NewWithoutDefault; impl LintPass for NewWithoutDefault { @@ -97,7 +97,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NewWithoutDefault { decl: &'tcx hir::FnDecl, _: &'tcx hir::Body, span: Span, - id: ast::NodeId + id: ast::NodeId, ) { if in_external_macro(cx, span) { return; @@ -109,13 +109,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NewWithoutDefault { return; } if !sig.generics.ty_params.is_empty() { - // when the result of `new()` depends on a type parameter we should not require an + // when the result of `new()` depends on a type parameter we should not require + // an // impl of `Default` return; } if decl.inputs.is_empty() && name == "new" && cx.access_levels.is_reachable(id) { - let self_ty = cx.tcx - .type_of(cx.tcx.hir.local_def_id(cx.tcx.hir.get_parent(id))); + let self_ty = cx.tcx.type_of( + cx.tcx.hir.local_def_id(cx.tcx.hir.get_parent(id)), + ); if_let_chain!{[ same_tys(cx, self_ty, return_ty(cx, id)), let Some(default_trait_id) = get_trait_def_id(cx, &paths::DEFAULT_TRAIT), diff --git a/clippy_lints/src/no_effect.rs b/clippy_lints/src/no_effect.rs index a88662356fb..c57df468f7c 100644 --- a/clippy_lints/src/no_effect.rs +++ b/clippy_lints/src/no_effect.rs @@ -62,10 +62,10 @@ fn has_no_effect(cx: &LateContext, expr: &Expr) -> bool { Expr_::ExprBox(ref inner) => has_no_effect(cx, inner), Expr_::ExprStruct(_, ref fields, ref base) => { fields.iter().all(|field| has_no_effect(cx, &field.expr)) && - match *base { - Some(ref base) => has_no_effect(cx, base), - None => true, - } + match *base { + Some(ref base) => has_no_effect(cx, base), + None => true, + } }, Expr_::ExprCall(ref callee, ref args) => { if let Expr_::ExprPath(ref qpath) = callee.node { @@ -83,11 +83,11 @@ fn has_no_effect(cx: &LateContext, expr: &Expr) -> bool { }, Expr_::ExprBlock(ref block) => { block.stmts.is_empty() && - if let Some(ref expr) = block.expr { - has_no_effect(cx, expr) - } else { - false - } + if let Some(ref expr) = block.expr { + has_no_effect(cx, expr) + } else { + false + } }, _ => false, } @@ -120,12 +120,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { return; } } - span_lint_and_sugg(cx, - UNNECESSARY_OPERATION, - stmt.span, - "statement can be reduced", - "replace it with", - snippet); + span_lint_and_sugg( + cx, + UNNECESSARY_OPERATION, + stmt.span, + "statement can be reduced", + "replace it with", + snippet, + ); } } } @@ -152,7 +154,14 @@ fn reduce_expression<'a>(cx: &LateContext, expr: &'a Expr) -> Option reduce_expression(cx, inner).or_else(|| Some(vec![inner])), Expr_::ExprStruct(_, ref fields, ref base) => { - Some(fields.iter().map(|f| &f.expr).chain(base).map(Deref::deref).collect()) + Some( + fields + .iter() + .map(|f| &f.expr) + .chain(base) + .map(Deref::deref) + .collect(), + ) }, Expr_::ExprCall(ref callee, ref args) => { if let Expr_::ExprPath(ref qpath) = callee.node { diff --git a/clippy_lints/src/non_expressive_names.rs b/clippy_lints/src/non_expressive_names.rs index 6b97ffee6db..fa915e83aed 100644 --- a/clippy_lints/src/non_expressive_names.rs +++ b/clippy_lints/src/non_expressive_names.rs @@ -113,7 +113,13 @@ fn whitelisted(interned_name: &str, list: &[&str]) -> bool { return true; } // *_name - if interned_name.chars().rev().zip(name.chars().rev()).all(|(l, r)| l == r) { + if interned_name.chars().rev().zip(name.chars().rev()).all( + |(l, + r)| { + l == r + }, + ) + { return true; } } @@ -128,10 +134,12 @@ impl<'a, 'tcx, 'b> SimilarNamesNameVisitor<'a, 'tcx, 'b> { } self.0.single_char_names.push(c); if self.0.single_char_names.len() as u64 >= self.0.lint.single_char_binding_names_threshold { - span_lint(self.0.cx, - MANY_SINGLE_CHAR_NAMES, - span, - &format!("{}th binding whose name is just one char", self.0.single_char_names.len())); + span_lint( + self.0.cx, + MANY_SINGLE_CHAR_NAMES, + span, + &format!("{}th binding whose name is just one char", self.0.single_char_names.len()), + ); } } fn check_name(&mut self, span: Span, name: Name) { @@ -166,22 +174,41 @@ impl<'a, 'tcx, 'b> SimilarNamesNameVisitor<'a, 'tcx, 'b> { } else { let mut interned_chars = interned_name.chars(); let mut existing_chars = existing_name.interned.chars(); - let first_i = interned_chars.next().expect("we know we have at least one char"); - let first_e = existing_chars.next().expect("we know we have at least one char"); + let first_i = interned_chars.next().expect( + "we know we have at least one char", + ); + let first_e = existing_chars.next().expect( + "we know we have at least one char", + ); let eq_or_numeric = |a: char, b: char| a == b || a.is_numeric() && b.is_numeric(); if eq_or_numeric(first_i, first_e) { - let last_i = interned_chars.next_back().expect("we know we have at least two chars"); - let last_e = existing_chars.next_back().expect("we know we have at least two chars"); + let last_i = interned_chars.next_back().expect( + "we know we have at least two chars", + ); + let last_e = existing_chars.next_back().expect( + "we know we have at least two chars", + ); if eq_or_numeric(last_i, last_e) { - if interned_chars.zip(existing_chars).filter(|&(i, e)| !eq_or_numeric(i, e)).count() != 1 { + if interned_chars + .zip(existing_chars) + .filter(|&(i, e)| !eq_or_numeric(i, e)) + .count() != 1 + { continue; } } else { - let second_last_i = interned_chars.next_back().expect("we know we have at least three chars"); - let second_last_e = existing_chars.next_back().expect("we know we have at least three chars"); + let second_last_i = interned_chars.next_back().expect( + "we know we have at least three chars", + ); + let second_last_e = existing_chars.next_back().expect( + "we know we have at least three chars", + ); if !eq_or_numeric(second_last_i, second_last_e) || second_last_i == '_' || - !interned_chars.zip(existing_chars).all(|(i, e)| eq_or_numeric(i, e)) { + !interned_chars.zip(existing_chars).all(|(i, e)| { + eq_or_numeric(i, e) + }) + { // allowed similarity foo_x, foo_y // or too many chars differ (foo_x, boo_y) or (foox, booy) continue; @@ -189,10 +216,17 @@ impl<'a, 'tcx, 'b> SimilarNamesNameVisitor<'a, 'tcx, 'b> { split_at = interned_name.char_indices().rev().next().map(|(i, _)| i); } } else { - let second_i = interned_chars.next().expect("we know we have at least two chars"); - let second_e = existing_chars.next().expect("we know we have at least two chars"); + let second_i = interned_chars.next().expect( + "we know we have at least two chars", + ); + let second_e = existing_chars.next().expect( + "we know we have at least two chars", + ); if !eq_or_numeric(second_i, second_e) || second_i == '_' || - !interned_chars.zip(existing_chars).all(|(i, e)| eq_or_numeric(i, e)) { + !interned_chars.zip(existing_chars).all(|(i, e)| { + eq_or_numeric(i, e) + }) + { // allowed similarity x_foo, y_foo // or too many chars differ (x_foo, y_boo) or (xfoo, yboo) continue; @@ -200,20 +234,26 @@ impl<'a, 'tcx, 'b> SimilarNamesNameVisitor<'a, 'tcx, 'b> { split_at = interned_name.chars().next().map(|c| c.len_utf8()); } } - span_lint_and_then(self.0.cx, - SIMILAR_NAMES, - span, - "binding's name is too similar to existing binding", - |diag| { - diag.span_note(existing_name.span, "existing binding defined here"); - if let Some(split) = split_at { - diag.span_help(span, - &format!("separate the discriminating character by an \ + span_lint_and_then( + self.0.cx, + SIMILAR_NAMES, + span, + "binding's name is too similar to existing binding", + |diag| { + diag.span_note(existing_name.span, "existing binding defined here"); + if let Some(split) = split_at { + diag.span_help( + span, + &format!( + "separate the discriminating character by an \ underscore like: `{}_{}`", - &interned_name[..split], - &interned_name[split..])); - } - }); + &interned_name[..split], + &interned_name[split..] + ), + ); + } + }, + ); return; } self.0.names.push(ExistingName { @@ -241,7 +281,8 @@ impl<'a, 'tcx> Visitor<'tcx> for SimilarNamesLocalVisitor<'a, 'tcx> { if let Some(ref init) = local.init { self.apply(|this| walk_expr(this, &**init)); } - // add the pattern after the expression because the bindings aren't available yet in the init + // add the pattern after the expression because the bindings aren't available + // yet in the init // expression SimilarNamesNameVisitor(self).visit_pat(&*local.pat); } diff --git a/clippy_lints/src/ok_if_let.rs b/clippy_lints/src/ok_if_let.rs index a831e9bd9b7..ee55ea882b0 100644 --- a/clippy_lints/src/ok_if_let.rs +++ b/clippy_lints/src/ok_if_let.rs @@ -4,7 +4,8 @@ use utils::{paths, method_chain_args, span_help_and_lint, match_type, snippet}; /// **What it does:*** Checks for unnecessary `ok()` in if let. /// -/// **Why is this bad?** Calling `ok()` in if let is unnecessary, instead match on `Ok(pat)` +/// **Why is this bad?** Calling `ok()` in if let is unnecessary, instead match +/// on `Ok(pat)` /// /// **Known problems:** None. /// diff --git a/clippy_lints/src/open_options.rs b/clippy_lints/src/open_options.rs index 429d02d068b..e67c1f4d148 100644 --- a/clippy_lints/src/open_options.rs +++ b/clippy_lints/src/open_options.rs @@ -23,7 +23,7 @@ declare_lint! { } -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] pub struct NonSensical; impl LintPass for NonSensical { @@ -109,16 +109,19 @@ fn check_open_options(cx: &LateContext, options: &[(OpenOption, Argument)], span let (mut create, mut append, mut truncate, mut read, mut write) = (false, false, false, false, false); let (mut create_arg, mut append_arg, mut truncate_arg, mut read_arg, mut write_arg) = (false, false, false, false, false); - // This code is almost duplicated (oh, the irony), but I haven't found a way to unify it. + // This code is almost duplicated (oh, the irony), but I haven't found a way to + // unify it. for option in options { match *option { (OpenOption::Create, arg) => { if create { - span_lint(cx, - NONSENSICAL_OPEN_OPTIONS, - span, - "the method \"create\" is called more than once"); + span_lint( + cx, + NONSENSICAL_OPEN_OPTIONS, + span, + "the method \"create\" is called more than once", + ); } else { create = true } @@ -126,10 +129,12 @@ fn check_open_options(cx: &LateContext, options: &[(OpenOption, Argument)], span }, (OpenOption::Append, arg) => { if append { - span_lint(cx, - NONSENSICAL_OPEN_OPTIONS, - span, - "the method \"append\" is called more than once"); + span_lint( + cx, + NONSENSICAL_OPEN_OPTIONS, + span, + "the method \"append\" is called more than once", + ); } else { append = true } @@ -137,10 +142,12 @@ fn check_open_options(cx: &LateContext, options: &[(OpenOption, Argument)], span }, (OpenOption::Truncate, arg) => { if truncate { - span_lint(cx, - NONSENSICAL_OPEN_OPTIONS, - span, - "the method \"truncate\" is called more than once"); + span_lint( + cx, + NONSENSICAL_OPEN_OPTIONS, + span, + "the method \"truncate\" is called more than once", + ); } else { truncate = true } @@ -148,10 +155,12 @@ fn check_open_options(cx: &LateContext, options: &[(OpenOption, Argument)], span }, (OpenOption::Read, arg) => { if read { - span_lint(cx, - NONSENSICAL_OPEN_OPTIONS, - span, - "the method \"read\" is called more than once"); + span_lint( + cx, + NONSENSICAL_OPEN_OPTIONS, + span, + "the method \"read\" is called more than once", + ); } else { read = true } @@ -159,10 +168,12 @@ fn check_open_options(cx: &LateContext, options: &[(OpenOption, Argument)], span }, (OpenOption::Write, arg) => { if write { - span_lint(cx, - NONSENSICAL_OPEN_OPTIONS, - span, - "the method \"write\" is called more than once"); + span_lint( + cx, + NONSENSICAL_OPEN_OPTIONS, + span, + "the method \"write\" is called more than once", + ); } else { write = true } @@ -175,9 +186,11 @@ fn check_open_options(cx: &LateContext, options: &[(OpenOption, Argument)], span span_lint(cx, NONSENSICAL_OPEN_OPTIONS, span, "file opened with \"truncate\" and \"read\""); } if append && truncate && append_arg && truncate_arg { - span_lint(cx, - NONSENSICAL_OPEN_OPTIONS, - span, - "file opened with \"append\" and \"truncate\""); + span_lint( + cx, + NONSENSICAL_OPEN_OPTIONS, + span, + "file opened with \"append\" and \"truncate\"", + ); } } diff --git a/clippy_lints/src/precedence.rs b/clippy_lints/src/precedence.rs index e7b34136891..f5a6833b4b0 100644 --- a/clippy_lints/src/precedence.rs +++ b/clippy_lints/src/precedence.rs @@ -5,8 +5,10 @@ use utils::{span_lint_and_sugg, snippet}; /// **What it does:** Checks for operations where precedence may be unclear /// and suggests to add parentheses. Currently it catches the following: -/// * mixed usage of arithmetic and bit shifting/combining operators without parentheses -/// * a "negative" numeric literal (which is really a unary `-` followed by a numeric literal) +/// * mixed usage of arithmetic and bit shifting/combining operators without +/// parentheses +/// * a "negative" numeric literal (which is really a unary `-` followed by a +/// numeric literal) /// followed by a method call /// /// **Why is this bad?** Not everyone knows the precedence of those operators by @@ -24,7 +26,7 @@ declare_lint! { "operations where precedence may be unclear" } -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] pub struct Precedence; impl LintPass for Precedence { @@ -37,12 +39,14 @@ impl EarlyLintPass for Precedence { fn check_expr(&mut self, cx: &EarlyContext, expr: &Expr) { if let ExprKind::Binary(Spanned { node: op, .. }, ref left, ref right) = expr.node { let span_sugg = |expr: &Expr, sugg| { - span_lint_and_sugg(cx, - PRECEDENCE, - expr.span, - "operator precedence can trip the unwary", - "consider parenthesizing your expression", - sugg); + span_lint_and_sugg( + cx, + PRECEDENCE, + expr.span, + "operator precedence can trip the unwary", + "consider parenthesizing your expression", + sugg, + ); }; if !is_bit_op(op) { @@ -50,24 +54,30 @@ impl EarlyLintPass for Precedence { } match (is_arith_expr(left), is_arith_expr(right)) { (true, true) => { - let sugg = format!("({}) {} ({})", - snippet(cx, left.span, ".."), - op.to_string(), - snippet(cx, right.span, "..")); + let sugg = format!( + "({}) {} ({})", + snippet(cx, left.span, ".."), + op.to_string(), + snippet(cx, right.span, "..") + ); span_sugg(expr, sugg); }, (true, false) => { - let sugg = format!("({}) {} {}", - snippet(cx, left.span, ".."), - op.to_string(), - snippet(cx, right.span, "..")); + let sugg = format!( + "({}) {} {}", + snippet(cx, left.span, ".."), + op.to_string(), + snippet(cx, right.span, "..") + ); span_sugg(expr, sugg); }, (false, true) => { - let sugg = format!("{} {} ({})", - snippet(cx, left.span, ".."), - op.to_string(), - snippet(cx, right.span, "..")); + let sugg = format!( + "{} {} ({})", + snippet(cx, left.span, ".."), + op.to_string(), + snippet(cx, right.span, "..") + ); span_sugg(expr, sugg); }, (false, false) => (), @@ -82,12 +92,14 @@ impl EarlyLintPass for Precedence { LitKind::Int(..) | LitKind::Float(..) | LitKind::FloatUnsuffixed(..) => { - span_lint_and_sugg(cx, - PRECEDENCE, - expr.span, - "unary minus has lower precedence than method call", - "consider adding parentheses to clarify your intent", - format!("-({})", snippet(cx, rhs.span, ".."))); + span_lint_and_sugg( + cx, + PRECEDENCE, + expr.span, + "unary minus has lower precedence than method call", + "consider adding parentheses to clarify your intent", + format!("-({})", snippet(cx, rhs.span, "..")), + ); }, _ => (), } diff --git a/clippy_lints/src/print.rs b/clippy_lints/src/print.rs index a7f498af5c2..bf734cc9c0e 100644 --- a/clippy_lints/src/print.rs +++ b/clippy_lints/src/print.rs @@ -5,10 +5,12 @@ use utils::paths; use utils::{is_expn_of, match_def_path, resolve_node, span_lint, match_path_old}; use format::get_argument_fmtstr_parts; -/// **What it does:** This lint warns when you using `print!()` with a format string that +/// **What it does:** This lint warns when you using `print!()` with a format +/// string that /// ends in a newline. /// -/// **Why is this bad?** You should use `println!()` instead, which appends the newline. +/// **Why is this bad?** You should use `println!()` instead, which appends the +/// newline. /// /// **Known problems:** None. /// diff --git a/clippy_lints/src/ptr.rs b/clippy_lints/src/ptr.rs index f7017dfc5c3..5b5c63c1aca 100644 --- a/clippy_lints/src/ptr.rs +++ b/clippy_lints/src/ptr.rs @@ -9,11 +9,14 @@ use syntax::codemap::Span; use syntax_pos::MultiSpan; use utils::{match_path, match_type, paths, span_lint, span_lint_and_then}; -/// **What it does:** This lint checks for function arguments of type `&String` or `&Vec` unless +/// **What it does:** This lint checks for function arguments of type `&String` +/// or `&Vec` unless /// the references are mutable. /// -/// **Why is this bad?** Requiring the argument to be of the specific size makes the function less -/// useful for no benefit; slices in the form of `&[T]` or `&str` usually suffice and can be +/// **Why is this bad?** Requiring the argument to be of the specific size +/// makes the function less +/// useful for no benefit; slices in the form of `&[T]` or `&str` usually +/// suffice and can be /// obtained from other types, too. /// /// **Known problems:** None. @@ -31,7 +34,8 @@ declare_lint! { /// **What it does:** This lint checks for equality comparisons with `ptr::null` /// -/// **Why is this bad?** It's easier and more readable to use the inherent `.is_null()` +/// **Why is this bad?** It's easier and more readable to use the inherent +/// `.is_null()` /// method instead /// /// **Known problems:** None. @@ -46,15 +50,20 @@ declare_lint! { "comparing a pointer to a null pointer, suggesting to use `.is_null()` instead." } -/// **What it does:** This lint checks for functions that take immutable references and return +/// **What it does:** This lint checks for functions that take immutable +/// references and return /// mutable ones. /// -/// **Why is this bad?** This is trivially unsound, as one can create two mutable references -/// from the same (immutable!) source. This [error](https://github.com/rust-lang/rust/issues/39465) +/// **Why is this bad?** This is trivially unsound, as one can create two +/// mutable references +/// from the same (immutable!) source. This +/// [error](https://github.com/rust-lang/rust/issues/39465) /// actually lead to an interim Rust release 1.15.1. /// -/// **Known problems:** To be on the conservative side, if there's at least one mutable reference -/// with the output lifetime, this lint will not trigger. In practice, this case is unlikely anyway. +/// **Known problems:** To be on the conservative side, if there's at least one +/// mutable reference +/// with the output lifetime, this lint will not trigger. In practice, this +/// case is unlikely anyway. /// /// **Example:** /// ```rust @@ -66,7 +75,7 @@ declare_lint! { "fns that create mutable refs from immutable ref args" } -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] pub struct PointerPass; impl LintPass for PointerPass { @@ -102,10 +111,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PointerPass { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { if let ExprBinary(ref op, ref l, ref r) = expr.node { if (op.node == BiEq || op.node == BiNe) && (is_null_path(l) || is_null_path(r)) { - span_lint(cx, - CMP_NULL, - expr.span, - "Comparing with null is better expressed by the .is_null() method"); + span_lint( + cx, + CMP_NULL, + expr.span, + "Comparing with null is better expressed by the .is_null() method", + ); } } } @@ -117,19 +128,28 @@ fn check_fn(cx: &LateContext, decl: &FnDecl, fn_id: NodeId) { let fn_ty = sig.skip_binder(); for (arg, ty) in decl.inputs.iter().zip(fn_ty.inputs()) { - if let ty::TyRef(_, ty::TypeAndMut { ty, mutbl: MutImmutable }) = ty.sty { + if let ty::TyRef(_, + ty::TypeAndMut { + ty, + mutbl: MutImmutable, + }) = ty.sty + { if match_type(cx, ty, &paths::VEC) { - span_lint(cx, - PTR_ARG, - arg.span, - "writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used \ - with non-Vec-based slices. Consider changing the type to `&[...]`"); + span_lint( + cx, + PTR_ARG, + arg.span, + "writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used \ + with non-Vec-based slices. Consider changing the type to `&[...]`", + ); } else if match_type(cx, ty, &paths::STRING) { - span_lint(cx, - PTR_ARG, - arg.span, - "writing `&String` instead of `&str` involves a new object where a slice will do. \ - Consider changing the type to `&str`"); + span_lint( + cx, + PTR_ARG, + arg.span, + "writing `&String` instead of `&str` involves a new object where a slice will do. \ + Consider changing the type to `&str`", + ); } } } @@ -138,10 +158,10 @@ fn check_fn(cx: &LateContext, decl: &FnDecl, fn_id: NodeId) { if let Some((out, MutMutable, _)) = get_rptr_lm(ty) { let mut immutables = vec![]; for (_, ref mutbl, ref argspan) in - decl.inputs - .iter() - .filter_map(|ty| get_rptr_lm(ty)) - .filter(|&(lt, _, _)| lt.name == out.name) { + decl.inputs.iter().filter_map(|ty| get_rptr_lm(ty)).filter( + |&(lt, _, _)| lt.name == out.name, + ) + { if *mutbl == MutMutable { return; } diff --git a/clippy_lints/src/ranges.rs b/clippy_lints/src/ranges.rs index 037ebf8ba2c..aa43fb6b620 100644 --- a/clippy_lints/src/ranges.rs +++ b/clippy_lints/src/ranges.rs @@ -21,7 +21,8 @@ declare_lint! { "using `Iterator::step_by(0)`, which produces an infinite iterator" } -/// **What it does:** Checks for zipping a collection with the range of `0.._.len()`. +/// **What it does:** Checks for zipping a collection with the range of +/// `0.._.len()`. /// /// **Why is this bad?** The code is better expressed with `.enumerate()`. /// @@ -37,7 +38,7 @@ declare_lint! { "zipping iterator with a range when `enumerate()` would do" } -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] pub struct StepByZero; impl LintPass for StepByZero { @@ -57,10 +58,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StepByZero { use rustc_const_math::ConstInt::Usize; if let Some((Constant::Int(Usize(us)), _)) = constant(cx, &args[1]) { if us.as_u64(cx.sess().target.uint_type) == 0 { - span_lint(cx, - ITERATOR_STEP_BY_ZERO, - expr.span, - "Iterator::step_by(0) will panic at runtime"); + span_lint( + cx, + ITERATOR_STEP_BY_ZERO, + expr.span, + "Iterator::step_by(0) will panic at runtime", + ); } } } else if name == "zip" && args.len() == 2 { diff --git a/clippy_lints/src/reference.rs b/clippy_lints/src/reference.rs index a148d99aca8..a8360c71f91 100644 --- a/clippy_lints/src/reference.rs +++ b/clippy_lints/src/reference.rs @@ -40,12 +40,14 @@ impl EarlyLintPass for Pass { fn check_expr(&mut self, cx: &EarlyContext, e: &Expr) { if let ExprKind::Unary(UnOp::Deref, ref deref_target) = e.node { if let ExprKind::AddrOf(_, ref addrof_target) = without_parens(deref_target).node { - span_lint_and_sugg(cx, - DEREF_ADDROF, - e.span, - "immediately dereferencing a reference", - "try this", - format!("{}", snippet(cx, addrof_target.span, "_"))); + span_lint_and_sugg( + cx, + DEREF_ADDROF, + e.span, + "immediately dereferencing a reference", + "try this", + format!("{}", snippet(cx, addrof_target.span, "_")), + ); } } } diff --git a/clippy_lints/src/regex.rs b/clippy_lints/src/regex.rs index f0225591571..4feeb6d0939 100644 --- a/clippy_lints/src/regex.rs +++ b/clippy_lints/src/regex.rs @@ -178,7 +178,8 @@ fn is_trivial_regex(s: ®ex_syntax::Expr) -> Option<&'static str> { }, 3 => { if let (&Expr::StartText, &Expr::Literal { .. }, &Expr::EndText) = - (&exprs[0], &exprs[1], &exprs[2]) { + (&exprs[0], &exprs[1], &exprs[2]) + { Some("consider using `==` on `str`s") } else { None @@ -211,18 +212,22 @@ fn check_regex(cx: &LateContext, expr: &Expr, utf8: bool) { match builder.parse(r) { Ok(r) => { if let Some(repl) = is_trivial_regex(&r) { - span_help_and_lint(cx, - TRIVIAL_REGEX, - expr.span, - "trivial regex", - &format!("consider using {}", repl)); + span_help_and_lint( + cx, + TRIVIAL_REGEX, + expr.span, + "trivial regex", + &format!("consider using {}", repl), + ); } }, Err(e) => { - span_lint(cx, - INVALID_REGEX, - str_span(expr.span, r, e.position()), - &format!("regex syntax error: {}", e.description())); + span_lint( + cx, + INVALID_REGEX, + str_span(expr.span, r, e.position()), + &format!("regex syntax error: {}", e.description()), + ); }, } } @@ -230,18 +235,22 @@ fn check_regex(cx: &LateContext, expr: &Expr, utf8: bool) { match builder.parse(&r) { Ok(r) => { if let Some(repl) = is_trivial_regex(&r) { - span_help_and_lint(cx, - TRIVIAL_REGEX, - expr.span, - "trivial regex", - &format!("consider using {}", repl)); + span_help_and_lint( + cx, + TRIVIAL_REGEX, + expr.span, + "trivial regex", + &format!("consider using {}", repl), + ); } }, Err(e) => { - span_lint(cx, - INVALID_REGEX, - expr.span, - &format!("regex syntax error on position {}: {}", e.position(), e.description())); + span_lint( + cx, + INVALID_REGEX, + expr.span, + &format!("regex syntax error on position {}: {}", e.position(), e.description()), + ); }, } } diff --git a/clippy_lints/src/returns.rs b/clippy_lints/src/returns.rs index 41601a80890..b9fcb62de73 100644 --- a/clippy_lints/src/returns.rs +++ b/clippy_lints/src/returns.rs @@ -23,7 +23,8 @@ declare_lint! { "using a return statement like `return expr;` where an expression would suffice" } -/// **What it does:** Checks for `let`-bindings, which are subsequently returned. +/// **What it does:** Checks for `let`-bindings, which are subsequently +/// returned. /// /// **Why is this bad?** It is just extraneous code. Remove it to make your code /// more rusty. @@ -93,13 +94,11 @@ impl ReturnPass { if in_external_macro(cx, inner_span) || in_macro(inner_span) { return; } - span_lint_and_then(cx, - NEEDLESS_RETURN, - ret_span, - "unneeded return statement", - |db| if let Some(snippet) = snippet_opt(cx, inner_span) { - db.span_suggestion(ret_span, "remove `return` as shown", snippet); - }); + span_lint_and_then(cx, NEEDLESS_RETURN, ret_span, "unneeded return statement", |db| { + if let Some(snippet) = snippet_opt(cx, inner_span) { + db.span_suggestion(ret_span, "remove `return` as shown", snippet); + } + }); } // Check for "let x = EXPR; x" diff --git a/clippy_lints/src/serde_api.rs b/clippy_lints/src/serde_api.rs index df803473a2a..4feaaa19287 100644 --- a/clippy_lints/src/serde_api.rs +++ b/clippy_lints/src/serde_api.rs @@ -9,7 +9,8 @@ use utils::{span_lint, get_trait_def_id, paths}; /// /// **Known problems:** None. /// -/// **Example:** Implementing `Visitor::visit_string` but not `Visitor::visit_str`. +/// **Example:** Implementing `Visitor::visit_string` but not +/// `Visitor::visit_str`. declare_lint! { pub SERDE_API_MISUSE, Warn, @@ -43,10 +44,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Serde { } if let Some(span) = seen_string { if seen_str.is_none() { - span_lint(cx, - SERDE_API_MISUSE, - span, - "you should not implement `visit_string` without also implementing `visit_str`"); + span_lint( + cx, + SERDE_API_MISUSE, + span, + "you should not implement `visit_string` without also implementing `visit_str`", + ); } } } diff --git a/clippy_lints/src/shadow.rs b/clippy_lints/src/shadow.rs index 8a6b950327b..e80636ca347 100644 --- a/clippy_lints/src/shadow.rs +++ b/clippy_lints/src/shadow.rs @@ -87,7 +87,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { decl: &'tcx FnDecl, body: &'tcx Body, _: Span, - _: NodeId + _: NodeId, ) { if in_external_macro(cx, body.value.span) { return; @@ -129,7 +129,13 @@ fn check_decl<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, decl: &'tcx Decl, bindings: return; } if let DeclLocal(ref local) = decl.node { - let Local { ref pat, ref ty, ref init, span, .. } = **local; + let Local { + ref pat, + ref ty, + ref init, + span, + .. + } = **local; if let Some(ref t) = *ty { check_ty(cx, t, bindings) } @@ -155,7 +161,7 @@ fn check_pat<'a, 'tcx>( pat: &'tcx Pat, init: Option<&'tcx Expr>, span: Span, - bindings: &mut Vec<(Name, Span)> + bindings: &mut Vec<(Name, Span)>, ) { // TODO: match more stuff / destructuring match pat.node { @@ -184,9 +190,9 @@ fn check_pat<'a, 'tcx>( if let ExprStruct(_, ref efields, _) = init_struct.node { for field in pfields { let name = field.node.name; - let efield = efields.iter() - .find(|f| f.name.node == name) - .map(|f| &*f.expr); + let efield = efields.iter().find(|f| f.name.node == name).map( + |f| &*f.expr, + ); check_pat(cx, &field.node.pat, efield, span, bindings); } } else { @@ -240,39 +246,51 @@ fn lint_shadow<'a, 'tcx: 'a>( span: Span, pattern_span: Span, init: Option<&'tcx Expr>, - prev_span: Span + prev_span: Span, ) { if let Some(expr) = init { if is_self_shadow(name, expr) { - span_lint_and_then(cx, - SHADOW_SAME, - span, - &format!("`{}` is shadowed by itself in `{}`", - snippet(cx, pattern_span, "_"), - snippet(cx, expr.span, "..")), - |db| { db.span_note(prev_span, "previous binding is here"); }); + span_lint_and_then( + cx, + SHADOW_SAME, + span, + &format!( + "`{}` is shadowed by itself in `{}`", + snippet(cx, pattern_span, "_"), + snippet(cx, expr.span, "..") + ), + |db| { db.span_note(prev_span, "previous binding is here"); }, + ); } else if contains_self(name, expr) { - span_lint_and_then(cx, - SHADOW_REUSE, - pattern_span, - &format!("`{}` is shadowed by `{}` which reuses the original value", - snippet(cx, pattern_span, "_"), - snippet(cx, expr.span, "..")), - |db| { - db.span_note(expr.span, "initialization happens here"); - db.span_note(prev_span, "previous binding is here"); - }); + span_lint_and_then( + cx, + SHADOW_REUSE, + pattern_span, + &format!( + "`{}` is shadowed by `{}` which reuses the original value", + snippet(cx, pattern_span, "_"), + snippet(cx, expr.span, "..") + ), + |db| { + db.span_note(expr.span, "initialization happens here"); + db.span_note(prev_span, "previous binding is here"); + }, + ); } else { - span_lint_and_then(cx, - SHADOW_UNRELATED, - pattern_span, - &format!("`{}` is shadowed by `{}`", - snippet(cx, pattern_span, "_"), - snippet(cx, expr.span, "..")), - |db| { - db.span_note(expr.span, "initialization happens here"); - db.span_note(prev_span, "previous binding is here"); - }); + span_lint_and_then( + cx, + SHADOW_UNRELATED, + pattern_span, + &format!( + "`{}` is shadowed by `{}`", + snippet(cx, pattern_span, "_"), + snippet(cx, expr.span, "..") + ), + |db| { + db.span_note(expr.span, "initialization happens here"); + db.span_note(prev_span, "previous binding is here"); + }, + ); } } else { @@ -357,7 +375,11 @@ fn is_self_shadow(name: Name, expr: &Expr) -> bool { ExprBox(ref inner) | ExprAddrOf(_, ref inner) => is_self_shadow(name, inner), ExprBlock(ref block) => { - block.stmts.is_empty() && block.expr.as_ref().map_or(false, |e| is_self_shadow(name, e)) + block.stmts.is_empty() && + block.expr.as_ref().map_or( + false, + |e| is_self_shadow(name, e), + ) }, ExprUnary(op, ref inner) => (UnDeref == op) && is_self_shadow(name, inner), ExprPath(QPath::Resolved(_, ref path)) => path_eq_name(name, path), diff --git a/clippy_lints/src/should_assert_eq.rs b/clippy_lints/src/should_assert_eq.rs index ea79a77877a..ecb2c9c3162 100644 --- a/clippy_lints/src/should_assert_eq.rs +++ b/clippy_lints/src/should_assert_eq.rs @@ -2,10 +2,12 @@ use rustc::lint::*; use rustc::hir::*; use utils::{is_direct_expn_of, is_expn_of, implements_trait, span_lint}; -/// **What it does:** Checks for `assert!(x == y)` or `assert!(x != y)` which can be better written +/// **What it does:** Checks for `assert!(x == y)` or `assert!(x != y)` which +/// can be better written /// using `assert_eq` or `assert_ne` if `x` and `y` implement `Debug` trait. /// -/// **Why is this bad?** `assert_eq` and `assert_ne` provide better assertion failure reporting. +/// **Why is this bad?** `assert_eq` and `assert_ne` provide better assertion +/// failure reporting. /// /// **Known problems:** Hopefully none. /// @@ -14,7 +16,8 @@ use utils::{is_direct_expn_of, is_expn_of, implements_trait, span_lint}; /// let (x, y) = (1, 2); /// /// assert!(x == y); // assertion failed: x == y -/// assert_eq!(x, y); // assertion failed: `(left == right)` (left: `1`, right: `2`) +/// assert_eq!(x, y); // assertion failed: `(left == right)` (left: `1`, right: +/// `2`) /// ``` declare_lint! { pub SHOULD_ASSERT_EQ, diff --git a/clippy_lints/src/strings.rs b/clippy_lints/src/strings.rs index 043d1dff8e5..9b61f902c49 100644 --- a/clippy_lints/src/strings.rs +++ b/clippy_lints/src/strings.rs @@ -96,18 +96,22 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringAdd { } } } - span_lint(cx, - STRING_ADD, - e.span, - "you added something to a string. Consider using `String::push_str()` instead"); + span_lint( + cx, + STRING_ADD, + e.span, + "you added something to a string. Consider using `String::push_str()` instead", + ); } } else if let ExprAssign(ref target, ref src) = e.node { if is_string(cx, target) && is_add(cx, src, target) { - span_lint(cx, - STRING_ADD_ASSIGN, - e.span, - "you assigned the result of adding something to this string. Consider using \ - `String::push_str()` instead"); + span_lint( + cx, + STRING_ADD_ASSIGN, + e.span, + "you assigned the result of adding something to this string. Consider using \ + `String::push_str()` instead", + ); } } } @@ -121,7 +125,11 @@ fn is_add(cx: &LateContext, src: &Expr, target: &Expr) -> bool { match src.node { ExprBinary(Spanned { node: BiAdd, .. }, ref left, _) => SpanlessEq::new(cx).eq_expr(target, left), ExprBlock(ref block) => { - block.stmts.is_empty() && block.expr.as_ref().map_or(false, |expr| is_add(cx, expr, target)) + block.stmts.is_empty() && + block.expr.as_ref().map_or( + false, + |expr| is_add(cx, expr, target), + ) }, _ => false, } @@ -147,12 +155,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringLitAsBytes { if let ExprLit(ref lit) = args[0].node { if let LitKind::Str(ref lit_content, _) = lit.node { if lit_content.as_str().chars().all(|c| c.is_ascii()) && !in_macro(args[0].span) { - span_lint_and_sugg(cx, - STRING_LIT_AS_BYTES, - e.span, - "calling `as_bytes()` on a string literal", - "consider using a byte string literal instead", - format!("b{}", snippet(cx, args[0].span, r#""foo""#))); + span_lint_and_sugg( + cx, + STRING_LIT_AS_BYTES, + e.span, + "calling `as_bytes()` on a string literal", + "consider using a byte string literal instead", + format!("b{}", snippet(cx, args[0].span, r#""foo""#)), + ); } } } diff --git a/clippy_lints/src/swap.rs b/clippy_lints/src/swap.rs index b2c56fe8bf3..e17170db192 100644 --- a/clippy_lints/src/swap.rs +++ b/clippy_lints/src/swap.rs @@ -41,7 +41,7 @@ declare_lint! { "`foo = bar; bar = foo` sequence" } -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] pub struct Swap; impl LintPass for Swap { diff --git a/clippy_lints/src/transmute.rs b/clippy_lints/src/transmute.rs index 1d67e06f811..13555e3bb05 100644 --- a/clippy_lints/src/transmute.rs +++ b/clippy_lints/src/transmute.rs @@ -49,7 +49,8 @@ declare_lint! { /// /// **Example:** /// ```rust -/// core::intrinsics::transmute(t)` // where the result type is the same as `*t` or `&t`'s +/// core::intrinsics::transmute(t)` // where the result type is the same as +/// `*t` or `&t`'s /// ``` declare_lint! { pub CROSSPOINTER_TRANSMUTE, @@ -79,7 +80,7 @@ pub struct Transmute; impl LintPass for Transmute { fn get_lints(&self) -> LintArray { - lint_array![CROSSPOINTER_TRANSMUTE, TRANSMUTE_PTR_TO_REF, USELESS_TRANSMUTE, WRONG_TRANSMUTE] + lint_array!(CROSSPOINTER_TRANSMUTE, TRANSMUTE_PTR_TO_REF, USELESS_TRANSMUTE, WRONG_TRANSMUTE) } } @@ -95,87 +96,101 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Transmute { match (&from_ty.sty, &to_ty.sty) { _ if from_ty == to_ty => { - span_lint(cx, - USELESS_TRANSMUTE, - e.span, - &format!("transmute from a type (`{}`) to itself", from_ty)) + span_lint( + cx, + USELESS_TRANSMUTE, + e.span, + &format!("transmute from a type (`{}`) to itself", from_ty), + ) }, (&ty::TyRef(_, rty), &ty::TyRawPtr(ptr_ty)) => { - span_lint_and_then(cx, - USELESS_TRANSMUTE, - e.span, - "transmute from a reference to a pointer", - |db| if let Some(arg) = sugg::Sugg::hir_opt(cx, &args[0]) { - let sugg = if ptr_ty == rty { - arg.as_ty(to_ty) - } else { - arg.as_ty(cx.tcx.mk_ptr(rty)).as_ty(to_ty) - }; + span_lint_and_then( + cx, + USELESS_TRANSMUTE, + e.span, + "transmute from a reference to a pointer", + |db| if let Some(arg) = sugg::Sugg::hir_opt(cx, &args[0]) { + let sugg = if ptr_ty == rty { + arg.as_ty(to_ty) + } else { + arg.as_ty(cx.tcx.mk_ptr(rty)).as_ty(to_ty) + }; - db.span_suggestion(e.span, "try", sugg.to_string()); - }) + db.span_suggestion(e.span, "try", sugg.to_string()); + }, + ) }, (&ty::TyInt(_), &ty::TyRawPtr(_)) | (&ty::TyUint(_), &ty::TyRawPtr(_)) => { - span_lint_and_then(cx, - USELESS_TRANSMUTE, - e.span, - "transmute from an integer to a pointer", - |db| if let Some(arg) = sugg::Sugg::hir_opt(cx, &args[0]) { - db.span_suggestion(e.span, - "try", - arg.as_ty(&to_ty.to_string()).to_string()); - }) + span_lint_and_then( + cx, + USELESS_TRANSMUTE, + e.span, + "transmute from an integer to a pointer", + |db| if let Some(arg) = sugg::Sugg::hir_opt(cx, &args[0]) { + db.span_suggestion(e.span, "try", arg.as_ty(&to_ty.to_string()).to_string()); + }, + ) }, (&ty::TyFloat(_), &ty::TyRef(..)) | (&ty::TyFloat(_), &ty::TyRawPtr(_)) | (&ty::TyChar, &ty::TyRef(..)) | (&ty::TyChar, &ty::TyRawPtr(_)) => { - span_lint(cx, - WRONG_TRANSMUTE, - e.span, - &format!("transmute from a `{}` to a pointer", from_ty)) + span_lint( + cx, + WRONG_TRANSMUTE, + e.span, + &format!("transmute from a `{}` to a pointer", from_ty), + ) }, (&ty::TyRawPtr(from_ptr), _) if from_ptr.ty == to_ty => { - span_lint(cx, - CROSSPOINTER_TRANSMUTE, - e.span, - &format!("transmute from a type (`{}`) to the type that it points to (`{}`)", - from_ty, - to_ty)) + span_lint( + cx, + CROSSPOINTER_TRANSMUTE, + e.span, + &format!( + "transmute from a type (`{}`) to the type that it points to (`{}`)", + from_ty, + to_ty + ), + ) }, (_, &ty::TyRawPtr(to_ptr)) if to_ptr.ty == from_ty => { - span_lint(cx, - CROSSPOINTER_TRANSMUTE, - e.span, - &format!("transmute from a type (`{}`) to a pointer to that type (`{}`)", - from_ty, - to_ty)) + span_lint( + cx, + CROSSPOINTER_TRANSMUTE, + e.span, + &format!("transmute from a type (`{}`) to a pointer to that type (`{}`)", from_ty, to_ty), + ) }, (&ty::TyRawPtr(from_pty), &ty::TyRef(_, to_rty)) => { - span_lint_and_then(cx, - TRANSMUTE_PTR_TO_REF, - e.span, - &format!("transmute from a pointer type (`{}`) to a reference type \ + span_lint_and_then( + cx, + TRANSMUTE_PTR_TO_REF, + e.span, + &format!( + "transmute from a pointer type (`{}`) to a reference type \ (`{}`)", - from_ty, - to_ty), - |db| { - let arg = sugg::Sugg::hir(cx, &args[0], ".."); - let (deref, cast) = if to_rty.mutbl == Mutability::MutMutable { - ("&mut *", "*mut") - } else { - ("&*", "*const") - }; + from_ty, + to_ty + ), + |db| { + let arg = sugg::Sugg::hir(cx, &args[0], ".."); + let (deref, cast) = if to_rty.mutbl == Mutability::MutMutable { + ("&mut *", "*mut") + } else { + ("&*", "*const") + }; - let arg = if from_pty.ty == to_rty.ty { - arg - } else { - arg.as_ty(&format!("{} {}", cast, get_type_snippet(cx, qpath, to_rty.ty))) - }; + let arg = if from_pty.ty == to_rty.ty { + arg + } else { + arg.as_ty(&format!("{} {}", cast, get_type_snippet(cx, qpath, to_rty.ty))) + }; - db.span_suggestion(e.span, "try", sugg::make_unop(deref, arg).to_string()); - }) + db.span_suggestion(e.span, "try", sugg::make_unop(deref, arg).to_string()); + }, + ) }, _ => return, }; @@ -185,8 +200,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Transmute { } } -/// Get the snippet of `Bar` in `…::transmute`. If that snippet is not available , use -/// the type's `ToString` implementation. In weird cases it could lead to types with invalid `'_` +/// Get the snippet of `Bar` in `…::transmute`. If that snippet is +/// not available , use +/// the type's `ToString` implementation. In weird cases it could lead to types +/// with invalid `'_` /// lifetime, but it should be rare. fn get_type_snippet(cx: &LateContext, path: &QPath, to_rty: Ty) -> String { let seg = last_path_segment(path); diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index 66cb5671c77..44e33d40a38 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -42,14 +42,21 @@ declare_lint! { /// /// **Why is this bad?** Gankro says: /// -/// > The TL;DR of `LinkedList` is that it's built on a massive amount of pointers and indirection. -/// > It wastes memory, it has terrible cache locality, and is all-around slow. `RingBuf`, while -/// > "only" amortized for push/pop, should be faster in the general case for almost every possible -/// > workload, and isn't even amortized at all if you can predict the capacity you need. +/// > The TL;DR of `LinkedList` is that it's built on a massive amount of +/// pointers and indirection. +/// > It wastes memory, it has terrible cache locality, and is all-around slow. +/// `RingBuf`, while +/// > "only" amortized for push/pop, should be faster in the general case for +/// almost every possible +/// > workload, and isn't even amortized at all if you can predict the capacity +/// you need. /// > -/// > `LinkedList`s are only really good if you're doing a lot of merging or splitting of lists. -/// > This is because they can just mangle some pointers instead of actually copying the data. Even -/// > if you're doing a lot of insertion in the middle of the list, `RingBuf` can still be better +/// > `LinkedList`s are only really good if you're doing a lot of merging or +/// splitting of lists. +/// > This is because they can just mangle some pointers instead of actually +/// copying the data. Even +/// > if you're doing a lot of insertion in the middle of the list, `RingBuf` +/// can still be better /// > because of how expensive it is to seek to the middle of a `LinkedList`. /// /// **Known problems:** False positives – the instances where using a @@ -68,7 +75,8 @@ declare_lint! { /// **What it does:** Checks for use of `&Box` anywhere in the code. /// -/// **Why is this bad?** Any `&Box` can also be a `&T`, which is more general. +/// **Why is this bad?** Any `&Box` can also be a `&T`, which is more +/// general. /// /// **Known problems:** None. /// @@ -161,11 +169,13 @@ fn check_ty(cx: &LateContext, ast_ty: &hir::Ty, is_local: bool) { return; // don't recurse into the type }} } else if match_def_path(cx.tcx, def_id, &paths::LINKED_LIST) { - span_help_and_lint(cx, - LINKEDLIST, - ast_ty.span, - "I see you're using a LinkedList! Perhaps you meant some other data structure?", - "a VecDeque might work"); + span_help_and_lint( + cx, + LINKEDLIST, + ast_ty.span, + "I see you're using a LinkedList! Perhaps you meant some other data structure?", + "a VecDeque might work", + ); return; // don't recurse into the type } } @@ -268,11 +278,15 @@ fn check_let_unit(cx: &LateContext, decl: &Decl) { if higher::is_from_for_desugar(decl) { return; } - span_lint(cx, - LET_UNIT_VALUE, - decl.span, - &format!("this let-binding has unit value. Consider omitting `let {} =`", - snippet(cx, local.pat.span, ".."))); + span_lint( + cx, + LET_UNIT_VALUE, + decl.span, + &format!( + "this let-binding has unit value. Consider omitting `let {} =`", + snippet(cx, local.pat.span, "..") + ), + ); }, _ => (), } @@ -336,12 +350,16 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnitCmp { BiEq | BiLe | BiGe => "true", _ => "false", }; - span_lint(cx, - UNIT_CMP, - expr.span, - &format!("{}-comparison of unit values detected. This will always be {}", - op.as_str(), - result)); + span_lint( + cx, + UNIT_CMP, + expr.span, + &format!( + "{}-comparison of unit values detected. This will always be {}", + op.as_str(), + result + ), + ); }, _ => (), } @@ -493,20 +511,24 @@ fn span_precision_loss_lint(cx: &LateContext, expr: &Expr, cast_from: Ty, cast_t } else { int_ty_to_nbits(cast_from).to_string() }; - span_lint(cx, - CAST_PRECISION_LOSS, - expr.span, - &format!("casting {0} to {1} causes a loss of precision {2}({0} is {3} bits wide, but {1}'s mantissa \ + span_lint( + cx, + CAST_PRECISION_LOSS, + expr.span, + &format!( + "casting {0} to {1} causes a loss of precision {2}({0} is {3} bits wide, but {1}'s mantissa \ is only {4} bits wide)", - cast_from, - if cast_to_f64 { "f64" } else { "f32" }, - if arch_dependent { - arch_dependent_str - } else { - "" - }, - from_nbits_str, - mantissa_nbits)); + cast_from, + if cast_to_f64 { "f64" } else { "f32" }, + if arch_dependent { + arch_dependent_str + } else { + "" + }, + from_nbits_str, + mantissa_nbits + ), + ); } enum ArchSuffix { @@ -520,70 +542,86 @@ fn check_truncation_and_wrapping(cx: &LateContext, expr: &Expr, cast_from: Ty, c let arch_32_suffix = " on targets with 32-bit wide pointers"; let cast_unsigned_to_signed = !cast_from.is_signed() && cast_to.is_signed(); let (from_nbits, to_nbits) = (int_ty_to_nbits(cast_from), int_ty_to_nbits(cast_to)); - let (span_truncation, suffix_truncation, span_wrap, suffix_wrap) = match (is_isize_or_usize(cast_from), - is_isize_or_usize(cast_to)) { - (true, true) | (false, false) => { - (to_nbits < from_nbits, - ArchSuffix::None, - to_nbits == from_nbits && cast_unsigned_to_signed, - ArchSuffix::None) - }, - (true, false) => { - (to_nbits <= 32, - if to_nbits == 32 { - ArchSuffix::_64 - } else { - ArchSuffix::None - }, - to_nbits <= 32 && cast_unsigned_to_signed, - ArchSuffix::_32) - }, - (false, true) => { - (from_nbits == 64, - ArchSuffix::_32, - cast_unsigned_to_signed, - if from_nbits == 64 { - ArchSuffix::_64 - } else { - ArchSuffix::_32 - }) - }, - }; + let (span_truncation, suffix_truncation, span_wrap, suffix_wrap) = + match (is_isize_or_usize(cast_from), is_isize_or_usize(cast_to)) { + (true, true) | (false, false) => { + ( + to_nbits < from_nbits, + ArchSuffix::None, + to_nbits == from_nbits && cast_unsigned_to_signed, + ArchSuffix::None, + ) + }, + (true, false) => { + ( + to_nbits <= 32, + if to_nbits == 32 { + ArchSuffix::_64 + } else { + ArchSuffix::None + }, + to_nbits <= 32 && cast_unsigned_to_signed, + ArchSuffix::_32, + ) + }, + (false, true) => { + ( + from_nbits == 64, + ArchSuffix::_32, + cast_unsigned_to_signed, + if from_nbits == 64 { + ArchSuffix::_64 + } else { + ArchSuffix::_32 + }, + ) + }, + }; if span_truncation { - span_lint(cx, - CAST_POSSIBLE_TRUNCATION, - expr.span, - &format!("casting {} to {} may truncate the value{}", - cast_from, - cast_to, - match suffix_truncation { - ArchSuffix::_32 => arch_32_suffix, - ArchSuffix::_64 => arch_64_suffix, - ArchSuffix::None => "", - })); + span_lint( + cx, + CAST_POSSIBLE_TRUNCATION, + expr.span, + &format!( + "casting {} to {} may truncate the value{}", + cast_from, + cast_to, + match suffix_truncation { + ArchSuffix::_32 => arch_32_suffix, + ArchSuffix::_64 => arch_64_suffix, + ArchSuffix::None => "", + } + ), + ); } if span_wrap { - span_lint(cx, - CAST_POSSIBLE_WRAP, - expr.span, - &format!("casting {} to {} may wrap around the value{}", - cast_from, - cast_to, - match suffix_wrap { - ArchSuffix::_32 => arch_32_suffix, - ArchSuffix::_64 => arch_64_suffix, - ArchSuffix::None => "", - })); + span_lint( + cx, + CAST_POSSIBLE_WRAP, + expr.span, + &format!( + "casting {} to {} may wrap around the value{}", + cast_from, + cast_to, + match suffix_wrap { + ArchSuffix::_32 => arch_32_suffix, + ArchSuffix::_64 => arch_64_suffix, + ArchSuffix::None => "", + } + ), + ); } } impl LintPass for CastPass { fn get_lints(&self) -> LintArray { - lint_array!(CAST_PRECISION_LOSS, - CAST_SIGN_LOSS, - CAST_POSSIBLE_TRUNCATION, - CAST_POSSIBLE_WRAP, - UNNECESSARY_CAST) + lint_array!( + CAST_PRECISION_LOSS, + CAST_SIGN_LOSS, + CAST_POSSIBLE_TRUNCATION, + CAST_POSSIBLE_WRAP, + UNNECESSARY_CAST + ) } } @@ -598,12 +636,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CastPass { LitKind::FloatUnsuffixed(_) => {}, _ => { if cast_from.sty == cast_to.sty && !in_external_macro(cx, expr.span) { - span_lint(cx, - UNNECESSARY_CAST, - expr.span, - &format!("casting to the same type is unnecessary (`{}` -> `{}`)", - cast_from, - cast_to)); + span_lint( + cx, + UNNECESSARY_CAST, + expr.span, + &format!("casting to the same type is unnecessary (`{}` -> `{}`)", cast_from, cast_to), + ); } }, } @@ -622,33 +660,42 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CastPass { } }, (false, true) => { - span_lint(cx, - CAST_POSSIBLE_TRUNCATION, - expr.span, - &format!("casting {} to {} may truncate the value", cast_from, cast_to)); + span_lint( + cx, + CAST_POSSIBLE_TRUNCATION, + expr.span, + &format!("casting {} to {} may truncate the value", cast_from, cast_to), + ); if !cast_to.is_signed() { - span_lint(cx, - CAST_SIGN_LOSS, - expr.span, - &format!("casting {} to {} may lose the sign of the value", cast_from, cast_to)); + span_lint( + cx, + CAST_SIGN_LOSS, + expr.span, + &format!("casting {} to {} may lose the sign of the value", cast_from, cast_to), + ); } }, (true, true) => { if cast_from.is_signed() && !cast_to.is_signed() { - span_lint(cx, - CAST_SIGN_LOSS, - expr.span, - &format!("casting {} to {} may lose the sign of the value", cast_from, cast_to)); + span_lint( + cx, + CAST_SIGN_LOSS, + expr.span, + &format!("casting {} to {} may lose the sign of the value", cast_from, cast_to), + ); } check_truncation_and_wrapping(cx, expr, cast_from, cast_to); }, (false, false) => { if let (&ty::TyFloat(FloatTy::F64), &ty::TyFloat(FloatTy::F32)) = - (&cast_from.sty, &cast_to.sty) { - span_lint(cx, - CAST_POSSIBLE_TRUNCATION, - expr.span, - "casting f64 to f32 may truncate the value"); + (&cast_from.sty, &cast_to.sty) + { + span_lint( + cx, + CAST_POSSIBLE_TRUNCATION, + expr.span, + "casting f64 to f32 may truncate the value", + ); } }, } @@ -700,7 +747,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeComplexityPass { decl: &'tcx FnDecl, _: &'tcx Body, _: Span, - _: NodeId + _: NodeId, ) { self.check_fndecl(cx, decl); } @@ -760,19 +807,18 @@ impl<'a, 'tcx> TypeComplexityPass { return; } let score = { - let mut visitor = TypeComplexityVisitor { - score: 0, - nest: 1, - }; + let mut visitor = TypeComplexityVisitor { score: 0, nest: 1 }; visitor.visit_ty(ty); visitor.score }; if score > self.threshold { - span_lint(cx, - TYPE_COMPLEXITY, - ty.span, - "very complex type used. Consider factoring parts into `type` definitions"); + span_lint( + cx, + TYPE_COMPLEXITY, + ty.span, + "very complex type used. Consider factoring parts into `type` definitions", + ); } } } @@ -798,8 +844,9 @@ impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor { TyBareFn(..) => (50 * self.nest, 1), TyTraitObject(ref param_bounds, _) => { - let has_lifetime_parameters = param_bounds.iter() - .any(|bound| !bound.bound_lifetimes.is_empty()); + let has_lifetime_parameters = param_bounds.iter().any( + |bound| !bound.bound_lifetimes.is_empty(), + ); if has_lifetime_parameters { // complex trait bounds like A<'a, 'b> (50 * self.nest, 1) @@ -922,7 +969,7 @@ fn detect_absurd_comparison<'a>( cx: &LateContext, op: BinOp_, lhs: &'a Expr, - rhs: &'a Expr + rhs: &'a Expr, ) -> Option<(ExtremeExpr<'a>, AbsurdComparisonResult)> { use types::ExtremeType::*; use types::AbsurdComparisonResult::*; @@ -1042,20 +1089,24 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AbsurdExtremeComparisons { AlwaysFalse => "this comparison is always false".to_owned(), AlwaysTrue => "this comparison is always true".to_owned(), InequalityImpossible => { - format!("the case where the two sides are not equal never occurs, consider using {} == {} \ + format!( + "the case where the two sides are not equal never occurs, consider using {} == {} \ instead", - snippet(cx, lhs.span, "lhs"), - snippet(cx, rhs.span, "rhs")) + snippet(cx, lhs.span, "lhs"), + snippet(cx, rhs.span, "rhs") + ) }, }; - let help = format!("because {} is the {} value for this type, {}", - snippet(cx, culprit.expr.span, "x"), - match culprit.which { - Minimum => "minimum", - Maximum => "maximum", - }, - conclusion); + let help = format!( + "because {} is the {} value for this type, {}", + snippet(cx, culprit.expr.span, "x"), + match culprit.which { + Minimum => "minimum", + Maximum => "maximum", + }, + conclusion + ); span_help_and_lint(cx, ABSURD_EXTREME_COMPARISONS, expr.span, msg, &help); } @@ -1113,7 +1164,9 @@ impl FullInt { impl PartialEq for FullInt { fn eq(&self, other: &Self) -> bool { - self.partial_cmp(other).expect("partial_cmp only returns Some(_)") == Ordering::Equal + self.partial_cmp(other).expect( + "partial_cmp only returns Some(_)", + ) == Ordering::Equal } } @@ -1129,7 +1182,9 @@ impl PartialOrd for FullInt { } impl Ord for FullInt { fn cmp(&self, other: &Self) -> Ordering { - self.partial_cmp(other).expect("partial_cmp for FullInt can never return None") + self.partial_cmp(other).expect( + "partial_cmp for FullInt can never return None", + ) } } @@ -1198,14 +1253,16 @@ fn node_as_const_fullint(cx: &LateContext, expr: &Expr) -> Option { fn err_upcast_comparison(cx: &LateContext, span: &Span, expr: &Expr, always: bool) { if let ExprCast(ref cast_val, _) = expr.node { - span_lint(cx, - INVALID_UPCAST_COMPARISONS, - *span, - &format!( + span_lint( + cx, + INVALID_UPCAST_COMPARISONS, + *span, + &format!( "because of the numeric bounds on `{}` prior to casting, this expression is always {}", snippet(cx, cast_val.span, "the expression"), if always { "true" } else { "false" }, - )); + ), + ); } } @@ -1216,7 +1273,7 @@ fn upcast_comparison_bounds_err( lhs_bounds: Option<(FullInt, FullInt)>, lhs: &Expr, rhs: &Expr, - invert: bool + invert: bool, ) { use utils::comparisons::*; @@ -1227,40 +1284,42 @@ fn upcast_comparison_bounds_err( err_upcast_comparison(cx, span, lhs, rel == Rel::Ne); } } else if match rel { - Rel::Lt => { - if invert { - norm_rhs_val < lb - } else { - ub < norm_rhs_val - } - }, - Rel::Le => { - if invert { - norm_rhs_val <= lb - } else { - ub <= norm_rhs_val - } - }, - Rel::Eq | Rel::Ne => unreachable!(), - } { + Rel::Lt => { + if invert { + norm_rhs_val < lb + } else { + ub < norm_rhs_val + } + }, + Rel::Le => { + if invert { + norm_rhs_val <= lb + } else { + ub <= norm_rhs_val + } + }, + Rel::Eq | Rel::Ne => unreachable!(), + } + { err_upcast_comparison(cx, span, lhs, true) } else if match rel { - Rel::Lt => { - if invert { - norm_rhs_val >= ub - } else { - lb >= norm_rhs_val - } - }, - Rel::Le => { - if invert { - norm_rhs_val > ub - } else { - lb > norm_rhs_val - } - }, - Rel::Eq | Rel::Ne => unreachable!(), - } { + Rel::Lt => { + if invert { + norm_rhs_val >= ub + } else { + lb >= norm_rhs_val + } + }, + Rel::Le => { + if invert { + norm_rhs_val > ub + } else { + lb > norm_rhs_val + } + }, + Rel::Eq | Rel::Ne => unreachable!(), + } + { err_upcast_comparison(cx, span, lhs, false) } } diff --git a/clippy_lints/src/unicode.rs b/clippy_lints/src/unicode.rs index 1d5ab7db346..ace8ea7558d 100644 --- a/clippy_lints/src/unicode.rs +++ b/clippy_lints/src/unicode.rs @@ -12,7 +12,8 @@ use utils::{snippet, span_help_and_lint}; /// /// **Known problems:** None. /// -/// **Example:** You don't see it, but there may be a zero-width space somewhere in this text. +/// **Example:** You don't see it, but there may be a zero-width space +/// somewhere in this text. declare_lint! { pub ZERO_WIDTH_SPACE, Deny, @@ -95,30 +96,40 @@ fn escape>(s: T) -> String { fn check_str(cx: &LateContext, span: Span) { let string = snippet(cx, span, ""); if string.contains('\u{200B}') { - span_help_and_lint(cx, - ZERO_WIDTH_SPACE, - span, - "zero-width space detected", - &format!("Consider replacing the string with:\n\"{}\"", - string.replace("\u{200B}", "\\u{200B}"))); + span_help_and_lint( + cx, + ZERO_WIDTH_SPACE, + span, + "zero-width space detected", + &format!( + "Consider replacing the string with:\n\"{}\"", + string.replace("\u{200B}", "\\u{200B}") + ), + ); } if string.chars().any(|c| c as u32 > 0x7F) { - span_help_and_lint(cx, - NON_ASCII_LITERAL, - span, - "literal non-ASCII character detected", - &format!("Consider replacing the string with:\n\"{}\"", - if cx.current_level(UNICODE_NOT_NFC) == Level::Allow { - escape(string.chars()) - } else { - escape(string.nfc()) - })); + span_help_and_lint( + cx, + NON_ASCII_LITERAL, + span, + "literal non-ASCII character detected", + &format!( + "Consider replacing the string with:\n\"{}\"", + if cx.current_level(UNICODE_NOT_NFC) == Level::Allow { + escape(string.chars()) + } else { + escape(string.nfc()) + } + ), + ); } if cx.current_level(NON_ASCII_LITERAL) == Level::Allow && string.chars().zip(string.nfc()).any(|(a, b)| a != b) { - span_help_and_lint(cx, - UNICODE_NOT_NFC, - span, - "non-nfc unicode sequence detected", - &format!("Consider replacing the string with:\n\"{}\"", string.nfc().collect::())); + span_help_and_lint( + cx, + UNICODE_NOT_NFC, + span, + "non-nfc unicode sequence detected", + &format!("Consider replacing the string with:\n\"{}\"", string.nfc().collect::()), + ); } } diff --git a/clippy_lints/src/unsafe_removed_from_name.rs b/clippy_lints/src/unsafe_removed_from_name.rs index 07afc55ae7f..036e6f0f0e6 100644 --- a/clippy_lints/src/unsafe_removed_from_name.rs +++ b/clippy_lints/src/unsafe_removed_from_name.rs @@ -38,13 +38,15 @@ impl EarlyLintPass for UnsafeNameRemoval { if let ItemKind::Use(ref item_use) = item.node { match item_use.node { ViewPath_::ViewPathSimple(ref name, ref path) => { - unsafe_to_safe_check(path.segments - .last() - .expect("use paths cannot be empty") - .identifier, - *name, - cx, - &item.span); + unsafe_to_safe_check( + path.segments + .last() + .expect("use paths cannot be empty") + .identifier, + *name, + cx, + &item.span, + ); }, ViewPath_::ViewPathList(_, ref path_list_items) => { for path_list_item in path_list_items.iter() { @@ -64,10 +66,12 @@ fn unsafe_to_safe_check(old_name: Ident, new_name: Ident, cx: &EarlyContext, spa let old_str = old_name.name.as_str(); let new_str = new_name.name.as_str(); if contains_unsafe(&old_str) && !contains_unsafe(&new_str) { - span_lint(cx, - UNSAFE_REMOVED_FROM_NAME, - *span, - &format!("removed \"unsafe\" from the name of `{}` in use as `{}`", old_str, new_str)); + span_lint( + cx, + UNSAFE_REMOVED_FROM_NAME, + *span, + &format!("removed \"unsafe\" from the name of `{}` in use as `{}`", old_str, new_str), + ); } } diff --git a/clippy_lints/src/unused_io_amount.rs b/clippy_lints/src/unused_io_amount.rs index 5a97254f3ad..ff2148c88a9 100644 --- a/clippy_lints/src/unused_io_amount.rs +++ b/clippy_lints/src/unused_io_amount.rs @@ -4,9 +4,12 @@ use utils::{span_lint, match_path, match_trait_method, is_try, paths}; /// **What it does:** Checks for unused written/read amount. /// -/// **Why is this bad?** `io::Write::write` and `io::Read::read` are not guaranteed to -/// process the entire buffer. They return how many bytes were processed, which might be smaller -/// than a given buffer's length. If you don't need to deal with partial-write/read, use +/// **Why is this bad?** `io::Write::write` and `io::Read::read` are not +/// guaranteed to +/// process the entire buffer. They return how many bytes were processed, which +/// might be smaller +/// than a given buffer's length. If you don't need to deal with +/// partial-write/read, use /// `write_all`/`read_exact` instead. /// /// **Known problems:** Detects only common patterns. @@ -73,15 +76,19 @@ fn check_method_call(cx: &LateContext, call: &hir::Expr, expr: &hir::Expr) { if let hir::ExprMethodCall(ref path, _, _) = call.node { let symbol = &*path.name.as_str(); if match_trait_method(cx, call, &paths::IO_READ) && symbol == "read" { - span_lint(cx, - UNUSED_IO_AMOUNT, - expr.span, - "handle read amount returned or use `Read::read_exact` instead"); + span_lint( + cx, + UNUSED_IO_AMOUNT, + expr.span, + "handle read amount returned or use `Read::read_exact` instead", + ); } else if match_trait_method(cx, call, &paths::IO_WRITE) && symbol == "write" { - span_lint(cx, - UNUSED_IO_AMOUNT, - expr.span, - "handle written amount returned or use `Write::write_all` instead"); + span_lint( + cx, + UNUSED_IO_AMOUNT, + expr.span, + "handle written amount returned or use `Write::write_all` instead", + ); } } } diff --git a/clippy_lints/src/unused_label.rs b/clippy_lints/src/unused_label.rs index 15f327fb5c2..8a8afe8a377 100644 --- a/clippy_lints/src/unused_label.rs +++ b/clippy_lints/src/unused_label.rs @@ -48,7 +48,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedLabel { decl: &'tcx hir::FnDecl, body: &'tcx hir::Body, span: Span, - fn_id: ast::NodeId + fn_id: ast::NodeId, ) { if in_macro(span) { return; diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs index af92589b4d2..7466ee9080b 100644 --- a/clippy_lints/src/utils/author.rs +++ b/clippy_lints/src/utils/author.rs @@ -7,7 +7,7 @@ use rustc::lint::*; use rustc::hir; use rustc::hir::{Expr, QPath, Expr_}; use rustc::hir::intravisit::{Visitor, NestedVisitorMap}; -use syntax::ast::{Attribute, NodeId, LitKind, DUMMY_NODE_ID, self}; +use syntax::ast::{self, Attribute, NodeId, LitKind, DUMMY_NODE_ID}; use syntax::codemap::Span; use std::collections::HashMap; @@ -166,13 +166,14 @@ impl PrintVisitor { Vacant(vac) => { vac.insert(0); s.to_owned() - } + }, } } } struct PrintVisitor { - /// Fields are the current index that needs to be appended to pattern binding names + /// Fields are the current index that needs to be appended to pattern + /// binding names ids: HashMap<&'static str, usize>, /// the name that needs to be destructured current: String, @@ -254,7 +255,7 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor { println!(" {}.as_str() == {:?}", str_pat, &*text.as_str()) }, } - } + }, Expr_::ExprCast(ref expr, ref _ty) => { let cast_pat = self.next("expr"); println!("Cast(ref {}, _) = {},", cast_pat, current); @@ -282,7 +283,7 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor { self.visit_expr(cond); self.current = then_pat; self.visit_expr(then); - } + }, Expr_::ExprWhile(ref _cond, ref _body, ref _opt_label) => { println!("While(ref cond, ref body, ref opt_label) = {},", current); println!(" // unimplemented: `ExprWhile` is not further destructured at the moment"); @@ -398,7 +399,13 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor { let fields_pat = self.next("fields"); if let Some(ref base) = *opt_base { let base_pat = self.next("base"); - println!("Struct(ref {}, ref {}, Some(ref {})) = {},", path_pat, fields_pat, base_pat, current); + println!( + "Struct(ref {}, ref {}, Some(ref {})) = {},", + path_pat, + fields_pat, + base_pat, + current + ); self.current = base_pat; self.visit_expr(base); } else { @@ -433,24 +440,27 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor { fn has_attr(attrs: &[Attribute]) -> bool { attrs.iter().any(|attr| { attr.check_name("clippy") && - attr.meta_item_list().map_or(false, |list| { - list.len() == 1 && match list[0].node { - ast::NestedMetaItemKind::MetaItem(ref it) => it.name == "author", - ast::NestedMetaItemKind::Literal(_) => false, - } - }) + attr.meta_item_list().map_or(false, |list| { + list.len() == 1 && + match list[0].node { + ast::NestedMetaItemKind::MetaItem(ref it) => it.name == "author", + ast::NestedMetaItemKind::Literal(_) => false, + } + }) }) } fn print_path(path: &QPath, first: &mut bool) { match *path { - QPath::Resolved(_, ref path) => for segment in &path.segments { - if *first { - *first = false; - } else { - print!(", "); + QPath::Resolved(_, ref path) => { + for segment in &path.segments { + if *first { + *first = false; + } else { + print!(", "); + } + print!("{:?}", segment.name.as_str()); } - print!("{:?}", segment.name.as_str()); }, QPath::TypeRelative(ref ty, ref segment) => { match ty.node { diff --git a/clippy_lints/src/utils/comparisons.rs b/clippy_lints/src/utils/comparisons.rs index f973c2afd27..5cb9b50a79d 100644 --- a/clippy_lints/src/utils/comparisons.rs +++ b/clippy_lints/src/utils/comparisons.rs @@ -17,7 +17,8 @@ pub enum Rel { Ne, } -/// Put the expression in the form `lhs < rhs`, `lhs <= rhs`, `lhs == rhs` or `lhs != rhs`. +/// Put the expression in the form `lhs < rhs`, `lhs <= rhs`, `lhs == rhs` or +/// `lhs != rhs`. pub fn normalize_comparison<'a>(op: BinOp_, lhs: &'a Expr, rhs: &'a Expr) -> Option<(Rel, &'a Expr, &'a Expr)> { match op { BinOp_::BiLt => Some((Rel::Lt, lhs, rhs)), diff --git a/clippy_lints/src/utils/conf.rs b/clippy_lints/src/utils/conf.rs index 0e6f8856382..ad9e7e20176 100644 --- a/clippy_lints/src/utils/conf.rs +++ b/clippy_lints/src/utils/conf.rs @@ -9,8 +9,9 @@ use toml; use std::sync::Mutex; /// Get the configuration file from arguments. -pub fn file_from_args(args: &[codemap::Spanned]) - -> Result, (&'static str, codemap::Span)> { +pub fn file_from_args( + args: &[codemap::Spanned], +) -> Result, (&'static str, codemap::Span)> { for arg in args.iter().filter_map(|a| a.meta_item()) { if arg.name() == "conf_file" { return match arg.node { @@ -38,12 +39,14 @@ pub enum Error { /// Not valid toml or doesn't fit the expected conf format Toml(String), /// Type error. - Type(/// The name of the key. - &'static str, - /// The expected type. - &'static str, - /// The type we got instead. - &'static str), + Type( + /// The name of the key. + &'static str, + /// The expected type. + &'static str, + /// The type we got instead. + &'static str + ), /// There is an unknown key is the file. UnknownKey(String), } @@ -234,11 +237,25 @@ pub fn read(path: Option<&path::Path>) -> (Conf, Vec) { Err(err) => return default(vec![err.into()]), }; - assert!(ERRORS.lock().expect("no threading -> mutex always safe").is_empty()); + assert!( + ERRORS + .lock() + .expect("no threading -> mutex always safe") + .is_empty() + ); match toml::from_str(&file) { - Ok(toml) => (toml, ERRORS.lock().expect("no threading -> mutex always safe").split_off(0)), + Ok(toml) => ( + toml, + ERRORS + .lock() + .expect("no threading -> mutex always safe") + .split_off(0), + ), Err(e) => { - let mut errors = ERRORS.lock().expect("no threading -> mutex always safe").split_off(0); + let mut errors = ERRORS + .lock() + .expect("no threading -> mutex always safe") + .split_off(0); errors.push(Error::Toml(e.to_string())); default(errors) }, diff --git a/clippy_lints/src/utils/constants.rs b/clippy_lints/src/utils/constants.rs index 87008307c5f..d47fbd5a043 100644 --- a/clippy_lints/src/utils/constants.rs +++ b/clippy_lints/src/utils/constants.rs @@ -7,5 +7,20 @@ /// See also [the reference][reference-types] for a list of such types. /// /// [reference-types]: https://doc.rust-lang.org/reference.html#types -pub const BUILTIN_TYPES: &'static [&'static str] = &["i8", "u8", "i16", "u16", "i32", "u32", "i64", "u64", "isize", - "usize", "f32", "f64", "bool", "str", "char"]; +pub const BUILTIN_TYPES: &'static [&'static str] = &[ + "i8", + "u8", + "i16", + "u16", + "i32", + "u32", + "i64", + "u64", + "isize", + "usize", + "f32", + "f64", + "bool", + "str", + "char", +]; diff --git a/clippy_lints/src/utils/higher.rs b/clippy_lints/src/utils/higher.rs index d25f8e7df2b..593cbf69f5b 100644 --- a/clippy_lints/src/utils/higher.rs +++ b/clippy_lints/src/utils/higher.rs @@ -1,4 +1,5 @@ -//! This module contains functions for retrieve the original AST from lowered `hir`. +//! This module contains functions for retrieve the original AST from lowered +//! `hir`. #![deny(missing_docs_in_private_items)] @@ -44,9 +45,11 @@ pub struct Range<'a> { /// Higher a `hir` range to something similar to `ast::ExprKind::Range`. pub fn range(expr: &hir::Expr) -> Option { - /// Find the field named `name` in the field. Always return `Some` for convenience. + /// Find the field named `name` in the field. Always return `Some` for + /// convenience. fn get_field<'a>(name: &str, fields: &'a [hir::Field]) -> Option<&'a hir::Expr> { - let expr = &fields.iter() + let expr = &fields + .iter() .find(|field| field.name.node == name) .unwrap_or_else(|| panic!("missing {} field for range", name)) .expr; @@ -54,7 +57,8 @@ pub fn range(expr: &hir::Expr) -> Option { Some(expr) } - // The range syntax is expanded to literal paths starting with `core` or `std` depending on + // The range syntax is expanded to literal paths starting with `core` or `std` + // depending on // `#[no_std]`. Testing both instead of resolving the paths. match expr.node { @@ -147,7 +151,8 @@ pub enum VecArgs<'a> { Vec(&'a [hir::Expr]), } -/// Returns the arguments of the `vec!` macro if this expression was expanded from `vec!`. +/// Returns the arguments of the `vec!` macro if this expression was expanded +/// from `vec!`. pub fn vec_macro<'e>(cx: &LateContext, expr: &'e hir::Expr) -> Option> { if_let_chain!{[ let hir::ExprCall(ref fun, ref args) = expr.node, diff --git a/clippy_lints/src/utils/hir_utils.rs b/clippy_lints/src/utils/hir_utils.rs index 3b943b83bb0..658a07ca146 100644 --- a/clippy_lints/src/utils/hir_utils.rs +++ b/clippy_lints/src/utils/hir_utils.rs @@ -7,14 +7,17 @@ use syntax::ast::Name; use syntax::ptr::P; use utils::differing_macro_contexts; -/// Type used to check whether two ast are the same. This is different from the operator -/// `==` on ast types as this operator would compare true equality with ID and span. +/// Type used to check whether two ast are the same. This is different from the +/// operator +/// `==` on ast types as this operator would compare true equality with ID and +/// span. /// /// Note that some expressions kinds are not considered but could be added. pub struct SpanlessEq<'a, 'tcx: 'a> { /// Context used to evaluate constant expressions. cx: &'a LateContext<'a, 'tcx>, - /// If is true, never consider as equal expressions containing function calls. + /// If is true, never consider as equal expressions containing function + /// calls. ignore_fn: bool, } @@ -52,7 +55,7 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> { /// Check whether two blocks are the same. pub fn eq_block(&self, left: &Block, right: &Block) -> bool { over(&left.stmts, &right.stmts, |l, r| self.eq_stmt(l, r)) && - both(&left.expr, &right.expr, |l, r| self.eq_expr(l, r)) + both(&left.expr, &right.expr, |l, r| self.eq_expr(l, r)) } pub fn eq_expr(&self, left: &Expr, right: &Expr) -> bool { @@ -78,13 +81,13 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> { (&ExprBlock(ref l), &ExprBlock(ref r)) => self.eq_block(l, r), (&ExprBinary(l_op, ref ll, ref lr), &ExprBinary(r_op, ref rl, ref rr)) => { l_op.node == r_op.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr) || - swap_binop(l_op.node, ll, lr).map_or(false, |(l_op, ll, lr)| { - l_op == r_op.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr) - }) + swap_binop(l_op.node, ll, lr).map_or(false, |(l_op, ll, lr)| { + l_op == r_op.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr) + }) }, (&ExprBreak(li, ref le), &ExprBreak(ri, ref re)) => { both(&li.ident, &ri.ident, |l, r| l.node.name.as_str() == r.node.name.as_str()) && - both(le, re, |l, r| self.eq_expr(l, r)) + both(le, re, |l, r| self.eq_expr(l, r)) }, (&ExprBox(ref l), &ExprBox(ref r)) => self.eq_expr(l, r), (&ExprCall(ref l_fun, ref l_args), &ExprCall(ref r_fun, ref r_args)) => { @@ -105,23 +108,23 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> { }, (&ExprMatch(ref le, ref la, ref ls), &ExprMatch(ref re, ref ra, ref rs)) => { ls == rs && self.eq_expr(le, re) && - over(la, ra, |l, r| { - self.eq_expr(&l.body, &r.body) && both(&l.guard, &r.guard, |l, r| self.eq_expr(l, r)) && - over(&l.pats, &r.pats, |l, r| self.eq_pat(l, r)) - }) + over(la, ra, |l, r| { + self.eq_expr(&l.body, &r.body) && both(&l.guard, &r.guard, |l, r| self.eq_expr(l, r)) && + over(&l.pats, &r.pats, |l, r| self.eq_pat(l, r)) + }) }, (&ExprMethodCall(ref l_path, _, ref l_args), &ExprMethodCall(ref r_path, _, ref r_args)) => { !self.ignore_fn && l_path == r_path && self.eq_exprs(l_args, r_args) }, (&ExprRepeat(ref le, ll_id), &ExprRepeat(ref re, rl_id)) => { self.eq_expr(le, re) && - self.eq_expr(&self.cx.tcx.hir.body(ll_id).value, &self.cx.tcx.hir.body(rl_id).value) + self.eq_expr(&self.cx.tcx.hir.body(ll_id).value, &self.cx.tcx.hir.body(rl_id).value) }, (&ExprRet(ref l), &ExprRet(ref r)) => both(l, r, |l, r| self.eq_expr(l, r)), (&ExprPath(ref l), &ExprPath(ref r)) => self.eq_qpath(l, r), (&ExprStruct(ref l_path, ref lf, ref lo), &ExprStruct(ref r_path, ref rf, ref ro)) => { self.eq_qpath(l_path, r_path) && both(lo, ro, |l, r| self.eq_expr(l, r)) && - over(lf, rf, |l, r| self.eq_field(l, r)) + over(lf, rf, |l, r| self.eq_field(l, r)) }, (&ExprTup(ref l_tup), &ExprTup(ref r_tup)) => self.eq_exprs(l_tup, r_tup), (&ExprTupField(ref le, li), &ExprTupField(ref re, ri)) => li.node == ri.node && self.eq_expr(le, re), @@ -167,7 +170,7 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> { (&PatKind::Ref(ref le, ref lm), &PatKind::Ref(ref re, ref rm)) => lm == rm && self.eq_pat(le, re), (&PatKind::Slice(ref ls, ref li, ref le), &PatKind::Slice(ref rs, ref ri, ref re)) => { over(ls, rs, |l, r| self.eq_pat(l, r)) && over(le, re, |l, r| self.eq_pat(l, r)) && - both(li, ri, |l, r| self.eq_pat(l, r)) + both(li, ri, |l, r| self.eq_pat(l, r)) }, (&PatKind::Wild, &PatKind::Wild) => true, _ => false, @@ -188,19 +191,19 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> { fn eq_path(&self, left: &Path, right: &Path) -> bool { left.is_global() == right.is_global() && - over(&left.segments, &right.segments, |l, r| self.eq_path_segment(l, r)) + over(&left.segments, &right.segments, |l, r| self.eq_path_segment(l, r)) } fn eq_path_parameters(&self, left: &PathParameters, right: &PathParameters) -> bool { match (left, right) { (&AngleBracketedParameters(ref left), &AngleBracketedParameters(ref right)) => { over(&left.lifetimes, &right.lifetimes, |l, r| self.eq_lifetime(l, r)) && - over(&left.types, &right.types, |l, r| self.eq_ty(l, r)) && - over(&left.bindings, &right.bindings, |l, r| self.eq_type_binding(l, r)) + over(&left.types, &right.types, |l, r| self.eq_ty(l, r)) && + over(&left.bindings, &right.bindings, |l, r| self.eq_type_binding(l, r)) }, (&ParenthesizedParameters(ref left), &ParenthesizedParameters(ref right)) => { over(&left.inputs, &right.inputs, |l, r| self.eq_ty(l, r)) && - both(&left.output, &right.output, |l, r| self.eq_ty(l, r)) + both(&left.output, &right.output, |l, r| self.eq_ty(l, r)) }, (&AngleBracketedParameters(_), &ParenthesizedParameters(_)) | (&ParenthesizedParameters(_), &AngleBracketedParameters(_)) => false, @@ -218,7 +221,7 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> { (&TySlice(ref l_vec), &TySlice(ref r_vec)) => self.eq_ty(l_vec, r_vec), (&TyArray(ref lt, ll_id), &TyArray(ref rt, rl_id)) => { self.eq_ty(lt, rt) && - self.eq_expr(&self.cx.tcx.hir.body(ll_id).value, &self.cx.tcx.hir.body(rl_id).value) + self.eq_expr(&self.cx.tcx.hir.body(ll_id).value, &self.cx.tcx.hir.body(rl_id).value) }, (&TyPtr(ref l_mut), &TyPtr(ref r_mut)) => l_mut.mutbl == r_mut.mutbl && self.eq_ty(&*l_mut.ty, &*r_mut.ty), (&TyRptr(_, ref l_rmut), &TyRptr(_, ref r_rmut)) => { @@ -247,22 +250,28 @@ fn swap_binop<'a>(binop: BinOp_, lhs: &'a Expr, rhs: &'a Expr) -> Option<(BinOp_ } } -/// Check if the two `Option`s are both `None` or some equal values as per `eq_fn`. +/// Check if the two `Option`s are both `None` or some equal values as per +/// `eq_fn`. fn both(l: &Option, r: &Option, mut eq_fn: F) -> bool - where F: FnMut(&X, &X) -> bool +where + F: FnMut(&X, &X) -> bool, { - l.as_ref().map_or_else(|| r.is_none(), |x| r.as_ref().map_or(false, |y| eq_fn(x, y))) + l.as_ref().map_or_else(|| r.is_none(), |x| { + r.as_ref().map_or(false, |y| eq_fn(x, y)) + }) } /// Check if two slices are equal as per `eq_fn`. fn over(left: &[X], right: &[X], mut eq_fn: F) -> bool - where F: FnMut(&X, &X) -> bool +where + F: FnMut(&X, &X) -> bool, { left.len() == right.len() && left.iter().zip(right).all(|(x, y)| eq_fn(x, y)) } -/// Type used to hash an ast element. This is different from the `Hash` trait on ast types as this +/// Type used to hash an ast element. This is different from the `Hash` trait +/// on ast types as this /// trait would consider IDs and spans. /// /// All expressions kind are hashed, but some might have a weaker hash. diff --git a/clippy_lints/src/utils/inspector.rs b/clippy_lints/src/utils/inspector.rs index 9962eca5075..ccb2cb7c67f 100644 --- a/clippy_lints/src/utils/inspector.rs +++ b/clippy_lints/src/utils/inspector.rs @@ -8,7 +8,8 @@ use rustc::hir::print; use syntax::ast::Attribute; use syntax::attr; -/// **What it does:** Dumps every ast/hir node which has the `#[clippy_dump]` attribute +/// **What it does:** Dumps every ast/hir node which has the `#[clippy_dump]` +/// attribute /// /// **Example:** /// ```rust @@ -54,8 +55,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { hir::Visibility::Public => println!("public"), hir::Visibility::Crate => println!("visible crate wide"), hir::Visibility::Restricted { ref path, .. } => { - println!("visible in module `{}`", - print::to_string(print::NO_ANN, |s| s.print_path(path, false))) + println!( + "visible in module `{}`", + print::to_string(print::NO_ANN, |s| s.print_path(path, false)) + ) }, hir::Visibility::Inherited => println!("visibility inherited from outer item"), } @@ -71,20 +74,23 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { hir::ImplItemKind::Type(_) => println!("associated type"), } } - // fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::TraitItem) { + // fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx + // hir::TraitItem) { // if !has_attr(&item.attrs) { // return; // } // } // - // fn check_variant(&mut self, cx: &LateContext<'a, 'tcx>, var: &'tcx hir::Variant, _: + // fn check_variant(&mut self, cx: &LateContext<'a, 'tcx>, var: &'tcx + // hir::Variant, _: // &hir::Generics) { // if !has_attr(&var.node.attrs) { // return; // } // } // - // fn check_struct_field(&mut self, cx: &LateContext<'a, 'tcx>, field: &'tcx hir::StructField) { + // fn check_struct_field(&mut self, cx: &LateContext<'a, 'tcx>, field: &'tcx + // hir::StructField) { // if !has_attr(&field.attrs) { // return; // } @@ -123,7 +129,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { hir::StmtSemi(ref e, _) => print_expr(cx, e, 0), } } - // fn check_foreign_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::ForeignItem) { + // fn check_foreign_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx + // hir::ForeignItem) { // if !has_attr(&item.attrs) { // return; // } @@ -345,8 +352,10 @@ fn print_item(cx: &LateContext, item: &hir::Item) { hir::Visibility::Public => println!("public"), hir::Visibility::Crate => println!("visible crate wide"), hir::Visibility::Restricted { ref path, .. } => { - println!("visible in module `{}`", - print::to_string(print::NO_ANN, |s| s.print_path(path, false))) + println!( + "visible in module `{}`", + print::to_string(print::NO_ANN, |s| s.print_path(path, false)) + ) }, hir::Visibility::Inherited => println!("visibility inherited from outer item"), } @@ -422,9 +431,11 @@ fn print_pat(cx: &LateContext, pat: &hir::Pat, indent: usize) { }, hir::PatKind::Struct(ref path, ref fields, ignore) => { println!("{}Struct", ind); - println!("{}name: {}", - ind, - print::to_string(print::NO_ANN, |s| s.print_qpath(path, false))); + println!( + "{}name: {}", + ind, + print::to_string(print::NO_ANN, |s| s.print_qpath(path, false)) + ); println!("{}ignore leftover fields: {}", ind, ignore); println!("{}fields:", ind); for field in fields { @@ -437,9 +448,11 @@ fn print_pat(cx: &LateContext, pat: &hir::Pat, indent: usize) { }, hir::PatKind::TupleStruct(ref path, ref fields, opt_dots_position) => { println!("{}TupleStruct", ind); - println!("{}path: {}", - ind, - print::to_string(print::NO_ANN, |s| s.print_qpath(path, false))); + println!( + "{}path: {}", + ind, + print::to_string(print::NO_ANN, |s| s.print_qpath(path, false)) + ); if let Some(dot_position) = opt_dots_position { println!("{}dot position: {}", ind, dot_position); } diff --git a/clippy_lints/src/utils/internal_lints.rs b/clippy_lints/src/utils/internal_lints.rs index 038dfc01d13..f81aff24338 100644 --- a/clippy_lints/src/utils/internal_lints.rs +++ b/clippy_lints/src/utils/internal_lints.rs @@ -63,20 +63,28 @@ impl LintPass for Clippy { impl EarlyLintPass for Clippy { fn check_crate(&mut self, cx: &EarlyContext, krate: &AstCrate) { - if let Some(utils) = krate.module.items.iter().find(|item| item.ident.name == "utils") { + if let Some(utils) = krate.module.items.iter().find( + |item| item.ident.name == "utils", + ) + { if let ItemKind::Mod(ref utils_mod) = utils.node { - if let Some(paths) = utils_mod.items.iter().find(|item| item.ident.name == "paths") { + if let Some(paths) = utils_mod.items.iter().find( + |item| item.ident.name == "paths", + ) + { if let ItemKind::Mod(ref paths_mod) = paths.node { let mut last_name: Option = None; for item in &paths_mod.items { let name = item.ident.name.as_str(); if let Some(ref last_name) = last_name { if **last_name > *name { - span_lint(cx, - CLIPPY_LINTS_INTERNAL, - item.span, - "this constant should be before the previous constant due to lexical \ - ordering"); + span_lint( + cx, + CLIPPY_LINTS_INTERNAL, + item.span, + "this constant should be before the previous constant due to lexical \ + ordering", + ); } } last_name = Some(name); @@ -128,13 +136,20 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LintWithoutLintPass { // not able to capture the error. // Therefore, we need to climb the macro expansion tree and find the // actual span that invoked `declare_lint!`: - let lint_span = lint_span.ctxt.outer().expn_info().map(|ei| ei.call_site).expect("unable to get call_site"); + let lint_span = lint_span + .ctxt + .outer() + .expn_info() + .map(|ei| ei.call_site) + .expect("unable to get call_site"); if !self.registered_lints.contains(lint_name) { - span_lint(cx, - LINT_WITHOUT_LINT_PASS, - lint_span, - &format!("the lint `{}` is not added to any `LintPass`", lint_name)); + span_lint( + cx, + LINT_WITHOUT_LINT_PASS, + lint_span, + &format!("the lint `{}` is not added to any `LintPass`", lint_name), + ); } } } @@ -142,7 +157,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LintWithoutLintPass { fn is_lint_ref_type(ty: &Ty) -> bool { - if let TyRptr(ref lt, MutTy { ty: ref inner, mutbl: MutImmutable }) = ty.node { + if let TyRptr(ref lt, + MutTy { + ty: ref inner, + mutbl: MutImmutable, + }) = ty.node + { if lt.is_elided() { return false; } diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index cdce1108be2..43c0eb68d69 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -93,7 +93,8 @@ macro_rules! if_let_chain { pub mod higher; -/// Returns true if the two spans come from differing expansions (i.e. one is from a macro and one +/// Returns true if the two spans come from differing expansions (i.e. one is +/// from a macro and one /// isn't). pub fn differing_macro_contexts(lhs: Span, rhs: Span) -> bool { rhs.ctxt != lhs.ctxt @@ -119,10 +120,12 @@ pub fn in_macro(span: Span) -> bool { }) } -/// Returns true if the macro that expanded the crate was outside of the current crate or was a +/// Returns true if the macro that expanded the crate was outside of the +/// current crate or was a /// compiler plugin. pub fn in_external_macro<'a, T: LintContext<'a>>(cx: &T, span: Span) -> bool { - /// Invokes `in_macro` with the expansion info of the given span slightly heavy, try to use + /// Invokes `in_macro` with the expansion info of the given span slightly + /// heavy, try to use /// this after other checks have already happened. fn in_macro_ext<'a, T: LintContext<'a>>(cx: &T, info: &ExpnInfo) -> bool { // no ExpnInfo = no macro @@ -133,11 +136,18 @@ pub fn in_external_macro<'a, T: LintContext<'a>>(cx: &T, span: Span) -> bool { // no span for the callee = external macro info.callee.span.map_or(true, |span| { // no snippet = external macro or compiler-builtin expansion - cx.sess().codemap().span_to_snippet(span).ok().map_or(true, |code| !code.starts_with("macro_rules")) + cx.sess().codemap().span_to_snippet(span).ok().map_or( + true, + |code| { + !code.starts_with("macro_rules") + }, + ) }) } - span.ctxt.outer().expn_info().map_or(false, |info| in_macro_ext(cx, &info)) + span.ctxt.outer().expn_info().map_or(false, |info| { + in_macro_ext(cx, &info) + }) } /// Check if a `DefId`'s path matches the given absolute type path usage. @@ -170,7 +180,10 @@ pub fn match_def_path(tcx: TyCtxt, def_id: DefId, path: &[&str]) -> bool { tcx.push_item_path(&mut apb, def_id); - apb.names.len() == path.len() && apb.names.into_iter().zip(path.iter()).all(|(a, &b)| *a == *b) + apb.names.len() == path.len() && + apb.names.into_iter().zip(path.iter()).all( + |(a, &b)| *a == *b, + ) } /// Check if type is struct, enum or union type with given def path. @@ -206,9 +219,9 @@ pub fn match_trait_method(cx: &LateContext, expr: &Expr, path: &[&str]) -> bool pub fn last_path_segment(path: &QPath) -> &PathSegment { match *path { QPath::Resolved(_, ref path) => { - path.segments - .last() - .expect("A path must have at least one segment") + path.segments.last().expect( + "A path must have at least one segment", + ) }, QPath::TypeRelative(_, ref seg) => seg, } @@ -235,7 +248,7 @@ pub fn match_path(path: &QPath, segments: &[&str]) -> bool { match ty.node { TyPath(ref inner_path) => { !segments.is_empty() && match_path(inner_path, &segments[..(segments.len() - 1)]) && - segment.name == segments[segments.len() - 1] + segment.name == segments[segments.len() - 1] }, _ => false, } @@ -244,7 +257,9 @@ pub fn match_path(path: &QPath, segments: &[&str]) -> bool { } pub fn match_path_old(path: &Path, segments: &[&str]) -> bool { - path.segments.iter().rev().zip(segments.iter().rev()).all(|(a, b)| a.name == *b) + path.segments.iter().rev().zip(segments.iter().rev()).all( + |(a, b)| a.name == *b, + ) } /// Match a `Path` against a slice of segment string literals, e.g. @@ -254,7 +269,9 @@ pub fn match_path_old(path: &Path, segments: &[&str]) -> bool { /// match_path(path, &["std", "rt", "begin_unwind"]) /// ``` pub fn match_path_ast(path: &ast::Path, segments: &[&str]) -> bool { - path.segments.iter().rev().zip(segments.iter().rev()).all(|(a, b)| a.identifier.name == *b) + path.segments.iter().rev().zip(segments.iter().rev()).all( + |(a, b)| a.identifier.name == *b, + ) } /// Get the definition associated to a path. @@ -262,7 +279,9 @@ pub fn path_to_def(cx: &LateContext, path: &[&str]) -> Option { let cstore = &cx.tcx.sess.cstore; let crates = cstore.crates(); - let krate = crates.iter().find(|&&krate| cstore.crate_name(krate) == path[0]); + let krate = crates.iter().find( + |&&krate| cstore.crate_name(krate) == path[0], + ); if let Some(krate) = krate { let krate = DefId { krate: *krate, @@ -312,14 +331,20 @@ pub fn implements_trait<'a, 'tcx>( cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>, trait_id: DefId, - ty_params: &[Ty<'tcx>] + ty_params: &[Ty<'tcx>], ) -> bool { let ty = cx.tcx.erase_regions(&ty); - let obligation = cx.tcx - .predicate_for_trait_def(cx.param_env, traits::ObligationCause::dummy(), trait_id, 0, ty, ty_params); - cx.tcx - .infer_ctxt() - .enter(|infcx| traits::SelectionContext::new(&infcx).evaluate_obligation_conservatively(&obligation)) + let obligation = cx.tcx.predicate_for_trait_def( + cx.param_env, + traits::ObligationCause::dummy(), + trait_id, + 0, + ty, + ty_params, + ); + cx.tcx.infer_ctxt().enter(|infcx| { + traits::SelectionContext::new(&infcx).evaluate_obligation_conservatively(&obligation) + }) } /// Resolve the definition of a node from its `NodeId`. @@ -330,7 +355,8 @@ pub fn resolve_node(cx: &LateContext, qpath: &QPath, id: NodeId) -> def::Def { /// Match an `Expr` against a chain of methods, and return the matched `Expr`s. /// /// For example, if `expr` represents the `.baz()` in `foo.bar().baz()`, -/// `matched_method_chain(expr, &["bar", "baz"])` will return a `Vec` containing the `Expr`s for +/// `matched_method_chain(expr, &["bar", "baz"])` will return a `Vec` +/// containing the `Expr`s for /// `.bar()` and `.baz()` pub fn method_chain_args<'a>(expr: &'a Expr, methods: &[&str]) -> Option> { let mut current = expr; @@ -382,8 +408,10 @@ pub fn snippet_opt<'a, T: LintContext<'a>>(cx: &T, span: Span) -> Option cx.sess().codemap().span_to_snippet(span).ok() } -/// Convert a span (from a block) to a code snippet if available, otherwise use default. -/// This trims the code of indentation, except for the first line. Use it for blocks or block-like +/// Convert a span (from a block) to a code snippet if available, otherwise use +/// default. +/// This trims the code of indentation, except for the first line. Use it for +/// blocks or block-like /// things which need to be printed as such. /// /// # Example @@ -401,7 +429,7 @@ pub fn expr_block<'a, 'b, T: LintContext<'b>>( cx: &T, expr: &Expr, option: Option, - default: &'a str + default: &'a str, ) -> Cow<'a, str> { let code = snippet_block(cx, expr.span, default); let string = option.unwrap_or_default(); @@ -414,7 +442,8 @@ pub fn expr_block<'a, 'b, T: LintContext<'b>>( } } -/// Trim indentation from a multiline string with possibility of ignoring the first line. +/// Trim indentation from a multiline string with possibility of ignoring the +/// first line. pub fn trim_multiline(s: Cow, ignore_first: bool) -> Cow { let s_space = trim_multiline_inner(s, ignore_first, ' '); let s_tab = trim_multiline_inner(s_space, ignore_first, '\t'); @@ -429,24 +458,28 @@ fn trim_multiline_inner(s: Cow, ignore_first: bool, ch: char) -> Cow { None } else { // ignore empty lines - Some(l.char_indices() - .find(|&(_, x)| x != ch) - .unwrap_or((l.len(), ch)) - .0) + Some( + l.char_indices() + .find(|&(_, x)| x != ch) + .unwrap_or((l.len(), ch)) + .0, + ) } }) .min() .unwrap_or(0); if x > 0 { - Cow::Owned(s.lines() - .enumerate() - .map(|(i, l)| if (ignore_first && i == 0) || l.is_empty() { - l - } else { - l.split_at(x).1 - }) - .collect::>() - .join("\n")) + Cow::Owned( + s.lines() + .enumerate() + .map(|(i, l)| if (ignore_first && i == 0) || l.is_empty() { + l + } else { + l.split_at(x).1 + }) + .collect::>() + .join("\n"), + ) } else { s } @@ -460,17 +493,22 @@ pub fn get_parent_expr<'c>(cx: &'c LateContext, e: &Expr) -> Option<&'c Expr> { if node_id == parent_id { return None; } - map.find(parent_id).and_then(|node| if let Node::NodeExpr(parent) = node { - Some(parent) - } else { - None - }) + map.find(parent_id).and_then( + |node| if let Node::NodeExpr(parent) = + node + { + Some(parent) + } else { + None + }, + ) } pub fn get_enclosing_block<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, node: NodeId) -> Option<&'tcx Block> { let map = &cx.tcx.hir; - let enclosing_node = map.get_enclosing_scope(node) - .and_then(|enclosing_id| map.find(enclosing_id)); + let enclosing_node = map.get_enclosing_scope(node).and_then(|enclosing_id| { + map.find(enclosing_id) + }); if let Some(node) = enclosing_node { match node { Node::NodeBlock(block) => Some(block), @@ -498,8 +536,10 @@ impl<'a> Drop for DiagnosticWrapper<'a> { impl<'a> DiagnosticWrapper<'a> { fn wiki_link(&mut self, lint: &'static Lint) { if env::var("CLIPPY_DISABLE_WIKI_LINKS").is_err() { - self.0.help(&format!("for further information visit https://github.com/Manishearth/rust-clippy/wiki#{}", - lint.name_lower())); + self.0.help(&format!( + "for further information visit https://github.com/Manishearth/rust-clippy/wiki#{}", + lint.name_lower() + )); } } } @@ -516,7 +556,7 @@ pub fn span_help_and_lint<'a, 'tcx: 'a, T: LintContext<'tcx>>( lint: &'static Lint, span: Span, msg: &str, - help: &str + help: &str, ) { let mut db = DiagnosticWrapper(cx.struct_span_lint(lint, span, msg)); if cx.current_level(lint) != Level::Allow { @@ -531,7 +571,7 @@ pub fn span_note_and_lint<'a, 'tcx: 'a, T: LintContext<'tcx>>( span: Span, msg: &str, note_span: Span, - note: &str + note: &str, ) { let mut db = DiagnosticWrapper(cx.struct_span_lint(lint, span, msg)); if cx.current_level(lint) != Level::Allow { @@ -549,8 +589,9 @@ pub fn span_lint_and_then<'a, 'tcx: 'a, T: LintContext<'tcx>, F>( lint: &'static Lint, sp: Span, msg: &str, - f: F -) where F: for<'b> FnOnce(&mut DiagnosticBuilder<'b>) + f: F, +) where + F: for<'b> FnOnce(&mut DiagnosticBuilder<'b>), { let mut db = DiagnosticWrapper(cx.struct_span_lint(lint, sp, msg)); if cx.current_level(lint) != Level::Allow { @@ -565,15 +606,17 @@ pub fn span_lint_and_sugg<'a, 'tcx: 'a, T: LintContext<'tcx>>( sp: Span, msg: &str, help: &str, - sugg: String + sugg: String, ) { span_lint_and_then(cx, lint, sp, msg, |db| { db.span_suggestion(sp, help, sugg); }); } /// Create a suggestion made from several `span → replacement`. /// -/// Note: in the JSON format (used by `compiletest_rs`), the help message will appear once per -/// replacement. In human-readable format though, it only appears once before the whole suggestion. +/// Note: in the JSON format (used by `compiletest_rs`), the help message will +/// appear once per +/// replacement. In human-readable format though, it only appears once before +/// the whole suggestion. pub fn multispan_sugg(db: &mut DiagnosticBuilder, help_msg: String, sugg: Vec<(Span, String)>) { let sugg = rustc_errors::CodeSuggestion { substitution_parts: sugg.into_iter() @@ -598,7 +641,8 @@ pub fn walk_ptrs_ty(ty: Ty) -> Ty { } } -/// Return the base type for references and raw pointers, and count reference depth. +/// Return the base type for references and raw pointers, and count reference +/// depth. pub fn walk_ptrs_ty_depth(ty: Ty) -> (Ty, usize) { fn inner(ty: Ty, depth: usize) -> (Ty, usize) { match ty.sty { @@ -639,7 +683,9 @@ impl LimitStack { LimitStack { stack: vec![limit] } } pub fn limit(&self) -> u64 { - *self.stack.last().expect("there should always be a value in the stack") + *self.stack.last().expect( + "there should always be a value in the stack", + ) } pub fn push_attrs(&mut self, sess: &Session, attrs: &[ast::Attribute], name: &'static str) { let stack = &mut self.stack; @@ -669,14 +715,14 @@ fn parse_attrs(sess: &Session, attrs: &[ast::Attribute], name: &' } } -/// Return the pre-expansion span if is this comes from an expansion of the macro `name`. +/// Return the pre-expansion span if is this comes from an expansion of the +/// macro `name`. /// See also `is_direct_expn_of`. pub fn is_expn_of(mut span: Span, name: &str) -> Option { loop { - let span_name_span = span.ctxt - .outer() - .expn_info() - .map(|ei| (ei.callee.name(), ei.call_site)); + let span_name_span = span.ctxt.outer().expn_info().map(|ei| { + (ei.callee.name(), ei.call_site) + }); match span_name_span { Some((mac_name, new_span)) if mac_name == name => return Some(new_span), @@ -686,18 +732,19 @@ pub fn is_expn_of(mut span: Span, name: &str) -> Option { } } -/// Return the pre-expansion span if is this directly comes from an expansion of the macro `name`. +/// Return the pre-expansion span if is this directly comes from an expansion +/// of the macro `name`. /// The difference with `is_expn_of` is that in /// ```rust,ignore /// foo!(bar!(42)); /// ``` -/// `42` is considered expanded from `foo!` and `bar!` by `is_expn_of` but only `bar!` by +/// `42` is considered expanded from `foo!` and `bar!` by `is_expn_of` but only +/// `bar!` by /// `is_direct_expn_of`. pub fn is_direct_expn_of(span: Span, name: &str) -> Option { - let span_name_span = span.ctxt - .outer() - .expn_info() - .map(|ei| (ei.callee.name(), ei.call_site)); + let span_name_span = span.ctxt.outer().expn_info().map(|ei| { + (ei.callee.name(), ei.call_site) + }); match span_name_span { Some((mac_name, new_span)) if mac_name == name => Some(new_span), @@ -705,7 +752,8 @@ pub fn is_direct_expn_of(span: Span, name: &str) -> Option { } } -/// Return the index of the character after the first camel-case component of `s`. +/// Return the index of the character after the first camel-case component of +/// `s`. pub fn camel_case_until(s: &str) -> usize { let mut iter = s.char_indices(); if let Some((_, first)) = iter.next() { @@ -771,10 +819,13 @@ pub fn return_ty<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, fn_item: NodeId) -> Ty<'t } /// Check if two types are the same. -// FIXME: this works correctly for lifetimes bounds (`for <'a> Foo<'a>` == `for <'b> Foo<'b>` but +// FIXME: this works correctly for lifetimes bounds (`for <'a> Foo<'a>` == `for +// <'b> Foo<'b>` but // not for type parameters. pub fn same_tys<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> bool { - cx.tcx.infer_ctxt().enter(|infcx| infcx.can_eq(cx.param_env, a, b).is_ok()) + cx.tcx.infer_ctxt().enter(|infcx| { + infcx.can_eq(cx.param_env, a, b).is_ok() + }) } /// Return whether the given type is an `unsafe` function. @@ -792,8 +843,10 @@ pub fn is_copy<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool { /// Return whether a pattern is refutable. pub fn is_refutable(cx: &LateContext, pat: &Pat) -> bool { fn is_enum_variant(cx: &LateContext, qpath: &QPath, did: NodeId) -> bool { - matches!(cx.tables.qpath_def(qpath, did), - def::Def::Variant(..) | def::Def::VariantCtor(..)) + matches!( + cx.tables.qpath_def(qpath, did), + def::Def::Variant(..) | def::Def::VariantCtor(..) + ) } fn are_refutable<'a, I: Iterator>(cx: &LateContext, mut i: I) -> bool { @@ -824,19 +877,26 @@ pub fn is_refutable(cx: &LateContext, pat: &Pat) -> bool { } }, PatKind::Slice(ref head, ref middle, ref tail) => { - are_refutable(cx, head.iter().chain(middle).chain(tail.iter()).map(|pat| &**pat)) + are_refutable( + cx, + head.iter().chain(middle).chain(tail.iter()).map( + |pat| &**pat, + ), + ) }, } } -/// Checks for the `#[automatically_derived]` attribute all `#[derive]`d implementations have. +/// Checks for the `#[automatically_derived]` attribute all `#[derive]`d +/// implementations have. pub fn is_automatically_derived(attrs: &[ast::Attribute]) -> bool { attr::contains_name(attrs, "automatically_derived") } /// Remove blocks around an expression. /// -/// Ie. `x`, `{ x }` and `{{{{ x }}}}` all give `x`. `{ x; y }` and `{}` return themselves. +/// Ie. `x`, `{ x }` and `{{{{ x }}}}` all give `x`. `{ x; y }` and `{}` return +/// themselves. pub fn remove_blocks(expr: &Expr) -> &Expr { if let ExprBlock(ref block) = expr.node { if block.stmts.is_empty() { @@ -948,5 +1008,7 @@ pub fn is_try(expr: &Expr) -> Option<&Expr> { } pub fn type_size<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>) -> Option { - ty.layout(cx.tcx, cx.param_env).ok().map(|layout| layout.size(cx.tcx).bytes()) + ty.layout(cx.tcx, cx.param_env).ok().map(|layout| { + layout.size(cx.tcx).bytes() + }) } diff --git a/clippy_lints/src/utils/paths.rs b/clippy_lints/src/utils/paths.rs index f423274711a..675d708781c 100644 --- a/clippy_lints/src/utils/paths.rs +++ b/clippy_lints/src/utils/paths.rs @@ -1,4 +1,5 @@ -//! This module contains paths to types and functions Clippy needs to know about. +//! This module contains paths to types and functions Clippy needs to know +//! about. pub const ASMUT_TRAIT: [&'static str; 3] = ["core", "convert", "AsMut"]; pub const ASREF_TRAIT: [&'static str; 3] = ["core", "convert", "AsRef"]; diff --git a/clippy_lints/src/utils/sugg.rs b/clippy_lints/src/utils/sugg.rs index 07872673b42..d46a6526395 100644 --- a/clippy_lints/src/utils/sugg.rs +++ b/clippy_lints/src/utils/sugg.rs @@ -20,7 +20,8 @@ pub enum Sugg<'a> { NonParen(Cow<'a, str>), /// An expression that does not fit in other variants. MaybeParen(Cow<'a, str>), - /// A binary operator expression, including `as`-casts and explicit type coercion. + /// A binary operator expression, including `as`-casts and explicit type + /// coercion. BinOp(AssocOp, Cow<'a, str>), } @@ -77,7 +78,8 @@ impl<'a> Sugg<'a> { }) } - /// Convenience function around `hir_opt` for suggestions with a default text. + /// Convenience function around `hir_opt` for suggestions with a default + /// text. pub fn hir(cx: &LateContext, expr: &hir::Expr, default: &'a str) -> Sugg<'a> { Self::hir_opt(cx, expr).unwrap_or_else(|| Sugg::NonParen(Cow::Borrowed(default))) } @@ -156,7 +158,8 @@ impl<'a> Sugg<'a> { make_unop("*", self) } - /// Convenience method to create the `..` or `...` suggestion. + /// Convenience method to create the `..` or `...` + /// suggestion. pub fn range(self, end: Self, limit: ast::RangeLimits) -> Sugg<'static> { match limit { ast::RangeLimits::HalfOpen => make_assoc(AssocOp::DotDot, &self, &end), @@ -164,7 +167,8 @@ impl<'a> Sugg<'a> { } } - /// Add parenthesis to any expression that might need them. Suitable to the `self` argument of + /// Add parenthesis to any expression that might need them. Suitable to the + /// `self` argument of /// a method call (eg. to build `bar.foo()` or `(1 + 2).foo()`). pub fn maybe_par(self) -> Self { match self { @@ -233,7 +237,8 @@ impl Display for ParenHelper { /// Build the string for `` adding parenthesis when necessary. /// -/// For convenience, the operator is taken as a string because all unary operators have the same +/// For convenience, the operator is taken as a string because all unary +/// operators have the same /// precedence. pub fn make_unop(op: &str, expr: Sugg) -> Sugg<'static> { Sugg::MaybeParen(format!("{}{}", op, expr.maybe_par()).into()) @@ -241,7 +246,8 @@ pub fn make_unop(op: &str, expr: Sugg) -> Sugg<'static> { /// Build the string for ` ` adding parenthesis when necessary. /// -/// Precedence of shift operator relative to other arithmetic operation is often confusing so +/// Precedence of shift operator relative to other arithmetic operation is +/// often confusing so /// parenthesis will always be added for a mix of these. pub fn make_assoc(op: AssocOp, lhs: &Sugg, rhs: &Sugg) -> Sugg<'static> { /// Whether the operator is a shift operator `<<` or `>>`. @@ -251,18 +257,21 @@ pub fn make_assoc(op: AssocOp, lhs: &Sugg, rhs: &Sugg) -> Sugg<'static> { /// Whether the operator is a arithmetic operator (`+`, `-`, `*`, `/`, `%`). fn is_arith(op: &AssocOp) -> bool { - matches!(*op, - AssocOp::Add | AssocOp::Subtract | AssocOp::Multiply | AssocOp::Divide | AssocOp::Modulus) + matches!( + *op, + AssocOp::Add | AssocOp::Subtract | AssocOp::Multiply | AssocOp::Divide | AssocOp::Modulus + ) } - /// Whether the operator `op` needs parenthesis with the operator `other` in the direction + /// Whether the operator `op` needs parenthesis with the operator `other` + /// in the direction /// `dir`. fn needs_paren(op: &AssocOp, other: &AssocOp, dir: Associativity) -> bool { other.precedence() < op.precedence() || - (other.precedence() == op.precedence() && - ((op != other && associativity(op) != dir) || - (op == other && associativity(op) != Associativity::Both))) || is_shift(op) && is_arith(other) || - is_shift(other) && is_arith(op) + (other.precedence() == op.precedence() && + ((op != other && associativity(op) != dir) || + (op == other && associativity(op) != Associativity::Both))) || + is_shift(op) && is_arith(other) || is_shift(other) && is_arith(op) } let lhs_paren = if let Sugg::BinOp(ref lop, _) = *lhs { @@ -316,11 +325,13 @@ enum Associativity { Right, } -/// Return the associativity/fixity of an operator. The difference with `AssocOp::fixity` is that +/// Return the associativity/fixity of an operator. The difference with +/// `AssocOp::fixity` is that /// an operator can be both left and right associative (such as `+`: /// `a + b + c == (a + b) + c == a + (b + c)`. /// -/// Chained `as` and explicit `:` type coercion never need inner parenthesis so they are considered +/// Chained `as` and explicit `:` type coercion never need inner parenthesis so +/// they are considered /// associative. fn associativity(op: &AssocOp) -> Associativity { use syntax::util::parser::AssocOp::*; @@ -374,10 +385,14 @@ fn astbinop2assignop(op: ast::BinOp) -> AssocOp { }) } -/// Return the indentation before `span` if there are nothing but `[ \t]` before it on its line. +/// Return the indentation before `span` if there are nothing but `[ \t]` +/// before it on its line. fn indentation<'a, T: LintContext<'a>>(cx: &T, span: Span) -> Option { let lo = cx.sess().codemap().lookup_char_pos(span.lo); - if let Some(line) = lo.file.get_line(lo.line - 1 /* line numbers in `Loc` are 1-based */) { + if let Some(line) = lo.file.get_line( + lo.line - 1, /* line numbers in `Loc` are 1-based */ + ) + { if let Some((pos, _)) = line.char_indices().find(|&(_, c)| c != ' ' && c != '\t') { // we can mix char and byte positions here because we only consider `[ \t]` if lo.col == CharPos(pos) { @@ -424,7 +439,10 @@ pub trait DiagnosticBuilderExt<'a, T: LintContext<'a>> { impl<'a, 'b, 'c, T: LintContext<'c>> DiagnosticBuilderExt<'c, T> for rustc_errors::DiagnosticBuilder<'b> { fn suggest_item_with_attr(&mut self, cx: &T, item: Span, msg: &str, attr: &D) { if let Some(indent) = indentation(cx, item) { - let span = Span { hi: item.lo, ..item }; + let span = Span { + hi: item.lo, + ..item + }; self.span_suggestion(span, msg, format!("{}\n{}", attr, indent)); } @@ -432,10 +450,14 @@ impl<'a, 'b, 'c, T: LintContext<'c>> DiagnosticBuilderExt<'c, T> for rustc_error fn suggest_prepend_item(&mut self, cx: &T, item: Span, msg: &str, new_item: &str) { if let Some(indent) = indentation(cx, item) { - let span = Span { hi: item.lo, ..item }; + let span = Span { + hi: item.lo, + ..item + }; let mut first = true; - let new_item = new_item.lines() + let new_item = new_item + .lines() .map(|l| if first { first = false; format!("{}\n", l) diff --git a/clippy_lints/src/vec.rs b/clippy_lints/src/vec.rs index 059f4e36a03..c864c9d2aeb 100644 --- a/clippy_lints/src/vec.rs +++ b/clippy_lints/src/vec.rs @@ -63,7 +63,10 @@ fn check_vec_macro(cx: &LateContext, vec_args: &higher::VecArgs, span: Span) { let parent_item = cx.tcx.hir.get_parent(len.id); let parent_def_id = cx.tcx.hir.local_def_id(parent_item); let substs = Substs::identity_for_item(cx.tcx, parent_def_id); - if ConstContext::new(cx.tcx, cx.param_env.and(substs), cx.tables).eval(len).is_ok() { + if ConstContext::new(cx.tcx, cx.param_env.and(substs), cx.tables) + .eval(len) + .is_ok() + { format!("&[{}; {}]", snippet(cx, elem.span, "elem"), snippet(cx, len.span, "len")).into() } else { return; @@ -84,12 +87,14 @@ fn check_vec_macro(cx: &LateContext, vec_args: &higher::VecArgs, span: Span) { }, }; - span_lint_and_sugg(cx, - USELESS_VEC, - span, - "useless use of `vec!`", - "you can use a slice directly", - snippet); + span_lint_and_sugg( + cx, + USELESS_VEC, + span, + "useless use of `vec!`", + "you can use a slice directly", + snippet, + ); } /// Return the item type of the vector (ie. the `T` in `Vec`). diff --git a/clippy_lints/src/zero_div_zero.rs b/clippy_lints/src/zero_div_zero.rs index b00d23d6fba..888cd339096 100644 --- a/clippy_lints/src/zero_div_zero.rs +++ b/clippy_lints/src/zero_div_zero.rs @@ -5,7 +5,8 @@ use utils::span_help_and_lint; /// **What it does:** Checks for `0.0 / 0.0`. /// -/// **Why is this bad?** It's less readable than `std::f32::NAN` or `std::f64::NAN`. +/// **Why is this bad?** It's less readable than `std::f32::NAN` or +/// `std::f64::NAN`. /// /// **Known problems:** None. /// diff --git a/src/main.rs b/src/main.rs index 266c1373ff2..8e92eb55ff0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -46,8 +46,13 @@ impl<'a> CompilerCalls<'a> for ClippyCompilerCalls { descriptions: &rustc_errors::registry::Registry, output: ErrorOutputType, ) -> Compilation { - self.default - .early_callback(matches, sopts, cfg, descriptions, output) + self.default.early_callback( + matches, + sopts, + cfg, + descriptions, + output, + ) } fn no_input( &mut self, @@ -58,8 +63,14 @@ impl<'a> CompilerCalls<'a> for ClippyCompilerCalls { ofile: &Option, descriptions: &rustc_errors::registry::Registry, ) -> Option<(Input, Option)> { - self.default - .no_input(matches, sopts, cfg, odir, ofile, descriptions) + self.default.no_input( + matches, + sopts, + cfg, + odir, + ofile, + descriptions, + ) } fn late_callback( &mut self, @@ -69,8 +80,13 @@ impl<'a> CompilerCalls<'a> for ClippyCompilerCalls { odir: &Option, ofile: &Option, ) -> Compilation { - self.default - .late_callback(matches, sess, input, odir, ofile) + self.default.late_callback( + matches, + sess, + input, + odir, + ofile, + ) } fn build_controller(&mut self, sess: &Session, matches: &getopts::Matches) -> driver::CompileController<'a> { let mut control = self.default.build_controller(sess, matches); @@ -79,13 +95,17 @@ impl<'a> CompilerCalls<'a> for ClippyCompilerCalls { let old = std::mem::replace(&mut control.after_parse.callback, box |_| {}); control.after_parse.callback = Box::new(move |state| { { - let mut registry = rustc_plugin::registry::Registry::new(state.session, - state - .krate - .as_ref() - .expect("at this compilation stage \ - the krate must be parsed") - .span); + let mut registry = rustc_plugin::registry::Registry::new( + state.session, + state + .krate + .as_ref() + .expect( + "at this compilation stage \ + the krate must be parsed", + ) + .span, + ); registry.args_hidden = Some(Vec::new()); clippy_lints::register_plugins(&mut registry); @@ -179,9 +199,9 @@ pub fn main() { if let Some("clippy") = std::env::args().nth(1).as_ref().map(AsRef::as_ref) { // this arm is executed on the initial call to `cargo clippy` - let manifest_path_arg = std::env::args() - .skip(2) - .find(|val| val.starts_with("--manifest-path=")); + let manifest_path_arg = std::env::args().skip(2).find(|val| { + val.starts_with("--manifest-path=") + }); let mut metadata = if let Ok(metadata) = cargo_metadata::metadata(manifest_path_arg.as_ref().map(AsRef::as_ref)) { @@ -191,55 +211,59 @@ pub fn main() { process::exit(101); }; - let manifest_path = manifest_path_arg.map(|arg| Path::new(&arg["--manifest-path=".len()..]) - .canonicalize().expect("manifest path could not be canonicalized")); + let manifest_path = manifest_path_arg.map(|arg| { + Path::new(&arg["--manifest-path=".len()..]) + .canonicalize() + .expect("manifest path could not be canonicalized") + }); let package_index = { - if let Some(manifest_path) = manifest_path { - metadata.packages.iter().position(|package| { + if let Some(manifest_path) = manifest_path { + metadata.packages.iter().position(|package| { + let package_manifest_path = Path::new(&package.manifest_path).canonicalize().expect( + "package manifest path could not be canonicalized", + ); + package_manifest_path == manifest_path + }) + } else { + let package_manifest_paths: HashMap<_, _> = metadata + .packages + .iter() + .enumerate() + .map(|(i, package)| { let package_manifest_path = Path::new(&package.manifest_path) - .canonicalize().expect("package manifest path could not be canonicalized"); - package_manifest_path == manifest_path + .parent() + .expect("could not find parent directory of package manifest") + .canonicalize() + .expect("package directory cannot be canonicalized"); + (package_manifest_path, i) }) - } else { - let package_manifest_paths: HashMap<_, _> = - metadata.packages.iter() - .enumerate() - .map(|(i, package)| { - let package_manifest_path = Path::new(&package.manifest_path) - .parent() - .expect("could not find parent directory of package manifest") - .canonicalize() - .expect("package directory cannot be canonicalized"); - (package_manifest_path, i) - }) - .collect(); + .collect(); - let current_dir = std::env::current_dir() - .expect("could not read current directory") - .canonicalize() - .expect("current directory cannot be canonicalized"); + let current_dir = std::env::current_dir() + .expect("could not read current directory") + .canonicalize() + .expect("current directory cannot be canonicalized"); - let mut current_path: &Path = ¤t_dir; + let mut current_path: &Path = ¤t_dir; - // This gets the most-recent parent (the one that takes the fewest `cd ..`s to - // reach). - loop { - if let Some(&package_index) = package_manifest_paths.get(current_path) { - break Some(package_index); - } - else { - // We'll never reach the filesystem root, because to get to this point in the code - // the call to `cargo_metadata::metadata` must have succeeded. So it's okay to - // unwrap the current path's parent. - current_path = current_path - .parent() - .unwrap_or_else(|| panic!("could not find parent of path {}", current_path.display())); - } + // This gets the most-recent parent (the one that takes the fewest `cd ..`s to + // reach). + loop { + if let Some(&package_index) = package_manifest_paths.get(current_path) { + break Some(package_index); + } else { + // We'll never reach the filesystem root, because to get to this point in the + // code + // the call to `cargo_metadata::metadata` must have succeeded. So it's okay to + // unwrap the current path's parent. + current_path = current_path.parent().unwrap_or_else(|| { + panic!("could not find parent of path {}", current_path.display()) + }); } } } - .expect("could not find matching package"); + }.expect("could not find matching package"); let package = metadata.packages.remove(package_index); for target in package.targets { @@ -250,9 +274,12 @@ pub fn main() { std::process::exit(code); } } else if ["bin", "example", "test", "bench"].contains(&&**first) { - if let Err(code) = process(vec![format!("--{}", first), target.name] - .into_iter() - .chain(args)) { + if let Err(code) = process( + vec![format!("--{}", first), target.name] + .into_iter() + .chain(args), + ) + { std::process::exit(code); } } @@ -280,7 +307,9 @@ pub fn main() { .and_then(|out| String::from_utf8(out.stdout).ok()) .map(|s| s.trim().to_owned()) }) - .expect("need to specify SYSROOT env var during clippy compilation, or use rustup or multirust") + .expect( + "need to specify SYSROOT env var during clippy compilation, or use rustup or multirust", + ) }; rustc_driver::in_rustc_thread(|| { @@ -310,13 +339,13 @@ pub fn main() { if let Err(CompileIncomplete::Errored(_)) = result { std::process::exit(1); } - }) - .expect("rustc_thread failed"); + }).expect("rustc_thread failed"); } } fn process(old_args: I) -> Result<(), i32> - where I: Iterator +where + I: Iterator, { let mut args = vec!["rustc".to_owned()]; diff --git a/tests/compile-test.rs b/tests/compile-test.rs index f7d0c69afb0..363eeced8a2 100644 --- a/tests/compile-test.rs +++ b/tests/compile-test.rs @@ -29,8 +29,6 @@ fn compile_test() { prepare_env(); run_mode("run-pass", "run-pass"); run_mode("ui", "ui"); - #[cfg(target_os = "windows")] - run_mode("ui-windows", "ui"); - #[cfg(not(target_os = "windows"))] - run_mode("ui-posix", "ui"); + #[cfg(target_os = "windows")] run_mode("ui-windows", "ui"); + #[cfg(not(target_os = "windows"))] run_mode("ui-posix", "ui"); } diff --git a/tests/dogfood.rs b/tests/dogfood.rs index 7a2f6701501..378d14972aa 100644 --- a/tests/dogfood.rs +++ b/tests/dogfood.rs @@ -24,7 +24,9 @@ fn dogfood() { let mut s = String::new(); s.push_str(" -L target/debug/"); s.push_str(" -L target/debug/deps"); - s.push_str(" -Zextra-plugins=clippy -Ltarget_recur/debug -Dwarnings -Dclippy_pedantic -Dclippy -Dclippy_internal"); + s.push_str( + " -Zextra-plugins=clippy -Ltarget_recur/debug -Dwarnings -Dclippy_pedantic -Dclippy -Dclippy_internal", + ); config.target_rustcflags = Some(s); if let Ok(name) = var("TESTNAME") { config.filter = Some(name.to_owned()) diff --git a/tests/issue-825.rs b/tests/issue-825.rs index 2d6c8ea384b..685715a111c 100644 --- a/tests/issue-825.rs +++ b/tests/issue-825.rs @@ -6,9 +6,10 @@ // this should compile in a reasonable amount of time fn rust_type_id(name: &str) { if "bool" == &name[..] || "uint" == &name[..] || "u8" == &name[..] || "u16" == &name[..] || - "u32" == &name[..] || "f32" == &name[..] || "f64" == &name[..] || "i8" == &name[..] || - "i16" == &name[..] || "i32" == &name[..] || - "i64" == &name[..] || "Self" == &name[..] || "str" == &name[..] { + "u32" == &name[..] || "f32" == &name[..] || "f64" == &name[..] || "i8" == &name[..] || + "i16" == &name[..] || "i32" == &name[..] || + "i64" == &name[..] || "Self" == &name[..] || "str" == &name[..] + { unreachable!(); } } diff --git a/tests/matches.rs b/tests/matches.rs index ade8db2aa27..2f9a61ed768 100644 --- a/tests/matches.rs +++ b/tests/matches.rs @@ -19,14 +19,28 @@ fn test_overlapping() { assert_eq!(None, overlapping::(&[])); assert_eq!(None, overlapping(&[sp(1, Bound::Included(4))])); assert_eq!(None, overlapping(&[sp(1, Bound::Included(4)), sp(5, Bound::Included(6))])); - assert_eq!(None, - overlapping(&[sp(1, Bound::Included(4)), - sp(5, Bound::Included(6)), - sp(10, Bound::Included(11))])); - assert_eq!(Some((&sp(1, Bound::Included(4)), &sp(3, Bound::Included(6)))), - overlapping(&[sp(1, Bound::Included(4)), sp(3, Bound::Included(6))])); - assert_eq!(Some((&sp(5, Bound::Included(6)), &sp(6, Bound::Included(11)))), - overlapping(&[sp(1, Bound::Included(4)), - sp(5, Bound::Included(6)), - sp(6, Bound::Included(11))])); + assert_eq!( + None, + overlapping( + &[ + sp(1, Bound::Included(4)), + sp(5, Bound::Included(6)), + sp(10, Bound::Included(11)), + ], + ) + ); + assert_eq!( + Some((&sp(1, Bound::Included(4)), &sp(3, Bound::Included(6)))), + overlapping(&[sp(1, Bound::Included(4)), sp(3, Bound::Included(6))]) + ); + assert_eq!( + Some((&sp(5, Bound::Included(6)), &sp(6, Bound::Included(11)))), + overlapping( + &[ + sp(1, Bound::Included(4)), + sp(5, Bound::Included(6)), + sp(6, Bound::Included(11)), + ], + ) + ); } diff --git a/tests/needless_continue_helpers.rs b/tests/needless_continue_helpers.rs index 0fcef518030..a669b6f9477 100644 --- a/tests/needless_continue_helpers.rs +++ b/tests/needless_continue_helpers.rs @@ -86,4 +86,3 @@ fn test_erode_block() { println!("input: {}\nexpected:\n{}\ngot:\n{}", input, expected, got); assert_eq!(expected, got); } -