about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMaybe Waffle <waffle.lapkin@gmail.com>2022-11-22 19:52:46 +0000
committerMaybe Waffle <waffle.lapkin@gmail.com>2022-11-23 15:40:27 +0000
commit11a5386256c3d9bf835cf51f0798dfffa51d00f0 (patch)
treec2e5f4c0162dbf7d114242630cc06265284e9f45
parent4e0d0d757e2f1b61ec809420b006545a9f8974c0 (diff)
downloadrust-11a5386256c3d9bf835cf51f0798dfffa51d00f0.tar.gz
rust-11a5386256c3d9bf835cf51f0798dfffa51d00f0.zip
Move `get_associated_type` from `clippy` to `rustc_lint`
-rw-r--r--compiler/rustc_lint/src/context.rs17
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs27
-rw-r--r--src/tools/clippy/clippy_utils/src/ty.rs19
5 files changed, 40 insertions, 31 deletions
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index 589b4d6a10f..67cf66f4708 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -1245,6 +1245,23 @@ impl<'tcx> LateContext<'tcx> {
 
         AbsolutePathPrinter { tcx: self.tcx }.print_def_path(def_id, &[]).unwrap()
     }
+
+    /// Returns the associated type `name` for `self_ty` as an implementation of `trait_id`.
+    /// Do not invoke without first verifying that the type implements the trait.
+    pub fn get_associated_type(
+        &self,
+        self_ty: Ty<'tcx>,
+        trait_id: DefId,
+        name: &str,
+    ) -> Option<Ty<'tcx>> {
+        let tcx = self.tcx;
+        tcx.associated_items(trait_id)
+            .find_by_name_and_kind(tcx, Ident::from_str(name), ty::AssocKind::Type, trait_id)
+            .and_then(|assoc| {
+                let proj = tcx.mk_projection(assoc.def_id, tcx.mk_substs_trait(self_ty, []));
+                tcx.try_normalize_erasing_regions(self.param_env, proj).ok()
+            })
+    }
 }
 
 impl<'tcx> abi::HasDataLayout for LateContext<'tcx> {
diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs b/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs
index 06a39c5997e..b4210d87510 100644
--- a/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::snippet_opt;
-use clippy_utils::ty::{get_associated_type, implements_trait, is_copy};
+use clippy_utils::ty::{implements_trait, is_copy};
 use rustc_errors::Applicability;
 use rustc_hir::Expr;
 use rustc_lint::LateContext;
@@ -25,7 +25,7 @@ pub(super) fn check<'tcx>(
         && let Some(method_id) = typeck.type_dependent_def_id(cloned_call.hir_id)
         && cx.tcx.trait_of_item(method_id) == Some(iter_id)
         && let cloned_recv_ty = typeck.expr_ty_adjusted(cloned_recv)
-        && let Some(iter_assoc_ty) = get_associated_type(cx, cloned_recv_ty, iter_id, "Item")
+        && let Some(iter_assoc_ty) = cx.get_associated_type(cloned_recv_ty, iter_id, "Item")
         && matches!(*iter_assoc_ty.kind(), ty::Ref(_, ty, _) if !is_copy(cx, ty))
     {
         if needs_into_iter
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs
index 4eb579af7a1..52a4ff7d1ae 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs
@@ -2,7 +2,7 @@ use super::utils::clone_or_copy_needed;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::higher::ForLoop;
 use clippy_utils::source::snippet_opt;
-use clippy_utils::ty::{get_associated_type, get_iterator_item_ty, implements_trait};
+use clippy_utils::ty::{get_iterator_item_ty, implements_trait};
 use clippy_utils::{fn_def_id, get_parent_expr};
 use rustc_errors::Applicability;
 use rustc_hir::{def_id::DefId, Expr, ExprKind};
@@ -54,7 +54,7 @@ pub fn check_for_loop_iter(
                 if let Some(into_iterator_trait_id) = cx.tcx.get_diagnostic_item(sym::IntoIterator);
                 let collection_ty = cx.typeck_results().expr_ty(collection);
                 if implements_trait(cx, collection_ty, into_iterator_trait_id, &[]);
-                if let Some(into_iter_item_ty) = get_associated_type(cx, collection_ty, into_iterator_trait_id, "Item");
+                if let Some(into_iter_item_ty) = cx.get_associated_type(collection_ty, into_iterator_trait_id, "Item");
 
                 if iter_item_ty == into_iter_item_ty;
                 if let Some(collection_snippet) = snippet_opt(cx, collection.span);
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
index 375ebc903b4..8b000cd754c 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
@@ -2,9 +2,11 @@ use super::implicit_clone::is_clone_like;
 use super::unnecessary_iter_cloned::{self, is_into_iter};
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_opt;
-use clippy_utils::ty::{get_associated_type, get_iterator_item_ty, implements_trait, is_copy, peel_mid_ty_refs};
+use clippy_utils::ty::{get_iterator_item_ty, implements_trait, is_copy, peel_mid_ty_refs};
 use clippy_utils::visitors::find_all_ret_expressions;
-use clippy_utils::{fn_def_id, get_parent_expr, is_diag_item_method, is_diag_trait_item, return_ty};
+use clippy_utils::{
+    fn_def_id, get_parent_expr, is_diag_item_method, is_diag_trait_item, return_ty,
+};
 use clippy_utils::{meets_msrv, msrvs};
 use rustc_errors::Applicability;
 use rustc_hir::{def_id::DefId, BorrowKind, Expr, ExprKind, ItemKind, Node};
@@ -18,7 +20,9 @@ use rustc_middle::ty::EarlyBinder;
 use rustc_middle::ty::{self, ParamTy, PredicateKind, ProjectionPredicate, TraitPredicate, Ty};
 use rustc_semver::RustcVersion;
 use rustc_span::{sym, Symbol};
-use rustc_trait_selection::traits::{query::evaluate_obligation::InferCtxtExt as _, Obligation, ObligationCause};
+use rustc_trait_selection::traits::{
+    query::evaluate_obligation::InferCtxtExt as _, Obligation, ObligationCause,
+};
 use std::cmp::max;
 
 use super::UNNECESSARY_TO_OWNED;
@@ -146,7 +150,7 @@ fn check_addr_of_expr(
             if_chain! {
                 if let Some(deref_trait_id) = cx.tcx.get_diagnostic_item(sym::Deref);
                 if implements_trait(cx, receiver_ty, deref_trait_id, &[]);
-                if get_associated_type(cx, receiver_ty, deref_trait_id, "Target") == Some(target_ty);
+                if cx.get_associated_type(receiver_ty, deref_trait_id, "Target") == Some(target_ty);
                 then {
                     if n_receiver_refs > 0 {
                         span_lint_and_sugg(
@@ -341,13 +345,13 @@ fn get_input_traits_and_projections<'tcx>(
                 if trait_predicate.trait_ref.self_ty() == input {
                     trait_predicates.push(trait_predicate);
                 }
-            },
+            }
             PredicateKind::Projection(projection_predicate) => {
                 if projection_predicate.projection_ty.self_ty() == input {
                     projection_predicates.push(projection_predicate);
                 }
-            },
-            _ => {},
+            }
+            _ => {}
         }
     }
     (trait_predicates, projection_predicates)
@@ -462,7 +466,12 @@ fn is_cloned_or_copied(cx: &LateContext<'_>, method_name: Symbol, method_def_id:
 
 /// Returns true if the named method can be used to convert the receiver to its "owned"
 /// representation.
-fn is_to_owned_like<'a>(cx: &LateContext<'a>, call_expr: &Expr<'a>, method_name: Symbol, method_def_id: DefId) -> bool {
+fn is_to_owned_like<'a>(
+    cx: &LateContext<'a>,
+    call_expr: &Expr<'a>,
+    method_name: Symbol,
+    method_def_id: DefId,
+) -> bool {
     is_clone_like(cx, method_name.as_str(), method_def_id)
         || is_cow_into_owned(cx, method_name, method_def_id)
         || is_to_string_on_string_like(cx, call_expr, method_name, method_def_id)
@@ -490,7 +499,7 @@ fn is_to_string_on_string_like<'a>(
         && let GenericArgKind::Type(ty) = generic_arg.unpack()
         && let Some(deref_trait_id) = cx.tcx.get_diagnostic_item(sym::Deref)
         && let Some(as_ref_trait_id) = cx.tcx.get_diagnostic_item(sym::AsRef)
-        && (get_associated_type(cx, ty, deref_trait_id, "Target") == Some(cx.tcx.types.str_) ||
+        && (cx.get_associated_type(ty, deref_trait_id, "Target") == Some(cx.tcx.types.str_) ||
             implements_trait(cx, ty, as_ref_trait_id, &[cx.tcx.types.str_.into()])) {
             true
         } else {
diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs
index 1b65b701409..8284dc5c28c 100644
--- a/src/tools/clippy/clippy_utils/src/ty.rs
+++ b/src/tools/clippy/clippy_utils/src/ty.rs
@@ -117,24 +117,7 @@ pub fn contains_ty_adt_constructor_opaque<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'
 pub fn get_iterator_item_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
     cx.tcx
         .get_diagnostic_item(sym::Iterator)
-        .and_then(|iter_did| get_associated_type(cx, ty, iter_did, "Item"))
-}
-
-/// Returns the associated type `name` for `ty` as an implementation of `trait_id`.
-/// Do not invoke without first verifying that the type implements the trait.
-pub fn get_associated_type<'tcx>(
-    cx: &LateContext<'tcx>,
-    ty: Ty<'tcx>,
-    trait_id: DefId,
-    name: &str,
-) -> Option<Ty<'tcx>> {
-    cx.tcx
-        .associated_items(trait_id)
-        .find_by_name_and_kind(cx.tcx, Ident::from_str(name), ty::AssocKind::Type, trait_id)
-        .and_then(|assoc| {
-            let proj = cx.tcx.mk_projection(assoc.def_id, cx.tcx.mk_substs_trait(ty, []));
-            cx.tcx.try_normalize_erasing_regions(cx.param_env, proj).ok()
-        })
+        .and_then(|iter_did| cx.get_associated_type(ty, iter_did, "Item"))
 }
 
 /// Get the diagnostic name of a type, e.g. `sym::HashMap`. To check if a type