about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2024-01-20 15:21:27 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2024-02-07 09:38:24 +0300
commit363b098245c44401dda0040c80624187539c3141 (patch)
tree4bc6614adb2afc9d2b66c769c8b7cf7ab22917ab /compiler
parentd4f6f9ee6a3b24f2cb97b1a5b82963609b93aa33 (diff)
downloadrust-363b098245c44401dda0040c80624187539c3141.tar.gz
rust-363b098245c44401dda0040c80624187539c3141.zip
hir: Make sure all `HirId`s have corresponding HIR `Node`s
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_ast_lowering/src/index.rs42
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs3
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_errors.rs3
-rw-r--r--compiler/rustc_hir/src/hir.rs33
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs2
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs7
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs10
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs12
9 files changed, 78 insertions, 36 deletions
diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs
index 993ddf00eb5..ff3870cf11b 100644
--- a/compiler/rustc_ast_lowering/src/index.rs
+++ b/compiler/rustc_ast_lowering/src/index.rs
@@ -15,7 +15,7 @@ struct NodeCollector<'a, 'hir> {
     bodies: &'a SortedMap<ItemLocalId, &'hir Body<'hir>>,
 
     /// Outputs
-    nodes: IndexVec<ItemLocalId, Option<ParentedNode<'hir>>>,
+    nodes: IndexVec<ItemLocalId, ParentedNode<'hir>>,
     parenting: LocalDefIdMap<ItemLocalId>,
 
     /// The parent of this node
@@ -29,16 +29,19 @@ pub(super) fn index_hir<'hir>(
     tcx: TyCtxt<'hir>,
     item: hir::OwnerNode<'hir>,
     bodies: &SortedMap<ItemLocalId, &'hir Body<'hir>>,
-) -> (IndexVec<ItemLocalId, Option<ParentedNode<'hir>>>, LocalDefIdMap<ItemLocalId>) {
-    let mut nodes = IndexVec::new();
+    num_nodes: usize,
+) -> (IndexVec<ItemLocalId, ParentedNode<'hir>>, LocalDefIdMap<ItemLocalId>) {
+    let zero_id = ItemLocalId::new(0);
+    let err_node = ParentedNode { parent: zero_id, node: Node::Err(item.span()) };
+    let mut nodes = IndexVec::from_elem_n(err_node, num_nodes);
     // This node's parent should never be accessed: the owner's parent is computed by the
     // hir_owner_parent query. Make it invalid (= ItemLocalId::MAX) to force an ICE whenever it is
     // used.
-    nodes.push(Some(ParentedNode { parent: ItemLocalId::INVALID, node: item.into() }));
+    nodes[zero_id] = ParentedNode { parent: ItemLocalId::INVALID, node: item.into() };
     let mut collector = NodeCollector {
         tcx,
         owner: item.def_id(),
-        parent_node: ItemLocalId::new(0),
+        parent_node: zero_id,
         nodes,
         bodies,
         parenting: Default::default(),
@@ -54,6 +57,14 @@ pub(super) fn index_hir<'hir>(
         OwnerNode::ForeignItem(item) => collector.visit_foreign_item(item),
     };
 
+    for (local_id, node) in collector.nodes.iter_enumerated() {
+        if let Node::Err(span) = node.node {
+            let hir_id = HirId { owner: item.def_id(), local_id };
+            let msg = format!("ID {hir_id} not encountered when visiting item HIR");
+            tcx.dcx().span_delayed_bug(*span, msg);
+        }
+    }
+
     (collector.nodes, collector.parenting)
 }
 
@@ -88,7 +99,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
             }
         }
 
-        self.nodes.insert(hir_id.local_id, ParentedNode { parent: self.parent_node, node });
+        self.nodes[hir_id.local_id] = ParentedNode { parent: self.parent_node, node };
     }
 
     fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_node_id: HirId, f: F) {
@@ -348,4 +359,23 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
 
         self.visit_nested_foreign_item(id);
     }
+
+    fn visit_where_predicate(&mut self, predicate: &'hir WherePredicate<'hir>) {
+        match predicate {
+            WherePredicate::BoundPredicate(pred) => {
+                self.insert(pred.span, pred.hir_id, Node::WhereBoundPredicate(pred));
+                self.with_parent(pred.hir_id, |this| {
+                    intravisit::walk_where_predicate(this, predicate)
+                })
+            }
+            _ => intravisit::walk_where_predicate(self, predicate),
+        }
+    }
+
+    fn visit_array_length(&mut self, len: &'hir ArrayLen) {
+        match len {
+            ArrayLen::Infer(inf) => self.insert(inf.span, inf.hir_id, Node::ArrayLenInfer(inf)),
+            ArrayLen::Body(..) => intravisit::walk_array_len(self, len),
+        }
+    }
 }
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 063b6627050..3f382627076 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -675,7 +675,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         } else {
             (None, None)
         };
