From 6b76932ba84958666d0866d5ae21703b3be14701 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 10 Aug 2016 17:29:24 -0400 Subject: [PATCH] introduce Deref/DerefMut to model subtype rel The idea is that ItemContentBuilder is a base-type of IndexBuilder. --- src/librustc_metadata/encoder.rs | 18 ++++++---- src/librustc_metadata/index_builder.rs | 50 +++++++++++++++++++------- 2 files changed, 50 insertions(+), 18 deletions(-) diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index f256d126934..49bd861b131 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -54,7 +54,7 @@ use rustc::hir::intravisit::Visitor; use rustc::hir::intravisit; use rustc::hir::map::DefKey; -use super::index_builder::{IndexBuilder, XRef}; +use super::index_builder::{IndexBuilder, ItemContentBuilder, XRef}; pub struct EncodeContext<'a, 'tcx: 'a> { pub diag: &'a Handler, @@ -132,7 +132,7 @@ fn encode_item_variances(rbml_w: &mut Encoder, rbml_w.end_tag(); } -impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { +impl<'a, 'tcx> ItemContentBuilder<'a, 'tcx> { fn encode_bounds_and_type_for_item(&mut self, rbml_w: &mut Encoder, id: NodeId) { @@ -164,7 +164,7 @@ fn write_closure_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w.mark_stable_position(); } -impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { +impl<'a, 'tcx> ItemContentBuilder<'a, 'tcx> { fn encode_type(&mut self, rbml_w: &mut Encoder, typ: Ty<'tcx>) { @@ -200,7 +200,9 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { rbml_w.end_tag(); } } +} +impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { fn encode_enum_variant_info(&mut self, rbml_w: &mut Encoder, did: DefId, @@ -302,7 +304,7 @@ fn encode_reexports(ecx: &EncodeContext, } } -impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { +impl<'a, 'tcx> ItemContentBuilder<'a, 'tcx> { fn encode_info_for_mod(&mut self, rbml_w: &mut Encoder, md: &hir::Mod, @@ -487,7 +489,9 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { rbml_w.end_tag(); } +} +impl<'a, 'tcx> ItemContentBuilder<'a, 'tcx> { fn encode_generics(&mut self, rbml_w: &mut Encoder, generics: &ty::Generics<'tcx>, @@ -532,7 +536,9 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { _ => encode_family(rbml_w, METHOD_FAMILY) } } +} +impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { fn encode_info_for_associated_const(&mut self, rbml_w: &mut Encoder, associated_const: &ty::AssociatedConst, @@ -680,7 +686,9 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { } rbml_w.end_tag(); } +} +impl<'a, 'tcx> ItemContentBuilder<'a, 'tcx> { fn encode_repr_attrs(&mut self, rbml_w: &mut Encoder, attrs: &[ast::Attribute]) { @@ -1237,9 +1245,7 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { } } } -} -impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { fn encode_info_for_foreign_item(&mut self, rbml_w: &mut Encoder, nitem: &hir::ForeignItem) { diff --git a/src/librustc_metadata/index_builder.rs b/src/librustc_metadata/index_builder.rs index 1e1ae064436..915bf98519c 100644 --- a/src/librustc_metadata/index_builder.rs +++ b/src/librustc_metadata/index_builder.rs @@ -15,11 +15,20 @@ use rustc::dep_graph::{DepNode, DepTask}; use rustc::hir::def_id::DefId; use rustc::ty; use rustc_data_structures::fnv::FnvHashMap; +use std::ops::{Deref, DerefMut}; +/// Builder that can encode new items, adding them into the index. +/// Item encoding cannot be nested. pub struct IndexBuilder<'a, 'tcx: 'a> { - ecx: &'a EncodeContext<'a, 'tcx>, items: IndexData, + builder: ItemContentBuilder<'a, 'tcx>, +} + +/// Builder that can encode the content of items, but can't start a +/// new item itself. Most code is attached to here. +pub struct ItemContentBuilder<'a, 'tcx: 'a> { xrefs: FnvHashMap, u32>, // sequentially-assigned + ecx: &'a EncodeContext<'a, 'tcx>, } /// "interned" entries referenced by id @@ -29,16 +38,14 @@ pub enum XRef<'tcx> { Predicate(ty::Predicate<'tcx>) } impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { pub fn new(ecx: &'a EncodeContext<'a, 'tcx>) -> Self { IndexBuilder { - ecx: ecx, items: IndexData::new(ecx.tcx.map.num_local_def_ids()), - xrefs: FnvHashMap() + builder: ItemContentBuilder { + ecx: ecx, + xrefs: FnvHashMap(), + }, } } - pub fn ecx(&self) -> &'a EncodeContext<'a, 'tcx> { - self.ecx - } - /// Records that `id` is being emitted at the current offset. /// This data is later used to construct the item index in the /// metadata so we can quickly find the data for a given item. @@ -51,13 +58,32 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { self.ecx.tcx.dep_graph.in_task(DepNode::MetaData(id)) } + pub fn into_fields(self) -> (IndexData, FnvHashMap, u32>) { + (self.items, self.builder.xrefs) + } +} + +impl<'a, 'tcx> Deref for IndexBuilder<'a, 'tcx> { + type Target = ItemContentBuilder<'a, 'tcx>; + + fn deref(&self) -> &Self::Target { + &self.builder + } +} + +impl<'a, 'tcx> DerefMut for IndexBuilder<'a, 'tcx> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.builder + } +} + +impl<'a, 'tcx> ItemContentBuilder<'a, 'tcx> { + pub fn ecx(&self) -> &'a EncodeContext<'a, 'tcx> { + self.ecx + } + pub fn add_xref(&mut self, xref: XRef<'tcx>) -> u32 { let old_len = self.xrefs.len() as u32; *self.xrefs.entry(xref).or_insert(old_len) } - - pub fn into_fields(self) -> (IndexData, FnvHashMap, u32>) { - (self.items, self.xrefs) - } } -