Use ItemId as a strongly typed index.

This commit is contained in:
Camille GILLOT 2021-01-30 12:06:04 +01:00
parent ac8961fc04
commit c676e358a5
28 changed files with 63 additions and 51 deletions

View File

@ -58,8 +58,8 @@ impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> {
self.lctx.with_hir_id_owner(item.id, |lctx| {
lctx.without_in_scope_lifetime_defs(|lctx| {
if let Some(hir_item) = lctx.lower_item(item) {
item_hir_id = Some(hir_item.hir_id);
lctx.insert_item(hir_item);
let id = lctx.insert_item(hir_item);
item_hir_id = Some(id);
}
})
});
@ -128,7 +128,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// only used when lowering a child item of a trait or impl.
fn with_parent_item_lifetime_defs<T>(
&mut self,
parent_hir_id: hir::HirId,
parent_hir_id: hir::ItemId,
f: impl FnOnce(&mut LoweringContext<'_, '_>) -> T,
) -> T {
let old_len = self.in_scope_lifetimes.len();

View File

@ -99,7 +99,7 @@ struct LoweringContext<'a, 'hir: 'a> {
arena: &'hir Arena<'hir>,
/// The items being lowered are collected here.
items: BTreeMap<hir::HirId, hir::Item<'hir>>,
items: BTreeMap<hir::ItemId, hir::Item<'hir>>,
trait_items: BTreeMap<hir::TraitItemId, hir::TraitItem<'hir>>,
impl_items: BTreeMap<hir::ImplItemId, hir::ImplItem<'hir>>,
@ -605,12 +605,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
}
fn insert_item(&mut self, item: hir::Item<'hir>) {
fn insert_item(&mut self, item: hir::Item<'hir>) -> hir::ItemId {
let id = item.hir_id;
// FIXME: Use `debug_asset-rt`.
assert_eq!(id.local_id, hir::ItemLocalId::from_u32(0));
let id = hir::ItemId { id };
self.items.insert(id, item);
self.modules.get_mut(&self.current_module).unwrap().items.insert(id);
id
}
fn allocate_hir_id_counter(&mut self, owner: NodeId) -> hir::HirId {

View File

@ -619,7 +619,7 @@ pub struct WhereEqPredicate<'hir> {
pub struct ModuleItems {
// Use BTreeSets here so items are in the same order as in the
// list of all items in Crate
pub items: BTreeSet<HirId>,
pub items: BTreeSet<ItemId>,
pub trait_items: BTreeSet<TraitItemId>,
pub impl_items: BTreeSet<ImplItemId>,
pub foreign_items: BTreeSet<ForeignItemId>,
@ -652,7 +652,7 @@ pub struct Crate<'hir> {
// does, because it can affect the order in which errors are
// detected, which in turn can make UI tests yield
// slightly different results.
pub items: BTreeMap<HirId, Item<'hir>>,
pub items: BTreeMap<ItemId, Item<'hir>>,
pub trait_items: BTreeMap<TraitItemId, TraitItem<'hir>>,
pub impl_items: BTreeMap<ImplItemId, ImplItem<'hir>>,
@ -677,7 +677,7 @@ pub struct Crate<'hir> {
}
impl Crate<'hir> {
pub fn item(&self, id: HirId) -> &Item<'hir> {
pub fn item(&self, id: ItemId) -> &Item<'hir> {
&self.items[&id]
}
@ -2541,7 +2541,7 @@ impl VariantData<'hir> {
// The bodies for items are stored "out of line", in a separate
// hashmap in the `Crate`. Here we just record the hir-id of the item
// so it can fetched later.
#[derive(Copy, Clone, Encodable, Debug)]
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Debug)]
pub struct ItemId {
pub id: HirId,
}

View File