-        let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies);
+        let num_nodes = self.item_local_id_counter.as_usize();
+        let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies, num_nodes);
         let nodes = hir::OwnerNodes { opt_hash_including_bodies, nodes, bodies };
         let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash };
 
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index 8c8ca1ead40..0733fc48ed5 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -216,7 +216,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                 if let Some(id) = placeholder.bound.kind.get_id()
                     && let Some(placeholder_id) = id.as_local()
                     && let gat_hir_id = self.infcx.tcx.local_def_id_to_hir_id(placeholder_id)
-                    && let Some(generics_impl) = hir.get_parent(gat_hir_id).generics()
+                    && let Some(generics_impl) =
+                        hir.get_parent(hir.parent_id(gat_hir_id)).generics()
                 {
                     Some((gat_hir_id, generics_impl))
                 } else {
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index ff50086ff8f..2468e91e8b9 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -835,7 +835,7 @@ pub struct OwnerNodes<'tcx> {
     // The zeroth node's parent should never be accessed: the owner's parent is computed by the
     // hir_owner_parent query. It is set to `ItemLocalId::INVALID` to force an ICE if accidentally
     // used.
-    pub nodes: IndexVec<ItemLocalId, Option<ParentedNode<'tcx>>>,
+    pub nodes: IndexVec<ItemLocalId, ParentedNode<'tcx>>,
     /// Content of local bodies.
     pub bodies: SortedMap<ItemLocalId, &'tcx Body<'tcx>>,
 }
@@ -843,9 +843,8 @@ pub struct OwnerNodes<'tcx> {
 impl<'tcx> OwnerNodes<'tcx> {
     pub fn node(&self) -> OwnerNode<'tcx> {
         use rustc_index::Idx;
-        let node = self.nodes[ItemLocalId::new(0)].as_ref().unwrap().node;
-        let node = node.as_owner().unwrap(); // Indexing must ensure it is an OwnerNode.
-        node
+        // Indexing must ensure it is an OwnerNode.
+        self.nodes[ItemLocalId::new(0)].node.as_owner().unwrap()
     }
 }
 
@@ -860,9 +859,7 @@ impl fmt::Debug for OwnerNodes<'_> {
                     .nodes
                     .iter_enumerated()
                     .map(|(id, parented_node)| {
-                        let parented_node = parented_node.as_ref().map(|node| node.parent);
-
-                        debug_fn(move |f| write!(f, "({id:?}, {parented_node:?})"))
+                        debug_fn(move |f| write!(f, "({id:?}, {:?})", parented_node.parent))
                     })
                     .collect::<Vec<_>>(),
             )
@@ -3351,13 +3348,15 @@ impl<'hir> OwnerNode<'hir> {
         }
     }
 
-    pub fn span(&self) -> Span {
+    // Span by reference to pass to `Node::Err`.
+    #[allow(rustc::pass_by_value)]
+    pub fn span(&self) -> &'hir Span {
         match self {
             OwnerNode::Item(Item { span, .. })
             | OwnerNode::ForeignItem(ForeignItem { span, .. })
             | OwnerNode::ImplItem(ImplItem { span, .. })
-            | OwnerNode::TraitItem(TraitItem { span, .. }) => *span,
-            OwnerNode::Crate(Mod { spans: ModSpans { inner_span, .. }, .. }) => *inner_span,
+            | OwnerNode::TraitItem(TraitItem { span, .. }) => span,
+            OwnerNode::Crate(Mod { spans: ModSpans { inner_span, .. }, .. }) => inner_span,
         }
     }
 
@@ -3486,17 +3485,18 @@ pub enum Node<'hir> {
     Arm(&'hir Arm<'hir>),
     Block(&'hir Block<'hir>),
     Local(&'hir Local<'hir>),
-
     /// `Ctor` refers to the constructor of an enum variant or struct. Only tuple or unit variants
     /// with synthesized constructors.
     Ctor(&'hir VariantData<'hir>),
