From 858a90295ce2a957516036a6d328a0d3d1177eb2 Mon Sep 17 00:00:00 2001 From: Tom Milligan Date: Wed, 3 Oct 2018 15:36:25 +0100 Subject: [PATCH 1/9] fix build failure --- clippy_lints/src/utils/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index fa3c72dbb7de..9dc2ce9be7d9 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -90,7 +90,7 @@ pub fn match_def_path(tcx: TyCtxt<'_, '_, '_>, def_id: DefId, path: &[&str]) -> let mut apb = AbsolutePathBuffer { names: vec![] }; - tcx.push_item_path(&mut apb, def_id, false); + tcx.push_item_path(&mut apb, def_id); apb.names.len() == path.len() && apb.names From c51250996d6ca20ac3c76e1ed92808019760f608 Mon Sep 17 00:00:00 2001 From: Tom Milligan Date: Wed, 3 Oct 2018 17:53:39 +0100 Subject: [PATCH 2/9] Working basic dereference clip --- clippy_lints/src/dereference.rs | 68 +++++++++++++++++++++++++++++++++ clippy_lints/src/lib.rs | 4 ++ tests/ui/dereference.rs | 20 ++++++++++ tests/ui/dereference.stderr | 16 ++++++++ 4 files changed, 108 insertions(+) create mode 100644 clippy_lints/src/dereference.rs create mode 100644 tests/ui/dereference.rs create mode 100644 tests/ui/dereference.stderr diff --git a/clippy_lints/src/dereference.rs b/clippy_lints/src/dereference.rs new file mode 100644 index 000000000000..893530a4868b --- /dev/null +++ b/clippy_lints/src/dereference.rs @@ -0,0 +1,68 @@ +use crate::rustc::hir::{Expr, ExprKind, QPath}; +use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; +use crate::rustc::{declare_tool_lint, lint_array}; +use if_chain::if_chain; +use crate::utils::span_lint_and_sugg; + +/// **What it does:** Checks for explicit deref() or deref_mut() method calls. +/// +/// **Why is this bad?** Derefencing by &*x or &mut *x is clearer and more concise, +/// when not part of a method chain. +/// +/// **Example:** +/// ```rust +/// let b = a.deref(); +/// let c = a.deref_mut(); +/// +/// // excludes +/// let e = d.deref().unwrap(); +/// let f = a.deref().unwrap(); +/// ``` +declare_clippy_lint! { + pub DEREF_METHOD_EXPLICIT, + complexity, + "Explicit use of deref or deref_mut method while not in a method chain." +} + +pub struct Pass; + +impl LintPass for Pass { + fn get_lints(&self) -> LintArray { + lint_array!(DEREF_METHOD_EXPLICIT) + } +} + +impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { + fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &Expr) { + if_chain! { + if let ExprKind::MethodCall(ref method_name, _, ref args) = &expr.node; + if let ExprKind::Path(QPath::Resolved(None, path)) = &args[0].node; + then { + let name = method_name.ident.as_str(); + match &*name { + "deref" => { + span_lint_and_sugg( + cx, + DEREF_METHOD_EXPLICIT, + expr.span, + "explicit deref method call", + "try this", + format!("&*{}", path), + ); + }, + "deref_mut" => { + span_lint_and_sugg( + cx, + DEREF_METHOD_EXPLICIT, + expr.span, + "explicit deref_mut method call", + "try this", + format!("&mut *{}", path), + ); + }, + _ => () + }; + } + } + } +} diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 9af4850b15c2..d3646ec27cc5 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -88,6 +88,7 @@ pub mod copies; pub mod copy_iterator; pub mod cyclomatic_complexity; pub mod default_trait_access; +pub mod dereference; pub mod derive; pub mod doc; pub mod double_comparison; @@ -356,6 +357,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) { reg.register_early_lint_pass(box misc_early::MiscEarly); reg.register_late_lint_pass(box panic_unimplemented::Pass); reg.register_late_lint_pass(box strings::StringLitAsBytes); + reg.register_late_lint_pass(box dereference::Pass); reg.register_late_lint_pass(box derive::Derive); reg.register_late_lint_pass(box types::CharLitAsU8); reg.register_late_lint_pass(box vec::Pass); @@ -523,6 +525,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) { copies::IF_SAME_THEN_ELSE, copies::IFS_SAME_COND, cyclomatic_complexity::CYCLOMATIC_COMPLEXITY, + dereference::DEREF_METHOD_EXPLICIT, derive::DERIVE_HASH_XOR_EQ, double_comparison::DOUBLE_COMPARISONS, double_parens::DOUBLE_PARENS, @@ -807,6 +810,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) { assign_ops::MISREFACTORED_ASSIGN_OP, booleans::NONMINIMAL_BOOL, cyclomatic_complexity::CYCLOMATIC_COMPLEXITY, + dereference::DEREF_METHOD_EXPLICIT, double_comparison::DOUBLE_COMPARISONS, double_parens::DOUBLE_PARENS, duration_subsec::DURATION_SUBSEC, diff --git a/tests/ui/dereference.rs b/tests/ui/dereference.rs new file mode 100644 index 000000000000..de8b52077f7e --- /dev/null +++ b/tests/ui/dereference.rs @@ -0,0 +1,20 @@ +#![feature(tool_lints)] + +use std::ops::{Deref, DerefMut}; + +#[allow(clippy::many_single_char_names, clippy::double_parens)] +#[allow(unused_variables)] +#[warn(clippy::deref_method_explicit)] +fn main() { + let mut a: String = String::from("foo"); + + { + let aref = &a; + let b = aref.deref(); + } + + { + let aref = &mut a; + let b = aref.deref_mut(); + } +} diff --git a/tests/ui/dereference.stderr b/tests/ui/dereference.stderr new file mode 100644 index 000000000000..1083f5f3d041 --- /dev/null +++ b/tests/ui/dereference.stderr @@ -0,0 +1,16 @@ +error: explicit deref method call + --> $DIR/dereference.rs:13:17 + | +13 | let b = aref.deref(); + | ^^^^^^^^^^^^ help: try this: `&*aref` + | + = note: `-D clippy::deref-method-explicit` implied by `-D warnings` + +error: explicit deref_mut method call + --> $DIR/dereference.rs:18:17 + | +18 | let b = aref.deref_mut(); + | ^^^^^^^^^^^^^^^^ help: try this: `&mut *aref` + +error: aborting due to 2 previous errors + From f62ca8473e57bd886d6f9b03342dbf9594789bf4 Mon Sep 17 00:00:00 2001 From: Tom Milligan Date: Thu, 4 Oct 2018 09:47:10 +0100 Subject: [PATCH 3/9] Added additional tests and comments for deref --- clippy_lints/src/dereference.rs | 3 ++ tests/ui/dereference.rs | 42 +++++++++++++++++++++++---- tests/ui/dereference.stderr | 50 ++++++++++++++++++++++++++++----- 3 files changed, 82 insertions(+), 13 deletions(-) diff --git a/clippy_lints/src/dereference.rs b/clippy_lints/src/dereference.rs index 893530a4868b..241b4d9e0bbd 100644 --- a/clippy_lints/src/dereference.rs +++ b/clippy_lints/src/dereference.rs @@ -35,10 +35,13 @@ impl LintPass for Pass { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &Expr) { if_chain! { + // if this is a method call if let ExprKind::MethodCall(ref method_name, _, ref args) = &expr.node; + // on a Path (i.e. a variable/name, not another method) if let ExprKind::Path(QPath::Resolved(None, path)) = &args[0].node; then { let name = method_name.ident.as_str(); + // alter help slightly to account for _mut match &*name { "deref" => { span_lint_and_sugg( diff --git a/tests/ui/dereference.rs b/tests/ui/dereference.rs index de8b52077f7e..2e5f9d0b40d4 100644 --- a/tests/ui/dereference.rs +++ b/tests/ui/dereference.rs @@ -2,19 +2,49 @@ use std::ops::{Deref, DerefMut}; -#[allow(clippy::many_single_char_names, clippy::double_parens)] +#[allow(clippy::many_single_char_names, clippy::clone_double_ref)] #[allow(unused_variables)] #[warn(clippy::deref_method_explicit)] fn main() { - let mut a: String = String::from("foo"); + let a: &mut String = &mut String::from("foo"); + // these should require linting { - let aref = &a; - let b = aref.deref(); + let b: &str = a.deref(); } { - let aref = &mut a; - let b = aref.deref_mut(); + let b: &mut str = a.deref_mut(); + } + + { + let b: String = a.deref().clone(); + } + + { + let b: usize = a.deref_mut().len(); + } + + { + let b: &usize = &a.deref().len(); + } + + { + // only first deref should get linted here + let b: &str = a.deref().deref(); + } + + { + // both derefs should get linted here + let b: String = format!("{}, {}", a.deref(), a.deref()); + } + + // these should not require linting + { + let b: &str = &*a; + } + + { + let b: &mut str = &mut *a; } } diff --git a/tests/ui/dereference.stderr b/tests/ui/dereference.stderr index 1083f5f3d041..dc58acd15240 100644 --- a/tests/ui/dereference.stderr +++ b/tests/ui/dereference.stderr @@ -1,16 +1,52 @@ error: explicit deref method call - --> $DIR/dereference.rs:13:17 + --> $DIR/dereference.rs:13:23 | -13 | let b = aref.deref(); - | ^^^^^^^^^^^^ help: try this: `&*aref` +13 | let b: &str = a.deref(); + | ^^^^^^^^^ help: try this: `&*a` | = note: `-D clippy::deref-method-explicit` implied by `-D warnings` error: explicit deref_mut method call - --> $DIR/dereference.rs:18:17 + --> $DIR/dereference.rs:17:27 | -18 | let b = aref.deref_mut(); - | ^^^^^^^^^^^^^^^^ help: try this: `&mut *aref` +17 | let b: &mut str = a.deref_mut(); + | ^^^^^^^^^^^^^ help: try this: `&mut *a` -error: aborting due to 2 previous errors +error: explicit deref method call + --> $DIR/dereference.rs:21:25 + | +21 | let b: String = a.deref().clone(); + | ^^^^^^^^^ help: try this: `&*a` + +error: explicit deref_mut method call + --> $DIR/dereference.rs:25:24 + | +25 | let b: usize = a.deref_mut().len(); + | ^^^^^^^^^^^^^ help: try this: `&mut *a` + +error: explicit deref method call + --> $DIR/dereference.rs:29:26 + | +29 | let b: &usize = &a.deref().len(); + | ^^^^^^^^^ help: try this: `&*a` + +error: explicit deref method call + --> $DIR/dereference.rs:34:23 + | +34 | let b: &str = a.deref().deref(); + | ^^^^^^^^^ help: try this: `&*a` + +error: explicit deref method call + --> $DIR/dereference.rs:39:43 + | +39 | let b: String = format!("{}, {}", a.deref(), a.deref()); + | ^^^^^^^^^ help: try this: `&*a` + +error: explicit deref method call + --> $DIR/dereference.rs:39:54 + | +39 | let b: String = format!("{}, {}", a.deref(), a.deref()); + | ^^^^^^^^^ help: try this: `&*a` + +error: aborting due to 8 previous errors From 656b75db9c1d7f3db472df26f0b21e551ed90593 Mon Sep 17 00:00:00 2001 From: Tom Milligan Date: Fri, 5 Oct 2018 10:06:26 +0100 Subject: [PATCH 4/9] Renamed to explicit_deref_method --- clippy_lints/src/dereference.rs | 8 ++++---- clippy_lints/src/lib.rs | 4 ++-- tests/ui/dereference.rs | 2 +- tests/ui/dereference.stderr | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/clippy_lints/src/dereference.rs b/clippy_lints/src/dereference.rs index 241b4d9e0bbd..f32c0f6a027e 100644 --- a/clippy_lints/src/dereference.rs +++ b/clippy_lints/src/dereference.rs @@ -19,7 +19,7 @@ use crate::utils::span_lint_and_sugg; /// let f = a.deref().unwrap(); /// ``` declare_clippy_lint! { - pub DEREF_METHOD_EXPLICIT, + pub EXPLICIT_DEREF_METHOD, complexity, "Explicit use of deref or deref_mut method while not in a method chain." } @@ -28,7 +28,7 @@ pub struct Pass; impl LintPass for Pass { fn get_lints(&self) -> LintArray { - lint_array!(DEREF_METHOD_EXPLICIT) + lint_array!(EXPLICIT_DEREF_METHOD) } } @@ -46,7 +46,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { "deref" => { span_lint_and_sugg( cx, - DEREF_METHOD_EXPLICIT, + EXPLICIT_DEREF_METHOD, expr.span, "explicit deref method call", "try this", @@ -56,7 +56,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { "deref_mut" => { span_lint_and_sugg( cx, - DEREF_METHOD_EXPLICIT, + EXPLICIT_DEREF_METHOD, expr.span, "explicit deref_mut method call", "try this", diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index d3646ec27cc5..e5e1ad9acc9d 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -525,7 +525,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) { copies::IF_SAME_THEN_ELSE, copies::IFS_SAME_COND, cyclomatic_complexity::CYCLOMATIC_COMPLEXITY, - dereference::DEREF_METHOD_EXPLICIT, + dereference::EXPLICIT_DEREF_METHOD, derive::DERIVE_HASH_XOR_EQ, double_comparison::DOUBLE_COMPARISONS, double_parens::DOUBLE_PARENS, @@ -810,7 +810,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) { assign_ops::MISREFACTORED_ASSIGN_OP, booleans::NONMINIMAL_BOOL, cyclomatic_complexity::CYCLOMATIC_COMPLEXITY, - dereference::DEREF_METHOD_EXPLICIT, + dereference::EXPLICIT_DEREF_METHOD, double_comparison::DOUBLE_COMPARISONS, double_parens::DOUBLE_PARENS, duration_subsec::DURATION_SUBSEC, diff --git a/tests/ui/dereference.rs b/tests/ui/dereference.rs index 2e5f9d0b40d4..5d8ee847374f 100644 --- a/tests/ui/dereference.rs +++ b/tests/ui/dereference.rs @@ -4,7 +4,7 @@ use std::ops::{Deref, DerefMut}; #[allow(clippy::many_single_char_names, clippy::clone_double_ref)] #[allow(unused_variables)] -#[warn(clippy::deref_method_explicit)] +#[warn(clippy::explicit_deref_method)] fn main() { let a: &mut String = &mut String::from("foo"); diff --git a/tests/ui/dereference.stderr b/tests/ui/dereference.stderr index dc58acd15240..a4c2487d06b9 100644 --- a/tests/ui/dereference.stderr +++ b/tests/ui/dereference.stderr @@ -4,7 +4,7 @@ error: explicit deref method call 13 | let b: &str = a.deref(); | ^^^^^^^^^ help: try this: `&*a` | - = note: `-D clippy::deref-method-explicit` implied by `-D warnings` + = note: `-D clippy::explicit-deref-method` implied by `-D warnings` error: explicit deref_mut method call --> $DIR/dereference.rs:17:27 From 2a0fb02eee23e2e3cc60f90584a0fa727e4ac827 Mon Sep 17 00:00:00 2001 From: Tom Milligan Date: Fri, 5 Oct 2018 10:20:11 +0100 Subject: [PATCH 5/9] Move explicit_deref_method from complexity to pedantic --- clippy_lints/src/dereference.rs | 2 +- clippy_lints/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/dereference.rs b/clippy_lints/src/dereference.rs index f32c0f6a027e..73fb6890b9b3 100644 --- a/clippy_lints/src/dereference.rs +++ b/clippy_lints/src/dereference.rs @@ -20,7 +20,7 @@ use crate::utils::span_lint_and_sugg; /// ``` declare_clippy_lint! { pub EXPLICIT_DEREF_METHOD, - complexity, + pedantic, "Explicit use of deref or deref_mut method while not in a method chain." } diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index e5e1ad9acc9d..d69713611d23 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -462,6 +462,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) { copies::MATCH_SAME_ARMS, copy_iterator::COPY_ITERATOR, default_trait_access::DEFAULT_TRAIT_ACCESS, + dereference::EXPLICIT_DEREF_METHOD, derive::EXPL_IMPL_CLONE_ON_COPY, doc::DOC_MARKDOWN, empty_enum::EMPTY_ENUM, @@ -810,7 +811,6 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) { assign_ops::MISREFACTORED_ASSIGN_OP, booleans::NONMINIMAL_BOOL, cyclomatic_complexity::CYCLOMATIC_COMPLEXITY, - dereference::EXPLICIT_DEREF_METHOD, double_comparison::DOUBLE_COMPARISONS, double_parens::DOUBLE_PARENS, duration_subsec::DURATION_SUBSEC, From a6a7593c8c996c0126fc23d8b88b991b394f29af Mon Sep 17 00:00:00 2001 From: Tom Milligan Date: Fri, 5 Oct 2018 10:38:39 +0100 Subject: [PATCH 6/9] Revert "fix build failure" This reverts commit 858a90295ce2a957516036a6d328a0d3d1177eb2. --- clippy_lints/src/utils/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 9dc2ce9be7d9..fa3c72dbb7de 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -90,7 +90,7 @@ pub fn match_def_path(tcx: TyCtxt<'_, '_, '_>, def_id: DefId, path: &[&str]) -> let mut apb = AbsolutePathBuffer { names: vec![] }; - tcx.push_item_path(&mut apb, def_id); + tcx.push_item_path(&mut apb, def_id, false); apb.names.len() == path.len() && apb.names From 66447a508070c1af351b6b40bee592892c8c8c9f Mon Sep 17 00:00:00 2001 From: Tom Milligan Date: Fri, 5 Oct 2018 12:26:59 +0100 Subject: [PATCH 7/9] ran update_lints --- CHANGELOG.md | 1 + README.md | 2 +- clippy_lints/src/lib.rs | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9bea1e8ef5e..066d9f7f228c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -677,6 +677,7 @@ All notable changes to this project will be documented in this file. [`expect_fun_call`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#expect_fun_call [`expl_impl_clone_on_copy`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#expl_impl_clone_on_copy [`explicit_counter_loop`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#explicit_counter_loop +[`explicit_deref_method`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#explicit_deref_method [`explicit_into_iter_loop`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#explicit_into_iter_loop [`explicit_iter_loop`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#explicit_iter_loop [`explicit_write`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#explicit_write diff --git a/README.md b/README.md index 40ece34c6faf..0156cdf65cce 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ We are currently in the process of discussing Clippy 1.0 via the RFC process in A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code. -[There are 279 lints included in this crate!](https://rust-lang-nursery.github.io/rust-clippy/master/index.html) +[There are 280 lints included in this crate!](https://rust-lang-nursery.github.io/rust-clippy/master/index.html) We have a bunch of lint categories to allow you to choose how much Clippy is supposed to ~~annoy~~ help you: diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index d69713611d23..e50af25427a3 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -526,7 +526,6 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) { copies::IF_SAME_THEN_ELSE, copies::IFS_SAME_COND, cyclomatic_complexity::CYCLOMATIC_COMPLEXITY, - dereference::EXPLICIT_DEREF_METHOD, derive::DERIVE_HASH_XOR_EQ, double_comparison::DOUBLE_COMPARISONS, double_parens::DOUBLE_PARENS, From b24101041faadb0eede5df30141bd364e2aa6910 Mon Sep 17 00:00:00 2001 From: Tom Milligan Date: Fri, 5 Oct 2018 12:59:45 +0100 Subject: [PATCH 8/9] Added failing test for deref in macro --- tests/ui/dereference.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/ui/dereference.rs b/tests/ui/dereference.rs index 5d8ee847374f..7800cd84c242 100644 --- a/tests/ui/dereference.rs +++ b/tests/ui/dereference.rs @@ -47,4 +47,9 @@ fn main() { { let b: &mut str = &mut *a; } + + { + macro_rules! expr_deref { ($body:expr) => { $body.deref() } } + let b: &str = expr_deref!(a); + } } From 1e52f802e20ceb4b0126d37c5d853320f448ae70 Mon Sep 17 00:00:00 2001 From: Tom Milligan Date: Fri, 5 Oct 2018 13:06:48 +0100 Subject: [PATCH 9/9] Ignore when part of macro expansion --- clippy_lints/src/dereference.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/dereference.rs b/clippy_lints/src/dereference.rs index 73fb6890b9b3..b6d245ff6e31 100644 --- a/clippy_lints/src/dereference.rs +++ b/clippy_lints/src/dereference.rs @@ -2,7 +2,7 @@ use crate::rustc::hir::{Expr, ExprKind, QPath}; use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use crate::rustc::{declare_tool_lint, lint_array}; use if_chain::if_chain; -use crate::utils::span_lint_and_sugg; +use crate::utils::{in_macro, span_lint_and_sugg}; /// **What it does:** Checks for explicit deref() or deref_mut() method calls. /// @@ -15,8 +15,7 @@ use crate::utils::span_lint_and_sugg; /// let c = a.deref_mut(); /// /// // excludes -/// let e = d.deref().unwrap(); -/// let f = a.deref().unwrap(); +/// let e = d.unwrap().deref(); /// ``` declare_clippy_lint! { pub EXPLICIT_DEREF_METHOD, @@ -34,6 +33,10 @@ impl LintPass for Pass { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &Expr) { + if in_macro(expr.span) { + return; + } + if_chain! { // if this is a method call if let ExprKind::MethodCall(ref method_name, _, ref args) = &expr.node;