Fix handling of item names for HIR
- Handle variants, fields, macros in `Node::ident()` - Handle the crate root in `opt_item_name` - Factor out `item_name_from_def_id` to reduce duplication - Look at HIR before the DefId for `opt_item_name` This gives accurate spans, which are not available from serialized metadata. - Don't panic on the crate root in `opt_item_name` - Add comments
This commit is contained in:
parent
dc06a36074
commit
67d0db6b00
3 changed files with 49 additions and 21 deletions
|
@ -2677,6 +2677,9 @@ impl<'hir> Node<'hir> {
|
||||||
Node::TraitItem(TraitItem { ident, .. })
|
Node::TraitItem(TraitItem { ident, .. })
|
||||||
| Node::ImplItem(ImplItem { ident, .. })
|
| Node::ImplItem(ImplItem { ident, .. })
|
||||||
| Node::ForeignItem(ForeignItem { ident, .. })
|
| Node::ForeignItem(ForeignItem { ident, .. })
|
||||||
|
| Node::Field(StructField { ident, .. })
|
||||||
|
| Node::Variant(Variant { ident, .. })
|
||||||
|
| Node::MacroDef(MacroDef { ident, .. })
|
||||||
| Node::Item(Item { ident, .. }) => Some(*ident),
|
| Node::Item(Item { ident, .. }) => Some(*ident),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
|
|
|
@ -478,7 +478,7 @@ impl<'hir> Map<'hir> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_if_local(&self, id: DefId) -> Option<Node<'hir>> {
|
pub fn get_if_local(&self, id: DefId) -> Option<Node<'hir>> {
|
||||||
id.as_local().map(|id| self.get(self.local_def_id_to_hir_id(id)))
|
id.as_local().and_then(|id| self.find(self.local_def_id_to_hir_id(id)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_generics(&self, id: DefId) -> Option<&'hir Generics<'hir>> {
|
pub fn get_generics(&self, id: DefId) -> Option<&'hir Generics<'hir>> {
|
||||||
|
|
|
@ -2795,10 +2795,52 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
.filter(|item| item.kind == AssocKind::Fn && item.defaultness.has_value())
|
.filter(|item| item.kind == AssocKind::Fn && item.defaultness.has_value())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn item_name_from_hir(self, def_id: DefId) -> Option<Ident> {
|
||||||
|
self.hir().get_if_local(def_id).and_then(|node| node.ident())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn item_name_from_def_id(self, def_id: DefId) -> Option<Symbol> {
|
||||||
|
if def_id.index == CRATE_DEF_INDEX {
|
||||||
|
Some(self.original_crate_name(def_id.krate))
|
||||||
|
} else {
|
||||||
|
let def_key = self.def_key(def_id);
|
||||||
|
match def_key.disambiguated_data.data {
|
||||||
|
// The name of a constructor is that of its parent.
|
||||||
|
rustc_hir::definitions::DefPathData::Ctor => self.item_name_from_def_id(DefId {
|
||||||
|
krate: def_id.krate,
|
||||||
|
index: def_key.parent.unwrap(),
|
||||||
|
}),
|
||||||
|
_ => def_key.disambiguated_data.data.get_opt_name(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Look up the name of an item across crates. This does not look at HIR.
|
||||||
|
///
|
||||||
|
/// When possible, this function should be used for cross-crate lookups over
|
||||||
|
/// [`opt_item_name`] to avoid invalidating the incremental cache. If you
|
||||||
|
/// need to handle items without a name, or HIR items that will not be
|
||||||
|
/// serialized cross-crate, or if you need the span of the item, use
|
||||||
|
/// [`opt_item_name`] instead.
|
||||||
|
///
|
||||||
|
/// [`opt_item_name`]: Self::opt_item_name
|
||||||
|
pub fn item_name(self, id: DefId) -> Symbol {
|
||||||
|
// Look at cross-crate items first to avoid invalidating the incremental cache
|
||||||
|
// unless we have to.
|
||||||
|
self.item_name_from_def_id(id)
|
||||||
|
.or_else(|| self.item_name_from_hir(id).map(|ident| ident.name))
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
bug!("item_name: no name for {:?}", self.def_path(id));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Look up the name and span of an item or [`Node`].
|
||||||
|
///
|
||||||
|
/// See [`item_name`][Self::item_name] for more information.
|
||||||
pub fn opt_item_name(self, def_id: DefId) -> Option<Ident> {
|
pub fn opt_item_name(self, def_id: DefId) -> Option<Ident> {
|
||||||
def_id
|
// Look at the HIR first so the span will be correct if this is a local item.
|
||||||
.as_local()
|
self.item_name_from_hir(def_id)
|
||||||
.and_then(|def_id| self.hir().get(self.hir().local_def_id_to_hir_id(def_id)).ident())
|
.or_else(|| self.item_name_from_def_id(def_id).map(Ident::with_dummy_span))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn opt_associated_item(self, def_id: DefId) -> Option<&'tcx AssocItem> {
|
pub fn opt_associated_item(self, def_id: DefId) -> Option<&'tcx AssocItem> {
|
||||||
|
@ -2921,23 +2963,6 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn item_name(self, id: DefId) -> Symbol {
|
|
||||||
if id.index == CRATE_DEF_INDEX {
|
|
||||||
self.original_crate_name(id.krate)
|
|
||||||
} else {
|
|
||||||
let def_key = self.def_key(id);
|
|
||||||
match def_key.disambiguated_data.data {
|
|
||||||
// The name of a constructor is that of its parent.
|
|
||||||
rustc_hir::definitions::DefPathData::Ctor => {
|
|
||||||
self.item_name(DefId { krate: id.krate, index: def_key.parent.unwrap() })
|
|
||||||
}
|
|
||||||
_ => def_key.disambiguated_data.data.get_opt_name().unwrap_or_else(|| {
|
|
||||||
bug!("item_name: no name for {:?}", self.def_path(id));
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the possibly-auto-generated MIR of a `(DefId, Subst)` pair.
|
/// Returns the possibly-auto-generated MIR of a `(DefId, Subst)` pair.
|
||||||
pub fn instance_mir(self, instance: ty::InstanceDef<'tcx>) -> &'tcx Body<'tcx> {
|
pub fn instance_mir(self, instance: ty::InstanceDef<'tcx>) -> &'tcx Body<'tcx> {
|
||||||
match instance {
|
match instance {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue