]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc/hir/lowering.rs
Allocate HIR id counters on demand
[rust.git] / src / librustc / hir / lowering.rs
index 52ad800e81c6abf65e693802bccd980925a6d70f..7dfb16602a3d44d911d9d05c451dc10f9053e3e4 100644 (file)
@@ -51,7 +51,6 @@
 use rustc_data_structures::sync::Lrc;
 
 use std::collections::{BTreeSet, BTreeMap};
-use std::fmt::Debug;
 use std::mem;
 use smallvec::SmallVec;
 use syntax::attr;
@@ -82,15 +81,14 @@ pub struct LoweringContext<'a> {
     resolver: &'a mut dyn Resolver,
 
     /// The items being lowered are collected here.
-    items: BTreeMap<NodeId, hir::Item>,
+    items: BTreeMap<hir::HirId, hir::Item>,
 
     trait_items: BTreeMap<hir::TraitItemId, hir::TraitItem>,
     impl_items: BTreeMap<hir::ImplItemId, hir::ImplItem>,
     bodies: BTreeMap<hir::BodyId, hir::Body>,
     exported_macros: Vec<hir::MacroDef>,
 
-    trait_impls: BTreeMap<DefId, Vec<NodeId>>,
-    trait_auto_impl: BTreeMap<DefId, NodeId>,
+    trait_impls: BTreeMap<DefId, Vec<hir::HirId>>,
 
     modules: BTreeMap<NodeId, hir::ModuleItems>,
 
@@ -233,7 +231,6 @@ pub fn lower_crate(
         impl_items: BTreeMap::new(),
         bodies: BTreeMap::new(),
         trait_impls: BTreeMap::new(),
-        trait_auto_impl: BTreeMap::new(),
         modules: BTreeMap::new(),
         exported_macros: Vec::new(),
         catch_scopes: Vec::new(),
@@ -323,7 +320,7 @@ enum AnonymousLifetimeMode {
     PassThrough,
 }
 
-struct ImplTraitTypeIdVisitor<'a> { ids: &'a mut SmallVec<[hir::ItemId; 1]> }
+struct ImplTraitTypeIdVisitor<'a> { ids: &'a mut SmallVec<[NodeId; 1]> }
 
 impl<'a, 'b> Visitor<'a> for ImplTraitTypeIdVisitor<'b> {
     fn visit_ty(&mut self, ty: &'a Ty) {
@@ -332,7 +329,7 @@ fn visit_ty(&mut self, ty: &'a Ty) {
             | TyKind::BareFn(_)
             => return,
 
-            TyKind::ImplTrait(id, _) => self.ids.push(hir::ItemId { id }),
+            TyKind::ImplTrait(id, _) => self.ids.push(id),
             _ => {},
         }
         visit::walk_ty(self, ty);
@@ -363,9 +360,40 @@ struct MiscCollector<'lcx, 'interner: 'lcx> {
             lctx: &'lcx mut LoweringContext<'interner>,
         }
 
+        impl MiscCollector<'_, '_> {
+            fn allocate_use_tree_hir_id_counters(
+                &mut self,
+                tree: &UseTree,
+                owner: DefIndex,
+            ) {
+                match tree.kind {
+                    UseTreeKind::Simple(_, id1, id2) => {
+                        for &id in &[id1, id2] {
+                            self.lctx.resolver.definitions().create_def_with_parent(
+                                owner,
+                                id,
+                                DefPathData::Misc,
+                                DefIndexAddressSpace::High,
+                                Mark::root(),
+                                tree.prefix.span,
+                            );
+                            self.lctx.allocate_hir_id_counter(id);
+                        }
+                    }
+                    UseTreeKind::Glob => (),
+                    UseTreeKind::Nested(ref trees) => {
+                        for &(ref use_tree, id) in trees {
+                            let hir_id = self.lctx.allocate_hir_id_counter(id).hir_id;
+                            self.allocate_use_tree_hir_id_counters(use_tree, hir_id.owner);
+                        }
+                    }
+                }
+            }
+        }
+
         impl<'lcx, 'interner> Visitor<'lcx> for MiscCollector<'lcx, 'interner> {
             fn visit_item(&mut self, item: &'lcx Item) {
-                self.lctx.allocate_hir_id_counter(item.id, item);
+                let hir_id = self.lctx.allocate_hir_id_counter(item.id).hir_id;
 
                 match item.node {
                     ItemKind::Struct(_, ref generics)
@@ -385,18 +413,21 @@ fn visit_item(&mut self, item: &'lcx Item) {
                             .count();
                         self.lctx.type_def_lifetime_params.insert(def_id, count);
                     }
+                    ItemKind::Use(ref use_tree) => {
+                        self.allocate_use_tree_hir_id_counters(use_tree, hir_id.owner);
+                    }
                     _ => {}
                 }
                 visit::walk_item(self, item);
             }
 
             fn visit_trait_item(&mut self, item: &'lcx TraitItem) {
-                self.lctx.allocate_hir_id_counter(item.id, item);
+                self.lctx.allocate_hir_id_counter(item.id);
                 visit::walk_trait_item(self, item);
             }
 
             fn visit_impl_item(&mut self, item: &'lcx ImplItem) {
-                self.lctx.allocate_hir_id_counter(item.id, item);
+                self.lctx.allocate_hir_id_counter(item.id);
                 visit::walk_impl_item(self, item);
             }
         }
@@ -436,17 +467,16 @@ fn visit_mod(&mut self, m: &'lcx Mod, _s: Span, _attrs: &[Attribute], n: NodeId)
             }
 
             fn visit_item(&mut self, item: &'lcx Item) {
-                let mut item_lowered = true;
+                let mut item_hir_id = None;
                 self.lctx.with_hir_id_owner(item.id, |lctx| {
                     if let Some(hir_item) = lctx.lower_item(item) {
-                        lctx.insert_item(item.id, hir_item);
-                    } else {
-                        item_lowered = false;
+                        item_hir_id = Some(hir_item.hir_id);
+                        lctx.insert_item(hir_item);
                     }
                 });
 
-                if item_lowered {
-                    let item_generics = match self.lctx.items.get(&item.id).unwrap().node {
+                if let Some(hir_id) = item_hir_id {
+                    let item_generics = match self.lctx.items.get(&hir_id).unwrap().node {
                         hir::ItemKind::Impl(_, _, _, ref generics, ..)
                         | hir::ItemKind::Trait(_, _, ref generics, ..) => {
                             generics.params.clone()
@@ -514,25 +544,25 @@ fn visit_impl_item(&mut self, item: &'lcx ImplItem) {
             bodies: self.bodies,
             body_ids,
             trait_impls: self.trait_impls,
-            trait_auto_impl: self.trait_auto_impl,
             modules: self.modules,
         }
     }
 
-    fn insert_item(&mut self, id: NodeId, item: hir::Item) {
+    fn insert_item(&mut self, item: hir::Item) {
+        let id = item.hir_id;
+        // FIXME: Use debug_asset-rt
+        assert_eq!(id.local_id, hir::ItemLocalId::from_u32(0));
         self.items.insert(id, item);
         self.modules.get_mut(&self.current_module).unwrap().items.insert(id);
     }
 
-    fn allocate_hir_id_counter<T: Debug>(&mut self, owner: NodeId, debug: &T) -> LoweredNodeId {
-        if self.item_local_id_counters.insert(owner, 0).is_some() {
-            bug!(
-                "Tried to allocate item_local_id_counter for {:?} twice",
-                debug
-            );
-        }
+    fn allocate_hir_id_counter(&mut self, owner: NodeId) -> LoweredNodeId {
+        // Setup the counter if needed
+        self.item_local_id_counters.entry(owner).or_insert(0);
         // Always allocate the first `HirId` for the owner itself.
-        self.lower_node_id_with_owner(owner, owner)
+        let lowered = self.lower_node_id_with_owner(owner, owner);
+        debug_assert_eq!(lowered.hir_id.local_id.as_u32(), 0);
+        lowered
     }
 
     fn lower_node_id_generic<F>(&mut self, ast_node_id: NodeId, alloc_hir_id: F) -> LoweredNodeId
@@ -1068,7 +1098,7 @@ fn lower_loop_destination(&mut self, destination: Option<(NodeId, Label)>) -> hi
         let target_id = match destination {
             Some((id, _)) => {
                 if let Def::Label(loop_id) = self.expect_full_def(id) {
-                    Ok(self.lower_node_id(loop_id).node_id)
+                    Ok(self.lower_node_id(loop_id).hir_id)
                 } else {
                     Err(hir::LoopIdError::UnresolvedLabel)
                 }
@@ -1077,7 +1107,7 @@ fn lower_loop_destination(&mut self, destination: Option<(NodeId, Label)>) -> hi
                 self.loop_scopes
                     .last()
                     .cloned()
-                    .map(|id| Ok(self.lower_node_id(id).node_id))
+                    .map(|id| Ok(self.lower_node_id(id).hir_id))
                     .unwrap_or(Err(hir::LoopIdError::OutsideLoopScope))
                     .into()
             }
@@ -1384,7 +1414,7 @@ fn lower_existential_impl_trait(
             .opt_def_index(exist_ty_node_id)
             .unwrap();
 
-        self.allocate_hir_id_counter(exist_ty_node_id, &"existential impl trait");
+        self.allocate_hir_id_counter(exist_ty_node_id);
 
         let hir_bounds = self.with_hir_id_owner(exist_ty_node_id, lower_bounds);
 
@@ -1425,10 +1455,10 @@ fn lower_existential_impl_trait(
             // Insert the item into the global list. This usually happens
             // automatically for all AST items. But this existential type item
             // does not actually exist in the AST.
-            lctx.insert_item(exist_ty_id.node_id, exist_ty_item);
+            lctx.insert_item(exist_ty_item);
 
             // `impl Trait` now just becomes `Foo<'a, 'b, ..>`.
-            hir::TyKind::Def(hir::ItemId { id: exist_ty_id.node_id }, lifetimes)
+            hir::TyKind::Def(hir::ItemId { id: exist_ty_id.hir_id }, lifetimes)
         })
     }
 
@@ -1618,9 +1648,11 @@ fn lower_global_asm(&mut self, ga: &GlobalAsm) -> P<hir::GlobalAsm> {
     }
 
     fn lower_variant(&mut self, v: &Variant) -> hir::Variant {
+        let LoweredNodeId { node_id: _, hir_id } = self.lower_node_id(v.node.id);
         Spanned {
             node: hir::VariantKind {
                 ident: v.node.ident,
+                id: hir_id,
                 attrs: self.lower_attrs(&v.node.attrs),
                 data: self.lower_variant_data(&v.node.data),
                 disr_expr: v.node.disr_expr.as_ref().map(|e| self.lower_anon_const(e)),
@@ -1932,7 +1964,6 @@ fn lower_path_segment(
 
         hir::PathSegment::new(
             segment.ident,
-            Some(id.node_id),
             Some(id.hir_id),
             Some(def),
             generic_args,
@@ -2004,9 +2035,9 @@ fn lower_parenthesized_parameter_data(
         )
     }
 
-    fn lower_local(&mut self, l: &Local) -> (hir::Local, SmallVec<[hir::ItemId; 1]>) {
+    fn lower_local(&mut self, l: &Local) -> (hir::Local, SmallVec<[NodeId; 1]>) {
         let LoweredNodeId { node_id: _, hir_id } = self.lower_node_id(l.id);
-        let mut ids = SmallVec::<[hir::ItemId; 1]>::new();
+        let mut ids = SmallVec::<[NodeId; 1]>::new();
         if self.sess.features_untracked().impl_trait_in_bindings {
             if let Some(ref ty) = l.ty {
                 let mut visitor = ImplTraitTypeIdVisitor { ids: &mut ids };
@@ -2673,18 +2704,10 @@ fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicat
 
     fn lower_variant_data(&mut self, vdata: &VariantData) -> hir::VariantData {
         match *vdata {
-            VariantData::Struct(ref fields, id) => {
-                let LoweredNodeId { node_id: _, hir_id } = self.lower_node_id(id);
-
-                hir::VariantData::Struct(
-                    fields
-                        .iter()
-                        .enumerate()
-                        .map(|f| self.lower_struct_field(f))
-                        .collect(),
-                    hir_id,
-                )
-            },
+            VariantData::Struct(ref fields, recovered) => hir::VariantData::Struct(
+                fields.iter().enumerate().map(|f| self.lower_struct_field(f)).collect(),
+                recovered,
+            ),
             VariantData::Tuple(ref fields, id) => {
                 let LoweredNodeId { node_id: _, hir_id } = self.lower_node_id(id);
 
@@ -2699,7 +2722,6 @@ fn lower_variant_data(&mut self, vdata: &VariantData) -> hir::VariantData {
             },
             VariantData::Unit(id) => {
                 let LoweredNodeId { node_id: _, hir_id } = self.lower_node_id(id);
-
                 hir::VariantData::Unit(hir_id)
             },
         }
@@ -2968,6 +2990,7 @@ fn lower_item_kind(
                 // method, it will not be considered an in-band
                 // lifetime to be added, but rather a reference to a
                 // parent lifetime.
+                let lowered_trait_impl_id = self.lower_node_id(id).hir_id;
                 let (generics, (trait_ref, lowered_ty)) = self.add_in_band_defs(
                     ast_generics,
                     def_id,
@@ -2979,7 +3002,8 @@ fn lower_item_kind(
 
                         if let Some(ref trait_ref) = trait_ref {
                             if let Def::Trait(def_id) = trait_ref.path.def {
-                                this.trait_impls.entry(def_id).or_default().push(id);
+                                this.trait_impls.entry(def_id).or_default().push(
+                                    lowered_trait_impl_id);
                             }
                         }
 
@@ -3074,7 +3098,6 @@ fn lower_use_tree(
                     }
                 }
 
-                let parent_def_index = self.current_hir_id_owner.last().unwrap().0;
                 let mut defs = self.expect_full_def_from_use(id);
                 // We want to return *something* from this function, so hold onto the first item
                 // for later.
@@ -3093,14 +3116,6 @@ fn lower_use_tree(
                         seg.id = self.sess.next_node_id();
                     }
                     let span = path.span;
-                    self.resolver.definitions().create_def_with_parent(
-                        parent_def_index,
-                        new_node_id,
-                        DefPathData::Misc,
-                        DefIndexAddressSpace::High,
-                        Mark::root(),
-                        span);
-                    self.allocate_hir_id_counter(new_node_id, &path);
 
                     self.with_hir_id_owner(new_node_id, |this| {
                         let new_id = this.lower_node_id(new_node_id);
@@ -3123,7 +3138,6 @@ fn lower_use_tree(
                         let vis = respan(vis.span, vis_kind);
 
                         this.insert_item(
-                            new_id.node_id,
                             hir::Item {
                                 hir_id: new_id.hir_id,
                                 ident,
@@ -3183,8 +3197,6 @@ fn lower_use_tree(
 
                 // Add all the nested `PathListItem`s to the HIR.
                 for &(ref use_tree, id) in trees {
-                    self.allocate_hir_id_counter(id, &use_tree);
-
                     let LoweredNodeId {
                         node_id: new_id,
                         hir_id: new_hir_id,
@@ -3228,7 +3240,6 @@ fn lower_use_tree(
                         let vis = respan(vis.span, vis_kind);
 
                         this.insert_item(
-                            new_id,
                             hir::Item {
                                 hir_id: new_hir_id,
                                 ident,
@@ -3276,10 +3287,8 @@ fn renumber_segment_ids(&mut self, path: &P<hir::Path>) -> P<hir::Path> {
         debug!("renumber_segment_ids(path = {:?})", path);
         let mut path = path.clone();
         for seg in path.segments.iter_mut() {
-            if seg.id.is_some() {
-                let next_id = self.next_id();
-                seg.id = Some(next_id.node_id);
-                seg.hir_id = Some(next_id.hir_id);
+            if seg.hir_id.is_some() {
+                seg.hir_id = Some(self.next_id().hir_id);
             }
         }
         path
@@ -3454,17 +3463,17 @@ fn lower_mod(&mut self, m: &Mod) -> hir::Mod {
     }
 
     fn lower_item_id(&mut self, i: &Item) -> SmallVec<[hir::ItemId; 1]> {
-        match i.node {
+        let node_ids = match i.node {
             ItemKind::Use(ref use_tree) => {
-                let mut vec = smallvec![hir::ItemId { id: i.id }];
+                let mut vec = smallvec![i.id];
                 self.lower_item_id_use_tree(use_tree, i.id, &mut vec);
                 vec
             }
             ItemKind::MacroDef(..) => SmallVec::new(),
             ItemKind::Fn(..) |
-            ItemKind::Impl(.., None, _, _) => smallvec![hir::ItemId { id: i.id }],
+            ItemKind::Impl(.., None, _, _) => smallvec![i.id],
             ItemKind::Static(ref ty, ..) => {
-                let mut ids = smallvec![hir::ItemId { id: i.id }];
+                let mut ids = smallvec![i.id];
                 if self.sess.features_untracked().impl_trait_in_bindings {
                     let mut visitor = ImplTraitTypeIdVisitor { ids: &mut ids };
                     visitor.visit_ty(ty);
@@ -3472,25 +3481,29 @@ fn lower_mod(&mut self, m: &Mod) -> hir::Mod {
                 ids
             },
             ItemKind::Const(ref ty, ..) => {
-                let mut ids = smallvec![hir::ItemId { id: i.id }];
+                let mut ids = smallvec![i.id];
                 if self.sess.features_untracked().impl_trait_in_bindings {
                     let mut visitor = ImplTraitTypeIdVisitor { ids: &mut ids };
                     visitor.visit_ty(ty);
                 }
                 ids
             },
-            _ => smallvec![hir::ItemId { id: i.id }],
-        }
+            _ => smallvec![i.id],
+        };
+
+        node_ids.into_iter().map(|node_id| hir::ItemId {
+            id: self.allocate_hir_id_counter(node_id).hir_id
+        }).collect()
     }
 
     fn lower_item_id_use_tree(&mut self,
                               tree: &UseTree,
                               base_id: NodeId,
-                              vec: &mut SmallVec<[hir::ItemId; 1]>)
+                              vec: &mut SmallVec<[NodeId; 1]>)
     {
         match tree.kind {
             UseTreeKind::Nested(ref nested_vec) => for &(ref nested, id) in nested_vec {
-                vec.push(hir::ItemId { id });
+                vec.push(id);
                 self.lower_item_id_use_tree(nested, id, vec);
             },
             UseTreeKind::Glob => {}
@@ -3499,7 +3512,7 @@ fn lower_item_id_use_tree(&mut self,
                                     .skip(1)
                                     .zip([id1, id2].iter())
                 {
-                    vec.push(hir::ItemId { id });
+                    vec.push(id);
                 }
             },
         }
@@ -3682,11 +3695,10 @@ fn lower_pat(&mut self, p: &Pat) -> P<hir::Pat> {
                             Some(Def::Local(id)) => id,
                             _ => p.id,
                         };
-                        let hir_id = self.lower_node_id(canonical_id).hir_id;
+
                         hir::PatKind::Binding(
                             self.lower_binding_mode(binding_mode),
-                            canonical_id,
-                            hir_id,
+                            self.lower_node_id(canonical_id).hir_id,
                             ident,
                             sub.as_ref().map(|x| self.lower_pat(x)),
                         )
@@ -4338,13 +4350,14 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                 //   }
 
                 // expand <head>
-                let head = self.lower_expr(head);
+                let mut head = self.lower_expr(head);
                 let head_sp = head.span;
                 let desugared_span = self.mark_span_with_reason(
                     CompilerDesugaringKind::ForLoop,
                     head_sp,
                     None,
                 );
+                head.span = desugared_span;
 
                 let iter = self.str_to_ident("iter");
 
@@ -4568,12 +4581,13 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                     let thin_attrs = ThinVec::from(attrs);
                     let catch_scope = self.catch_scopes.last().map(|x| *x);
                     let ret_expr = if let Some(catch_node) = catch_scope {
+                        let target_id = Ok(self.lower_node_id(catch_node).hir_id);
                         P(self.expr(
                             e.span,
                             hir::ExprKind::Break(
                                 hir::Destination {
                                     label: None,
-                                    target_id: Ok(catch_node),
+                                    target_id,
                                 },
                                 Some(from_err_expr),
                             ),
@@ -4614,6 +4628,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                 let mut ids: SmallVec<[hir::Stmt; 1]> = item_ids
                     .into_iter()
                     .map(|item_id| {
+                        let item_id = hir::ItemId { id: self.lower_node_id(item_id).hir_id };
                         let LoweredNodeId { node_id: _, hir_id } = self.next_id();
 
                         hir::Stmt {
@@ -4988,7 +5003,7 @@ fn pat_ident_binding_mode(
         (
             P(hir::Pat {
                 hir_id,
-                node: hir::PatKind::Binding(bm, node_id, hir_id, ident.with_span_pos(span), None),
+                node: hir::PatKind::Binding(bm, hir_id, ident.with_span_pos(span), None),
                 span,
             }),
             node_id
@@ -5024,8 +5039,8 @@ fn std_path(
 
 
         for seg in path.segments.iter_mut() {
-            if let Some(id) = seg.id {
-                seg.id = Some(self.lower_node_id(id).node_id);
+            if seg.hir_id.is_some() {
+                seg.hir_id = Some(self.next_id().hir_id);
             }
         }
         path