about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGnomedDev <david2005thomas@gmail.com>2024-09-21 16:11:15 +0100
committerGnomedDev <david2005thomas@gmail.com>2024-09-23 08:58:32 +0100
commitd099ceddadde4197b08c2de404100a627d3ba605 (patch)
tree6bc0584a448d33b8014b4cc5aba3e385ddaca713
parent43e338458168db91b8459735ba6ac0f230d78d92 (diff)
downloadrust-d099ceddadde4197b08c2de404100a627d3ba605.tar.gz
rust-d099ceddadde4197b08c2de404100a627d3ba605.zip
Split def_path_res into two parts
-rw-r--r--clippy_utils/src/lib.rs40
1 files changed, 25 insertions, 15 deletions
diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs
index a925549b0bf..2fee6473910 100644
--- a/clippy_utils/src/lib.rs
+++ b/clippy_utils/src/lib.rs
@@ -671,6 +671,17 @@ fn item_children_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Vec<Re
     }
 }
 
+/// Finds the crates called `name`, may be multiple due to multiple major versions.
+pub fn find_crates(tcx: TyCtxt<'_>, name: Symbol) -> Vec<Res> {
+    tcx.crates(())
+        .iter()
+        .copied()
+        .filter(move |&num| tcx.crate_name(num) == name)
+        .map(CrateNum::as_def_id)
+        .map(|id| Res::Def(tcx.def_kind(id), id))
+        .collect()
+}
+
 /// Resolves a def path like `std::vec::Vec`.
 ///
 /// 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
 ///
 /// This function is expensive and should be used sparingly.
 pub fn def_path_res(tcx: TyCtxt<'_>, path: &[&str]) -> Vec<Res> {
-    fn find_crates(tcx: TyCtxt<'_>, name: Symbol) -> impl Iterator<Item = DefId> + '_ {
-        tcx.crates(())
-            .iter()
-            .copied()
-            .filter(move |&num| tcx.crate_name(num) == name)
-            .map(CrateNum::as_def_id)
-    }
-
-    let (base, mut path) = match *path {
+    let (base, path) = match *path {
         [primitive] => {
             return vec![PrimTy::from_name(Symbol::intern(primitive)).map_or(Res::Err, Res::PrimTy)];
         },
@@ -705,18 +708,25 @@ pub fn def_path_res(tcx: TyCtxt<'_>, path: &[&str]) -> Vec<Res> {
         None
     };
 
-    let starts = find_primitive_impls(tcx, base)
-        .chain(find_crates(tcx, base_sym))
+    let crates = find_primitive_impls(tcx, base)
         .chain(local_crate)
-        .map(|id| Res::Def(tcx.def_kind(id), id));
+        .map(|id| Res::Def(tcx.def_kind(id), id))
+        .chain(find_crates(tcx, base_sym))
+        .collect();
 
-    let mut resolutions: Vec<Res> = starts.collect();
+    def_path_res_with_base(tcx, crates, path)
+}
 
+/// Resolves a def path like `vec::Vec` with the base `std`.
+///
+/// This is lighter than [`def_path_res`], and should be called with [`find_crates`] looking up
+/// items from the same crate repeatedly, although should still be used sparingly.
+pub fn def_path_res_with_base(tcx: TyCtxt<'_>, mut base: Vec<Res>, mut path: &[&str]) -> Vec<Res> {
     while let [segment, rest @ ..] = path {
         path = rest;
         let segment = Symbol::intern(segment);
 
-        resolutions = resolutions
+        base = base
             .into_iter()
             .filter_map(|res| res.opt_def_id())
             .flat_map(|def_id| {
@@ -735,7 +745,7 @@ pub fn def_path_res(tcx: TyCtxt<'_>, path: &[&str]) -> Vec<Res> {
             .collect();
     }
 
-    resolutions
+    base
 }
 
 /// Resolves a def path like `std::vec::Vec` to its [`DefId`]s, see [`def_path_res`].