about summary refs log tree commit diff
path: root/clippy_lints/src
diff options
context:
space:
mode:
authorAlex Macleod <alex@macleod.io>2023-08-19 18:06:46 +0000
committerAlex Macleod <alex@macleod.io>2023-08-19 20:22:45 +0000
commit8f2d47ea72fdc754697b381441fb49953bf37b58 (patch)
treed72fd31eb1d50e7a4dd08181047eeb066fb893f6 /clippy_lints/src
parentd9e6aac8bb498ae3ac3c4b1d8575061d219339ab (diff)
downloadrust-8f2d47ea72fdc754697b381441fb49953bf37b58.tar.gz
rust-8f2d47ea72fdc754697b381441fb49953bf37b58.zip
Check that the suggested method exists in unwrap_or_default
Diffstat (limited to 'clippy_lints/src')
-rw-r--r--clippy_lints/src/methods/or_fun_call.rs19
1 files changed, 17 insertions, 2 deletions
diff --git a/clippy_lints/src/methods/or_fun_call.rs b/clippy_lints/src/methods/or_fun_call.rs
index 8b2f57160af..942f3bd79a6 100644
--- a/clippy_lints/src/methods/or_fun_call.rs
+++ b/clippy_lints/src/methods/or_fun_call.rs
@@ -65,11 +65,26 @@ pub(super) fn check<'tcx>(
         };
 
         let sugg = match (name, call_expr.is_some()) {
-            ("unwrap_or", true) | ("unwrap_or_else", false) => "unwrap_or_default",
-            ("or_insert", true) | ("or_insert_with", false) => "or_default",
+            ("unwrap_or", true) | ("unwrap_or_else", false) => sym!(unwrap_or_default),
+            ("or_insert", true) | ("or_insert_with", false) => sym!(or_default),
             _ => return false,
         };
 
+        let receiver_ty = cx.typeck_results().expr_ty_adjusted(receiver).peel_refs();
+        let has_suggested_method = receiver_ty.ty_adt_def().is_some_and(|adt_def| {
+            cx.tcx
+                .inherent_impls(adt_def.did())
+                .iter()
+                .flat_map(|impl_id| cx.tcx.associated_items(impl_id).filter_by_name_unhygienic(sugg))
+                .any(|assoc| {
+                    assoc.fn_has_self_parameter
+                        && cx.tcx.fn_sig(assoc.def_id).skip_binder().inputs().skip_binder().len() == 1
+                })
+        });
+        if !has_suggested_method {
+            return false;
+        }
+
         // needs to target Default::default in particular or be *::new and have a Default impl
         // available
         if (is_new(fun) && output_type_implements_default(fun))