Skip to content

Commit 11a5386

Browse files
committed
Move get_associated_type from clippy to rustc_lint
1 parent 4e0d0d7 commit 11a5386

File tree

5 files changed

+40
-31
lines changed

5 files changed

+40
-31
lines changed

compiler/rustc_lint/src/context.rs

+17
Original file line numberDiff line numberDiff line change
@@ -1245,6 +1245,23 @@ impl<'tcx> LateContext<'tcx> {
12451245

12461246
AbsolutePathPrinter { tcx: self.tcx }.print_def_path(def_id, &[]).unwrap()
12471247
}
1248+
1249+
/// Returns the associated type `name` for `self_ty` as an implementation of `trait_id`.
1250+
/// Do not invoke without first verifying that the type implements the trait.
1251+
pub fn get_associated_type(
1252+
&self,
1253+
self_ty: Ty<'tcx>,
1254+
trait_id: DefId,
1255+
name: &str,
1256+
) -> Option<Ty<'tcx>> {
1257+
let tcx = self.tcx;
1258+
tcx.associated_items(trait_id)
1259+
.find_by_name_and_kind(tcx, Ident::from_str(name), ty::AssocKind::Type, trait_id)
1260+
.and_then(|assoc| {
1261+
let proj = tcx.mk_projection(assoc.def_id, tcx.mk_substs_trait(self_ty, []));
1262+
tcx.try_normalize_erasing_regions(self.param_env, proj).ok()
1263+
})
1264+
}
12481265
}
12491266

