about summary refs log tree commit diff
path: root/clippy_utils/src/lib.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-04-13 20:31:22 +0000
committerbors <bors@rust-lang.org>2021-04-13 20:31:22 +0000
commit8f3c2450c2dff0d4ae82395699809d3ea726d6c2 (patch)
tree7c429833696b8844dcea2cfcd60c8ab54732362b /clippy_utils/src/lib.rs
parente9728b80ce38a1ab94d90d125726d5503e6ab3bb (diff)
parent76bd5d232c767dbdab63005eca07a9563982e9dd (diff)
Auto merge of #7074 - camsteffen:diag-methods, r=llogiq
Split `is_diagnostic_assoc_item`

changelog: none

* Split `is_diagnostic_assoc_item` into `is_diag_item_method` and `is_diag_trait_item`
  * `is_diag_item_method` is a bit more nuanced with the `tcx.type_of(impl_id).ty_adt_def()` step, so it seems better to keep that separate.
  * No need to generalize over traits and Adt's since we know which one we want at compile time
  * "item" vs. "method" because a trait may have associated items.
* Replaces the usage of the `sym::slice` diagnostic item with the `slice_alloc` lang item. The diagnostic item should be removed from rustc because it is on the `slice_alloc` impl, not slice itself (and it's not needed).
Diffstat (limited to 'clippy_utils/src/lib.rs')
-rw-r--r--clippy_utils/src/lib.rs32
1 files changed, 17 insertions, 15 deletions
diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs
index e99ffbe269b..ec140463a8a 100644
--- a/clippy_utils/src/lib.rs
+++ b/clippy_utils/src/lib.rs
@@ -293,27 +293,29 @@ pub fn match_trait_method(cx: &LateContext<'_>, expr: &Expr<'_>, path: &[&str])
     trt_id.map_or(false, |trt_id| match_def_path(cx, trt_id, path))
 }
 
-/// Checks if the method call given in `def_id` belongs to a trait or other container with a given
-/// diagnostic item
-pub fn is_diagnostic_assoc_item(cx: &LateContext<'_>, def_id: DefId, diag_item: Symbol) -> bool {
-    cx.tcx
-        .opt_associated_item(def_id)
-        .and_then(|associated_item| match associated_item.container {
-            rustc_ty::TraitContainer(assoc_def_id) => Some(assoc_def_id),
-            rustc_ty::ImplContainer(assoc_def_id) => match cx.tcx.type_of(assoc_def_id).kind() {
-                rustc_ty::Adt(adt, _) => Some(adt.did),
-                rustc_ty::Slice(_) => cx.tcx.get_diagnostic_item(sym::slice), // this isn't perfect but it works
-                _ => None,
-            },
-        })
-        .map_or(false, |assoc_def_id| cx.tcx.is_diagnostic_item(diag_item, assoc_def_id))
+/// Checks if a method is defined in an impl of a diagnostic item
+pub fn is_diag_item_method(cx: &LateContext<'_>, def_id: DefId, diag_item: Symbol) -> bool {
+    if let Some(impl_did) = cx.tcx.impl_of_method(def_id) {
+        if let Some(adt) = cx.tcx.type_of(impl_did).ty_adt_def() {
+            return cx.tcx.is_diagnostic_item(diag_item, adt.did);
+        }
+    }
+    false
+}
+
+/// Checks if a method is in a diagnostic item trait
+pub fn is_diag_trait_item(cx: &LateContext<'_>, def_id: DefId, diag_item: Symbol) -> bool {
+    if let Some(trait_did) = cx.tcx.trait_of_item(def_id) {
+        return cx.tcx.is_diagnostic_item(diag_item, trait_did);
+    }
+    false
 }
 
 /// Checks if the method call given in `expr` belongs to the given trait.
 pub fn is_trait_method(cx: &LateContext<'_>, expr: &Expr<'_>, diag_item: Symbol) -> bool {
     cx.typeck_results()
         .type_dependent_def_id(expr.hir_id)
-        .map_or(false, |did| is_diagnostic_assoc_item(cx, did, diag_item))
+        .map_or(false, |did| is_diag_trait_item(cx, did, diag_item))
 }
 
 /// Checks if an expression references a variable of the given name.