Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit d099ced

Browse files
committed
Split def_path_res into two parts
1 parent 43e3384 commit d099ced

File tree

1 file changed

+25
-15
lines changed

1 file changed

+25
-15
lines changed

clippy_utils/src/lib.rs

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,17 @@ fn item_children_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Vec<Re
671671
}
672672
}
673673

674+
/// Finds the crates called `name`, may be multiple due to multiple major versions.
675+
pub fn find_crates(tcx: TyCtxt<'_>, name: Symbol) -> Vec<Res> {
676+
tcx.crates(())
677+
.iter()
678+
.copied()
679+
.filter(move |&num| tcx.crate_name(num) == name)
680+
.map(CrateNum::as_def_id)
681+
.map(|id| Res::Def(tcx.def_kind(id), id))
682+
.collect()
683+
}
684+
674685
/// Resolves a def path like `std::vec::Vec`.
675686
///
676687
/// Can return multiple resolutions when there are multiple versions of the same crate, e.g.
@@ -681,15 +692,7 @@ fn item_children_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Vec<Re
681692
///
682693
/// This function is expensive and should be used sparingly.
683694
pub fn def_path_res(tcx: TyCtxt<'_>, path: &[&str]) -> Vec<Res> {
684-
fn find_crates(tcx: TyCtxt<'_>, name: Symbol) -> impl Iterator<Item = DefId> + '_ {
685-
tcx.crates(())
686-
.iter()
687-
.copied()
688-
.filter(move |&num| tcx.crate_name(num) == name)
689-
.map(CrateNum::as_def_id)
690-
}
691-
692-
let (base, mut path) = match *path {
695+
let (base, path) = match *path {
693696
[primitive] => {
694697
return vec![PrimTy::from_name(Symbol::intern(primitive)).map_or(Res::Err, Res::PrimTy)];
695698
},
@@ -705,18 +708,25 @@ pub fn def_path_res(tcx: TyCtxt<'_>, path: &[&str]) -> Vec<Res> {
705708
None
706709
};
707710

708-
let starts = find_primitive_impls(tcx, base)
709-
.chain(find_crates(tcx, base_sym))
711+
let crates = find_primitive_impls(tcx, base)
710712
.chain(local_crate)
711-
.map(|id| Res::Def(tcx.def_kind(id), id));
713+
.map(|id| Res::Def(tcx.def_kind(id), id))
714+
.chain(find_crates(tcx, base_sym))
715+
.collect();
712716

713-
let mut resolutions: Vec<Res> = starts.collect();
717+
def_path_res_with_base(tcx, crates, path)
718+
}
714719

720+
/// Resolves a def path like `vec::Vec` with the base `std`.
721+
///
722+
/// This is lighter than [`def_path_res`], and should be called with [`find_crates`] looking up
723+
/// items from the same crate repeatedly, although should still be used sparingly.
724+
pub fn def_path_res_with_base(tcx: TyCtxt<'_>, mut base: Vec<Res>, mut path: &[&str]) -> Vec<Res> {
715725
while let [segment, rest @ ..] = path {
716726
path = rest;
717727
let segment = Symbol::intern(segment);
718728

719-
resolutions = resolutions
729+
base = base
720730
.into_iter()
721731
.filter_map(|res| res.opt_def_id())
722732
.flat_map(|def_id| {
@@ -735,7 +745,7 @@ pub fn def_path_res(tcx: TyCtxt<'_>, path: &[&str]) -> Vec<Res> {
735745
.collect();
736746
}
737747

738-
resolutions
748+
base
739749
}
740750

741751
/// Resolves a def path like `std::vec::Vec` to its [`DefId`]s, see [`def_path_res`].

0 commit comments

Comments
 (0)