@ -133,7 +133,7 @@ pub trait Map<'hir> {
/// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found.
fn find(&self, hir_id: HirId) -> Option<Node<'hir>>;
fn body(&self, id: BodyId) -> &'hir Body<'hir>;
fn item(&self, id: HirId) -> &'hir Item<'hir>;
fn item(&self, id: ItemId) -> &'hir Item<'hir>;
fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir>;
fn impl_item(&self, id: ImplItemId) -> &'hir ImplItem<'hir>;
fn foreign_item(&self, id: ForeignItemId) -> &'hir ForeignItem<'hir>;
@ -150,7 +150,7 @@ impl<'hir> Map<'hir> for ErasedMap<'hir> {
fn body(&self, id: BodyId) -> &'hir Body<'hir> {
self.0.body(id)
}
fn item(&self, id: HirId) -> &'hir Item<'hir> {
fn item(&self, id: ItemId) -> &'hir Item<'hir> {
self.0.item(id)
}
fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir> {
@ -269,7 +269,7 @@ pub trait Visitor<'v>: Sized {
/// reason to override this method is if you want a nested pattern
/// but cannot supply a `Map`; see `nested_visit_map` for advice.
fn visit_nested_item(&mut self, id: ItemId) {
let opt_item = self.nested_visit_map().inter().map(|map| map.item(id.id));
let opt_item = self.nested_visit_map().inter().map(|map| map.item(id));
walk_list!(self, visit_item, opt_item);
}

View File

@ -34,6 +34,15 @@ impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for HirId {
}
}
impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for ItemId {
type KeyType = (DefPathHash, ItemLocalId);
#[inline]
fn to_stable_hash_key(&self, hcx: &HirCtx) -> (DefPathHash, ItemLocalId) {
self.id.to_stable_hash_key(hcx)
}
}
impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for TraitItemId {
type KeyType = (DefPathHash, ItemLocalId);

View File

@ -54,7 +54,7 @@ pub const NO_ANN: &dyn PpAnn = &NoAnn;
impl PpAnn for hir::Crate<'_> {
fn nested(&self, state: &mut State<'_>, nested: Nested) {
match nested {
Nested::Item(id) => state.print_item(self.item(id.id)),
Nested::Item(id) => state.print_item(self.item(id)),
Nested::TraitItem(id) => state.print_trait_item(self.trait_item(id)),
Nested::ImplItem(id) => state.print_impl_item(self.impl_item(id)),
Nested::ForeignItem(id) => state.print_foreign_item(self.foreign_item(id)),
@ -69,7 +69,7 @@ impl PpAnn for hir::Crate<'_> {
impl PpAnn for &dyn rustc_hir::intravisit::Map<'_> {
fn nested(&self, state: &mut State<'_>, nested: Nested) {
match nested {
Nested::Item(id) => state.print_item(self.item(id.id)),
Nested::Item(id) => state.print_item(self.item(id)),
Nested::TraitItem(id) => state.print_trait_item(self.trait_item(id)),
Nested::ImplItem(id) => state.print_impl_item(self.impl_item(id)),
Nested::ForeignItem(id) => state.print_foreign_item(self.foreign_item(id)),

View File

@ -234,7 +234,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
}
match fn_return.kind {
TyKind::OpaqueDef(item_id, _) => {
let item = tcx.hir().item(item_id.id);
let item = tcx.hir().item(item_id);
let opaque = if let ItemKind::OpaqueTy(opaque) = &item.kind {
opaque
} else {

View File

@ -178,7 +178,7 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
}
fn visit_stmt(&mut self, s: &'tcx hir::Stmt<'tcx>) {
let get_item = |id: hir::ItemId| self.context.tcx.hir().item(id.id);
let get_item = |id: hir::ItemId| self.context.tcx.hir().item(id);
let attrs = &s.kind.attrs(get_item);
// See `EarlyContextAndPass::visit_stmt` for an explanation
// of why we call `walk_stmt` outside of `with_lint_attrs`

View File

@ -309,7 +309,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
fn visit_nested_item(&mut self, item: ItemId) {
debug!("visit_nested_item: {:?}", item);
self.visit_item(self.krate.item(item.id));
self.visit_item(self.krate.item(item));
}
fn visit_nested_trait_item(&mut self, item_id: TraitItemId) {

View File

@ -300,8 +300,8 @@ impl<'hir> Map<'hir> {
self.find_entry(id).unwrap()
}
pub fn item(&self, id: HirId) -> &'hir Item<'hir> {
match self.find(id).unwrap() {
pub fn item(&self, id: ItemId) -> &'hir Item<'hir> {
match self.find(id.id).unwrap() {
Node::Item(item) => item,
_ => bug!(),
}
@ -479,19 +479,19 @@ impl<'hir> Map<'hir> {
let module = self.tcx.hir_module_items(module);
for id in &module.items {
visitor.visit_item(self.expect_item(*id));
visitor.visit_item(self.item(*id));
}
for id in &module.trait_items {
visitor.visit_trait_item(self.expect_trait_item(id.hir_id));
visitor.visit_trait_item(self.trait_item(*id));
}
for id in &module.impl_items {
visitor.visit_impl_item(self.expect_impl_item(id.hir_id));
visitor.visit_impl_item(self.impl_item(*id));
}
for id in &module.foreign_items {
visitor.visit_foreign_item(self.expect_foreign_item(id.hir_id));
visitor.visit_foreign_item(self.foreign_item(*id));
}
}
@ -863,7 +863,7 @@ impl<'hir> Map<'hir> {
Node::Variant(ref v) => &v.attrs[..],
Node::Field(ref f) => &f.attrs[..],
Node::Expr(ref e) => &*e.attrs,
Node::Stmt(ref s) => s.kind.attrs(|id| self.item(id.id)),
Node::Stmt(ref s) => s.kind.attrs(|id| self.item(id)),
Node::Arm(ref a) => &*a.attrs,
Node::GenericParam(param) => &param.attrs[..],
// Unit/tuple structs/variants take the attributes straight from
@ -977,7 +977,7 @@ impl<'hir> intravisit::Map<'hir> for Map<'hir> {
self.body(id)
}
fn item(&self, id: HirId) -> &'hir Item<'hir> {
fn item(&self, id: ItemId) -> &'hir Item<'hir> {
self.item(id)
}

View File

@ -55,7 +55,7 @@ impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> {
let item_ids_hash = item_ids
.iter()
.map(|id| {
let (def_path_hash, local_id) = id.id.to_stable_hash_key(hcx);
let (def_path_hash, local_id) = id.to_stable_hash_key(hcx);
debug_assert_eq!(local_id, hir::ItemLocalId::from_u32(0));
def_path_hash.0
})

View File

@ -289,7 +289,7 @@ impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor<'v> {
}
hir::TyKind::OpaqueDef(item_id, _) => {
self.0.push(ty);
let item = self.1.expect_item(item_id.id);
let item = self.1.item(item_id);
hir::intravisit::walk_item(self, item);
}
_ => {}

View File

@ -767,7 +767,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
let hir = self.infcx.tcx.hir();
if let hir::TyKind::OpaqueDef(id, _) = hir_ty.kind {
let opaque_ty = hir.item(id.id);
let opaque_ty = hir.item(id);
if let hir::ItemKind::OpaqueTy(hir::OpaqueTy {
bounds:
[hir::GenericBound::LangItemTrait(

View File

@ -329,7 +329,7 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
if let TyKind::OpaqueDef(item_id, _) = ty.kind {
let item = self.tcx.hir().expect_item(item_id.id);
let item = self.tcx.hir().item(item_id);
intravisit::walk_item(self, item);
}
intravisit::walk_ty(self, ty);

View File

@ -100,7 +100,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
}
fn visit_nested_item(&mut self, id: hir::ItemId) {
let nested_item = self.krate.unwrap().item(id.id);
let nested_item = self.krate.unwrap().item(id);
self.visit_item(nested_item)
}

View File

@ -588,8 +588,8 @@ impl EmbargoVisitor<'tcx> {
.map(|module_hir_id| self.tcx.hir().expect_item(module_hir_id))
{
if let hir::ItemKind::Mod(m) = &item.kind {
for item_id in m.item_ids {
let item = self.tcx.hir().expect_item(item_id.id);
for &item_id in m.item_ids {
let item = self.tcx.hir().item(item_id);
let def_id = self.tcx.hir().local_def_id(item_id.id);
if !self.tcx.hygienic_eq(segment.ident, item.ident, def_id.to_def_id()) {
continue;

View File

@ -587,7 +587,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
// `type MyAnonTy<'b> = impl MyTrait<'b>;`
// ^ ^ this gets resolved in the scope of
// the opaque_ty generics
let opaque_ty = self.tcx.hir().expect_item(item_id.id);
let opaque_ty = self.tcx.hir().item(item_id);
let (generics, bounds) = match opaque_ty.kind {
// Named opaque `impl Trait` types are reached via `TyKind::Path`.
// This arm is for `impl Trait` in the types of statics, constants and locals.
@ -632,11 +632,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
// Ensure that the parent of the def is an item, not HRTB
let parent_id = self.tcx.hir().get_parent_node(hir_id);
let parent_item_id = hir::ItemId { id: parent_id };
let parent_impl_id = hir::ImplItemId { hir_id: parent_id };
let parent_trait_id = hir::TraitItemId { hir_id: parent_id };
let krate = self.tcx.hir().krate();
if !(krate.items.contains_key(&parent_id)
if !(krate.items.contains_key(&parent_item_id)
|| krate.impl_items.contains_key(&parent_impl_id)
|| krate.trait_items.contains_key(&parent_trait_id))
{

View File

@ -1382,7 +1382,7 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> {
});
}
hir::TyKind::OpaqueDef(item_id, _) => {
let item = self.tcx.hir().item(item_id.id);
let item = self.tcx.hir().item(item_id);
self.nest_typeck_results(self.tcx.hir().local_def_id(item_id.id), |v| {
v.visit_item(item)
});

View File

@ -317,7 +317,7 @@ impl<'hir> Sig for hir::Ty<'hir> {
Ok(replace_text(nested_ty, text))
}
hir::TyKind::OpaqueDef(item_id, _) => {
let item = scx.tcx.hir().item(item_id.id);
let item = scx.tcx.hir().item(item_id);
item.make(offset, Some(item_id.id), scx)
}
hir::TyKind::Typeof(_) | hir::TyKind::Infer | hir::TyKind::Err => Err("Ty"),

View File

@ -2210,7 +2210,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
self.res_to_ty(opt_self_ty, path, false)
}
hir::TyKind::OpaqueDef(item_id, ref lifetimes) => {
let opaque_ty = tcx.hir().expect_item(item_id.id);
let opaque_ty = tcx.hir().item(item_id);
let def_id = tcx.hir().local_def_id(item_id.id).to_def_id();
match opaque_ty.kind {

View File

@ -1445,8 +1445,8 @@ impl intravisit::Visitor<'tcx> for UsePlacementFinder<'tcx> {
return;
}
// Find a `use` statement.
for item_id in module.item_ids {
let item = self.tcx.hir().expect_item(item_id.id);
for &item_id in module.item_ids {
let item = self.tcx.hir().item(item_id);
match item.kind {
hir::ItemKind::Use(..) => {
// Don't suggest placing a `use` before the prelude

View File

@ -133,7 +133,7 @@ impl Clean<ExternalCrate> for CrateNum {
.item_ids
.iter()
.filter_map(|&id| {
let item = cx.tcx.hir().expect_item(id.id);
let item = cx.tcx.hir().item(id);
match item.kind {
hir::ItemKind::Mod(_) => as_primitive(Res::Def(
DefKind::Mod,
@ -185,7 +185,7 @@ impl Clean<ExternalCrate> for CrateNum {
.item_ids
.iter()
.filter_map(|&id| {
let item = cx.tcx.hir().expect_item(id.id);
let item = cx.tcx.hir().item(id);
match item.kind {
hir::ItemKind::Mod(_) => as_keyword(Res::Def(
DefKind::Mod,
@ -1475,7 +1475,7 @@ impl Clean<Type> for hir::Ty<'_> {
}
TyKind::Tup(ref tys) => Tuple(tys.clean(cx)),
TyKind::OpaqueDef(item_id, _) => {
let item = cx.tcx.hir().expect_item(item_id.id);
let item = cx.tcx.hir().item(item_id);
if let hir::ItemKind::OpaqueTy(ref ty) = item.kind {
ImplTrait(ty.bounds.clean(cx))
} else {

View File

@ -132,8 +132,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
// Keep track of if there were any private modules in the path.
let orig_inside_public_path = self.inside_public_path;
self.inside_public_path &= vis.node.is_pub();
for i in m.item_ids {
let item = self.cx.tcx.hir().expect_item(i.id);
for &i in m.item_ids {
let item = self.cx.tcx.hir().item(i);
self.visit_item(item, None, &mut om);
}
self.inside_public_path = orig_inside_public_path;
@ -231,8 +231,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
let ret = match tcx.hir().get(res_hir_id) {
Node::Item(&hir::Item { kind: hir::ItemKind::Mod(ref m), .. }) if glob => {
let prev = mem::replace(&mut self.inlining, true);
for i in m.item_ids {
let i = self.cx.tcx.hir().expect_item(i.id);
for &i in m.item_ids {
let i = self.cx.tcx.hir().item(i);
self.visit_item(i, None, om);
}
self.inlining = prev;

View File

@ -375,7 +375,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
match ty.kind {
TyKind::OpaqueDef(item, _) => {
let map = self.cx.tcx.hir();
let item = map.expect_item(item.id);
let item = map.item(item);
walk_item(self, item);
walk_ty(self, ty);
},

View File

@ -102,7 +102,7 @@ fn future_trait_ref<'tcx>(
) -> Option<(&'tcx TraitRef<'tcx>, Vec<LifetimeName>)> {
if_chain! {
if let TyKind::OpaqueDef(item_id, bounds) = ty.kind;
let item = cx.tcx.hir().item(item_id.id);
let item = cx.tcx.hir().item(item_id);
if let ItemKind::OpaqueTy(opaque) = &item.kind;
if let Some(trait_ref) = opaque.bounds.iter().find_map(|bound| {
if let GenericBound::Trait(poly, _) = bound {

View File

@ -107,7 +107,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
// trait method with default body needs inline in case
// an impl is not provided
let desc = "a default trait method";
let item = cx.tcx.hir().expect_trait_item(tit.id.hir_id);
let item = cx.tcx.hir().trait_item(tit.id);
check_missing_inline_attrs(cx, &item.attrs, item.span, desc);
}
},

View File

@ -130,7 +130,7 @@ impl<'tcx> LateLintPass<'tcx> for Author {
}
fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx hir::Stmt<'_>) {
if !has_attr(cx.sess(), stmt.kind.attrs(|id| cx.tcx.hir().item(id.id))) {
if !has_attr(cx.sess(), stmt.kind.attrs(|id| cx.tcx.hir().item(id))) {
return;
}
prelude();

View File

@ -109,7 +109,7 @@ impl<'tcx> LateLintPass<'tcx> for DeepCodeInspector {
}
fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx hir::Stmt<'_>) {
if !has_attr(cx.sess(), stmt.kind.attrs(|id| cx.tcx.hir().item(id.id))) {
if !has_attr(cx.sess(), stmt.kind.attrs(|id| cx.tcx.hir().item(id))) {
return;
}
match stmt.kind {