array_size: ConstInt,
) -> Option<(ConstInt, ConstInt)> {
let start = match *start {
- Some(Some(&ty::Const { val: ConstVal::Integral(x), .. })) => x,
+ Some(Some(&ty::Const {
+ val: ConstVal::Integral(x),
+ ..
+ })) => x,
Some(_) => return None,
None => ConstInt::U8(0),
};
let end = match *end {
- Some(Some(&ty::Const { val: ConstVal::Integral(x), .. })) => if limits == RangeLimits::Closed {
+ Some(Some(&ty::Const {
+ val: ConstVal::Integral(x),
+ ..
+ })) => if limits == RangeLimits::Closed {
match x {
ConstInt::U8(_) => (x + ConstInt::U8(1)),
ConstInt::U16(_) => (x + ConstInt::U16(1)),
if_chain! {
if parent_impl != ast::CRATE_NODE_ID;
if let hir::map::Node::NodeItem(item) = cx.tcx.hir.get(parent_impl);
- if let hir::Item_::ItemImpl(_, _, _, _, Some(ref trait_ref), _, _) = item.node;
+ if let hir::Item_::ItemImpl(_, _, _, _, Some(ref trait_ref), _, _) =
+ item.node;
if trait_ref.path.def.def_id() == trait_id;
then { return; }
}
use semver::Version;
use syntax::ast::{Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem, NestedMetaItemKind};
use syntax::codemap::Span;
-use utils::{in_macro, match_def_path, paths, snippet_opt, span_lint, span_lint_and_then, opt_def_id};
+use utils::{in_macro, match_def_path, opt_def_id, paths, snippet_opt, span_lint, span_lint_and_then};
/// **What it does:** Checks for items annotated with `#[inline(always)]`,
/// unless the annotated function is empty or simply panics.
const BRACED_EXPR_MESSAGE: &str = "omit braces around single expression condition";
const COMPLEX_BLOCK_MESSAGE: &str = "in an 'if' condition, avoid complex blocks or closures with blocks; \
- instead, move the block or closure higher and bind it with a 'let'";
+ instead, move the block or closure higher and bind it with a 'let'";
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BlockInIfCondition {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
BLOCK_IN_IF_CONDITION_EXPR,
check.span,
BRACED_EXPR_MESSAGE,
- &format!("try\nif {} {} ... ",
- snippet_block(cx, ex.span, ".."),
- snippet_block(cx, then.span, "..")),
+ &format!(
+ "try\nif {} {} ... ",
+ snippet_block(cx, ex.span, ".."),
+ snippet_block(cx, then.span, "..")
+ ),
);
}
} else {
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, "..")),
+ &format!(
+ "try\nlet res = {};\nif res {} ... ",
+ snippet_block(cx, block.span, ".."),
+ snippet_block(cx, then.span, "..")
+ ),
);
}
}
}
// 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);
+ 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);
}
if improvement {
improvements.push(suggestion);
use rustc::lint::*;
use rustc::ty;
use syntax::ast::{Name, UintTy};
-use utils::{contains_name, get_pat_name, match_type, paths, single_segment_path,
- snippet, span_lint_and_sugg, walk_ptrs_ty};
+use utils::{contains_name, get_pat_name, match_type, paths, single_segment_path, snippet, span_lint_and_sugg,
+ walk_ptrs_ty};
/// **What it does:** Checks for naive byte counts
///
-use syntax::ast::{Item, ItemKind, TyKind, Ty};
-use rustc::lint::{LintPass, EarlyLintPass, LintArray, EarlyContext};
-use utils::{span_lint_and_then, in_macro};
+use syntax::ast::{Item, ItemKind, Ty, TyKind};
+use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
+use utils::{in_macro, span_lint_and_then};
/// **What it does:** Checks for constants with an explicit `'static` lifetime.
///
/// ```
declare_lint! {
- pub CONST_STATIC_LIFETIME,
+ pub CONST_STATIC_LIFETIME,
Warn,
"Using explicit `'static` lifetime for constants when elision rules would allow omitting them."
}
TyKind::Array(ref ty, _) => {
self.visit_type(&*ty, cx);
},
- TyKind::Tup(ref tup) => {
- for tup_ty in tup {
- self.visit_type(&*tup_ty, cx);
- }
+ TyKind::Tup(ref tup) => for tup_ty in tup {
+ self.visit_type(&*tup_ty, cx);
},
// This is what we are looking for !
TyKind::Rptr(ref optional_lifetime, ref borrow_type) => {
// Verify that the path is a str
if lifetime.ident.name == "'static" {
let mut sug: String = String::new();
- span_lint_and_then(cx,
- CONST_STATIC_LIFETIME,
- lifetime.span,
- "Constants have by default a `'static` lifetime",
- |db| {db.span_suggestion(lifetime.span,"consider removing `'static`",sug);});
+ span_lint_and_then(
+ cx,
+ CONST_STATIC_LIFETIME,
+ lifetime.span,
+ "Constants have by default a `'static` lifetime",
+ |db| {
+ db.span_suggestion(lifetime.span, "consider removing `'static`", sug);
+ },
+ );
}
}
}
// Look for the PartialEq implementations for `ty`
cx.tcx.for_each_relevant_impl(peq_trait_def_id, ty, |impl_id| {
let peq_is_automatically_derived = is_automatically_derived(&cx.tcx.get_attrs(impl_id));
-
+
if peq_is_automatically_derived == hash_is_automatically_derived {
return;
}
-
+
let trait_ref = cx.tcx.impl_trait_ref(impl_id).expect("must be a trait implementation");
-
+
// Only care about `impl PartialEq<Foo> for Foo`
// For `impl PartialEq<B> for A, input_types is [A, B]
if trait_ref.substs.type_at(1) == ty {
} else {
"you are deriving `Hash` but have implemented `PartialEq` explicitly"
};
-
+
span_lint_and_then(
cx, DERIVE_HASH_XOR_EQ, span,
mess,
EXPL_IMPL_CLONE_ON_COPY,
item.span,
"you are implementing `Clone` explicitly on a `Copy` type",
- |db| { db.span_note(item.span, "consider deriving `Clone` or removing `Copy`"); },
+ |db| {
+ db.span_note(item.span, "consider deriving `Clone` or removing `Copy`");
+ },
);
}
}
End(CodeBlock(_)) | End(Code) => in_code = false,
Start(Link(link, _)) => in_link = Some(link),
End(Link(_, _)) => in_link = None,
- Start(_tag) | End(_tag) => (), // We don't care about other tags
+ Start(_tag) | End(_tag) => (), // We don't care about other tags
Html(_html) | InlineHtml(_html) => (), // HTML is weird, just ignore it
SoftBreak => (),
HardBreak => (),
s
};
- 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().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
}
fn has_underscore(s: &str) -> bool {
if let Ok(url) = Url::parse(word) {
// try to get around the fact that `foo::bar` parses as a valid URL
if !url.cannot_be_a_base() {
- span_lint(cx,
- DOC_MARKDOWN,
- span,
- "you should put bare URLs between `<`/`>` or make a proper Markdown link");
+ span_lint(
+ cx,
+ DOC_MARKDOWN,
+ span,
+ "you should put bare URLs between `<`/`>` or make a proper Markdown link",
+ );
return;
}
use rustc::lint::*;
use rustc::ty;
use rustc::hir::*;
-use utils::{is_copy, match_def_path, paths, span_note_and_lint, opt_def_id};
+use utils::{is_copy, match_def_path, opt_def_id, paths, span_note_and_lint};
/// **What it does:** Checks for calls to `std::mem::drop` with a reference
/// instead of an owned value.
let msg;
let arg = &args[0];
let arg_ty = cx.tables.expr_ty(arg);
-
+
if let ty::TyRef(..) = arg_ty.sty {
if match_def_path(cx.tcx, def_id, &paths::DROP) {
lint = DROP_REF;
then {
let map = ¶ms[0];
let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(map));
-
+
return if match_type(cx, obj_ty, &paths::BTREEMAP) {
Some(("BTreeMap", map, key))
}
snippet(self.cx, self.map.span, "map"),
snippet(self.cx, params[1].span, ".."),
snippet(self.cx, params[2].span, ".."));
-
+
db.span_suggestion(self.span, "consider using", help);
}
else {
let help = format!("{}.entry({})",
snippet(self.cx, self.map.span, "map"),
snippet(self.cx, params[1].span, ".."));
-
+
db.span_suggestion(self.span, "consider using", help);
}
});
.at(expr.span)
.const_eval(param_env.and((did, substs)))
{
- Ok(&ty::Const { val: ConstVal::Integral(Usize(Us64(i))), .. }) => u64::from(i as u32) != i,
- Ok(&ty::Const { val: ConstVal::Integral(Isize(Is64(i))), .. }) => i64::from(i as i32) != i,
+ Ok(&ty::Const {
+ val: ConstVal::Integral(Usize(Us64(i))),
+ ..
+ }) => u64::from(i as u32) != i,
+ Ok(&ty::Const {
+ val: ConstVal::Integral(Isize(Is64(i))),
+ ..
+ }) => i64::from(i as i32) != i,
_ => false,
};
if bad {
}
for var in &def.variants {
let name = var2str(var);
- if partial_match(item_name, &name) == item_name_chars &&
- name.chars().nth(item_name_chars).map_or(false, |c| !c.is_lowercase()) {
+ if partial_match(item_name, &name) == item_name_chars
+ && name.chars()
+ .nth(item_name_chars)
+ .map_or(false, |c| !c.is_lowercase())
+ {
span_lint(cx, lint, var.span, "Variant name starts with the enum's name");
}
if partial_rmatch(item_name, &name) == item_name_chars {
use rustc::hir;
use rustc::ty;
use syntax_pos::Span;
-use utils::{method_chain_args, match_def_path, span_lint_and_then, walk_ptrs_ty};
+use utils::{match_def_path, method_chain_args, span_lint_and_then, walk_ptrs_ty};
use utils::paths::{BEGIN_PANIC, BEGIN_PANIC_FMT, FROM_TRAIT, OPTION, RESULT};
/// **What it does:** Checks for impls of `From<..>` that contain `panic!()` or `unwrap()`
// check for `unwrap`
if let Some(arglists) = method_chain_args(expr, &["unwrap"]) {
let reciever_ty = walk_ptrs_ty(self.tables.expr_ty(&arglists[0][0]));
- if match_type(self.tcx, reciever_ty, &OPTION) ||
- match_type(self.tcx, reciever_ty, &RESULT)
- {
+ if match_type(self.tcx, reciever_ty, &OPTION) || match_type(self.tcx, reciever_ty, &RESULT) {
self.result.push(expr.span);
}
}
result: Vec::new(),
};
fpu.visit_expr(&body.value);
-
+
// if we've found one, lint
if !fpu.result.is_empty() {
span_lint_and_then(
use rustc::ty;
use syntax::ast::LitKind;
use utils::paths;
-use utils::{is_expn_of, match_def_path, match_type, resolve_node, span_lint, walk_ptrs_ty, opt_def_id};
+use utils::{is_expn_of, match_def_path, match_type, opt_def_id, resolve_node, span_lint, walk_ptrs_ty};
/// **What it does:** Checks for the use of `format!("string literal with no
/// argument")` and `format!("{}", foo)` where `foo` is a string.
if match_def_path(cx.tcx, fun_def_id, &paths::DISPLAY_FMT_METHOD);
then {
let ty = walk_ptrs_ty(cx.tables.pat_ty(&pat[0]));
-
+
return ty.sty == ty::TyStr || match_type(cx, ty, &paths::STRING);
}
}
/// 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()
+ if !differing_macro_contexts(first.span, second.span) && !in_macro(first.span) && unsugar_if(first).is_some()
+ && unsugar_if(second).is_some()
{
// where the else would be
let else_span = first.span.between(second.span);
ConstInt::U32(i) => i == !0,
ConstInt::U64(i) => i == !0,
ConstInt::U128(i) => i == !0,
- _ => false
+ _ => false,
}
}
use rustc::lint::*;
use syntax::ast::*;
-use utils::{span_help_and_lint, in_external_macro};
+use utils::{in_external_macro, span_help_and_lint};
/// **What it does:** Checks for usage of `!` or `!=` in an if condition with an
/// else branch.
use rustc::lint::*;
use syntax::ast::*;
-use utils::{span_lint_and_then, snippet_opt};
+use utils::{snippet_opt, span_lint_and_then};
/// **What it does:** Checks for usage of `x >= y + 1` or `x - 1 >= y` (and `<=`) in a block
///
#[allow(cast_sign_loss)]
fn check_lit(&self, lit: &Lit, target_value: i128) -> bool {
if let LitKind::Int(value, ..) = lit.node {
- return value == (target_value as u128)
+ return value == (target_value as u128);
}
false
}
(BinOpKind::Ge, &ExprKind::Binary(ref lhskind, ref lhslhs, ref lhsrhs), _) => {
match (lhskind.node, &lhslhs.node, &lhsrhs.node) {
// `-1 + x`
- (BinOpKind::Add, &ExprKind::Lit(ref lit), _) if self.check_lit(lit, -1) => self.generate_recommendation(cx, binop, lhsrhs, rhs, Side::LHS),
+ (BinOpKind::Add, &ExprKind::Lit(ref lit), _) if self.check_lit(lit, -1) => {
+ self.generate_recommendation(cx, binop, lhsrhs, rhs, Side::LHS)
+ },
// `x - 1`
- (BinOpKind::Sub, _, &ExprKind::Lit(ref lit)) if self.check_lit(lit, 1) => self.generate_recommendation(cx, binop, lhslhs, rhs, Side::LHS),
- _ => None
+ (BinOpKind::Sub, _, &ExprKind::Lit(ref lit)) if self.check_lit(lit, 1) => {
+ self.generate_recommendation(cx, binop, lhslhs, rhs, Side::LHS)
+ },
+ _ => None,
}
},
// case where `... >= y + 1` or `... >= 1 + y`
- (BinOpKind::Ge, _, &ExprKind::Binary(ref rhskind, ref rhslhs, ref rhsrhs)) if rhskind.node == BinOpKind::Add => {
+ (BinOpKind::Ge, _, &ExprKind::Binary(ref rhskind, ref rhslhs, ref rhsrhs))
+ if rhskind.node == BinOpKind::Add =>
+ {
match (&rhslhs.node, &rhsrhs.node) {
// `y + 1` and `1 + y`
- (&ExprKind::Lit(ref lit), _) if self.check_lit(lit, 1) => self.generate_recommendation(cx, binop, rhsrhs, lhs, Side::RHS),
- (_, &ExprKind::Lit(ref lit)) if self.check_lit(lit, 1) => self.generate_recommendation(cx, binop, rhslhs, lhs, Side::RHS),
- _ => None
+ (&ExprKind::Lit(ref lit), _) if self.check_lit(lit, 1) => {
+ self.generate_recommendation(cx, binop, rhsrhs, lhs, Side::RHS)
+ },
+ (_, &ExprKind::Lit(ref lit)) if self.check_lit(lit, 1) => {
+ self.generate_recommendation(cx, binop, rhslhs, lhs, Side::RHS)
+ },
+ _ => None,
}
- },
+ }
// case where `x + 1 <= ...` or `1 + x <= ...`
- (BinOpKind::Le, &ExprKind::Binary(ref lhskind, ref lhslhs, ref lhsrhs), _) if lhskind.node == BinOpKind::Add => {
+ (BinOpKind::Le, &ExprKind::Binary(ref lhskind, ref lhslhs, ref lhsrhs), _)
+ if lhskind.node == BinOpKind::Add =>
+ {
match (&lhslhs.node, &lhsrhs.node) {
// `1 + x` and `x + 1`
- (&ExprKind::Lit(ref lit), _) if self.check_lit(lit, 1) => self.generate_recommendation(cx, binop, lhsrhs, rhs, Side::LHS),
- (_, &ExprKind::Lit(ref lit)) if self.check_lit(lit, 1) => self.generate_recommendation(cx, binop, lhslhs, rhs, Side::LHS),
- _ => None
+ (&ExprKind::Lit(ref lit), _) if self.check_lit(lit, 1) => {
+ self.generate_recommendation(cx, binop, lhsrhs, rhs, Side::LHS)
+ },
+ (_, &ExprKind::Lit(ref lit)) if self.check_lit(lit, 1) => {
+ self.generate_recommendation(cx, binop, lhslhs, rhs, Side::LHS)
+ },
+ _ => None,
}
- },
+ }
// case where `... >= y - 1` or `... >= -1 + y`
(BinOpKind::Le, _, &ExprKind::Binary(ref rhskind, ref rhslhs, ref rhsrhs)) => {
match (rhskind.node, &rhslhs.node, &rhsrhs.node) {
// `-1 + y`
- (BinOpKind::Add, &ExprKind::Lit(ref lit), _) if self.check_lit(lit, -1) => self.generate_recommendation(cx, binop, rhsrhs, lhs, Side::RHS),
+ (BinOpKind::Add, &ExprKind::Lit(ref lit), _) if self.check_lit(lit, -1) => {
+ self.generate_recommendation(cx, binop, rhsrhs, lhs, Side::RHS)
+ },
// `y - 1`
- (BinOpKind::Sub, _, &ExprKind::Lit(ref lit)) if self.check_lit(lit, 1) => self.generate_recommendation(cx, binop, rhslhs, lhs, Side::RHS),
- _ => None
+ (BinOpKind::Sub, _, &ExprKind::Lit(ref lit)) if self.check_lit(lit, 1) => {
+ self.generate_recommendation(cx, binop, rhslhs, lhs, Side::RHS)
+ },
+ _ => None,
}
},
- _ => None
+ _ => None,
}
}
- fn generate_recommendation(&self, cx: &EarlyContext, binop: BinOpKind, node: &Expr, other_side: &Expr, side: Side) -> Option<String> {
+ fn generate_recommendation(
+ &self,
+ cx: &EarlyContext,
+ binop: BinOpKind,
+ node: &Expr,
+ other_side: &Expr,
+ side: Side,
+ ) -> Option<String> {
let binop_string = match binop {
BinOpKind::Ge => ">",
BinOpKind::Le => "<",
- _ => return None
+ _ => return None,
};
if let Some(snippet) = snippet_opt(cx, node.span) {
if let Some(other_side_snippet) = snippet_opt(cx, other_side.span) {
}
fn emit_warning(&self, cx: &EarlyContext, block: &Expr, recommendation: String) {
- span_lint_and_then(cx,
- INT_PLUS_ONE,
- block.span,
- "Unnecessary `>= y + 1` or `x - 1 >=`",
- |db| {
+ span_lint_and_then(cx, INT_PLUS_ONE, block.span, "Unnecessary `>= y + 1` or `x - 1 >=`", |db| {
db.span_suggestion(block.span, "change `>= y + 1` to `> y` as shown", recommendation);
});
}
use rustc::lint::*;
use rustc::ty;
use rustc::hir::*;
-use utils::{match_def_path, paths, span_help_and_lint, opt_def_id};
+use utils::{match_def_path, opt_def_id, paths, span_help_and_lint};
/// **What it does:** Checks for creation of references to zeroed or uninitialized memory.
///
/// **Why is this bad?** Creation of null references is undefined behavior.
///
-/// **Known problems:** None.
+/// **Known problems:** None.
///
/// **Example:**
/// ```rust
const ZERO_REF_SUMMARY: &str = "reference to zeroed memory";
const UNINIT_REF_SUMMARY: &str = "reference to uninitialized memory";
-const HELP: &str = "Creation of a null reference is undefined behavior; see https://doc.rust-lang.org/reference/behavior-considered-undefined.html";
+const HELP: &str = "Creation of a null reference is undefined behavior; \
+ see https://doc.rust-lang.org/reference/behavior-considered-undefined.html";
-pub struct InvalidRef;
+pub struct InvalidRef;
impl LintPass for InvalidRef {
fn get_lints(&self) -> LintArray {
if let ExprCall(ref path, ref args) = expr.node;
if let ExprPath(ref qpath) = path.node;
if args.len() == 0;
- if let ty::TyRef(..) = cx.tables.expr_ty(expr).sty;
+ if let ty::TyRef(..) = cx.tables.expr_ty(expr).sty;
if let Some(def_id) = opt_def_id(cx.tables.qpath_def(qpath, path.hir_id));
then {
- let msg = if match_def_path(cx.tcx, def_id, &paths::MEM_ZEROED) | match_def_path(cx.tcx, def_id, &paths::INIT) {
+ let msg = if match_def_path(cx.tcx, def_id, &paths::MEM_ZEROED) |
+ match_def_path(cx.tcx, def_id, &paths::INIT)
+ {
ZERO_REF_SUMMARY
- } else if match_def_path(cx.tcx, def_id, &paths::MEM_UNINIT) | match_def_path(cx.tcx, def_id, &paths::UNINIT) {
+ } else if match_def_path(cx.tcx, def_id, &paths::MEM_UNINIT) |
+ match_def_path(cx.tcx, def_id, &paths::UNINIT)
+ {
UNINIT_REF_SUMMARY
} else {
return;
};
span_help_and_lint(cx, INVALID_REF, expr.span, msg, HELP);
}
- }
+ }
return;
}
}
// like `panic!()`
match final_stmt.node {
StmtKind::Expr(_) => false,
- StmtKind::Semi(ref expr) => {
- match expr.node {
- ExprKind::Break(_, _) |
- ExprKind::Continue(_) |
- ExprKind::Ret(_) => false,
- _ => true,
- }
+ StmtKind::Semi(ref expr) => match expr.node {
+ ExprKind::Break(_, _) | ExprKind::Continue(_) | ExprKind::Ret(_) => false,
+ _ => true,
},
_ => true,
}
.iter()
.flat_map(|&i| cx.tcx.associated_items(i))
.any(|i| {
- i.kind == ty::AssociatedKind::Method && i.method_has_self_argument && i.name == "is_empty" &&
- cx.tcx.fn_sig(i.def_id).inputs().skip_binder().len() == 1
+ i.kind == ty::AssociatedKind::Method && i.method_has_self_argument && i.name == "is_empty"
+ && cx.tcx.fn_sig(i.def_id).inputs().skip_binder().len() == 1
});
if !is_empty_method_found {
if !used_in_expr(cx, canonical_id, value);
then {
let span = stmt.span.to(if_.span);
-
+
let (default_multi_stmts, default) = if let Some(ref else_) = *else_ {
if let hir::ExprBlock(ref else_) = else_.node {
if let Some(default) = check_assign(cx, canonical_id, else_) {
} else {
continue;
};
-
+
let mutability = match mode {
BindingAnnotation::RefMut | BindingAnnotation::Mutable => "<mut> ",
_ => "",
};
-
+
// FIXME: this should not suggest `mut` if we can detect that the variable is not
// use mutably after the `if`
-
+
let sug = format!(
"let {mut}{name} = if {cond} {{{then} {value} }} else {{{else} {default} }};",
mut=mutability,
id: decl,
used: false,
};
-
+
for s in block.stmts.iter().take(block.stmts.len()-1) {
hir::intravisit::walk_stmt(&mut v, s);
-
+
if v.used {
return None;
}
}
-
+
return Some(value);
}
}
#![feature(inclusive_range_syntax, range_contains)]
#![feature(macro_vis_matcher)]
#![allow(unknown_lints, indexing_slicing, shadow_reuse, missing_docs_in_private_items)]
-
-#![recursion_limit="256"]
+#![recursion_limit = "256"]
#[macro_use]
extern crate rustc;
.digits
.split_terminator('.')
.collect();
-
+
// Lint integral and fractional parts separately, and then check consistency of digit
// groups if both pass.
let _ = Self::do_lint(parts[0])
use rustc::ty::subst::{Subst, Substs};
use rustc_const_eval::ConstContext;
use std::collections::{HashMap, HashSet};
-use std::iter::{Iterator, once};
+use std::iter::{once, Iterator};
use syntax::ast;
use syntax::codemap::Span;
use utils::sugg;
// check for never_loop
match expr.node {
- ExprWhile(_, ref block, _) |
- ExprLoop(ref block, _, _) => {
+ ExprWhile(_, ref block, _) | ExprLoop(ref block, _, _) => {
let mut state = NeverLoopState {
breaks: HashSet::new(),
continues: HashSet::new(),
if let ExprMatch(ref matchexpr, ref arms, ref source) = inner.node {
// ensure "if let" compatible match structure
match *source {
- 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_simple_break_expr(&arms[1].body)
+ 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_simple_break_expr(&arms[1].body)
{
if in_external_macro(cx, expr.span) {
return;
}
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)
+ if let (
+ &PatKind::TupleStruct(ref qpath, ref pat_args, _),
+ &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])
+ 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])
{
let iterator = snippet(cx, method_args[0].span, "_");
let loop_var = snippet(cx, pat_args[0].span, "_");
fn stmt_to_expr(stmt: &Stmt) -> Option<&Expr> {
match stmt.node {
- StmtSemi(ref e, ..) |
- StmtExpr(ref e, ..) => Some(e),
+ StmtSemi(ref e, ..) | StmtExpr(ref e, ..) => Some(e),
StmtDecl(ref d, ..) => decl_to_expr(d),
}
}
ExprTupField(ref e, _) |
ExprAddrOf(_, ref e) |
ExprRepeat(ref e, _) => never_loop_expr(e, state),
- ExprArray(ref es) |
- ExprMethodCall(_, _, ref es) |
- ExprTup(ref es) => never_loop_expr_seq(&mut es.iter(), state),
+ ExprArray(ref es) | ExprMethodCall(_, _, ref es) | ExprTup(ref es) => {
+ never_loop_expr_seq(&mut es.iter(), state)
+ },
ExprCall(ref e, ref es) => never_loop_expr_seq(&mut once(&**e).chain(es.iter()), state),
ExprBinary(_, ref e1, ref e2) |
ExprAssign(ref e1, ref e2) |
},
ExprBlock(ref b) => never_loop_block(b, state),
ExprAgain(d) => {
- let id = d.target_id.opt_id().expect("target id can only be missing in the presence of compilation errors");
+ let id = d.target_id
+ .opt_id()
+ .expect("target id can only be missing in the presence of compilation errors");
state.continues.insert(id);
false
},
ExprBreak(d, _) => {
- let id = d.target_id.opt_id().expect("target id can only be missing in the presence of compilation errors");
+ let id = d.target_id
+ .opt_id()
+ .expect("target id can only be missing in the presence of compilation errors");
state.breaks.insert(id);
false
},
}
}
-fn never_loop_expr_seq<'a, T: Iterator<Item=&'a Expr>>(es: &mut T, state: &mut NeverLoopState) -> bool {
- es.map(|e| never_loop_expr(e, state)).fold(true, |a, b| a && b)
+fn never_loop_expr_seq<'a, T: Iterator<Item = &'a Expr>>(es: &mut T, state: &mut NeverLoopState) -> bool {
+ es.map(|e| never_loop_expr(e, state))
+ .fold(true, |a, b| a && b)
}
-fn never_loop_expr_branch<'a, T: Iterator<Item=&'a Expr>>(e: &mut T, state: &mut NeverLoopState) -> bool {
- e.map(|e| never_loop_expr(e, state)).fold(false, |a, b| a || b)
+fn never_loop_expr_branch<'a, T: Iterator<Item = &'a Expr>>(e: &mut T, state: &mut NeverLoopState) -> bool {
+ e.map(|e| never_loop_expr(e, state))
+ .fold(false, |a, b| a || b)
}
fn check_for_loop<'a, 'tcx>(
fn get_fixed_offset_var<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &Expr, var: ast::NodeId) -> Option<FixedOffsetVar> {
fn extract_offset<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, e: &Expr, var: ast::NodeId) -> Option<String> {
match e.node {
- ExprLit(ref l) => {
- match l.node {
- ast::LitKind::Int(x, _ty) => Some(x.to_string()),
- _ => None,
- }
+ ExprLit(ref l) => match l.node {
+ ast::LitKind::Int(x, _ty) => Some(x.to_string()),
+ _ => None,
},
ExprPath(..) if !same_var(cx, e, var) => Some(snippet_opt(cx, e.span).unwrap_or_else(|| "??".into())),
_ => None,
}
let offset = match idx.node {
- ExprBinary(op, ref lhs, ref rhs) => {
- match op.node {
- BinOp_::BiAdd => {
- let offset_opt = if same_var(cx, lhs, var) {
- extract_offset(cx, rhs, var)
- } else if same_var(cx, rhs, var) {
- extract_offset(cx, lhs, var)
- } else {
- None
- };
+ ExprBinary(op, ref lhs, ref rhs) => match op.node {
+ BinOp_::BiAdd => {
+ let offset_opt = if same_var(cx, lhs, var) {
+ extract_offset(cx, rhs, var)
+ } else if same_var(cx, rhs, var) {
+ extract_offset(cx, lhs, var)
+ } else {
+ None
+ };
- offset_opt.map(Offset::positive)
- },
- BinOp_::BiSub if same_var(cx, lhs, var) => extract_offset(cx, rhs, var).map(Offset::negative),
- _ => None,
- }
+ offset_opt.map(Offset::positive)
+ },
+ BinOp_::BiSub if same_var(cx, lhs, var) => extract_offset(cx, rhs, var).map(Offset::negative),
+ _ => None,
},
- ExprPath(..) => {
- if same_var(cx, idx, var) {
- Some(Offset::positive("0".into()))
- } else {
- None
- }
+ ExprPath(..) => if same_var(cx, idx, var) {
+ Some(Offset::positive("0".into()))
+ } else {
+ None
},
_ => None,
};
.iter()
.map(|stmt| match stmt.node {
Stmt_::StmtDecl(..) => None,
- Stmt_::StmtExpr(ref e, _node_id) |
- Stmt_::StmtSemi(ref e, _node_id) => Some(get_assignment(cx, e, var)),
+ Stmt_::StmtExpr(ref e, _node_id) | Stmt_::StmtSemi(ref e, _node_id) => Some(get_assignment(cx, e, var)),
})
- .chain(expr.as_ref().into_iter().map(|e| {
- Some(get_assignment(cx, &*e, var))
- }))
+ .chain(
+ expr.as_ref()
+ .into_iter()
+ .map(|e| Some(get_assignment(cx, &*e, var))),
+ )
.filter_map(|op| op)
.collect::<Option<Vec<_>>>()
.unwrap_or_else(|| vec![])
expr: &'tcx Expr,
) {
if let Some(higher::Range {
- start: Some(start),
- ref end,
- limits,
- }) = higher::range(arg)
+ start: Some(start),
+ ref end,
+ limits,
+ }) = higher::range(arg)
{
// the var must be a single name
if let PatKind::Binding(_, canonical_id, _, _) = pat.node {
let print_sum = |arg1: &Offset, arg2: &Offset| -> String {
match (&arg1.value[..], arg1.negate, &arg2.value[..], arg2.negate) {
("0", _, "0", _) => "".into(),
- ("0", _, x, false) |
- (x, false, "0", false) => x.into(),
- ("0", _, x, true) |
- (x, false, "0", true) => format!("-{}", x),
+ ("0", _, x, false) | (x, false, "0", false) => x.into(),
+ ("0", _, x, true) | (x, false, "0", true) => format!("-{}", x),
(x, false, y, false) => format!("({} + {})", x, y),
(x, false, y, true) => format!("({} - {})", x, y),
(x, true, y, false) => format!("({} - {})", y, x),
expr: &'tcx Expr,
) {
if let Some(higher::Range {
- start: Some(start),
- ref end,
- limits,
- }) = higher::range(arg)
+ start: Some(start),
+ ref end,
+ limits,
+ }) = higher::range(arg)
{
// the var must be a single name
if let PatKind::Binding(_, canonical_id, ref ident, _) = pat.node {
// linting condition: we only indexed one variable, and indexed it directly
// (`indexed_directly` is subset of `indexed`)
if visitor.indexed.len() == 1 && visitor.indexed_directly.len() == 1 {
- let (indexed, indexed_extent) = visitor.indexed_directly.into_iter().next().expect(
- "already checked that we have exactly 1 element",
- );
+ let (indexed, indexed_extent) = visitor
+ .indexed_directly
+ .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 {
fn check_for_loop_reverse_range<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, arg: &'tcx Expr, expr: &'tcx 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)
+ 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);
// who think that this will iterate from the larger value to the
// smaller value.
let (sup, eq) = match (start_idx, end_idx) {
- (&ty::Const { val: ConstVal::Integral(start_idx), .. },
- &ty::Const { val: ConstVal::Integral(end_idx), .. }) => {
- (start_idx > end_idx, start_idx == end_idx)
- },
+ (
+ &ty::Const {
+ val: ConstVal::Integral(start_idx),
+ ..
+ },
+ &ty::Const {
+ val: ConstVal::Integral(end_idx),
+ ..
+ },
+ ) => (start_idx > end_idx, start_idx == end_idx),
_ => (false, false),
};
// If the length is greater than 32 no traits are implemented for array and
// therefore we cannot use `&`.
ty::TypeVariants::TyArray(_, size) if const_to_u64(size) > 32 => (),
- _ => lint_iter_method(cx, args, arg, method_name)
+ _ => lint_iter_method(cx, args, arg, method_name),
};
} else {
let object = snippet(cx, args[0].span, "_");
// 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,
if pat.len() == 2 {
let arg_span = arg.span;
let (new_pat_span, kind, ty, mutbl) = match cx.tables.expr_ty(arg).sty {
- ty::TyRef(_, ref tam) => {
- match (&pat[0].node, &pat[1].node) {
- (key, _) if pat_is_wild(key, body) => (pat[1].span, "value", tam.ty, tam.mutbl),
- (_, value) if pat_is_wild(value, body) => (pat[0].span, "key", tam.ty, MutImmutable),
- _ => return,
- }
+ ty::TyRef(_, ref tam) => match (&pat[0].node, &pat[1].node) {
+ (key, _) if pat_is_wild(key, body) => (pat[1].span, "value", tam.ty, tam.mutbl),
+ (_, value) if pat_is_wild(value, body) => (pat[0].span, "key", tam.ty, MutImmutable),
+ _ => return,
},
_ => return,
};
}
impl<'tcx> Delegate<'tcx> for MutateDelegate {
- fn consume(&mut self, _: NodeId, _: Span, _: cmt<'tcx>, _: ConsumeMode) {
- }
+ fn consume(&mut self, _: NodeId, _: Span, _: cmt<'tcx>, _: ConsumeMode) {}
- fn matched_pat(&mut self, _: &Pat, _: cmt<'tcx>, _: MatchMode) {
- }
+ fn matched_pat(&mut self, _: &Pat, _: cmt<'tcx>, _: MatchMode) {}
- fn consume_pat(&mut self, _: &Pat, _: cmt<'tcx>, _: ConsumeMode) {
- }
+ fn consume_pat(&mut self, _: &Pat, _: cmt<'tcx>, _: ConsumeMode) {}
fn borrow(&mut self, _: NodeId, sp: Span, cmt: cmt<'tcx>, _: ty::Region, bk: ty::BorrowKind, _: LoanCause) {
if let ty::BorrowKind::MutBorrow = bk {
}
}
- fn decl_without_init(&mut self, _: NodeId, _: Span) {
- }
+ fn decl_without_init(&mut self, _: NodeId, _: Span) {}
}
impl<'tcx> MutateDelegate {
}
fn check_for_mut_range_bound(cx: &LateContext, arg: &Expr, body: &Expr) {
- if let Some(higher::Range { start: Some(start), end: Some(end), .. }) = higher::range(arg) {
- let mut_ids = vec![check_for_mutability(cx, start), check_for_mutability(cx, end)];
+ if let Some(higher::Range {
+ start: Some(start),
+ end: Some(end),
+ ..
+ }) = higher::range(arg)
+ {
+ let mut_ids = vec![
+ check_for_mutability(cx, start),
+ check_for_mutability(cx, end),
+ ];
if mut_ids[0].is_some() || mut_ids[1].is_some() {
let (span_low, span_high) = check_for_mutation(cx, body, &mut_ids);
mut_warn_with_span(cx, span_low);
fn mut_warn_with_span(cx: &LateContext, span: Option<Span>) {
if let Some(sp) = span {
- span_lint(cx, MUT_RANGE_BOUND, sp, "attempt to mutate range bound within loop; note that the range of the loop is unchanged");
+ span_lint(
+ cx,
+ MUT_RANGE_BOUND,
+ sp,
+ "attempt to mutate range bound within loop; note that the range of the loop is unchanged",
+ );
}
}
}
fn check_for_mutation(cx: &LateContext, body: &Expr, bound_ids: &[Option<NodeId>]) -> (Option<Span>, Option<Span>) {
- let mut delegate = MutateDelegate { node_id_low: bound_ids[0], node_id_high: bound_ids[1], span_low: None, span_high: None };
+ let mut delegate = MutateDelegate {
+ node_id_low: bound_ids[0],
+ node_id_high: bound_ids[1],
+ span_low: None,
+ span_high: None,
+ };
let def_id = def_id::DefId::local(body.hir_id.owner);
let region_scope_tree = &cx.tcx.region_scope_tree(def_id);
ExprUseVisitor::new(&mut delegate, cx.tcx, cx.param_env, region_scope_tree, cx.tables, None).walk_expr(body);
struct UsedVisitor {
var: ast::Name, // var to look for
- used: bool, // has the var been used otherwise?
+ used: bool, // has the var been used otherwise?
}
impl<'tcx> Visitor<'tcx> for UsedVisitor {
fn extract_first_expr(block: &Block) -> Option<&Expr> {
match block.expr {
Some(ref expr) if block.stmts.is_empty() => Some(expr),
- None if !block.stmts.is_empty() => {
- match block.stmts[0].node {
- StmtExpr(ref expr, _) |
- StmtSemi(ref expr, _) => Some(expr),
- StmtDecl(..) => None,
- }
+ None if !block.stmts.is_empty() => match block.stmts[0].node {
+ StmtExpr(ref expr, _) | StmtSemi(ref expr, _) => Some(expr),
+ StmtDecl(..) => None,
},
_ => None,
}
fn is_simple_break_expr(expr: &Expr) -> bool {
match expr.node {
ExprBreak(dest, ref passed_expr) if dest.ident.is_none() && passed_expr.is_none() => true,
- ExprBlock(ref b) => {
- match extract_first_expr(b) {
- Some(subexpr) => is_simple_break_expr(subexpr),
- None => false,
- }
+ ExprBlock(ref b) => match extract_first_expr(b) {
+ Some(subexpr) => is_simple_break_expr(subexpr),
+ None => false,
},
_ => false,
}
// at the start of the loop.
#[derive(PartialEq)]
enum VarState {
- Initial, // Not examined yet
+ Initial, // Not examined yet
IncrOnce, // Incremented exactly once, may be a loop counter
Declared, // Declared but not (yet) initialized to zero
Warn,
/// Scan a for loop for variables that are incremented exactly once.
struct IncrementVisitor<'a, 'tcx: 'a> {
- cx: &'a LateContext<'a, 'tcx>, // context reference
+ cx: &'a LateContext<'a, 'tcx>, // context reference
states: HashMap<NodeId, VarState>, // incremented variables
- depth: u32, // depth of conditional expressions
+ depth: u32, // depth of conditional expressions
done: bool,
}
/// Check whether a variable is initialized to zero at the start of a loop.
struct InitializeVisitor<'a, 'tcx: 'a> {
cx: &'a LateContext<'a, 'tcx>, // context reference
- end_expr: &'tcx Expr, // the for loop. Stop scanning here.
+ end_expr: &'tcx Expr, // the for loop. Stop scanning here.
var_id: NodeId,
state: VarState,
name: Option<Name>,
return false;
}
match cx.tcx.hir.find(parent) {
- Some(NodeExpr(expr)) => {
- match expr.node {
- ExprLoop(..) | ExprWhile(..) => {
- return true;
- },
- _ => (),
- }
+ Some(NodeExpr(expr)) => match expr.node {
+ ExprLoop(..) | ExprWhile(..) => {
+ return true;
+ },
+ _ => (),
},
Some(NodeBlock(block)) => {
let mut block_visitor = LoopNestVisitor {
#[derive(PartialEq, Eq)]
enum Nesting {
- Unknown, // no nesting detected yet
- RuledOut, // the iterator is initialized or assigned within scope
+ Unknown, // no nesting detected yet
+ RuledOut, // the iterator is initialized or assigned within scope
LookFurther, // no nesting detected, no further walk required
}
return;
}
match expr.node {
- ExprAssign(ref path, _) |
- ExprAssignOp(_, ref path, _) => {
- if match_var(path, self.iterator) {
- self.nesting = RuledOut;
- }
+ ExprAssign(ref path, _) | ExprAssignOp(_, ref path, _) => if match_var(path, self.iterator) {
+ self.nesting = RuledOut;
},
_ => walk_expr(self, expr),
}
}
/// Get all arms that are unbounded `PatRange`s.
-fn all_ranges<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, arms: &'tcx [Arm], id: NodeId) -> Vec<SpannedRange<&'tcx ty::Const<'tcx>>> {
+fn all_ranges<'a, 'tcx>(
+ cx: &LateContext<'a, 'tcx>,
+ arms: &'tcx [Arm],
+ id: NodeId,
+) -> Vec<SpannedRange<&'tcx ty::Const<'tcx>>> {
let parent_item = cx.tcx.hir.get_parent(id);
let parent_def_id = cx.tcx.hir.local_def_id(parent_item);
let substs = Substs::identity_for_item(cx.tcx, parent_def_id);
ranges
.iter()
.filter_map(|range| match range.node {
- (&ty::Const { val: ConstVal::Integral(start), .. }, Bound::Included(&ty::Const { val: ConstVal::Integral(end), .. })) => Some(SpannedRange {
+ (
+ &ty::Const {
+ val: ConstVal::Integral(start),
+ ..
+ },
+ Bound::Included(&ty::Const {
+ val: ConstVal::Integral(end),
+ ..
+ }),
+ ) => Some(SpannedRange {
span: range.span,
node: (start, Bound::Included(end)),
}),
- (&ty::Const { val: ConstVal::Integral(start), .. }, Bound::Excluded(&ty::Const { val: ConstVal::Integral(end), .. })) => Some(SpannedRange {
+ (
+ &ty::Const {
+ val: ConstVal::Integral(start),
+ ..
+ },
+ Bound::Excluded(&ty::Const {
+ val: ConstVal::Integral(end),
+ ..
+ }),
+ ) => Some(SpannedRange {
span: range.span,
node: (start, Bound::Excluded(end)),
}),
- (&ty::Const { val: ConstVal::Integral(start), .. }, Bound::Unbounded) => Some(SpannedRange {
+ (
+ &ty::Const {
+ val: ConstVal::Integral(start),
+ ..
+ },
+ Bound::Unbounded,
+ ) => Some(SpannedRange {
span: range.span,
node: (start, Bound::Unbounded),
}),
use rustc::lint::*;
use rustc::hir::{Expr, ExprCall, ExprPath};
-use utils::{match_def_path, paths, span_lint, opt_def_id};
+use utils::{match_def_path, opt_def_id, paths, span_lint};
/// **What it does:** Checks for usage of `std::mem::forget(t)` where `t` is
/// `Drop`.
GET_UNWRAP,
STRING_EXTEND_CHARS,
ITER_CLONED_COLLECT,
- USELESS_ASREF)
+ USELESS_ASREF
+ )
}
}
}
}
}
-
+
// check conventions w.r.t. conversion method names and predicates
let def_id = cx.tcx.hir.local_def_id(item.id);
let ty = cx.tcx.type_of(def_id);
for &(ref conv, self_kinds) in &CONVENTIONS {
if_chain! {
if conv.check(&name.as_str());
- if !self_kinds.iter().any(|k| k.matches(first_arg_ty, first_arg, self_ty, is_copy, &implitem.generics));
+ if !self_kinds
+ .iter()
+ .any(|k| k.matches(first_arg_ty, first_arg, self_ty, is_copy, &implitem.generics));
then {
let lint = if item.vis == hir::Visibility::Public {
WRONG_PUB_SELF_CONVENTION
}
}
}
-
+
let ret_ty = return_ty(cx, implitem.id);
if name == "new" &&
!ret_ty.walk().any(|t| same_tys(cx, t, ty)) {
// don't lint for constant values
// FIXME: can we `expect` here instead of match?
let owner_def = cx.tcx.hir.get_parent_did(arg.id);
- let promotable = cx.tcx
- .rvalue_promotable_map(owner_def)
- [&arg.hir_id.local_id];
+ let promotable = cx.tcx.rvalue_promotable_map(owner_def)[&arg.hir_id.local_id];
if promotable {
return;
}
expr.span,
"using '.clone()' on a ref-counted pointer",
"try this",
- format!("{}::clone(&{})",
- caller_type,
- snippet(cx, arg.span, "_")
- )
+ format!("{}::clone(&{})", caller_type, snippet(cx, arg.span, "_")),
);
-
}
if let Def::Method(did) = cx.tables.qpath_def(path, fun.hir_id);
if match_def_path(cx.tcx, did, &paths::CSTRING_NEW);
then {
- span_lint_and_then(cx, TEMPORARY_CSTRING_AS_PTR, expr.span,
- "you are getting the inner pointer of a temporary `CString`",
- |db| {
- db.note("that pointer will be invalid outside this expression");
- db.span_help(unwrap.span, "assign the `CString` to a variable to extend its lifetime");
- });
+ span_lint_and_then(
+ cx,
+ TEMPORARY_CSTRING_AS_PTR,
+ expr.span,
+ "you are getting the inner pointer of a temporary `CString`",
+ |db| {
+ db.note("that pointer will be invalid outside this expression");
+ db.span_help(unwrap.span, "assign the `CString` to a variable to extend its lifetime");
+ });
}
}
}
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()
+ 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,
// lint message
// comparing the snippet from source to raw text ("None") below is safe
// because we already have checked the type.
- let arg = if unwrap_snippet == "None" { "None" } else { "a" };
- let suggest = if unwrap_snippet == "None" { "and_then(f)" } else { "map_or(a, f)" };
+ let arg = if unwrap_snippet == "None" {
+ "None"
+ } else {
+ "a"
+ };
+ let suggest = if unwrap_snippet == "None" {
+ "and_then(f)"
+ } else {
+ "map_or(a, f)"
+ };
let msg = &format!(
"called `map(f).unwrap_or({})` on an Option value. \
This can be done more directly by calling `{}` instead",
// lint message
let msg = if is_option {
"called `map(f).unwrap_or_else(g)` on an Option value. This can be done more directly by calling \
- `map_or_else(g, f)` instead"
+ `map_or_else(g, f)` instead"
} else {
"called `map(f).unwrap_or_else(g)` on a Result value. This can be done more directly by calling \
- `ok().map_or_else(g, f)` instead"
+ `ok().map_or_else(g, f)` instead"
};
// get snippets for args to map() and unwrap_or_else()
let map_snippet = snippet(cx, map_args[1].span, "..");
/// lint use of `_.map_or(None, _)` for `Option`s
fn lint_map_or_none<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr, map_or_args: &'tcx [hir::Expr]) {
-
if match_type(cx, cx.tables.expr_ty(&map_or_args[0]), &paths::OPTION) {
// check if the first non-self argument to map_or() is None
let map_or_arg_is_none = if let hir::Expr_::ExprPath(ref qpath) = map_or_args[1].node {
let map_or_self_snippet = snippet(cx, map_or_args[0].span, "..");
let map_or_func_snippet = snippet(cx, map_or_args[2].span, "..");
let hint = format!("{0}.and_then({1})", map_or_self_snippet, map_or_func_snippet);
- span_lint_and_then(
- cx,
- OPTION_MAP_OR_NONE,
- expr.span,
- msg,
- |db| { db.span_suggestion(expr.span, "try using and_then instead", hint); },
- );
+ span_lint_and_then(cx, OPTION_MAP_OR_NONE, expr.span, msg, |db| {
+ db.span_suggestion(expr.span, "try using and_then instead", hint);
+ });
}
}
}
}
/// lint use of `filter().map()` for `Iterators`
-fn lint_filter_map<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr, _filter_args: &'tcx [hir::Expr], _map_args: &'tcx [hir::Expr]) {
+fn lint_filter_map<'a, 'tcx>(
+ cx: &LateContext<'a, 'tcx>,
+ expr: &'tcx hir::Expr,
+ _filter_args: &'tcx [hir::Expr],
+ _map_args: &'tcx [hir::Expr],
+) {
// lint if caller of `.filter().map()` is an Iterator
if match_trait_method(cx, expr, &paths::ITERATOR) {
let msg = "called `filter(p).map(q)` on an `Iterator`. \
}
/// lint use of `filter().map()` for `Iterators`
-fn lint_filter_map_map<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr, _filter_args: &'tcx [hir::Expr], _map_args: &'tcx [hir::Expr]) {
+fn lint_filter_map_map<'a, 'tcx>(
+ cx: &LateContext<'a, 'tcx>,
+ expr: &'tcx hir::Expr,
+ _filter_args: &'tcx [hir::Expr],
+ _map_args: &'tcx [hir::Expr],
+) {
// lint if caller of `.filter().map()` is an Iterator
if match_trait_method(cx, expr, &paths::ITERATOR) {
let msg = "called `filter_map(p).map(q)` on an `Iterator`. \
}
/// lint use of `filter().flat_map()` for `Iterators`
-fn lint_filter_flat_map<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr, _filter_args: &'tcx [hir::Expr], _map_args: &'tcx [hir::Expr]) {
+fn lint_filter_flat_map<'a, 'tcx>(
+ cx: &LateContext<'a, 'tcx>,
+ expr: &'tcx hir::Expr,
+ _filter_args: &'tcx [hir::Expr],
+ _map_args: &'tcx [hir::Expr],
+) {
// lint if caller of `.filter().flat_map()` is an Iterator
if match_trait_method(cx, expr, &paths::ITERATOR) {
let msg = "called `filter(p).flat_map(q)` on an `Iterator`. \
}
/// lint use of `filter_map().flat_map()` for `Iterators`
-fn lint_filter_map_flat_map<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr, _filter_args: &'tcx [hir::Expr], _map_args: &'tcx [hir::Expr]) {
+fn lint_filter_map_flat_map<'a, 'tcx>(
+ cx: &LateContext<'a, 'tcx>,
+ expr: &'tcx hir::Expr,
+ _filter_args: &'tcx [hir::Expr],
+ _map_args: &'tcx [hir::Expr],
+) {
// lint if caller of `.filter_map().flat_map()` is an Iterator
if match_trait_method(cx, expr, &paths::ITERATOR) {
let msg = "called `filter_map(p).flat_map(q)` on an `Iterator`. \
}
/// Wrapper fn for `CHARS_NEXT_CMP` and `CHARS_NEXT_CMP` lints.
-fn lint_chars_cmp<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, info: &BinaryExprInfo, chain_methods: &[&str], lint: &'static Lint, suggest: &str) -> bool {
+fn lint_chars_cmp<'a, 'tcx>(
+ cx: &LateContext<'a, 'tcx>,
+ info: &BinaryExprInfo,
+ chain_methods: &[&str],
+ lint: &'static Lint,
+ suggest: &str,
+) -> bool {
if_chain! {
if let Some(args) = method_chain_args(info.chain, chain_methods);
if let hir::ExprCall(ref fun, ref arg_char) = info.other.node;
if segment.name == "Some";
then {
let self_ty = walk_ptrs_ty(cx.tables.expr_ty_adjusted(&args[0][0]));
-
+
if self_ty.sty != ty::TyStr {
return false;
}
-
+
span_lint_and_sugg(cx,
lint,
info.expr.span,
snippet(cx, args[0][0].span, "_"),
suggest,
snippet(cx, arg_char[0].span, "_")));
-
+
return true;
}
}
}
/// Wrapper fn for `CHARS_NEXT_CMP` and `CHARS_LAST_CMP` lints with `unwrap()`.
-fn lint_chars_cmp_with_unwrap<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, info: &BinaryExprInfo, chain_methods: &[&str], lint: &'static Lint, suggest: &str) -> bool {
+fn lint_chars_cmp_with_unwrap<'a, 'tcx>(
+ cx: &LateContext<'a, 'tcx>,
+ info: &BinaryExprInfo,
+ chain_methods: &[&str],
+ lint: &'static Lint,
+ suggest: &str,
+) -> bool {
if_chain! {
if let Some(args) = method_chain_args(info.chain, chain_methods);
if let hir::ExprLit(ref lit) = info.other.node;
suggest,
c)
);
-
+
return true;
}
}
let parent_item = cx.tcx.hir.get_parent(arg.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 let Ok(&ty::Const { val: ConstVal::Str(r), .. }) = ConstContext::new(cx.tcx, cx.param_env.and(substs), cx.tables).eval(arg) {
+ if let Ok(&ty::Const {
+ val: 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(
SINGLE_CHAR_PATTERN,
arg.span,
"single-character string constant used as pattern",
- |db| { db.span_suggestion(expr.span, "try using a char instead", hint); },
+ |db| {
+ db.span_suggestion(expr.span, "try using a char instead", hint);
+ },
);
}
}
fn is_as_ref_or_mut_trait(ty: &hir::Ty, self_ty: &hir::Ty, generics: &hir::Generics, name: &[&str]) -> bool {
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(path, name) &&
- path.segments
- .last()
- .map_or(false, |s| {
- if let Some(ref params) = s.parameters {
- if params.parenthesized {
- false
- } else {
- params.types.len() == 1 &&
- (is_self_ty(¶ms.types[0])
- || is_ty(&*params.types[0], self_ty))
- }
- } else {
- false
- }
- })
- } else {
- false
+ 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(path, name) && path.segments.last().map_or(false, |s| {
+ if let Some(ref params) = s.parameters {
+ if params.parenthesized {
+ false
+ } else {
+ params.types.len() == 1
+ && (is_self_ty(¶ms.types[0]) || is_ty(&*params.types[0], self_ty))
+ }
+ } else {
+ false
+ }
})
+ } else {
+ false
+ }
+ })
})
})
}
use rustc::lint::*;
use rustc::hir::*;
use std::cmp::{Ordering, PartialOrd};
-use utils::{match_def_path, paths, span_lint, opt_def_id};
+use utils::{match_def_path, opt_def_id, paths, span_lint};
/// **What it does:** Checks for expressions where `std::cmp::min` and `max` are
/// used to clamp values, but switched so that the result is constant.
}
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")
+ if name == "eq" || name == "ne" || name == "is_nan" || name.starts_with("eq_")
+ || name.ends_with("_eq")
{
return;
}
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",
- );
+ 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",
+ );
+ }
});
}
}
let parent_def_id = cx.tcx.hir.local_def_id(parent_item);
let substs = Substs::identity_for_item(cx.tcx, parent_def_id);
let res = ConstContext::new(cx.tcx, cx.param_env.and(substs), cx.tables).eval(expr);
- if let Ok(&ty::Const { val: ConstVal::Float(val), .. }) = res {
+ if let Ok(&ty::Const {
+ val: ConstVal::Float(val),
+ ..
+ }) = res
+ {
use std::cmp::Ordering;
match val.ty {
FloatTy::F32 => {
bits: u128::from(::std::f32::NEG_INFINITY.to_bits()),
};
- 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(zero) == Ok(Ordering::Equal) || val.try_cmp(infinity) == Ok(Ordering::Equal)
+ || val.try_cmp(neg_infinity) == Ok(Ordering::Equal)
},
FloatTy::F64 => {
let zero = ConstFloat {
bits: u128::from(::std::f64::NEG_INFINITY.to_bits()),
};
- 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(zero) == Ok(Ordering::Equal) || val.try_cmp(infinity) == Ok(Ordering::Equal)
+ || val.try_cmp(neg_infinity) == Ok(Ordering::Equal)
},
}
} else {
/// Test whether `def` is a variable defined outside a macro.
fn non_macro_local(cx: &LateContext, def: &def::Def) -> bool {
match *def {
- def::Def::Local(id) | def::Def::Upvar(id, _, _) => {
- !in_macro(cx.tcx.hir.span(id))
- },
+ def::Def::Local(id) | def::Def::Upvar(id, _, _) => !in_macro(cx.tcx.hir.span(id)),
_ => false,
}
}
if let Some(snippet) = snippet_opt(cx, inner.span) {
db.span_suggestion(e.span, "change this to", snippet);
}
- }
+ },
);
}
}
const MSG_REDUNDANT_ELSE_BLOCK: &str = "This else block is redundant.\n";
const MSG_ELSE_BLOCK_NOT_NEEDED: &str = "There is no need for an explicit `else` block for this `if` \
- expression\n";
+ expression\n";
const DROP_ELSE_BLOCK_AND_MERGE_MSG: &str = "Consider dropping the else clause and merging the code that \
- follows (in the loop) with the if block, like so:\n";
+ follows (in the loop) with the if block, like so:\n";
const DROP_ELSE_BLOCK_MSG: &str = "Consider dropping the else clause, and moving out the code in the else \
- block, like so:\n";
+ block, like so:\n";
fn emit_warning<'a>(ctx: &EarlyContext, data: &'a LintData, header: &str, typ: LintType) {
}
fn check_and_warn<'a>(ctx: &EarlyContext, expr: &'a ast::Expr) {
- with_loop_block(expr, |loop_block| for (i, stmt) in loop_block.stmts.iter().enumerate() {
- with_if_expr(stmt, |if_expr, cond, then_block, else_expr| {
- let data = &LintData {
- stmt_idx: i,
- if_expr: if_expr,
- if_cond: cond,
- if_block: then_block,
- else_expr: else_expr,
- block_stmts: &loop_block.stmts,
- };
- if needless_continue_in_else(else_expr) {
- emit_warning(ctx, data, DROP_ELSE_BLOCK_AND_MERGE_MSG, LintType::ContinueInsideElseBlock);
- } else if is_first_block_stmt_continue(then_block) {
- emit_warning(ctx, data, DROP_ELSE_BLOCK_MSG, LintType::ContinueInsideThenBlock);
- }
- });
+ with_loop_block(expr, |loop_block| {
+ for (i, stmt) in loop_block.stmts.iter().enumerate() {
+ with_if_expr(stmt, |if_expr, cond, then_block, else_expr| {
+ let data = &LintData {
+ stmt_idx: i,
+ if_expr: if_expr,
+ if_cond: cond,
+ if_block: then_block,
+ else_expr: else_expr,
+ block_stmts: &loop_block.stmts,
+ };
+ if needless_continue_in_else(else_expr) {
+ emit_warning(ctx, data, DROP_ELSE_BLOCK_AND_MERGE_MSG, LintType::ContinueInsideElseBlock);
+ } else if is_first_block_stmt_continue(then_block) {
+ emit_warning(ctx, data, DROP_ELSE_BLOCK_MSG, LintType::ContinueInsideThenBlock);
+ }
+ });
+ }
});
}
let preds = traits::elaborate_predicates(cx.tcx, cx.param_env.caller_bounds.to_vec())
.filter(|p| !p.is_global())
- .filter_map(|pred| if let ty::Predicate::Trait(poly_trait_ref) = pred {
- if poly_trait_ref.def_id() == sized_trait || poly_trait_ref.skip_binder().has_escaping_regions() {
- return None;
+ .filter_map(|pred| {
+ if let ty::Predicate::Trait(poly_trait_ref) = pred {
+ if poly_trait_ref.def_id() == sized_trait || poly_trait_ref.skip_binder().has_escaping_regions() {
+ return None;
+ }
+ Some(poly_trait_ref)
+ } else {
+ None
}
- Some(poly_trait_ref)
- } else {
- None
})
.collect::<Vec<_>>();
// can't be implemented by default
return;
}
- if !cx.generics.expect("method must have generics").ty_params.is_empty() {
- // when the result of `new()` depends on a type parameter we should not require
- // an
- // impl of `Default`
- return;
+ if !cx.generics
+ .expect("method must have generics")
+ .ty_params
+ .is_empty()
+ {
+ // 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)));
if_chain! {
- if same_tys(cx, self_ty, return_ty(cx, id));
- if let Some(default_trait_id) = get_trait_def_id(cx, &paths::DEFAULT_TRAIT);
- if !implements_trait(cx, self_ty, default_trait_id, &[]);
- then {
- if let Some(sp) = can_derive_default(self_ty, cx, default_trait_id) {
- span_lint_and_then(cx,
- NEW_WITHOUT_DEFAULT_DERIVE, span,
- &format!("you should consider deriving a \
- `Default` implementation for `{}`",
- self_ty),
- |db| {
- db.suggest_item_with_attr(cx, sp, "try this", "#[derive(Default)]");
- });
- } else {
- span_lint_and_then(cx,
- NEW_WITHOUT_DEFAULT, span,
- &format!("you should consider adding a \
- `Default` implementation for `{}`",
- self_ty),
- |db| {
- db.suggest_prepend_item(cx,
- span,
- "try this",
- &format!(
-"impl Default for {} {{
- fn default() -> Self {{
- Self::new()
- }}
-}}",
- self_ty));
- });
- }
- }
+ if same_tys(cx, self_ty, return_ty(cx, id));
+ if let Some(default_trait_id) = get_trait_def_id(cx, &paths::DEFAULT_TRAIT);
+ if !implements_trait(cx, self_ty, default_trait_id, &[]);
+ then {
+ if let Some(sp) = can_derive_default(self_ty, cx, default_trait_id) {
+ span_lint_and_then(
+ cx,
+ NEW_WITHOUT_DEFAULT_DERIVE,
+ span,
+ &format!("you should consider deriving a `Default` implementation for `{}`", self_ty),
+ |db| {
+ db.suggest_item_with_attr(cx, sp, "try this", "#[derive(Default)]");
+ });
+ } else {
+ span_lint_and_then(
+ cx,
+ NEW_WITHOUT_DEFAULT,
+ span,
+ &format!("you should consider adding a `Default` implementation for `{}`", self_ty),
+ |db| {
+ db.suggest_prepend_item(
+ cx,
+ span,
+ "try this",
+ &create_new_without_default_suggest_msg(self_ty),
+ );
+ },
+ );
+ }
+ }
}
}
}
}
}
+fn create_new_without_default_suggest_msg(ty: Ty) -> String {
+ #[rustfmt_skip]
+ format!(
+"impl Default for {} {{
+ fn default() -> Self {{
+ Self::new()
+ }}
+}}", ty)
+}
+
fn can_derive_default<'t, 'c>(ty: Ty<'t>, cx: &LateContext<'c, 't>, default_trait_id: DefId) -> Option<Span> {
match ty.sty {
ty::TyAdt(adt_def, substs) if adt_def.is_struct() => {
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
use rustc::hir::def::Def;
use rustc::hir::{BiAnd, BiOr, BlockCheckMode, Expr, Expr_, Stmt, StmtSemi, UnsafeSource};
-use utils::{in_macro, snippet_opt, span_lint, span_lint_and_sugg, has_drop};
+use utils::{has_drop, in_macro, snippet_opt, span_lint, span_lint_and_sugg};
use std::ops::Deref;
/// **What it does:** Checks for statements which have no effect.
Expr_::ExprTupField(ref inner, _) |
Expr_::ExprAddrOf(_, ref inner) |
Expr_::ExprBox(ref inner) => reduce_expression(cx, inner).or_else(|| Some(vec![inner])),
- Expr_::ExprStruct(_, ref fields, ref base) => {
- if has_drop(cx, expr) {
- None
- } else {
- Some(
- fields
- .iter()
- .map(|f| &f.expr)
- .chain(base)
- .map(Deref::deref)
- .collect())
- }
+ Expr_::ExprStruct(_, ref fields, ref base) => if has_drop(cx, expr) {
+ None
+ } else {
+ 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 {
let def = cx.tables.qpath_def(qpath, callee.hir_id);
match def {
- Def::Struct(..) | Def::Variant(..) | Def::StructCtor(..) | Def::VariantCtor(..) if !has_drop(cx, expr) => {
+ Def::Struct(..) | Def::Variant(..) | Def::StructCtor(..) | Def::VariantCtor(..)
+ if !has_drop(cx, expr) =>
+ {
Some(args.iter().collect())
},
_ => None,
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(eq_or_numeric)
+ if !eq_or_numeric((second_last_i, second_last_e)) || second_last_i == '_'
+ || !interned_chars.zip(existing_chars).all(eq_or_numeric)
{
// allowed similarity foo_x, foo_y
// or too many chars differ (foo_x, boo_y) or (foox, booy)
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(eq_or_numeric)
+ if !eq_or_numeric((second_i, second_e)) || second_i == '_'
+ || !interned_chars.zip(existing_chars).all(eq_or_numeric)
{
// allowed similarity x_foo, y_foo
// or too many chars differ (x_foo, y_boo) or (xfoo, yboo)
if let ExprMethodCall(_, _, ref result_types) = op.node; //check is expr.ok() has type Result<T,E>.ok()
if let PatKind::TupleStruct(QPath::Resolved(_, ref x), ref y, _) = body[0].pats[0].node; //get operation
if method_chain_args(op, &["ok"]).is_some(); //test to see if using ok() methoduse std::marker::Sized;
-
+
then {
let is_result_type = match_type(cx, cx.tables.expr_ty(&result_types[0]), &paths::RESULT);
let some_expr_string = snippet(cx, y[0].span, "");
}
} else {
return; // The function is called with a literal
- // which is not a boolean literal. This is theoretically
- // possible, but not very likely.
+ // which is not a boolean literal. This is theoretically
+ // possible, but not very likely.
}
},
_ => Argument::Unknown,
use rustc::hir::*;
use rustc::lint::*;
use syntax::ast::LitKind;
-use utils::{is_direct_expn_of, match_def_path, paths, resolve_node, span_lint, opt_def_id};
+use utils::{is_direct_expn_of, match_def_path, opt_def_id, paths, resolve_node, span_lint};
/// **What it does:** Checks for missing parameters in `panic!`.
///
use syntax::symbol::InternedString;
use syntax_pos::Span;
use utils::{is_expn_of, match_def_path, match_path, resolve_node, span_lint};
-use utils::{paths, opt_def_id};
+use utils::{opt_def_id, paths};
/// **What it does:** This lint warns when you using `println!("")` to
/// print a newline.
if let ExprPath(ref qpath) = fun.node;
if let Some(fun_id) = opt_def_id(resolve_node(cx, qpath, fun.hir_id));
then {
-
+
// Search for `std::io::_print(..)` which is unique in a
// `print!` expansion.
if match_def_path(cx.tcx, fun_id, &paths::IO_PRINT) {
Some(span) => (span, "println"),
None => (span, "print"),
};
-
+
span_lint(cx, PRINT_STDOUT, span, &format!("use of `{}!`", name));
-
+
if_chain! {
// ensure we're calling Arguments::new_v1
if args.len() == 1;
use syntax::ast::NodeId;
use syntax::codemap::Span;
use syntax_pos::MultiSpan;
-use utils::{match_qpath, match_type, paths, snippet_opt, span_lint, span_lint_and_then,
- walk_ptrs_hir_ty};
+use utils::{match_qpath, match_type, paths, snippet_opt, span_lint, span_lint_and_then, walk_ptrs_hir_ty};
use utils::ptr::get_spans;
/// **What it does:** This lint checks for function arguments of type `&String`
fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx TraitItem) {
if let TraitItemKind::Method(ref sig, ref trait_method) = item.node {
- let body_id = if let TraitMethod::Provided(b) = *trait_method { Some(b) } else { None };
+ let body_id = if let TraitMethod::Provided(b) = *trait_method {
+ Some(b)
+ } else {
+ None
+ };
check_fn(cx, &sig.decl, item.id, body_id);
}
}
with non-Vec-based slices.",
|db| {
if let Some(ref snippet) = ty_snippet {
- db.span_suggestion(arg.span,
- "change this to",
- format!("&[{}]", snippet));
+ db.span_suggestion(arg.span, "change this to", format!("&[{}]", snippet));
}
for (clonespan, suggestion) in spans {
- db.span_suggestion(clonespan,
- &snippet_opt(cx, clonespan).map_or("change the call to".into(),
- |x| Cow::Owned(format!("change `{}` to", x))),
- suggestion.into());
+ db.span_suggestion(
+ clonespan,
+ &snippet_opt(cx, clonespan).map_or(
+ "change the call to".into(),
+ |x| Cow::Owned(format!("change `{}` to", x)),
+ ),
+ suggestion.into(),
+ );
}
- }
+ },
);
}
} else if match_type(cx, ty, &paths::STRING) {
arg.span,
"writing `&String` instead of `&str` involves a new object where a slice will do.",
|db| {
- db.span_suggestion(arg.span,
- "change this to",
- "&str".into());
+ db.span_suggestion(arg.span, "change this to", "&str".into());
for (clonespan, suggestion) in spans {
- db.span_suggestion_short(clonespan,
- &snippet_opt(cx, clonespan).map_or("change the call to".into(),
- |x| Cow::Owned(format!("change `{}` to", x))),
- suggestion.into());
+ db.span_suggestion_short(
+ clonespan,
+ &snippet_opt(cx, clonespan).map_or(
+ "change the call to".into(),
+ |x| Cow::Owned(format!("change `{}` to", x)),
+ ),
+ suggestion.into(),
+ );
}
- }
+ },
);
}
}
impl LintPass for Pass {
fn get_lints(&self) -> LintArray {
- lint_array!(
- ITERATOR_STEP_BY_ZERO,
- RANGE_ZIP_WITH_LEN,
- RANGE_PLUS_ONE,
- RANGE_MINUS_ONE
- )
+ lint_array!(ITERATOR_STEP_BY_ZERO, RANGE_ZIP_WITH_LEN, RANGE_PLUS_ONE, RANGE_MINUS_ONE)
}
}
fn y_plus_one(expr: &Expr) -> Option<&Expr> {
match expr.node {
- ExprBinary(Spanned { node: BiAdd, .. }, ref lhs, ref rhs) => {
- if is_integer_literal(lhs, 1) {
- Some(rhs)
- } else if is_integer_literal(rhs, 1) {
- Some(lhs)
- } else {
- None
- }
+ ExprBinary(Spanned { node: BiAdd, .. }, ref lhs, ref rhs) => if is_integer_literal(lhs, 1) {
+ Some(rhs)
+ } else if is_integer_literal(rhs, 1) {
+ Some(lhs)
+ } else {
+ None
},
_ => None,
}
use syntax::ast::{LitKind, NodeId};
use syntax::codemap::{BytePos, Span};
use syntax::symbol::InternedString;
-use utils::{is_expn_of, match_def_path, match_type, paths, span_help_and_lint, span_lint, opt_def_id};
+use utils::{is_expn_of, match_def_path, match_type, opt_def_id, paths, span_help_and_lint, span_lint};
/// **What it does:** Checks [regex](https://crates.io/crates/regex) creation
/// (with `Regex::new`,`RegexBuilder::new` or `RegexSet::new`) for correct
let parent_def_id = cx.tcx.hir.local_def_id(parent_item);
let substs = Substs::identity_for_item(cx.tcx, parent_def_id);
match ConstContext::new(cx.tcx, cx.param_env.and(substs), cx.tables).eval(e) {
- Ok(&ty::Const { val: ConstVal::Str(r), .. }) => Some(r),
+ Ok(&ty::Const {
+ val: ConstVal::Str(r),
+ ..
+ }) => Some(r),
_ => None,
}
}
snippet(cx, pattern_span, "_"),
snippet(cx, expr.span, "..")
),
- |db| { db.span_note(prev_span, "previous binding is here"); },
+ |db| {
+ db.span_note(prev_span, "previous binding is here");
+ },
);
} else if contains_name(name, expr) {
span_lint_and_then(
SHADOW_UNRELATED,
span,
&format!("`{}` shadows a previous declaration", snippet(cx, pattern_span, "_")),
- |db| { db.span_note(prev_span, "previous binding is here"); },
+ |db| {
+ db.span_note(prev_span, "previous binding is here");
+ },
);
}
}
match expr.node {
ExprBox(ref inner) | ExprAddrOf(_, ref inner) => is_self_shadow(name, inner),
ExprBlock(ref block) => {
- block.stmts.is_empty() &&
- block
+ block.stmts.is_empty()
+ && block
.expr
.as_ref()
.map_or(false, |e| is_self_shadow(name, e))
match src.node {
ExprBinary(Spanned { node: BiAdd, .. }, ref left, _) => SpanlessEq::new(cx).eq_expr(target, left),
ExprBlock(ref block) => {
- block.stmts.is_empty() &&
- block
+ block.stmts.is_empty()
+ && block
.expr
.as_ref()
.map_or(false, |expr| is_add(cx, expr, target))
if let ExprIndex(ref lhs2, ref idx2) = lhs2.node {
if SpanlessEq::new(cx).ignore_fn().eq_expr(lhs1, lhs2) {
let ty = walk_ptrs_ty(cx.tables.expr_ty(lhs1));
-
+
if matches!(ty.sty, ty::TySlice(_)) ||
matches!(ty.sty, ty::TyArray(_, _)) ||
match_type(cx, ty, &paths::VEC) ||
}
}
}
-
+
None
}
-
+
let (replace, what, sugg) = if let Some((slice, idx1, idx2)) = check_for_slice(cx, lhs1, lhs2) {
if let Some(slice) = Sugg::hir_opt(cx, slice) {
(false,
} else {
(true, "".to_owned(), "".to_owned())
};
-
+
let span = w[0].span.to(second.span);
-
+
span_lint_and_then(cx,
MANUAL_SWAP,
span,
|db| {
if !sugg.is_empty() {
db.span_suggestion(span, "try", sugg);
-
+
if replace {
db.note("or maybe you should use `std::mem::replace`?");
}
let lhs0 = Sugg::hir_opt(cx, lhs0);
let rhs0 = Sugg::hir_opt(cx, rhs0);
let (what, lhs, rhs) = if let (Some(first), Some(second)) = (lhs0, rhs0) {
- (format!(" `{}` and `{}`", first, second), first.mut_addr().to_string(), second.mut_addr().to_string())
+ (
+ format!(" `{}` and `{}`", first, second),
+ first.mut_addr().to_string(),
+ second.mut_addr().to_string(),
+ )
} else {
("".to_owned(), "".to_owned(), "".to_owned())
};
-
+
let span = first.span.to(second.span);
-
+
span_lint_and_then(cx,
ALMOST_SWAPPED,
span,
use std::borrow::Cow;
use syntax::ast;
use utils::{last_path_segment, match_def_path, paths, snippet, span_lint, span_lint_and_then};
-use utils::{sugg, opt_def_id};
+use utils::{opt_def_id, sugg};
/// **What it does:** Checks for transmutes that can't ever be correct on any
/// architecture.
if let ExprCall(ref path_expr, ref args) = e.node {
if let ExprPath(ref qpath) = path_expr.node {
if let Some(def_id) = opt_def_id(cx.tables.qpath_def(qpath, path_expr.hir_id)) {
-
if match_def_path(cx.tcx, def_id, &paths::TRANSMUTE) {
let from_ty = cx.tables.expr_ty(&args[0]);
let to_ty = cx.tables.expr_ty(e);
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());
- },
- ),
+ (&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());
+ },
+ )
+ },
(&ty::TyFloat(_), &ty::TyRef(..)) |
(&ty::TyFloat(_), &ty::TyRawPtr(_)) |
(&ty::TyChar, &ty::TyRef(..)) |
cx,
CROSSPOINTER_TRANSMUTE,
e.span,
- &format!("transmute from a type (`{}`) to a pointer to that type (`{}`)", from_ty, to_ty),
+ &format!(
+ "transmute from a type (`{}`) to a pointer to that type (`{}`)",
+ from_ty,
+ to_ty
+ ),
),
(&ty::TyRawPtr(from_pty), &ty::TyRef(_, to_ref_ty)) => span_lint_and_then(
cx,
e.span,
&format!(
"transmute from a pointer type (`{}`) to a reference type \
- (`{}`)",
+ (`{}`)",
from_ty,
to_ty
),
} else {
arg
};
- db.span_suggestion(e.span, "consider using", format!("std::char::from_u32({}).unwrap()", arg.to_string()));
- }
+ db.span_suggestion(
+ e.span,
+ "consider using",
+ format!("std::char::from_u32({}).unwrap()", arg.to_string()),
+ );
+ },
),
(&ty::TyRef(_, ref ref_from), &ty::TyRef(_, ref ref_to)) => {
if_chain! {
}
}
},
- (&ty::TyInt(ast::IntTy::I8), &ty::TyBool) |
- (&ty::TyUint(ast::UintTy::U8), &ty::TyBool) => span_lint_and_then(
- cx,
- TRANSMUTE_INT_TO_BOOL,
- e.span,
- &format!("transmute from a `{}` to a `bool`", from_ty),
- |db| {
- let arg = sugg::Sugg::hir(cx, &args[0], "..");
- let zero = sugg::Sugg::NonParen(Cow::from("0"));
- db.span_suggestion(e.span, "consider using", sugg::make_binop(ast::BinOpKind::Ne, &arg, &zero).to_string());
- }
- ),
- (&ty::TyInt(_), &ty::TyFloat(_)) |
- (&ty::TyUint(_), &ty::TyFloat(_)) => span_lint_and_then(
- cx,
- TRANSMUTE_INT_TO_FLOAT,
- e.span,
- &format!("transmute from a `{}` to a `{}`", from_ty, to_ty),
- |db| {
- let arg = sugg::Sugg::hir(cx, &args[0], "..");
- let arg = if let ty::TyInt(int_ty) = from_ty.sty {
- arg.as_ty(format!("u{}", int_ty.bit_width().map_or_else(|| "size".to_string(), |v| v.to_string())))
- } else {
- arg
- };
- db.span_suggestion(e.span, "consider using", format!("{}::from_bits({})", to_ty, arg.to_string()));
- }
- ),
+ (&ty::TyInt(ast::IntTy::I8), &ty::TyBool) | (&ty::TyUint(ast::UintTy::U8), &ty::TyBool) => {
+ span_lint_and_then(
+ cx,
+ TRANSMUTE_INT_TO_BOOL,
+ e.span,
+ &format!("transmute from a `{}` to a `bool`", from_ty),
+ |db| {
+ let arg = sugg::Sugg::hir(cx, &args[0], "..");
+ let zero = sugg::Sugg::NonParen(Cow::from("0"));
+ db.span_suggestion(
+ e.span,
+ "consider using",
+ sugg::make_binop(ast::BinOpKind::Ne, &arg, &zero).to_string(),
+ );
+ },
+ )
+ },
+ (&ty::TyInt(_), &ty::TyFloat(_)) | (&ty::TyUint(_), &ty::TyFloat(_)) => {
+ span_lint_and_then(
+ cx,
+ TRANSMUTE_INT_TO_FLOAT,
+ e.span,
+ &format!("transmute from a `{}` to a `{}`", from_ty, to_ty),
+ |db| {
+ let arg = sugg::Sugg::hir(cx, &args[0], "..");
+ let arg = if let ty::TyInt(int_ty) = from_ty.sty {
+ arg.as_ty(format!(
+ "u{}",
+ int_ty
+ .bit_width()
+ .map_or_else(|| "size".to_string(), |v| v.to_string())
+ ))
+ } else {
+ arg
+ };
+ db.span_suggestion(
+ e.span,
+ "consider using",
+ format!("{}::from_bits({})", to_ty, arg.to_string()),
+ );
+ },
+ )
+ },
_ => return,
};
}
if let Some(did) = opt_def_id(cx.tables.qpath_def(qpath, cx.tcx.hir.node_to_hir_id(vec.id)));
if match_def_path(cx.tcx, did, &paths::VEC);
then {
- span_help_and_lint(cx,
- BOX_VEC,
- ast_ty.span,
- "you seem to be trying to use `Box<Vec<T>>`. Consider using just `Vec<T>`",
- "`Vec<T>` is already on the heap, `Box<Vec<T>>` makes an extra allocation.");
+ span_help_and_lint(
+ cx,
+ BOX_VEC,
+ ast_ty.span,
+ "you seem to be trying to use `Box<Vec<T>>`. Consider using just `Vec<T>`",
+ "`Vec<T>` is already on the heap, `Box<Vec<T>>` makes an extra allocation.",
+ );
return; // don't recurse into the type
}
}
// Ignore `Box<Any>` types, see #1884 for details.
return;
}
-
+
let ltopt = if lt.is_elided() {
"".to_owned()
} else {
if !same_tys(self.cx, self.target.ty(), self.body.expr_ty(e)) {
return;
}
-
+
if match_path(ty_path, &paths::HASHMAP) {
if method.name == "new" {
self.suggestions
then {
let parameters = &item_path.segments.last().expect(SEGMENTS_MSG).parameters;
let should_check = if let Some(ref params) = *parameters {
- !params.parenthesized && params.lifetimes.len() == 0
+ !params.parenthesized && params.lifetimes.len() == 0
} else {
true
};
// FIXME: also check int type
LitKind::Int(i, _) => println!(" if let LitKind::Int({}, _) = {}.node;", i, lit_pat),
LitKind::Float(..) => println!(" if let LitKind::Float(..) = {}.node;", lit_pat),
- LitKind::FloatUnsuffixed(_) => println!(" if let LitKind::FloatUnsuffixed(_) = {}.node;", lit_pat),
+ LitKind::FloatUnsuffixed(_) => {
+ println!(" if let LitKind::FloatUnsuffixed(_) = {}.node;", lit_pat)
+ },
LitKind::ByteStr(ref vec) => {
let vec_pat = self.next("vec");
println!(" if let LitKind::ByteStr(ref {}) = {}.node;", vec_pat, lit_pat);
use rustc::hir;
use rustc::lint::LateContext;
use syntax::ast;
-use utils::{is_expn_of, match_def_path, match_qpath, paths, resolve_node, opt_def_id};
+use utils::{is_expn_of, match_def_path, match_qpath, opt_def_id, paths, resolve_node};
/// Convert a hir binary operator to the corresponding `ast` type.
pub fn binop(op: hir::BinOp_) -> ast::BinOpKind {
/// 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()
- .find(|field| field.name.node == name)?
- .expr;
+ let expr = &fields.iter().find(|field| field.name.node == name)?.expr;
Some(expr)
}
None
}
},
- hir::ExprStruct(ref path, ref fields, None) => if match_qpath(path, &paths::RANGE_FROM_STD) ||
- match_qpath(path, &paths::RANGE_FROM)
+ hir::ExprStruct(ref path, ref fields, None) => if match_qpath(path, &paths::RANGE_FROM_STD)
+ || match_qpath(path, &paths::RANGE_FROM)
{
Some(Range {
start: Some(get_field("start", fields)?),
return Some(VecArgs::Vec(&*args));
}
}
-
+
None
}
else {
/// 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))
+ over(&left.stmts, &right.stmts, |l, r| self.eq_stmt(l, r))
+ && both(&left.expr, &right.expr, |l, r| self.eq_expr(l, r))
}
pub fn eq_expr(&self, left: &Expr, right: &Expr) -> bool {
},
(&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.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)
})
},
(&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(&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))
},
(&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)) => {
},
(&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))
+ 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(le, re)
+ && 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))
+ 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))
},
(&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),
},
(&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))
+ 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))
},
(&PatKind::Wild, &PatKind::Wild) => true,
_ => false,
}
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))
+ left.is_global() == right.is_global()
+ && over(&left.segments, &right.segments, |l, r| self.eq_path_segment(l, r))
}
fn eq_path_parameters(&self, left: &PathParameters, right: &PathParameters) -> bool {
if !(left.parenthesized || right.parenthesized) {
- 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.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))
} else if left.parenthesized && right.parenthesized {
- over(left.inputs(), right.inputs(), |l, r| self.eq_ty(l, r)) &&
- both(
+ over(left.inputs(), right.inputs(), |l, r| self.eq_ty(l, r))
+ && both(
&Some(&left.bindings[0].ty),
&Some(&right.bindings[0].ty),
|l, r| self.eq_ty(l, r),
match (&left.parameters, &right.parameters) {
(&None, &None) => true,
(&Some(ref l), &Some(ref r)) => self.eq_path_parameters(l, r),
- _ => false
+ _ => false,
}
}
match (&left.node, &right.node) {
(&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_ty(lt, rt)
+ && 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)) => {
tcx.push_item_path(&mut apb, def_id);
- apb.names.len() == path.len() &&
- apb.names
+ apb.names.len() == path.len()
+ && apb.names
.into_iter()
.zip(path.iter())
.all(|(a, &b)| *a == *b)
QPath::Resolved(_, ref path) => match_path(path, segments),
QPath::TypeRelative(ref ty, ref segment) => match ty.node {
TyPath(ref inner_path) => {
- !segments.is_empty() && match_qpath(inner_path, &segments[..(segments.len() - 1)]) &&
- segment.name == segments[segments.len() - 1]
+ !segments.is_empty() && match_qpath(inner_path, &segments[..(segments.len() - 1)])
+ && segment.name == segments[segments.len() - 1]
},
_ => false,
},
/// Get the definition associated to a path.
pub fn path_to_def(cx: &LateContext, path: &[&str]) -> Option<def::Def> {
-
let crates = cx.tcx.crates();
let krate = crates
.iter()
}
pub fn const_to_u64(c: &ty::Const) -> u64 {
- c.val.to_const_int().expect("eddyb says this works").to_u64().expect("see previous expect")
+ c.val
+ .to_const_int()
+ .expect("eddyb says this works")
+ .to_u64()
+ .expect("see previous expect")
}
/// Convenience function to get the `DefId` of a trait by path.
Cow::Owned(
s.lines()
.enumerate()
- .map(|(i, l)| if (ignore_first && i == 0) || l.is_empty() {
- l
- } else {
- l.split_at(x).1
+ .map(|(i, l)| {
+ if (ignore_first && i == 0) || l.is_empty() {
+ l
+ } else {
+ l.split_at(x).1
+ }
})
.collect::<Vec<_>>()
.join("\n"),
if node_id == parent_id {
return None;
}
- map.find(parent_id)
- .and_then(|node| if let Node::NodeExpr(parent) = node {
+ 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> {
help: &str,
sugg: String,
) {
- span_lint_and_then(cx, lint, sp, msg, |db| { db.span_suggestion(sp, help, sugg); });
+ span_lint_and_then(cx, lint, sp, msg, |db| {
+ db.span_suggestion(sp, help, sugg);
+ });
}
/// Create a suggestion made from several `span → replacement`.
/// the whole suggestion.
pub fn multispan_sugg<I>(db: &mut DiagnosticBuilder, help_msg: String, sugg: I)
where
- I: IntoIterator<Item=(Span, String)>,
+ I: IntoIterator<Item = (Span, String)>,
{
let sugg = rustc_errors::CodeSuggestion {
substitution_parts: sugg.into_iter()
/// Return the base type for HIR references and pointers.
pub fn walk_ptrs_hir_ty(ty: &hir::Ty) -> &hir::Ty {
match ty.node {
- TyPtr(ref mut_ty) |
- TyRptr(_, ref mut_ty) => walk_ptrs_hir_ty(&mut_ty.ty),
- _ => ty
+ TyPtr(ref mut_ty) | TyRptr(_, ref mut_ty) => walk_ptrs_hir_ty(&mut_ty.ty),
+ _ => ty,
}
}
/// 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()
+ || (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 {
let mut first = true;
let new_item = new_item
.lines()
- .map(|l| if first {
- first = false;
- format!("{}\n", l)
- } else {
- format!("{}{}\n", indent, l)
+ .map(|l| {
+ if first {
+ first = false;
+ format!("{}\n", l)
+ } else {
+ format!("{}{}\n", indent, l)
+ }
})
.collect::<String>();
if is_copy(cx, vec_type(cx.tables.expr_ty_adjusted(arg)));
then {
// report the error around the `vec!` not inside `<std macros>:`
- let span = arg.span.ctxt().outer().expn_info().map(|info| info.call_site).expect("unable to get call_site");
+ let span = arg.span
+ .ctxt()
+ .outer()
+ .expn_info()
+ .map(|info| info.call_site)
+ .expect("unable to get call_site");
check_vec_macro(cx, &vec_args, span);
}
}
| (_, FloatWidth::F64) => "f64",
_ => "f32"
};
- span_help_and_lint(cx, ZERO_DIVIDED_BY_ZERO, expr.span,
+ span_help_and_lint(
+ cx,
+ ZERO_DIVIDED_BY_ZERO,
+ expr.span,
"constant division of 0.0 with 0.0 will always result in NaN",
- &format!("Consider using `std::{}::NAN` if you would like a constant representing NaN", float_type));
+ &format!(
+ "Consider using `std::{}::NAN` if you would like a constant representing NaN",
+ float_type,
+ ),
+ );
}
}
}
max_width = 120
-ideal_width = 100
+comment_width = 100
fn_call_width = 80
match_block_trailing_comma = true
-fn_args_layout = "Block"
closure_block_indent_threshold = 0
-fn_return_indent = "WithWhereClause"
wrap_comments = true
.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(|| {
let mut args: Vec<String> = if orig_args.iter().any(|s| s == "--sysroot") {
orig_args.clone()
} else {
- orig_args.clone().into_iter()
+ orig_args
+ .clone()
+ .into_iter()
.chain(Some("--sysroot".to_owned()))
.chain(Some(sys_root))
.collect()
// this check ensures that dependencies are built but not linted and the final
// crate is
// linted but not built
- let clippy_enabled = env::var("CLIPPY_TESTS").ok().map_or(false, |val| val == "true") ||
- orig_args.iter().any(|s| s == "--emit=metadata");
+ let clippy_enabled = env::var("CLIPPY_TESTS")
+ .ok()
+ .map_or(false, |val| val == "true")
+ || orig_args.iter().any(|s| s == "--emit=metadata");
if clippy_enabled {
args.extend_from_slice(&["--cfg".to_owned(), r#"feature="cargo-clippy""#.to_owned()]);
.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))
- {
+ let mut metadata = if let Ok(metadata) = cargo_metadata::metadata(manifest_path_arg.as_ref().map(AsRef::as_ref)) {
metadata
} else {
let _ = io::stderr().write_fmt(format_args!("error: Could not obtain cargo metadata.\n"));
#![feature(plugin)]
-#![plugin(clippy(conf_file="./tests/auxiliary/conf_whitelisted.toml"))]
-
+#![plugin(clippy(conf_file = "./tests/auxiliary/conf_whitelisted.toml"))]
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())
// 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[..]
+ 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[..]
{
unreachable!();
}