diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index b9ec18688c5f2..3c72937ad3134 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2677,6 +2677,9 @@ impl<'hir> Node<'hir> { Node::TraitItem(TraitItem { ident, .. }) | Node::ImplItem(ImplItem { ident, .. }) | Node::ForeignItem(ForeignItem { ident, .. }) + | Node::Field(StructField { ident, .. }) + | Node::Variant(Variant { ident, .. }) + | Node::MacroDef(MacroDef { ident, .. }) | Node::Item(Item { ident, .. }) => Some(*ident), _ => None, } diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 106fa8c78fa28..d86e898719557 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -478,7 +478,7 @@ impl<'hir> Map<'hir> { } pub fn get_if_local(&self, id: DefId) -> Option> { - 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>> { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index aa5a696b09c3b..0042b4a3a4279 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2795,10 +2795,50 @@ impl<'tcx> TyCtxt<'tcx> { .filter(|item| item.kind == AssocKind::Fn && item.defaultness.has_value()) } + fn item_name_from_hir(self, def_id: DefId) -> Option { + self.hir().get_if_local(def_id).and_then(|node| node.ident()) + } + + fn item_name_from_def_id(self, def_id: DefId) -> Option { + 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).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 { - def_id - .as_local() - .and_then(|def_id| self.hir().get(self.hir().local_def_id_to_hir_id(def_id)).ident()) + // Look at the HIR first so the span will be correct if this is a local item. + self.item_name_from_hir(def_id) + .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> { @@ -2921,23 +2961,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. pub fn instance_mir(self, instance: ty::InstanceDef<'tcx>) -> &'tcx Body<'tcx> { match instance {