-
     Lifetime(&'hir Lifetime),
     GenericParam(&'hir GenericParam<'hir>),
-
     Crate(&'hir Mod<'hir>),
-
     Infer(&'hir InferArg),
+    WhereBoundPredicate(&'hir WhereBoundPredicate<'hir>),
+    ArrayLenInfer(&'hir InferArg),
+    // Span by reference to minimize `Node`'s size
+    #[allow(rustc::pass_by_value)]
+    Err(&'hir Span),
 }
 
 impl<'hir> Node<'hir> {
@@ -3541,7 +3541,10 @@ impl<'hir> Node<'hir> {
             | Node::Crate(..)
             | Node::Ty(..)
             | Node::TraitRef(..)
-            | Node::Infer(..) => None,
+            | Node::Infer(..)
+            | Node::WhereBoundPredicate(..)
+            | Node::ArrayLenInfer(..)
+            | Node::Err(..) => None,
         }
     }
 
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index 5cdcc1bb860..2b73cbc0e46 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -509,6 +509,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
             x => bug!("unexpected non-type Node::GenericParam: {:?}", x),
         },
 
+        Node::ArrayLenInfer(_) => tcx.types.usize,
+
         x => {
             bug!("unexpected sort of node in type_of(): {:?}", x);
         }
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 9d0c5cb0f32..95f8a754664 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -117,6 +117,13 @@ impl<'a> State<'a> {
             Node::Ctor(..) => panic!("cannot print isolated Ctor"),
             Node::Local(a) => self.print_local_decl(a),
             Node::Crate(..) => panic!("cannot print Crate"),
+            Node::WhereBoundPredicate(pred) => {
+                self.print_formal_generic_params(pred.bound_generic_params);
+                self.print_type(pred.bounded_ty);
+                self.print_bounds(":", pred.bounds);
+            }
+            Node::ArrayLenInfer(_) => self.word("_"),
+            Node::Err(_) => self.word("/*ERROR*/"),
         }
     }
 }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 5395ffda1d1..eccfd0d0c96 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -1055,7 +1055,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             if self.can_coerce(found, ty) {
                 if let Some(node) = self.tcx.opt_hir_node(fn_id)
                     && let Some(owner_node) = node.as_owner()
-                    && let Some(span) = expr.span.find_ancestor_inside(owner_node.span())
+                    && let Some(span) = expr.span.find_ancestor_inside(*owner_node.span())
                 {
                     err.multipart_suggestion(
                         "you might have meant to return this value",
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 85631bd8edb..79aa9a547f7 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1388,13 +1388,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             if should_encode_fn_sig(def_kind) {
                 record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
             }
-            // FIXME: Some anonymous constants produced by `#[rustc_legacy_const_generics]`
-            // do not have corresponding HIR nodes, so some queries usually making sense for
-            // anonymous constants will not work on them and panic. It's not clear whether it
-            // can cause any observable issues or not.
-            let anon_const_without_hir = def_kind == DefKind::AnonConst
-                && tcx.opt_hir_node(tcx.local_def_id_to_hir_id(local_id)).is_none();
-            if should_encode_generics(def_kind) && !anon_const_without_hir {
+            if should_encode_generics(def_kind) {
                 let g = tcx.generics_of(def_id);
                 record!(self.tables.generics_of[def_id] <- g);
                 record!(self.tables.explicit_predicates_of[def_id] <- self.tcx.explicit_predicates_of(def_id));
@@ -1408,7 +1402,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                     }
                 }
             }
-            if should_encode_type(tcx, local_id, def_kind) && !anon_const_without_hir {
+            if should_encode_type(tcx, local_id, def_kind) {
                 record!(self.tables.type_of[def_id] <- self.tcx.type_of(def_id));
             }
             if should_encode_constness(def_kind) {
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index ba1ae46626b..64e19e0946f 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -159,9 +159,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
     /// Retrieves the `hir::Node` corresponding to `id`, returning `None` if cannot be found.
     pub fn opt_hir_node(self, id: HirId) -> Option<Node<'tcx>> {
-        let owner = self.hir_owner_nodes(id.owner);
-        let node = owner.nodes[id.local_id].as_ref()?;
-        Some(node.node)
+        Some(self.hir_owner_nodes(id.owner).nodes[id.local_id].node)
     }
 
     /// Retrieves the `hir::Node` corresponding to `id`, returning `None` if cannot be found.
@@ -233,7 +231,7 @@ impl<'hir> Map<'hir> {
             Some(self.tcx.hir_owner_parent(id.owner))
         } else {
             let owner = self.tcx.hir_owner_nodes(id.owner);
-            let node = owner.nodes[id.local_id].as_ref()?;
+            let node = &owner.nodes[id.local_id];
             let hir_id = HirId { owner: id.owner, local_id: node.parent };
             // HIR indexing should have checked that.
             debug_assert_ne!(id.local_id, node.parent);
@@ -994,6 +992,9 @@ impl<'hir> Map<'hir> {
             Node::Infer(i) => i.span,
             Node::Local(local) => local.span,
             Node::Crate(item) => item.spans.inner_span,
+            Node::WhereBoundPredicate(pred) => pred.span,
+            Node::ArrayLenInfer(inf) => inf.span,
+            Node::Err(span) => *span,
         }
     }
 
@@ -1255,6 +1256,9 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
             format!("{id} (generic_param {})", path_str(param.def_id))
         }
         Some(Node::Crate(..)) => String::from("(root_crate)"),
+        Some(Node::WhereBoundPredicate(_)) => node_str("where bound predicate"),
+        Some(Node::ArrayLenInfer(_)) => node_str("array len infer"),
+        Some(Node::Err(_)) => node_str("error"),
         None => format!("{id} (unknown node)"),
     }
 }