about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/methods/unwrap_or_else_default.rs25
-rw-r--r--clippy_utils/src/lib.rs2
-rw-r--r--tests/ui/unwrap_or_else_default.fixed2
-rw-r--r--tests/ui/unwrap_or_else_default.stderr10
4 files changed, 31 insertions, 8 deletions
diff --git a/clippy_lints/src/methods/unwrap_or_else_default.rs b/clippy_lints/src/methods/unwrap_or_else_default.rs
index 4811048439c..5f04d8e1828 100644
--- a/clippy_lints/src/methods/unwrap_or_else_default.rs
+++ b/clippy_lints/src/methods/unwrap_or_else_default.rs
@@ -1,10 +1,11 @@
 //! Lint for `some_result_or_option.unwrap_or_else(Default::default)`
 
 use super::UNWRAP_OR_ELSE_DEFAULT;
-use clippy_utils::{
-    diagnostics::span_lint_and_sugg, is_default_equivalent, is_trait_item, source::snippet_with_applicability,
-    ty::is_type_diagnostic_item,
+use clippy_utils::{diagnostics::span_lint_and_sugg, is_trait_item, source::snippet_with_applicability, ty::is_type_diagnostic_item,
+                   is_default_equivalent_ctor, is_diag_trait_item
 };
+use rustc_hir::ExprKind;
+
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::LateContext;
@@ -23,9 +24,25 @@ pub(super) fn check<'tcx>(
     let is_option = is_type_diagnostic_item(cx, recv_ty, sym::Option);
     let is_result = is_type_diagnostic_item(cx, recv_ty, sym::Result);
 
+    let is_default_eq = match &u_arg.kind {
+        ExprKind::Path(qpath) => {
+            if let Some(repl_def_id) = cx.qpath_res(qpath, u_arg.hir_id).opt_def_id() {
+                if is_diag_trait_item(cx, repl_def_id, sym::Default)
+                    || is_default_equivalent_ctor(cx, repl_def_id, qpath) {
+                    true
+                } else {
+                    false
+                }
+            } else {
+                false
+            }
+        },
+        _ => {false}
+    };
+
     if_chain! {
         if is_option || is_result;
-        if is_trait_item(cx, u_arg, sym::Default) || is_default_equivalent(cx, u_arg);
+        if is_trait_item(cx, u_arg, sym::Default) || is_default_eq;
         then {
             let mut applicability = Applicability::MachineApplicable;
 
diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs
index 76f4408573b..1b56bfbe1d6 100644
--- a/clippy_utils/src/lib.rs
+++ b/clippy_utils/src/lib.rs
@@ -637,7 +637,7 @@ pub fn can_mut_borrow_both(cx: &LateContext<'_>, e1: &Expr<'_>, e2: &Expr<'_>) -
 
 /// Returns true if the `def_id` associated with the `path` is recognized as a "default-equivalent"
 /// constructor from the std library
-fn is_default_equivalent_ctor(cx: &LateContext<'_>, def_id: DefId, path: &QPath<'_>) -> bool {
+pub fn is_default_equivalent_ctor(cx: &LateContext<'_>, def_id: DefId, path: &QPath<'_>) -> bool {
     let std_types_symbols = &[
         sym::String,
         sym::Vec,
diff --git a/tests/ui/unwrap_or_else_default.fixed b/tests/ui/unwrap_or_else_default.fixed
index 5849dc4cebb..c2b9bd2c881 100644
--- a/tests/ui/unwrap_or_else_default.fixed
+++ b/tests/ui/unwrap_or_else_default.fixed
@@ -45,7 +45,7 @@ fn unwrap_or_else_default() {
     with_enum.unwrap_or_else(Enum::A);
 
     let with_new = Some(vec![1]);
-    with_new.unwrap_or_else(Vec::new);
+    with_new.unwrap_or_default();
 
     let with_err: Result<_, ()> = Ok(vec![1]);
     with_err.unwrap_or_else(make);
diff --git a/tests/ui/unwrap_or_else_default.stderr b/tests/ui/unwrap_or_else_default.stderr
index feb215b09f6..b49b7fb77c2 100644
--- a/tests/ui/unwrap_or_else_default.stderr
+++ b/tests/ui/unwrap_or_else_default.stderr
@@ -1,10 +1,16 @@
 error: use of `.unwrap_or_else(..)` to construct default value
+  --> $DIR/unwrap_or_else_default.rs:48:5
+   |
+LL |     with_new.unwrap_or_else(Vec::new);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `with_new.unwrap_or_default()`
+   |
+   = note: `-D clippy::unwrap-or-else-default` implied by `-D warnings`
+
+error: use of `.unwrap_or_else(..)` to construct default value
   --> $DIR/unwrap_or_else_default.rs:62:5
    |
 LL |     with_real_default.unwrap_or_else(<HasDefaultAndDuplicate as Default>::default);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `with_real_default.unwrap_or_default()`
-   |
-   = note: `-D clippy::unwrap-or-else-default` implied by `-D warnings`
 
 error: use of `.unwrap_or_else(..)` to construct default value
   --> $DIR/unwrap_or_else_default.rs:65:5