Skip to content

Commit 8305908

Browse files
committed
Split def_path_res into two parts
1 parent 0e1ded0 commit 8305908

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
@@ -673,6 +673,17 @@ fn item_children_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Vec<Re
673673
}
674674
}
675675

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

710-
let starts = find_primitive_impls(tcx, base)
711-
.chain(find_crates(tcx, base_sym))
713+
let crates = find_primitive_impls(tcx, base)
712714
.chain(local_crate)
713-
.map(|id| Res::Def(tcx.def_kind(id), id));
715+
.map(|id| Res::Def(tcx.def_kind(id), id))
716+
.chain(find_crates(tcx, base_sym))
717+
.collect();
714718

715-
let mut resolutions: Vec<Res> = starts.collect();
719+
def_path_res_in_crates(tcx, crates, path)
720+
}
716721

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

721-
resolutions = resolutions
731+
crates = crates
722732
.into_iter()
723733
.filter_map(|res| res.opt_def_id())
724734
.flat_map(|def_id| {
@@ -737,7 +747,7 @@ pub fn def_path_res(tcx: TyCtxt<'_>, path: &[&str]) -> Vec<Res> {
737747
.collect();
738748
}
739749

740-
resolutions
750+
crates
741751
}
742752

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

0 commit comments

Comments
 (0)