Skip to content

Commit f23772c

Browse files
committed
Move lookup_path and similar into clippy_utils::paths
1 parent b768fbe commit f23772c

File tree

15 files changed

+243
-236
lines changed

15 files changed

+243
-236
lines changed

clippy_config/src/types.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use clippy_utils::PathNS;
1+
use clippy_utils::paths::{PathNS, find_crates, lookup_path};
22
use rustc_data_structures::fx::FxHashMap;
33
use rustc_errors::{Applicability, Diag};
44
use rustc_hir::PrimTy;
@@ -148,7 +148,7 @@ pub fn create_disallowed_map<const REPLACEMENT_ALLOWED: bool>(
148148
for disallowed_path in disallowed_paths {
149149
let path = disallowed_path.path();
150150
let sym_path: Vec<Symbol> = path.split("::").map(Symbol::intern).collect();
151-
let mut resolutions = clippy_utils::lookup_path(tcx, ns, &sym_path);
151+
let mut resolutions = lookup_path(tcx, ns, &sym_path);
152152
resolutions.retain(|&def_id| def_kind_predicate(tcx.def_kind(def_id)));
153153

154154
let (prim_ty, found_prim_ty) = if let &[name] = sym_path.as_slice()
@@ -164,10 +164,10 @@ pub fn create_disallowed_map<const REPLACEMENT_ALLOWED: bool>(
164164
&& !disallowed_path.allow_invalid
165165
// Don't warn about unloaded crates:
166166
// https://github.com/rust-lang/rust-clippy/pull/14397#issuecomment-2848328221
167-
&& (sym_path.len() < 2 || !clippy_utils::find_crates(tcx, sym_path[0]).is_empty())
167+
&& (sym_path.len() < 2 || !find_crates(tcx, sym_path[0]).is_empty())
168168
{
169169
// Relookup the path in an arbitrary namespace to get a good `expected, found` message
170-
let found_def_ids = clippy_utils::lookup_path(tcx, PathNS::Arbitrary, &sym_path);
170+
let found_def_ids = lookup_path(tcx, PathNS::Arbitrary, &sym_path);
171171
let message = if let Some(&def_id) = found_def_ids.first() {
172172
let (article, description) = tcx.article_and_description(def_id);
173173
format!("expected a {predicate_description}, found {article} {description}")

clippy_lints/src/await_holding_invalid.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use clippy_config::Conf;
22
use clippy_config::types::{DisallowedPathWithoutReplacement, create_disallowed_map};
33
use clippy_utils::diagnostics::span_lint_and_then;
4-
use clippy_utils::{PathNS, paths};
4+
use clippy_utils::paths::{self, PathNS};
55
use rustc_hir as hir;
66
use rustc_hir::def_id::{DefId, DefIdMap};
77
use rustc_lint::{LateContext, LateLintPass};

clippy_lints/src/disallowed_macros.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use clippy_config::Conf;
22
use clippy_config::types::{DisallowedPath, create_disallowed_map};
3-
use clippy_utils::PathNS;
43
use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};
54
use clippy_utils::macros::macro_backtrace;
5+
use clippy_utils::paths::PathNS;
66
use rustc_data_structures::fx::FxHashSet;
77
use rustc_hir::def::DefKind;
88
use rustc_hir::def_id::DefIdMap;

clippy_lints/src/disallowed_methods.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use clippy_config::Conf;
22
use clippy_config::types::{DisallowedPath, create_disallowed_map};
3-
use clippy_utils::PathNS;
43
use clippy_utils::diagnostics::span_lint_and_then;
4+
use clippy_utils::paths::PathNS;
55
use rustc_hir::def::{CtorKind, DefKind, Res};
66
use rustc_hir::def_id::DefIdMap;
77
use rustc_hir::{Expr, ExprKind};

clippy_lints/src/disallowed_types.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use clippy_config::Conf;
22
use clippy_config::types::{DisallowedPath, create_disallowed_map};
3-
use clippy_utils::PathNS;
43
use clippy_utils::diagnostics::span_lint_and_then;
4+
use clippy_utils::paths::PathNS;
55
use rustc_data_structures::fx::FxHashMap;
66
use rustc_hir::def::{DefKind, Res};
77
use rustc_hir::def_id::DefIdMap;

clippy_lints/src/functions/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ mod too_many_lines;
1010

1111
use clippy_config::Conf;
1212
use clippy_utils::msrvs::Msrv;
13-
use clippy_utils::{PathNS, lookup_path_str};
13+
use clippy_utils::paths::{PathNS, lookup_path_str};
1414
use rustc_hir as hir;
1515
use rustc_hir::intravisit;
1616
use rustc_lint::{LateContext, LateLintPass};

clippy_lints/src/missing_enforced_import_rename.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use clippy_config::Conf;
22
use clippy_utils::diagnostics::span_lint_and_sugg;
3+
use clippy_utils::paths::{PathNS, lookup_path_str};
34
use clippy_utils::source::SpanRangeExt;
4-
use clippy_utils::{PathNS, lookup_path_str};
55
use rustc_errors::Applicability;
66
use rustc_hir::def::Res;
77
use rustc_hir::def_id::DefIdMap;

clippy_lints/src/non_std_lazy_statics.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use clippy_config::Conf;
22
use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
33
use clippy_utils::msrvs::{self, Msrv};
4+
use clippy_utils::paths::{self, PathNS, find_crates, lookup_path_str};
45
use clippy_utils::visitors::for_each_expr;
5-
use clippy_utils::{PathNS, find_crates, fn_def_id, is_no_std_crate, lookup_path_str, path_def_id, paths, sym};
6+
use clippy_utils::{fn_def_id, is_no_std_crate, path_def_id, sym};
67
use rustc_data_structures::fx::FxIndexMap;
78
use rustc_errors::Applicability;
89
use rustc_hir::def::{DefKind, Res};

clippy_lints_internal/src/internal_paths.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use clippy_utils::paths::PathLookup;
2-
use clippy_utils::{PathNS, sym, type_path, value_path};
1+
use clippy_utils::paths::{PathLookup, PathNS};
2+
use clippy_utils::{sym, type_path, value_path};
33

44
// Paths inside rustc
55
pub static EARLY_LINT_PASS: PathLookup = type_path!(rustc_lint::passes::EarlyLintPass);

clippy_lints_internal/src/unnecessary_def_path.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::internal_paths;
22
use clippy_utils::diagnostics::span_lint_and_then;
3-
use clippy_utils::{PathNS, lookup_path, path_def_id, peel_ref_operators};
3+
use clippy_utils::paths::{PathNS, lookup_path};
4+
use clippy_utils::{path_def_id, peel_ref_operators};
45
use rustc_hir::def_id::DefId;
56
use rustc_hir::{Expr, ExprKind};
67
use rustc_lint::{LateContext, LateLintPass};

clippy_utils/src/lib.rs

Lines changed: 11 additions & 214 deletions
Original file line numberDiff line numberDiff line change
@@ -96,30 +96,29 @@ use rustc_data_structures::fx::FxHashMap;
9696
use rustc_data_structures::packed::Pu128;
9797
use rustc_data_structures::unhash::UnhashMap;
9898
use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk};
99-
use rustc_hir::def::Namespace::{MacroNS, TypeNS, ValueNS};
100-
use rustc_hir::def::{DefKind, Namespace, Res};
101-
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId, LocalModDefId};
99+
use rustc_hir::def::{DefKind, Res};
100+
use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
102101
use rustc_hir::definitions::{DefPath, DefPathData};
103102
use rustc_hir::hir_id::{HirIdMap, HirIdSet};
104103
use rustc_hir::intravisit::{FnKind, Visitor, walk_expr};
105104
use rustc_hir::{
106-
self as hir, Arm, BindingMode, Block, BlockCheckMode, Body, ByRef, Closure, ConstArgKind, ConstContext,
107-
CoroutineDesugaring, CoroutineKind, Destination, Expr, ExprField, ExprKind, FnDecl, FnRetTy, GenericArg,
108-
GenericArgs, HirId, Impl, ImplItem, ImplItemKind, ImplItemRef, Item, ItemKind, LangItem, LetStmt, MatchSource,
109-
Mutability, Node, OwnerId, OwnerNode, Param, Pat, PatExpr, PatExprKind, PatKind, Path, PathSegment, QPath, Stmt,
110-
StmtKind, TraitFn, TraitItem, TraitItemKind, TraitItemRef, TraitRef, TyKind, UnOp, def,
105+
self as hir, Arm, BindingMode, Block, BlockCheckMode, Body, ByRef, Closure, ConstArgKind, CoroutineDesugaring,
106+
CoroutineKind, Destination, Expr, ExprField, ExprKind, FnDecl, FnRetTy, GenericArg, GenericArgs, HirId, Impl,
107+
ImplItem, ImplItemKind, Item, ItemKind, LangItem, LetStmt, MatchSource, Mutability, Node, OwnerId, OwnerNode,
108+
Param, Pat, PatExpr, PatExprKind, PatKind, Path, PathSegment, QPath, Stmt, StmtKind, TraitFn, TraitItem,
109+
TraitItemKind, TraitRef, TyKind, UnOp, def,
111110
};
112111
use rustc_lexer::{TokenKind, tokenize};
113112
use rustc_lint::{LateContext, Level, Lint, LintContext};
113+
use rustc_middle::hir::nested_filter;
114114
use rustc_middle::hir::place::PlaceBase;
115115
use rustc_middle::lint::LevelAndSource;
116116
use rustc_middle::mir::{AggregateKind, Operand, RETURN_PLACE, Rvalue, StatementKind, TerminatorKind};
117117
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
118-
use rustc_middle::ty::fast_reject::SimplifiedType;
119118
use rustc_middle::ty::layout::IntegerExt;
120119
use rustc_middle::ty::{
121-
self as rustc_ty, Binder, BorrowKind, ClosureKind, EarlyBinder, FloatTy, GenericArgKind, GenericArgsRef, IntTy, Ty,
122-
TyCtxt, TypeFlags, TypeVisitableExt, UintTy, UpvarCapture,
120+
self as rustc_ty, Binder, BorrowKind, ClosureKind, EarlyBinder, GenericArgKind, GenericArgsRef, IntTy, Ty, TyCtxt,
121+
TypeFlags, TypeVisitableExt, UintTy, UpvarCapture,
123122
};
124123
use rustc_span::hygiene::{ExpnKind, MacroKind};
125124
use rustc_span::source_map::SourceMap;
@@ -132,7 +131,6 @@ use crate::consts::{ConstEvalCtxt, Constant, mir_to_const};
132131
use crate::higher::Range;
133132
use crate::ty::{adt_and_variant_of_res, can_partially_move_ty, expr_sig, is_copy, is_recursively_primitive_type};
134133
use crate::visitors::for_each_expr_without_closures;
135-
use rustc_middle::hir::nested_filter;
136134

137135
#[macro_export]
138136
macro_rules! extract_msrv_attr {
@@ -240,7 +238,7 @@ pub fn is_in_const_context(cx: &LateContext<'_>) -> bool {
240238
/// * const blocks (or inline consts)
241239
/// * associated constants
242240
pub fn is_inside_always_const_context(tcx: TyCtxt<'_>, hir_id: HirId) -> bool {
243-
use ConstContext::{Const, ConstFn, Static};
241+
use rustc_hir::ConstContext::{Const, ConstFn, Static};
244242
let Some(ctx) = tcx.hir_body_const_context(tcx.hir_enclosing_body_owner(hir_id)) else {
245243
return false;
246244
};
@@ -513,207 +511,6 @@ pub fn path_def_id<'tcx>(cx: &LateContext<'_>, maybe_path: &impl MaybePath<'tcx>
513511
path_res(cx, maybe_path).opt_def_id()
514512
}
515513

516-
fn find_primitive_impls(tcx: TyCtxt<'_>, name: Symbol) -> &[DefId] {
517-
let ty = match name {
518-
sym::bool => SimplifiedType::Bool,
519-
sym::char => SimplifiedType::Char,
520-
sym::str => SimplifiedType::Str,
521-
sym::array => SimplifiedType::Array,
522-
sym::slice => SimplifiedType::Slice,
523-
// FIXME: rustdoc documents these two using just `pointer`.
524-
//
525-
// Maybe this is something we should do here too.
526-
sym::const_ptr => SimplifiedType::Ptr(Mutability::Not),
527-
sym::mut_ptr => SimplifiedType::Ptr(Mutability::Mut),
528-
sym::isize => SimplifiedType::Int(IntTy::Isize),
529-
sym::i8 => SimplifiedType::Int(IntTy::I8),
530-
sym::i16 => SimplifiedType::Int(IntTy::I16),
531-
sym::i32 => SimplifiedType::Int(IntTy::I32),
532-
sym::i64 => SimplifiedType::Int(IntTy::I64),
533-
sym::i128 => SimplifiedType::Int(IntTy::I128),
534-
sym::usize => SimplifiedType::Uint(UintTy::Usize),
535-
sym::u8 => SimplifiedType::Uint(UintTy::U8),
536-
sym::u16 => SimplifiedType::Uint(UintTy::U16),
537-
sym::u32 => SimplifiedType::Uint(UintTy::U32),
538-
sym::u64 => SimplifiedType::Uint(UintTy::U64),
539-
sym::u128 => SimplifiedType::Uint(UintTy::U128),
540-
sym::f32 => SimplifiedType::Float(FloatTy::F32),
541-
sym::f64 => SimplifiedType::Float(FloatTy::F64),
542-
_ => return &[],
543-
};
544-
545-
tcx.incoherent_impls(ty)
546-
}
547-
548-
fn non_local_item_child_by_name(tcx: TyCtxt<'_>, def_id: DefId, ns: PathNS, name: Symbol) -> Option<DefId> {
549-
match tcx.def_kind(def_id) {
550-
DefKind::Mod | DefKind::Enum | DefKind::Trait => tcx.module_children(def_id).iter().find_map(|child| {
551-
if child.ident.name == name && ns.matches(child.res.ns()) {
552-
child.res.opt_def_id()
553-
} else {
554-
None
555-
}
556-
}),
557-
DefKind::Impl { .. } => tcx
558-
.associated_item_def_ids(def_id)
559-
.iter()
560-
.copied()
561-
.find(|assoc_def_id| tcx.item_name(*assoc_def_id) == name && ns.matches(tcx.def_kind(assoc_def_id).ns())),
562-
_ => None,
563-
}
564-
}
565-
566-
fn local_item_child_by_name(tcx: TyCtxt<'_>, local_id: LocalDefId, ns: PathNS, name: Symbol) -> Option<DefId> {
567-
let root_mod;
568-
let item_kind = match tcx.hir_node_by_def_id(local_id) {
569-
Node::Crate(r#mod) => {
570-
root_mod = ItemKind::Mod(Ident::dummy(), r#mod);
571-
&root_mod
572-
},
573-
Node::Item(item) => &item.kind,
574-
_ => return None,
575-
};
576-
577-
let res = |ident: Ident, owner_id: OwnerId| {
578-
if ident.name == name && ns.matches(tcx.def_kind(owner_id).ns()) {
579-
Some(owner_id.to_def_id())
580-
} else {
581-
None
582-
}
583-
};
584-
585-
match item_kind {
586-
ItemKind::Mod(_, r#mod) => r#mod.item_ids.iter().find_map(|&item_id| {
587-
let ident = tcx.hir_item(item_id).kind.ident()?;
588-
res(ident, item_id.owner_id)
589-
}),
590-
ItemKind::Impl(r#impl) => r#impl
591-
.items
592-
.iter()
593-
.find_map(|&ImplItemRef { ident, id, .. }| res(ident, id.owner_id)),
594-
ItemKind::Trait(.., trait_item_refs) => trait_item_refs
595-
.iter()
596-
.find_map(|&TraitItemRef { ident, id, .. }| res(ident, id.owner_id)),
597-
_ => None,
598-
}
599-
}
600-
601-
fn item_child_by_name(tcx: TyCtxt<'_>, def_id: DefId, ns: PathNS, name: Symbol) -> Option<DefId> {
602-
if let Some(local_id) = def_id.as_local() {
603-
local_item_child_by_name(tcx, local_id, ns, name)
604-
} else {
605-
non_local_item_child_by_name(tcx, def_id, ns, name)
606-
}
607-
}
608-
609-
/// Finds the crates called `name`, may be multiple due to multiple major versions.
610-
pub fn find_crates(tcx: TyCtxt<'_>, name: Symbol) -> &'static [DefId] {
611-
static BY_NAME: OnceLock<FxHashMap<Symbol, Vec<DefId>>> = OnceLock::new();
612-
let map = BY_NAME.get_or_init(|| {
613-
let mut map = FxHashMap::default();
614-
map.insert(tcx.crate_name(LOCAL_CRATE), vec![LOCAL_CRATE.as_def_id()]);
615-
for &num in tcx.crates(()) {
616-
map.entry(tcx.crate_name(num)).or_default().push(num.as_def_id());
617-
}
618-
map
619-
});
620-
match map.get(&name) {
621-
Some(def_ids) => def_ids,
622-
None => &[],
623-
}
624-
}
625-
626-
/// Specifies whether to resolve a path in the [`TypeNS`], [`ValueNS`], [`MacroNS`] or in an
627-
/// arbitrary namespace
628-
#[derive(Clone, Copy, PartialEq, Debug)]
629-
pub enum PathNS {
630-
Type,
631-
Value,
632-
Macro,
633-
634-
/// Resolves to the name in the first available namespace, e.g. for `std::vec` this would return
635-
/// either the macro or the module but **not** both
636-
///
637-
/// Must only be used when the specific resolution is unimportant such as in
638-
/// `missing_enforced_import_renames`
639-
Arbitrary,
640-
}
641-
642-
impl PathNS {
643-
fn matches(self, ns: Option<Namespace>) -> bool {
644-
let required = match self {
645-
PathNS::Type => TypeNS,
646-
PathNS::Value => ValueNS,
647-
PathNS::Macro => MacroNS,
648-
PathNS::Arbitrary => return true,
649-
};
650-
651-
ns == Some(required)
652-
}
653-
}
654-
655-
/// Resolves a def path like `std::vec::Vec`.
656-
///
657-
/// Typically it will return one [`DefId`] or none, but in some situations there can be multiple:
658-
/// - `memchr::memchr` could return the functions from both memchr 1.0 and memchr 2.0
659-
/// - `alloc::boxed::Box::downcast` would return a function for each of the different inherent impls
660-
/// ([1], [2], [3])
661-
///
662-
/// This function is expensive and should be used sparingly.
663-
///
664-
/// [1]: https://doc.rust-lang.org/std/boxed/struct.Box.html#method.downcast
665-
/// [2]: https://doc.rust-lang.org/std/boxed/struct.Box.html#method.downcast-1
666-
/// [3]: https://doc.rust-lang.org/std/boxed/struct.Box.html#method.downcast-2
667-
pub fn lookup_path(tcx: TyCtxt<'_>, ns: PathNS, path: &[Symbol]) -> Vec<DefId> {
668-
let (root, rest) = match *path {
669-
[] | [_] => return Vec::new(),
670-
[root, ref rest @ ..] => (root, rest),
671-
};
672-
673-
let mut out = Vec::new();
674-
for &base in find_crates(tcx, root).iter().chain(find_primitive_impls(tcx, root)) {
675-
lookup_path_with_base(tcx, base, ns, rest, &mut out);
676-
}
677-
out
678-
}
679-
680-
/// Resolves a def path like `vec::Vec` with the base `std`.
681-
fn lookup_path_with_base(tcx: TyCtxt<'_>, mut base: DefId, ns: PathNS, mut path: &[Symbol], out: &mut Vec<DefId>) {
682-
loop {
683-
match *path {
684-
[segment] => {
685-
out.extend(item_child_by_name(tcx, base, ns, segment));
686-
687-
// When the current def_id is e.g. `struct S`, check the impl items in
688-
// `impl S { ... }`
689-
let inherent_impl_children = tcx
690-
.inherent_impls(base)
691-
.iter()
692-
.filter_map(|&impl_def_id| item_child_by_name(tcx, impl_def_id, ns, segment));
693-
out.extend(inherent_impl_children);
694-
695-
return;
696-
},
697-
[segment, ref rest @ ..] => {
698-
path = rest;
699-
let Some(child) = item_child_by_name(tcx, base, PathNS::Type, segment) else {
700-
return;
701-
};
702-
base = child;
703-
},
704-
[] => unreachable!(),
705-
}
706-
}
707-
}
708-
709-
/// Equivalent to a [`lookup_path`] after splitting the input string on `::`
710-
///
711-
/// This function is expensive and should be used sparingly.
712-
pub fn lookup_path_str(tcx: TyCtxt<'_>, ns: PathNS, path: &str) -> Vec<DefId> {
713-
let path: Vec<Symbol> = path.split("::").map(Symbol::intern).collect();
714-
lookup_path(tcx, ns, &path)
715-
}
716-
717514
/// Gets the `hir::TraitRef` of the trait the given method is implemented for.
718515
///
719516
/// Use this if you want to find the `TraitRef` of the `Add` trait in this example:

0 commit comments

Comments
 (0)