Split def_path_res into two parts
This commit is contained in:
parent
43e3384581
commit
d099ceddad
|
@ -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`.
|
/// Resolves a def path like `std::vec::Vec`.
|
||||||
///
|
///
|
||||||
/// Can return multiple resolutions when there are multiple versions of the same crate, e.g.
|
/// 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.
|
/// This function is expensive and should be used sparingly.
|
||||||
pub fn def_path_res(tcx: TyCtxt<'_>, path: &[&str]) -> Vec<Res> {
|
pub fn def_path_res(tcx: TyCtxt<'_>, path: &[&str]) -> Vec<Res> {
|
||||||
fn find_crates(tcx: TyCtxt<'_>, name: Symbol) -> impl Iterator<Item = DefId> + '_ {
|
let (base, path) = match *path {
|
||||||
tcx.crates(())
|
|
||||||
.iter()
|
|
||||||
.copied()
|
|
||||||
.filter(move |&num| tcx.crate_name(num) == name)
|
|
||||||
.map(CrateNum::as_def_id)
|
|
||||||
}
|
|
||||||
|
|
||||||
let (base, mut path) = match *path {
|
|
||||||
[primitive] => {
|
[primitive] => {
|
||||||
return vec![PrimTy::from_name(Symbol::intern(primitive)).map_or(Res::Err, Res::PrimTy)];
|
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
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let starts = find_primitive_impls(tcx, base)
|
let crates = find_primitive_impls(tcx, base)
|
||||||
.chain(find_crates(tcx, base_sym))
|
|
||||||
.chain(local_crate)
|
.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 {
|
while let [segment, rest @ ..] = path {
|
||||||
path = rest;
|
path = rest;
|
||||||
let segment = Symbol::intern(segment);
|
let segment = Symbol::intern(segment);
|
||||||
|
|
||||||
resolutions = resolutions
|
base = base
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|res| res.opt_def_id())
|
.filter_map(|res| res.opt_def_id())
|
||||||
.flat_map(|def_id| {
|
.flat_map(|def_id| {
|
||||||
|
@ -735,7 +745,7 @@ pub fn def_path_res(tcx: TyCtxt<'_>, path: &[&str]) -> Vec<Res> {
|
||||||
.collect();
|
.collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
resolutions
|
base
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resolves a def path like `std::vec::Vec` to its [`DefId`]s, see [`def_path_res`].
|
/// Resolves a def path like `std::vec::Vec` to its [`DefId`]s, see [`def_path_res`].
|
||||||
|
|
Loading…
Reference in New Issue