[Jump to usage instructions](#usage)
##Lints
-There are 71 lints included in this crate:
+There are 72 lints included in this crate:
name | default | meaning
-------------------------------------------------------------------------------------------------------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
use rustc_front::hir::*;
use rustc::middle::ty;
-use utils::{snippet, span_lint};
+use utils::{snippet, span_lint, is_adjusted};
#[allow(missing_copy_implementations)]
}
}
-fn is_adjusted(cx: &LateContext, e: &Expr) -> bool {
- cx.tcx.tables.borrow().adjustments.get(&e.id).is_some()
-}
-
fn check_closure(cx: &LateContext, expr: &Expr) {
if let ExprClosure(_, ref decl, ref blk) = expr.node {
if !blk.stmts.is_empty() {
use rustc_front::hir::*;
use syntax::ast::Ident;
use utils::OPTION_PATH;
-use utils::{match_trait_method, match_type, snippet, span_help_and_lint};
+use utils::{is_adjusted, match_trait_method, match_type, snippet, span_help_and_lint};
use utils::{walk_ptrs_ty, walk_ptrs_ty_depth};
declare_lint!(pub MAP_CLONE, Warn,
let Some(type_name) = get_type_name(cx, expr, &args[0])
], {
// look for derefs, for .map(|x| *x)
- if only_derefs(&*closure_expr, arg_ident) &&
+ if only_derefs(cx, &*closure_expr, arg_ident) &&
// .cloned() only removes one level of indirection, don't lint on more
walk_ptrs_ty_depth(cx.tcx.pat_ty(&*decl.inputs[0].pat)).1 == 1
{
}
}
-fn only_derefs(expr: &Expr, id: Ident) -> bool {
- if expr_eq_ident(expr, id) {
- true
- } else if let ExprUnary(UnDeref, ref subexpr) = expr.node {
- only_derefs(subexpr, id)
- } else {
- false
+fn only_derefs(cx: &LateContext, expr: &Expr, id: Ident) -> bool {
+ match expr.node {
+ ExprUnary(UnDeref, ref subexpr) if !is_adjusted(cx, subexpr) => {
+ only_derefs(cx, subexpr, id)
+ },
+ _ => expr_eq_ident(expr, id),
}
}
#![allow(unused)]
+use std::ops::Deref;
+
fn map_clone_iter() {
let x = [1,2,3];
x.iter().map(|y| y.clone()); //~ ERROR you seem to be using .map()
x.map(|y| *y);
}
+#[derive(Copy, Clone)]
+struct UnusualDeref;
+static NINE: i32 = 9;
+
+impl Deref for UnusualDeref {
+ type Target = i32;
+ fn deref(&self) -> &i32 { &NINE }
+}
+
+fn map_clone_deref() {
+ let x = Some(UnusualDeref);
+ let _: Option<UnusualDeref> = x.as_ref().map(|y| *y); //~ ERROR you seem to be using .map()
+ //~^ HELP try
+
+ // Not linted: using deref conversion
+ let _: Option<i32> = x.map(|y| *y);
+
+ // Not linted: using regular deref but also deref conversion
+ let _: Option<i32> = x.as_ref().map(|y| **y);
+}
+
fn main() { }