12501267
impl<'tcx> abi::HasDataLayout for LateContext<'tcx> {

src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use clippy_utils::diagnostics::span_lint_and_then;
22
use clippy_utils::source::snippet_opt;
3-
use clippy_utils::ty::{get_associated_type, implements_trait, is_copy};
3+
use clippy_utils::ty::{implements_trait, is_copy};
44
use rustc_errors::Applicability;
55
use rustc_hir::Expr;
66
use rustc_lint::LateContext;
@@ -25,7 +25,7 @@ pub(super) fn check<'tcx>(
2525
&& let Some(method_id) = typeck.type_dependent_def_id(cloned_call.hir_id)
2626
&& cx.tcx.trait_of_item(method_id) == Some(iter_id)
2727
&& let cloned_recv_ty = typeck.expr_ty_adjusted(cloned_recv)
28-
&& let Some(iter_assoc_ty) = get_associated_type(cx, cloned_recv_ty, iter_id, "Item")
28+
&& let Some(iter_assoc_ty) = cx.get_associated_type(cloned_recv_ty, iter_id, "Item")
2929
&& matches!(*iter_assoc_ty.kind(), ty::Ref(_, ty, _) if !is_copy(cx, ty))
3030
{
3131
if needs_into_iter

src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use super::utils::clone_or_copy_needed;
22
use clippy_utils::diagnostics::span_lint_and_then;
33
use clippy_utils::higher::ForLoop;
44
use clippy_utils::source::snippet_opt;
5-
use clippy_utils::ty::{get_associated_type, get_iterator_item_ty, implements_trait};
5+
use clippy_utils::ty::{get_iterator_item_ty, implements_trait};
66
use clippy_utils::{fn_def_id, get_parent_expr};
77
use rustc_errors::Applicability;
88
use rustc_hir::{def_id::DefId, Expr, ExprKind};
@@ -54,7 +54,7 @@ pub fn check_for_loop_iter(
5454
if let Some(into_iterator_trait_id) = cx.tcx.get_diagnostic_item(sym::IntoIterator);
5555
let collection_ty = cx.typeck_results().expr_ty(collection);
5656
if implements_trait(cx, collection_ty, into_iterator_trait_id, &[]);
57-
if let Some(into_iter_item_ty) = get_associated_type(cx, collection_ty, into_iterator_trait_id, "Item");
57+
if let Some(into_iter_item_ty) = cx.get_associated_type(collection_ty, into_iterator_trait_id, "Item");
5858

5959
if iter_item_ty == into_iter_item_ty;
6060
if let Some(collection_snippet) = snippet_opt(cx, collection.span);

src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs

+18-9
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ use super::implicit_clone::is_clone_like;
22
use super::unnecessary_iter_cloned::{self, is_into_iter};
33
use clippy_utils::diagnostics::span_lint_and_sugg;
44
use clippy_utils::source::snippet_opt;
5-
use clippy_utils::ty::{get_associated_type, get_iterator_item_ty, implements_trait, is_copy, peel_mid_ty_refs};
5+
use clippy_utils::ty::{get_iterator_item_ty, implements_trait, is_copy, peel_mid_ty_refs};
66
use clippy_utils::visitors::find_all_ret_expressions;
7-
use clippy_utils::{fn_def_id, get_parent_expr, is_diag_item_method, is_diag_trait_item, return_ty};
7+
use clippy_utils::{
8+
fn_def_id, get_parent_expr, is_diag_item_method, is_diag_trait_item, return_ty,
9+
};
810
use clippy_utils::{meets_msrv, msrvs};
911
use rustc_errors::Applicability;
1012
use rustc_hir::{def_id::DefId, BorrowKind, Expr, ExprKind, ItemKind, Node};
@@ -18,7 +20,9 @@ use rustc_middle::ty::EarlyBinder;
1820
use rustc_middle::ty::{self, ParamTy, PredicateKind, ProjectionPredicate, TraitPredicate, Ty};
1921
use rustc_semver::RustcVersion;
2022
use rustc_span::{sym, Symbol};
21-
use rustc_trait_selection::traits::{query::evaluate_obligation::InferCtxtExt as _, Obligation, ObligationCause};
23+
use rustc_trait_selection::traits::{
24+
query::evaluate_obligation::InferCtxtExt as _, Obligation, ObligationCause,
25+
};
2226
use std::cmp::max;
2327

2428
use super::UNNECESSARY_TO_OWNED;
@@ -146,7 +150,7 @@ fn check_addr_of_expr(
146150
if_chain! {
147151
if let Some(deref_trait_id) = cx.tcx.get_diagnostic_item(sym::Deref);
148152
if implements_trait(cx, receiver_ty, deref_trait_id, &[]);
149-
if get_associated_type(cx, receiver_ty, deref_trait_id, "Target") == Some(target_ty);
153+
if cx.get_associated_type(receiver_ty, deref_trait_id, "Target") == Some(target_ty);
150154
then {
151155
if n_receiver_refs > 0 {
152156
span_lint_and_sugg(
@@ -341,13 +345,13 @@ fn get_input_traits_and_projections<'tcx>(
341345
if trait_predicate.trait_ref.self_ty() == input {
342346
trait_predicates.push(trait_predicate);
343347
}
344-
},
348+
}
345349
PredicateKind::Projection(projection_predicate) => {
346350
if projection_predicate.projection_ty.self_ty() == input {
347351
projection_predicates.push(projection_predicate);
348352
}
349-
},
350-
_ => {},
353+
}
354+
_ => {}
351355
}
352356
}
353357
(trait_predicates, projection_predicates)
@@ -462,7 +466,12 @@ fn is_cloned_or_copied(cx: &LateContext<'_>, method_name: Symbol, method_def_id:
462466

463467
/// Returns true if the named method can be used to convert the receiver to its "owned"
464468
/// representation.
465-
fn is_to_owned_like<'a>(cx: &LateContext<'a>, call_expr: &Expr<'a>, method_name: Symbol, method_def_id: DefId) -> bool {
469+
fn is_to_owned_like<'a>(
470+
cx: &LateContext<'a>,
471+
call_expr: &Expr<'a>,
472+
method_name: Symbol,
473+
method_def_id: DefId,
474+
) -> bool {
466475
is_clone_like(cx, method_name.as_str(), method_def_id)
467476
|| is_cow_into_owned(cx, method_name, method_def_id)
468477
|| 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>(
490499
&& let GenericArgKind::Type(ty) = generic_arg.unpack()
491500
&& let Some(deref_trait_id) = cx.tcx.get_diagnostic_item(sym::Deref)
492501
&& let Some(as_ref_trait_id) = cx.tcx.get_diagnostic_item(sym::AsRef)
493-
&& (get_associated_type(cx, ty, deref_trait_id, "Target") == Some(cx.tcx.types.str_) ||
502+
&& (cx.get_associated_type(ty, deref_trait_id, "Target") == Some(cx.tcx.types.str_) ||
494503
implements_trait(cx, ty, as_ref_trait_id, &[cx.tcx.types.str_.into()])) {
495504
true
496505
} else {

src/tools/clippy/clippy_utils/src/ty.rs

+1-18
Original file line numberDiff line numberDiff line change
@@ -117,24 +117,7 @@ pub fn contains_ty_adt_constructor_opaque<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'
117117
pub fn get_iterator_item_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
118118
cx.tcx
119119
.get_diagnostic_item(sym::Iterator)
120-
.and_then(|iter_did| get_associated_type(cx, ty, iter_did, "Item"))
121-
}
122-
123-
/// Returns the associated type `name` for `ty` as an implementation of `trait_id`.
124-
/// Do not invoke without first verifying that the type implements the trait.
125-
pub fn get_associated_type<'tcx>(
126-
cx: &LateContext<'tcx>,
127-
ty: Ty<'tcx>,
128-
trait_id: DefId,
129-
name: &str,
130-
) -> Option<Ty<'tcx>> {
131-
cx.tcx
132-
.associated_items(trait_id)
133-
.find_by_name_and_kind(cx.tcx, Ident::from_str(name), ty::AssocKind::Type, trait_id)
134-
.and_then(|assoc| {
135-
let proj = cx.tcx.mk_projection(assoc.def_id, cx.tcx.mk_substs_trait(ty, []));
136-
cx.tcx.try_normalize_erasing_regions(cx.param_env, proj).ok()
137-
})
120+
.and_then(|iter_did| cx.get_associated_type(ty, iter_did, "Item"))
138121
}
139122

140123
/// Get the diagnostic name of a type, e.g. `sym::HashMap`. To check if a type

0 commit comments

Comments
 (0)