mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 15:23:46 +00:00
refactor try_resolve_did and also support resolving crates/modules
This commit is contained in:
parent
0822c311fb
commit
245857beb7
@ -74,38 +74,66 @@ const UNIX_IO_ERROR_TABLE: &[(&str, std::io::ErrorKind)] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Gets an instance for a path.
|
/// Gets an instance for a path.
|
||||||
fn try_resolve_did<'tcx>(tcx: TyCtxt<'tcx>, path: &[&str], namespace: Namespace) -> Option<DefId> {
|
///
|
||||||
tcx.crates(()).iter().find(|&&krate| tcx.crate_name(krate).as_str() == path[0]).and_then(
|
/// A `None` namespace indicates we are looking for a module.
|
||||||
|krate| {
|
fn try_resolve_did<'tcx>(
|
||||||
let krate = DefId { krate: *krate, index: CRATE_DEF_INDEX };
|
tcx: TyCtxt<'tcx>,
|
||||||
let mut items = tcx.module_children(krate);
|
path: &[&str],
|
||||||
|
namespace: Option<Namespace>,
|
||||||
|
) -> Option<DefId> {
|
||||||
|
/// Yield all children of the given item, that have the given name.
|
||||||
|
fn find_children<'tcx: 'a, 'a>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
item: DefId,
|
||||||
|
name: &'a str,
|
||||||
|
) -> impl Iterator<Item = DefId> + 'a {
|
||||||
|
tcx.module_children(item)
|
||||||
|
.iter()
|
||||||
|
.filter(move |item| item.ident.name.as_str() == name)
|
||||||
|
.map(move |item| item.res.def_id())
|
||||||
|
}
|
||||||
|
|
||||||
for &segment in &path[1..path.len() - 1] {
|
// Take apart the path: leading crate, a sequence of modules, and potentially a final item.
|
||||||
let next_mod = items.iter().find(|item| {
|
let (&crate_name, path) = path.split_first().expect("paths must have at least one segment");
|
||||||
item.ident.name.as_str() == segment
|
let (modules, item) = if let Some(namespace) = namespace {
|
||||||
&& tcx.def_kind(item.res.def_id()) == DefKind::Mod
|
let (&item_name, modules) =
|
||||||
})?;
|
path.split_last().expect("non-module paths must have at least 2 segments");
|
||||||
|
(modules, Some((item_name, namespace)))
|
||||||
|
} else {
|
||||||
|
(path, None)
|
||||||
|
};
|
||||||
|
|
||||||
items = tcx.module_children(next_mod.res.def_id());
|
// First find the crate.
|
||||||
}
|
let krate =
|
||||||
|
tcx.crates(()).iter().find(|&&krate| tcx.crate_name(krate).as_str() == crate_name)?;
|
||||||
let item_name = *path.last().unwrap();
|
let mut cur_item = DefId { krate: *krate, index: CRATE_DEF_INDEX };
|
||||||
|
// Then go over the modules.
|
||||||
let item = items.iter().find(|item| {
|
for &segment in modules {
|
||||||
item.ident.name.as_str() == item_name
|
cur_item = find_children(tcx, cur_item, segment)
|
||||||
&& tcx.def_kind(item.res.def_id()).ns() == Some(namespace)
|
.find(|item| tcx.def_kind(item) == DefKind::Mod)?;
|
||||||
})?;
|
}
|
||||||
|
// Finally, look up the desired item in this module, if any.
|
||||||
Some(item.res.def_id())
|
match item {
|
||||||
},
|
Some((item_name, namespace)) =>
|
||||||
)
|
Some(
|
||||||
|
find_children(tcx, cur_item, item_name)
|
||||||
|
.find(|item| tcx.def_kind(item).ns() == Some(namespace))?,
|
||||||
|
),
|
||||||
|
None => Some(cur_item),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
|
/// Checks if the given crate/module exists.
|
||||||
|
fn have_module(&self, path: &[&str]) -> bool {
|
||||||
|
try_resolve_did(*self.eval_context_ref().tcx, path, None).is_some()
|
||||||
|
}
|
||||||
|
|
||||||
/// Gets an instance for a path; fails gracefully if the path does not exist.
|
/// Gets an instance for a path; fails gracefully if the path does not exist.
|
||||||
fn try_resolve_path(&self, path: &[&str], namespace: Namespace) -> Option<ty::Instance<'tcx>> {
|
fn try_resolve_path(&self, path: &[&str], namespace: Namespace) -> Option<ty::Instance<'tcx>> {
|
||||||
let did = try_resolve_did(self.eval_context_ref().tcx.tcx, path, namespace)?;
|
let tcx = self.eval_context_ref().tcx.tcx;
|
||||||
Some(ty::Instance::mono(self.eval_context_ref().tcx.tcx, did))
|
let did = try_resolve_did(tcx, path, Some(namespace))?;
|
||||||
|
Some(ty::Instance::mono(tcx, did))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets an instance for a path.
|
/// Gets an instance for a path.
|
||||||
|
Loading…
Reference in New Issue
Block a user