Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix handling of item names for HIR #78345

Merged
merged 2 commits into from
Nov 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/hir/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ impl<'hir> Map<'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>> {
Expand Down
63 changes: 43 additions & 20 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<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).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> {
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> {
Expand Down Expand Up @@ -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 {
Expand Down