match pat.node {
PatKind::Binding(_, _, ref spname, _) => Some(spname.node),
PatKind::Path(ref qpath) => single_segment_path(qpath).map(|ps| ps.name),
- PatKind::Box(ref p) | PatKind::Ref(ref p, _) => get_pat_name(&*p),
- _ => None
+ PatKind::Box(ref p) |
+ PatKind::Ref(ref p, _) => get_pat_name(&*p),
+ _ => None,
}
}
fn get_path_name(expr: &Expr) -> Option<Name> {
match expr.node {
- ExprBox(ref e) | ExprAddrOf(_, ref e) | ExprUnary(UnOp::UnDeref, ref e) => get_path_name(e),
- ExprBlock(ref b) => if b.stmts.is_empty() {
- b.expr.as_ref().and_then(|p| get_path_name(p))
- } else { None },
+ ExprBox(ref e) |
+ ExprAddrOf(_, ref e) |
+ ExprUnary(UnOp::UnDeref, ref e) => get_path_name(e),
+ ExprBlock(ref b) => {
+ if b.stmts.is_empty() {
+ b.expr.as_ref().and_then(|p| get_path_name(p))
+ } else {
+ None
+ }
+ },
ExprPath(ref qpath) => single_segment_path(qpath).map(|ps| ps.name),
- _ => None
+ _ => None,
}
}
-
/// [using `|`](https://doc.rust-lang.org/book/patterns.html#multiple-patterns).
///
/// **Known problems:** False positive possible with order dependent `match`
-/// (see issue [#860](https://github.com/rust-lang-nursery/rust-clippy/issues/860)).
+/// (see issue
+/// [#860](https://github.com/rust-lang-nursery/rust-clippy/issues/860)).
///
/// **Example:**
/// ```rust,ignore
return (
doc.to_owned(),
vec![
- (
- doc.len(),
- span.with_lo(span.lo() + BytePos(prefix.len() as u32)),
- ),
+ (doc.len(), span.with_lo(span.lo() + BytePos(prefix.len() as u32))),
],
);
}
debug_assert_eq!(offset as u32 as usize, offset);
contains_initial_stars |= line.trim_left().starts_with('*');
// +1 for the newline
- sizes.push((
- line.len() + 1,
- span.with_lo(span.lo() + BytePos(offset as u32)),
- ));
+ sizes.push((line.len() + 1, span.with_lo(span.lo() + BytePos(offset as u32))));
}
if !contains_initial_stars {
return (doc.to_string(), sizes);
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
let (lint, msg) = match complete_infinite_iter(cx, expr) {
Infinite => (INFINITE_ITER, "infinite iteration detected"),
- MaybeInfinite => (MAYBE_INFINITE_ITER,
- "possible infinite iteration detected"),
- Finite => { return; }
+ MaybeInfinite => (MAYBE_INFINITE_ITER, "possible infinite iteration detected"),
+ Finite => {
+ return;
+ },
};
span_lint(cx, lint, expr.span, msg)
}
enum Finiteness {
Infinite,
MaybeInfinite,
- Finite
+ Finite,
}
use self::Finiteness::{Infinite, MaybeInfinite, Finite};
fn and(self, b: Self) -> Self {
match (self, b) {
(Finite, _) | (_, Finite) => Finite,
- (MaybeInfinite, _) | (_, MaybeInfinite) => MaybeInfinite,
- _ => Infinite
+ (MaybeInfinite, _) |
+ (_, MaybeInfinite) => MaybeInfinite,
+ _ => Infinite,
}
}
fn or(self, b: Self) -> Self {
match (self, b) {
(Infinite, _) | (_, Infinite) => Infinite,
- (MaybeInfinite, _) | (_, MaybeInfinite) => MaybeInfinite,
- _ => Finite
+ (MaybeInfinite, _) |
+ (_, MaybeInfinite) => MaybeInfinite,
+ _ => Finite,
}
}
}
/// infinite if any of the supplied arguments is
Any,
/// infinite if all of the supplied arguments are
- All
+ All,
}
use self::Heuristic::{Always, First, Any, All};
/// returns an infinite or possibly infinite iterator. The finiteness
/// is an upper bound, e.g. some methods can return a possibly
/// infinite iterator at worst, e.g. `take_while`.
-static HEURISTICS : &[(&str, usize, Heuristic, Finiteness)] = &[
+static HEURISTICS: &[(&str, usize, Heuristic, Finiteness)] = &[
("zip", 2, All, Infinite),
("chain", 2, Any, Infinite),
("cycle", 1, Always, Infinite),
("flat_map", 2, First, Infinite),
("unzip", 1, First, Infinite),
("take_while", 2, First, MaybeInfinite),
- ("scan", 3, First, MaybeInfinite)
+ ("scan", 3, First, MaybeInfinite),
];
fn is_infinite(cx: &LateContext, expr: &Expr) -> Finiteness {
for &(name, len, heuristic, cap) in HEURISTICS.iter() {
if method.name == name && args.len() == len {
return (match heuristic {
- Always => Infinite,
- First => is_infinite(cx, &args[0]),
- Any => is_infinite(cx, &args[0]).or(is_infinite(cx, &args[1])),
- All => is_infinite(cx, &args[0]).and(is_infinite(cx, &args[1])),
- }).and(cap);
+ Always => Infinite,
+ First => is_infinite(cx, &args[0]),
+ Any => is_infinite(cx, &args[0]).or(is_infinite(cx, &args[1])),
+ All => is_infinite(cx, &args[0]).and(is_infinite(cx, &args[1])),
+ }).and(cap);
}
}
if method.name == "flat_map" && args.len() == 2 {
}
Finite
},
- ExprBlock(ref block) =>
- block.expr.as_ref().map_or(Finite, |e| is_infinite(cx, e)),
- ExprBox(ref e) | ExprAddrOf(_, ref e) => is_infinite(cx, e),
+ ExprBlock(ref block) => block.expr.as_ref().map_or(Finite, |e| is_infinite(cx, e)),
+ ExprBox(ref e) |
+ ExprAddrOf(_, ref e) => is_infinite(cx, e),
ExprCall(ref path, _) => {
if let ExprPath(ref qpath) = path.node {
match_qpath(qpath, &paths::REPEAT).into()
- } else { Finite }
+ } else {
+ Finite
+ }
},
ExprStruct(..) => {
- higher::range(expr).map_or(false, |r| r.end.is_none()).into()
+ higher::range(expr)
+ .map_or(false, |r| r.end.is_none())
+ .into()
},
- _ => Finite
+ _ => Finite,
}
}
/// the names and argument lengths of methods that *may* exhaust their
/// iterators
-static POSSIBLY_COMPLETING_METHODS : &[(&str, usize)] = &[
+static POSSIBLY_COMPLETING_METHODS: &[(&str, usize)] = &[
("find", 2),
("rfind", 2),
("position", 2),
("rposition", 2),
("any", 2),
- ("all", 2)
+ ("all", 2),
];
/// the names and argument lengths of methods that *always* exhaust
/// their iterators
-static COMPLETING_METHODS : &[(&str, usize)] = &[
+static COMPLETING_METHODS: &[(&str, usize)] = &[
("count", 1),
("collect", 1),
("fold", 3),
("min_by", 2),
("min_by_key", 2),
("sum", 1),
- ("product", 1)
+ ("product", 1),
];
fn complete_infinite_iter(cx: &LateContext, expr: &Expr) -> Finiteness {
}
}
if method.name == "last" && args.len() == 1 &&
- get_trait_def_id(cx, &paths::DOUBLE_ENDED_ITERATOR).map_or(false,
- |id| !implements_trait(cx,
- cx.tables.expr_ty(&args[0]),
- id,
- &[])) {
+ get_trait_def_id(cx, &paths::DOUBLE_ENDED_ITERATOR).map_or(
+ false,
+ |id| {
+ !implements_trait(cx, cx.tables.expr_ty(&args[0]), id, &[])
+ },
+ )
+ {
return is_infinite(cx, &args[0]);
}
},
ExprBinary(op, ref l, ref r) => {
if op.node.is_comparison() {
- return is_infinite(cx, l).and(is_infinite(cx, r)).and(MaybeInfinite)
+ return is_infinite(cx, l).and(is_infinite(cx, r)).and(
+ MaybeInfinite,
+ );
}
}, //TODO: ExprLoop + Match
- _ => ()
+ _ => (),
}
Finite
}
cx,
UNIT_EXPR,
expr.span,
- "This expression evaluates to the Unit type ()",
+ "This expression evaluates to the Unit type ()",
span,
"Consider removing the trailing semicolon",
);
}
fn is_unit_expr(expr: &Expr) -> Option<Span> {
match expr.node {
- ExprKind::Block(ref block) => if check_last_stmt_in_block(block) {
- Some(block.stmts[block.stmts.len() - 1].span)
- } else {
- None
+ ExprKind::Block(ref block) => {
+ if check_last_stmt_in_block(block) {
+ Some(block.stmts[block.stmts.len() - 1].span)
+ } else {
+ None
+ }
},
ExprKind::If(_, ref then, ref else_) => {
let check_then = check_last_stmt_in_block(then);
return Some(*expr_else);
}
}
- if check_then {
- Some(expr.span)
- } else {
- None
- }
+ if check_then { Some(expr.span) } else { None }
},
ExprKind::Match(ref _pattern, ref arms) => {
for arm in arms {
let final_stmt = &block.stmts[block.stmts.len() - 1];
- //Made a choice here to risk false positives on divergent macro invocations like `panic!()`
+ // Made a choice here to risk false positives on divergent macro invocations
+ // like `panic!()`
match final_stmt.node {
StmtKind::Expr(_) => false,
- StmtKind::Semi(ref expr) => match expr.node {
- ExprKind::Break(_, _) | ExprKind::Ret(_) => false,
- _ => true,
+ StmtKind::Semi(ref expr) => {
+ match expr.node {
+ ExprKind::Break(_, _) |
+ ExprKind::Ret(_) => false,
+ _ => true,
+ }
},
_ => true,
}
}
}
- if cx.access_levels.is_exported(visited_trait.id) &&
- trait_items
- .iter()
- .any(|i| is_named_self(cx, i, "len"))
- {
+ if cx.access_levels.is_exported(visited_trait.id) && trait_items.iter().any(|i| is_named_self(cx, i, "len")) {
let mut current_and_super_traits = HashSet::new();
fill_trait_set(visited_trait, &mut current_and_super_traits, cx);
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 s.parameters.parenthesized {
+ path.segments.last().map_or(
+ false,
+ |s| if s.parameters.parenthesized {
false
} else {
s.parameters.types.len() == 1 &&
(is_self_ty(&s.parameters.types[0]) || is_ty(&*s.parameters.types[0], self_ty))
- }
- })
+ },
+ )
} else {
false
}
//
//
//
+//
// rs#L246
//
/// **What it does:** Checks for useless borrowed references.
///
-/// **Why is this bad?** It is mostly useless and make the code look more complex than it
+/// **Why is this bad?** It is mostly useless and make the code look more
+/// complex than it
/// actually is.
///
/// **Known problems:** It seems that the `&ref` pattern is sometimes useful.
///
/// fn foo(a: &Animal, b: &Animal) {
/// match (a, b) {
-/// (&Animal::Cat(v), k) | (k, &Animal::Cat(v)) => (), // lifetime mismatch error
+/// (&Animal::Cat(v), k) | (k, &Animal::Cat(v)) => (), // lifetime
+/// mismatch error
/// (&Animal::Dog(ref c), &Animal::Dog(_)) => ()
/// }
/// }
/// ```
-/// There is a lifetime mismatch error for `k` (indeed a and b have distinct lifetime).
+/// There is a lifetime mismatch error for `k` (indeed a and b have distinct
+/// lifetime).
/// This can be fixed by using the `&ref` pattern.
/// However, the code can also be fixed by much cleaner ways
///
}}
}
}
-
match (si.next(), si.next()) {
(Some((l, _)), Some((h, _))) => {
- Span::new(
- base.lo() + BytePos(l as u32),
- base.lo() + BytePos(h as u32),
- base.ctxt(),
- )
+ Span::new(base.lo() + BytePos(l as u32), base.lo() + BytePos(h as u32), base.ctxt())
},
_ => base,
}
fn path_eq_name(name: Name, path: &Path) -> bool {
!path.is_global() && path.segments.len() == 1 && path.segments[0].name.as_str() == name.as_str()
}
-
match *qpath {
QPath::Resolved(Some(ref ty), ref p) => {
check_ty(cx, ty, is_local);
- for ty in p.segments.iter().flat_map(|seg| seg.parameters.types.iter()) {
+ for ty in p.segments.iter().flat_map(
+ |seg| seg.parameters.types.iter(),
+ )
+ {
check_ty(cx, ty, is_local);
}
},
QPath::Resolved(None, ref p) => {
- for ty in p.segments.iter().flat_map(|seg| seg.parameters.types.iter()) {
+ for ty in p.segments.iter().flat_map(
+ |seg| seg.parameters.types.iter(),
+ )
+ {
check_ty(cx, ty, is_local);
}
},
/// Will return 0 if the type is not an int or uint variant
fn int_ty_to_nbits(typ: Ty, tcx: TyCtxt) -> u64 {
match typ.sty {
- ty::TyInt(i) => match i {
- IntTy::Is => tcx.data_layout.pointer_size.bits(),
- IntTy::I8 => 8,
- IntTy::I16 => 16,
- IntTy::I32 => 32,
- IntTy::I64 => 64,
- IntTy::I128 => 128,
+ ty::TyInt(i) => {
+ match i {
+ IntTy::Is => tcx.data_layout.pointer_size.bits(),
+ IntTy::I8 => 8,
+ IntTy::I16 => 16,
+ IntTy::I32 => 32,
+ IntTy::I64 => 64,
+ IntTy::I128 => 128,
+ }
},
- ty::TyUint(i) => match i {
- UintTy::Us => tcx.data_layout.pointer_size.bits(),
- UintTy::U8 => 8,
- UintTy::U16 => 16,
- UintTy::U32 => 32,
- UintTy::U64 => 64,
- UintTy::U128 => 128,
+ ty::TyUint(i) => {
+ match i {
+ UintTy::Us => tcx.data_layout.pointer_size.bits(),
+ UintTy::U8 => 8,
+ UintTy::U16 => 16,
+ UintTy::U32 => 32,
+ UintTy::U64 => 64,
+ UintTy::U128 => 128,
+ }
},
_ => 0,
}
}
fn span_lossless_lint(cx: &LateContext, expr: &Expr, op: &Expr, cast_from: Ty, cast_to: Ty) {
- span_lint_and_sugg(cx,
- CAST_LOSSLESS,
- expr.span,
- &format!("casting {} to {} may become silently lossy if types change",
- cast_from,
- cast_to),
- "try",
- format!("{}::from({})", cast_to, &snippet(cx, op.span, "..")));
+ span_lint_and_sugg(
+ cx,
+ CAST_LOSSLESS,
+ expr.span,
+ &format!("casting {} to {} may become silently lossy if types change", cast_from, cast_to),
+ "try",
+ format!("{}::from({})", cast_to, &snippet(cx, op.span, "..")),
+ );
}
enum ArchSuffix {
let cast_signed_to_unsigned = cast_from.is_signed() && !cast_to.is_signed();
let from_nbits = int_ty_to_nbits(cast_from, cx.tcx);
let to_nbits = int_ty_to_nbits(cast_to, cx.tcx);
- if !is_isize_or_usize(cast_from) && !is_isize_or_usize(cast_to) &&
- from_nbits < to_nbits && !cast_signed_to_unsigned {
+ if !is_isize_or_usize(cast_from) && !is_isize_or_usize(cast_to) && from_nbits < to_nbits &&
+ !cast_signed_to_unsigned
+ {
span_lossless_lint(cx, expr, op, cast_from, cast_to);
}
}
);
}
if let (&ty::TyFloat(FloatTy::F32), &ty::TyFloat(FloatTy::F64)) =
- (&cast_from.sty, &cast_to.sty) {
+ (&cast_from.sty, &cast_to.sty)
+ {
span_lossless_lint(cx, expr, ex, cast_from, cast_to);
}
},
/// **Known problems:** For `usize` the size of the current compile target will
/// be assumed (e.g. 64 bits on 64 bit systems). This means code that uses such
/// a comparison to detect target pointer width will trigger this lint. One can
-/// use `mem::sizeof` and compare its value or conditional compilation attributes
+/// use `mem::sizeof` and compare its value or conditional compilation
+/// attributes
/// like `#[cfg(target_pointer_width = "64")] ..` instead.
///
/// **Example:**
/// will mistakenly imply that it is possible for `x` to be outside the range of
/// `u8`.
///
-/// **Known problems:** https://github.com/rust-lang-nursery/rust-clippy/issues/886
+/// **Known problems:**
+/// https://github.com/rust-lang-nursery/rust-clippy/issues/886
///
/// **Example:**
/// ```rust
ty::TyInt(int_ty) => {
Some(match int_ty {
IntTy::I8 => (FullInt::S(i128::from(i8::min_value())), FullInt::S(i128::from(i8::max_value()))),
- IntTy::I16 => (FullInt::S(i128::from(i16::min_value())), FullInt::S(i128::from(i16::max_value()))),
- IntTy::I32 => (FullInt::S(i128::from(i32::min_value())), FullInt::S(i128::from(i32::max_value()))),
- IntTy::I64 => (FullInt::S(i128::from(i64::min_value())), FullInt::S(i128::from(i64::max_value()))),
+ IntTy::I16 => (
+ FullInt::S(i128::from(i16::min_value())),
+ FullInt::S(i128::from(i16::max_value())),
+ ),
+ IntTy::I32 => (
+ FullInt::S(i128::from(i32::min_value())),
+ FullInt::S(i128::from(i32::max_value())),
+ ),
+ IntTy::I64 => (
+ FullInt::S(i128::from(i64::min_value())),
+ FullInt::S(i128::from(i64::max_value())),
+ ),
IntTy::I128 => (FullInt::S(i128::min_value() as i128), FullInt::S(i128::max_value() as i128)),
IntTy::Is => (FullInt::S(isize::min_value() as i128), FullInt::S(isize::max_value() as i128)),
})
ty::TyUint(uint_ty) => {
Some(match uint_ty {
UintTy::U8 => (FullInt::U(u128::from(u8::min_value())), FullInt::U(u128::from(u8::max_value()))),
- UintTy::U16 => (FullInt::U(u128::from(u16::min_value())), FullInt::U(u128::from(u16::max_value()))),
- UintTy::U32 => (FullInt::U(u128::from(u32::min_value())), FullInt::U(u128::from(u32::max_value()))),
- UintTy::U64 => (FullInt::U(u128::from(u64::min_value())), FullInt::U(u128::from(u64::max_value()))),
+ UintTy::U16 => (
+ FullInt::U(u128::from(u16::min_value())),
+ FullInt::U(u128::from(u16::max_value())),
+ ),
+ UintTy::U32 => (
+ FullInt::U(u128::from(u32::min_value())),
+ FullInt::U(u128::from(u32::max_value())),
+ ),
+ UintTy::U64 => (
+ FullInt::U(u128::from(u64::min_value())),
+ FullInt::U(u128::from(u64::max_value())),
+ ),
UintTy::U128 => (FullInt::U(u128::min_value() as u128), FullInt::U(u128::max_value() as u128)),
UintTy::Us => (FullInt::U(usize::min_value() as u128), FullInt::U(usize::max_value() as u128)),
})
/// **What it does:** Checks for unnecessary repetition of structure name when a
/// replacement with `Self` is applicable.
///
-/// **Why is this bad?** Unnecessary repetition. Mixed use of `Self` and struct name
+/// **Why is this bad?** Unnecessary repetition. Mixed use of `Self` and struct
+/// name
/// feels inconsistent.
///
/// **Known problems:** None.
impl<'a, 'tcx> Visitor<'tcx> for UseSelfVisitor<'a, 'tcx> {
fn visit_path(&mut self, path: &'tcx Path, _id: NodeId) {
- if self.item_path.def == path.def &&
- path.segments
- .last()
- .expect(SEGMENTS_MSG)
- .name != SelfType.name() {
+ if self.item_path.def == path.def && path.segments.last().expect(SEGMENTS_MSG).name != SelfType.name() {
span_lint_and_then(self.cx, USE_SELF, path.span, "unnecessary structure name repetition", |db| {
db.span_suggestion(path.span, "use the applicable keyword", "Self".to_owned());
});
end: get_field("end", fields),
limits: ast::RangeLimits::HalfOpen,
})
- } else if match_qpath(path, &paths::RANGE_TO_INCLUSIVE_STD) || match_qpath(path, &paths::RANGE_TO_INCLUSIVE) {
+ } else if match_qpath(path, &paths::RANGE_TO_INCLUSIVE_STD) ||
+ match_qpath(path, &paths::RANGE_TO_INCLUSIVE)
+ {
Some(Range {
start: None,
end: get_field("end", fields),
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(&Some(&left.bindings[0].ty), &Some(&right.bindings[0].ty), |l, r| self.eq_ty(l, r))
+ 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),
+ )
} else {
false
}
hir::ExprYield(ref sub) => {
println!("{}Yield", ind);
print_expr(cx, sub, indent + 1);
- }
+ },
hir::ExprBlock(_) => {
println!("{}Block", ind);
},