From b5fa8ab593a106dd58c8c98b7f9b00a47561a663 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 10 Aug 2016 14:27:06 -0400 Subject: [PATCH 01/22] move CrateIndex into its own module --- src/librustc_metadata/encoder.rs | 45 ++++---------------- src/librustc_metadata/index_builder.rs | 59 ++++++++++++++++++++++++++ src/librustc_metadata/lib.rs | 1 + 3 files changed, 68 insertions(+), 37 deletions(-) create mode 100644 src/librustc_metadata/index_builder.rs diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 320ba3c8d9dc8..3ce9064f80ab5 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -25,7 +25,7 @@ use middle::cstore::{LOCAL_CRATE, InlinedItemRef, LinkMeta, tls}; use rustc::hir::def; use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId}; use middle::dependency_format::Linkage; -use rustc::dep_graph::{DepGraph, DepNode, DepTask}; +use rustc::dep_graph::DepNode; use rustc::traits::specialization_graph; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::util::IntTypeExt; @@ -54,6 +54,8 @@ use rustc::hir::intravisit::Visitor; use rustc::hir::intravisit; use rustc::hir::map::DefKey; +use super::index_builder::{CrateIndex, XRef}; + pub struct EncodeContext<'a, 'tcx: 'a> { pub diag: &'a Handler, pub tcx: TyCtxt<'a, 'tcx, 'tcx>, @@ -71,35 +73,6 @@ impl<'a, 'tcx> EncodeContext<'a,'tcx> { } } -/// "interned" entries referenced by id -#[derive(PartialEq, Eq, Hash)] -pub enum XRef<'tcx> { Predicate(ty::Predicate<'tcx>) } - -struct CrateIndex<'a, 'tcx> { - dep_graph: &'a DepGraph, - items: IndexData, - xrefs: FnvHashMap, u32>, // sequentially-assigned -} - -impl<'a, 'tcx> CrateIndex<'a, 'tcx> { - /// 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. - /// - /// Returns a dep-graph task that you should keep live as long as - /// the data for this item is being emitted. - fn record(&mut self, id: DefId, rbml_w: &mut Encoder) -> DepTask<'a> { - let position = rbml_w.mark_stable_position(); - self.items.record(id, position); - self.dep_graph.in_task(DepNode::MetaData(id)) - } - - 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) - } -} - fn encode_name(rbml_w: &mut Encoder, name: Name) { rbml_w.wr_tagged_str(tag_paths_data_name, &name.as_str()); } @@ -1380,11 +1353,7 @@ fn encode_info_for_items<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, -> CrateIndex<'a, 'tcx> { let krate = ecx.tcx.map.krate(); - let mut index = CrateIndex { - dep_graph: &ecx.tcx.dep_graph, - items: IndexData::new(ecx.tcx.map.num_local_def_ids()), - xrefs: FnvHashMap() - }; + let mut index = CrateIndex::new(ecx); rbml_w.start_tag(tag_items_data); { @@ -1929,12 +1898,14 @@ fn encode_metadata_inner(rbml_w: &mut Encoder, stats.item_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i; rbml_w.end_tag(); + let (items, xrefs) = index.into_fields(); + i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap(); - encode_item_index(rbml_w, index.items); + encode_item_index(rbml_w, items); stats.index_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i; i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap(); - encode_xrefs(&ecx, rbml_w, index.xrefs); + encode_xrefs(&ecx, rbml_w, xrefs); stats.xref_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i; encode_struct_field_attrs(&ecx, rbml_w, krate); diff --git a/src/librustc_metadata/index_builder.rs b/src/librustc_metadata/index_builder.rs new file mode 100644 index 0000000000000..3921a9160ef15 --- /dev/null +++ b/src/librustc_metadata/index_builder.rs @@ -0,0 +1,59 @@ +// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use encoder::EncodeContext; +use index::IndexData; +use rbml::writer::Encoder; +use rustc::dep_graph::{DepGraph, DepNode, DepTask}; +use rustc::hir::def_id::DefId; +use rustc::ty; +use rustc_data_structures::fnv::FnvHashMap; + +pub struct CrateIndex<'a, 'tcx> { + dep_graph: &'a DepGraph, + items: IndexData, + xrefs: FnvHashMap, u32>, // sequentially-assigned +} + +/// "interned" entries referenced by id +#[derive(PartialEq, Eq, Hash)] +pub enum XRef<'tcx> { Predicate(ty::Predicate<'tcx>) } + +impl<'a, 'tcx> CrateIndex<'a, 'tcx> { + pub fn new(ecx: &EncodeContext<'a, 'tcx>) -> Self { + CrateIndex { + dep_graph: &ecx.tcx.dep_graph, + items: IndexData::new(ecx.tcx.map.num_local_def_ids()), + xrefs: FnvHashMap() + } + } + + /// 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. + /// + /// Returns a dep-graph task that you should keep live as long as + /// the data for this item is being emitted. + pub fn record(&mut self, id: DefId, rbml_w: &mut Encoder) -> DepTask<'a> { + let position = rbml_w.mark_stable_position(); + self.items.record(id, position); + self.dep_graph.in_task(DepNode::MetaData(id)) + } + + 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) + } +} + diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index cd92493e3db70..a96fa8a006d89 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -54,6 +54,7 @@ pub mod def_key; pub mod tyencode; pub mod tydecode; pub mod encoder; +mod index_builder; pub mod decoder; pub mod creader; pub mod csearch; From 85ac63e9ec9b61bec8584b9df3a67aa504eb1076 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 10 Aug 2016 14:27:36 -0400 Subject: [PATCH 02/22] rename CrateIndex to IndexBuilder --- src/librustc_metadata/encoder.rs | 36 +++++++++++++------------- src/librustc_metadata/index_builder.rs | 6 ++--- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 3ce9064f80ab5..97c780f84e9ff 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::{CrateIndex, XRef}; +use super::index_builder::{IndexBuilder, XRef}; pub struct EncodeContext<'a, 'tcx: 'a> { pub diag: &'a Handler, @@ -134,7 +134,7 @@ fn encode_item_variances(rbml_w: &mut Encoder, fn encode_bounds_and_type_for_item<'a, 'tcx>(rbml_w: &mut Encoder, ecx: &EncodeContext<'a, 'tcx>, - index: &mut CrateIndex<'a, 'tcx>, + index: &mut IndexBuilder<'a, 'tcx>, id: NodeId) { encode_bounds_and_type(rbml_w, ecx, @@ -145,7 +145,7 @@ fn encode_bounds_and_type_for_item<'a, 'tcx>(rbml_w: &mut Encoder, fn encode_bounds_and_type<'a, 'tcx>(rbml_w: &mut Encoder, ecx: &EncodeContext<'a, 'tcx>, - index: &mut CrateIndex<'a, 'tcx>, + index: &mut IndexBuilder<'a, 'tcx>, scheme: &ty::TypeScheme<'tcx>, predicates: &ty::GenericPredicates<'tcx>) { encode_generics(rbml_w, ecx, index, &scheme.generics, &predicates); @@ -204,7 +204,7 @@ fn encode_enum_variant_info<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w: &mut Encoder, did: DefId, vis: &hir::Visibility, - index: &mut CrateIndex<'a, 'tcx>) { + index: &mut IndexBuilder<'a, 'tcx>) { debug!("encode_enum_variant_info(did={:?})", did); let repr_hints = ecx.tcx.lookup_repr_hints(did); let repr_type = ecx.tcx.enum_repr_type(repr_hints.get(0)); @@ -424,7 +424,7 @@ fn encode_item_sort(rbml_w: &mut Encoder, sort: char) { fn encode_field<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w: &mut Encoder, field: ty::FieldDef<'tcx>, - index: &mut CrateIndex<'a, 'tcx>) { + index: &mut IndexBuilder<'a, 'tcx>) { let nm = field.name; let id = ecx.local_id(field.did); @@ -448,7 +448,7 @@ fn encode_info_for_struct_ctor<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w: &mut Encoder, name: Name, struct_def: &hir::VariantData, - index: &mut CrateIndex<'a, 'tcx>, + index: &mut IndexBuilder<'a, 'tcx>, struct_id: NodeId) { let ctor_id = struct_def.id(); let ctor_def_id = ecx.tcx.map.local_def_id(ctor_id); @@ -480,7 +480,7 @@ fn encode_info_for_struct_ctor<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, fn encode_generics<'a, 'tcx>(rbml_w: &mut Encoder, ecx: &EncodeContext<'a, 'tcx>, - index: &mut CrateIndex<'a, 'tcx>, + index: &mut IndexBuilder<'a, 'tcx>, generics: &ty::Generics<'tcx>, predicates: &ty::GenericPredicates<'tcx>) { @@ -493,7 +493,7 @@ fn encode_generics<'a, 'tcx>(rbml_w: &mut Encoder, } fn encode_predicates<'a,'tcx>(rbml_w: &mut Encoder, - index: &mut CrateIndex<'a, 'tcx>, + index: &mut IndexBuilder<'a, 'tcx>, predicates: &ty::GenericPredicates<'tcx>, tag: usize) { @@ -510,7 +510,7 @@ fn encode_predicates<'a,'tcx>(rbml_w: &mut Encoder, fn encode_method_ty_fields<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w: &mut Encoder, - index: &mut CrateIndex<'a, 'tcx>, + index: &mut IndexBuilder<'a, 'tcx>, method_ty: &ty::Method<'tcx>) { encode_def_id_and_key(ecx, rbml_w, method_ty.def_id); encode_name(rbml_w, method_ty.name); @@ -528,7 +528,7 @@ fn encode_method_ty_fields<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, fn encode_info_for_associated_const<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w: &mut Encoder, - index: &mut CrateIndex<'a, 'tcx>, + index: &mut IndexBuilder<'a, 'tcx>, associated_const: &ty::AssociatedConst, parent_id: NodeId, impl_item_opt: Option<&hir::ImplItem>) { @@ -570,7 +570,7 @@ fn encode_info_for_associated_const<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w: &mut Encoder, - index: &mut CrateIndex<'a, 'tcx>, + index: &mut IndexBuilder<'a, 'tcx>, m: &ty::Method<'tcx>, is_default_impl: bool, parent_id: NodeId, @@ -618,7 +618,7 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, fn encode_info_for_associated_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w: &mut Encoder, - index: &mut CrateIndex<'a, 'tcx>, + index: &mut IndexBuilder<'a, 'tcx>, associated_type: &ty::AssociatedType<'tcx>, parent_id: NodeId, impl_item_opt: Option<&hir::ImplItem>) { @@ -765,7 +765,7 @@ fn encode_xrefs<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w: &mut Encoder, item: &hir::Item, - index: &mut CrateIndex<'a, 'tcx>) { + index: &mut IndexBuilder<'a, 'tcx>) { let tcx = ecx.tcx; debug!("encoding info for item at {}", @@ -1237,7 +1237,7 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, fn encode_info_for_foreign_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w: &mut Encoder, nitem: &hir::ForeignItem, - index: &mut CrateIndex<'a, 'tcx>) { + index: &mut IndexBuilder<'a, 'tcx>) { debug!("writing foreign item {}", ecx.tcx.node_path_str(nitem.id)); let def_id = ecx.tcx.map.local_def_id(nitem.id); let abi = ecx.tcx.map.get_foreign_abi(nitem.id); @@ -1285,7 +1285,7 @@ fn encode_info_for_foreign_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, fn my_visit_expr(expr: &hir::Expr, rbml_w: &mut Encoder, ecx: &EncodeContext, - index: &mut CrateIndex) { + index: &mut IndexBuilder) { match expr.node { hir::ExprClosure(..) => { let def_id = ecx.tcx.map.local_def_id(expr.id); @@ -1316,7 +1316,7 @@ fn my_visit_expr(expr: &hir::Expr, struct EncodeVisitor<'a, 'b:'a, 'c:'a, 'tcx:'c> { rbml_w_for_visit_item: &'a mut Encoder<'b>, ecx: &'a EncodeContext<'c, 'tcx>, - index: &'a mut CrateIndex<'c, 'tcx>, + index: &'a mut IndexBuilder<'c, 'tcx>, } impl<'a, 'b, 'c, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'b, 'c, 'tcx> { @@ -1350,10 +1350,10 @@ impl<'a, 'b, 'c, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'b, 'c, 'tcx> { fn encode_info_for_items<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w: &mut Encoder) - -> CrateIndex<'a, 'tcx> { + -> IndexBuilder<'a, 'tcx> { let krate = ecx.tcx.map.krate(); - let mut index = CrateIndex::new(ecx); + let mut index = IndexBuilder::new(ecx); rbml_w.start_tag(tag_items_data); { diff --git a/src/librustc_metadata/index_builder.rs b/src/librustc_metadata/index_builder.rs index 3921a9160ef15..b7af35da751d9 100644 --- a/src/librustc_metadata/index_builder.rs +++ b/src/librustc_metadata/index_builder.rs @@ -16,7 +16,7 @@ use rustc::hir::def_id::DefId; use rustc::ty; use rustc_data_structures::fnv::FnvHashMap; -pub struct CrateIndex<'a, 'tcx> { +pub struct IndexBuilder<'a, 'tcx> { dep_graph: &'a DepGraph, items: IndexData, xrefs: FnvHashMap, u32>, // sequentially-assigned @@ -26,9 +26,9 @@ pub struct CrateIndex<'a, 'tcx> { #[derive(PartialEq, Eq, Hash)] pub enum XRef<'tcx> { Predicate(ty::Predicate<'tcx>) } -impl<'a, 'tcx> CrateIndex<'a, 'tcx> { +impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { pub fn new(ecx: &EncodeContext<'a, 'tcx>) -> Self { - CrateIndex { + IndexBuilder { dep_graph: &ecx.tcx.dep_graph, items: IndexData::new(ecx.tcx.map.num_local_def_ids()), xrefs: FnvHashMap() From 25bb51d98fee9d991c06169784a48e4533fff035 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 10 Aug 2016 14:35:45 -0400 Subject: [PATCH 03/22] store ecx, not dep-graph --- src/librustc_metadata/index_builder.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/librustc_metadata/index_builder.rs b/src/librustc_metadata/index_builder.rs index b7af35da751d9..0f52252c6a005 100644 --- a/src/librustc_metadata/index_builder.rs +++ b/src/librustc_metadata/index_builder.rs @@ -17,7 +17,7 @@ use rustc::ty; use rustc_data_structures::fnv::FnvHashMap; pub struct IndexBuilder<'a, 'tcx> { - dep_graph: &'a DepGraph, + ecx: &'a EncodeContext<'a, 'tcx>, items: IndexData, xrefs: FnvHashMap, u32>, // sequentially-assigned } @@ -29,12 +29,16 @@ pub enum XRef<'tcx> { Predicate(ty::Predicate<'tcx>) } impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { pub fn new(ecx: &EncodeContext<'a, 'tcx>) -> Self { IndexBuilder { - dep_graph: &ecx.tcx.dep_graph, + ecx: ecx, items: IndexData::new(ecx.tcx.map.num_local_def_ids()), xrefs: FnvHashMap() } } + pub fn ecx(&self) { + 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. @@ -44,7 +48,7 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { pub fn record(&mut self, id: DefId, rbml_w: &mut Encoder) -> DepTask<'a> { let position = rbml_w.mark_stable_position(); self.items.record(id, position); - self.dep_graph.in_task(DepNode::MetaData(id)) + self.ecx.tcx.dep_graph.in_task(DepNode::MetaData(id)) } pub fn add_xref(&mut self, xref: XRef<'tcx>) -> u32 { From 92f269e665bd7fdccf83da6f545ee755b211bbb9 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 10 Aug 2016 14:49:22 -0400 Subject: [PATCH 04/22] put ecx into IndexBuilder so we don't have to pass --- src/librustc_metadata/encoder.rs | 95 ++++++++++++++------------ src/librustc_metadata/index_builder.rs | 8 +-- 2 files changed, 54 insertions(+), 49 deletions(-) diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 97c780f84e9ff..6f0ccf5af9963 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -762,10 +762,10 @@ fn encode_xrefs<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w.end_tag(); } -fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, - rbml_w: &mut Encoder, +fn encode_info_for_item<'a, 'tcx>(rbml_w: &mut Encoder, item: &hir::Item, index: &mut IndexBuilder<'a, 'tcx>) { + let ecx = index.ecx(); let tcx = ecx.tcx; debug!("encoding info for item at {}", @@ -1234,10 +1234,11 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, } } -fn encode_info_for_foreign_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, - rbml_w: &mut Encoder, +fn encode_info_for_foreign_item<'a, 'tcx>(rbml_w: &mut Encoder, nitem: &hir::ForeignItem, index: &mut IndexBuilder<'a, 'tcx>) { + let ecx = index.ecx(); + debug!("writing foreign item {}", ecx.tcx.node_path_str(nitem.id)); let def_id = ecx.tcx.map.local_def_id(nitem.id); let abi = ecx.tcx.map.get_foreign_abi(nitem.id); @@ -1282,10 +1283,50 @@ fn encode_info_for_foreign_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w.end_tag(); } -fn my_visit_expr(expr: &hir::Expr, - rbml_w: &mut Encoder, - ecx: &EncodeContext, - index: &mut IndexBuilder) { +struct EncodeVisitor<'a, 'data:'a, 'ecx: 'a, 'tcx: 'ecx> { + rbml_w_for_visit_item: &'a mut Encoder<'data>, + index: &'a mut IndexBuilder<'ecx, 'tcx>, +} + +impl<'a, 'data, 'ecx, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'data, 'ecx, 'tcx> { + fn visit_expr(&mut self, ex: &'tcx hir::Expr) { + intravisit::walk_expr(self, ex); + encode_info_for_expr(ex, self.rbml_w_for_visit_item, self.index); + } + fn visit_item(&mut self, i: &'tcx hir::Item) { + intravisit::walk_item(self, i); + encode_info_for_item(self.rbml_w_for_visit_item, i, self.index); + } + fn visit_foreign_item(&mut self, ni: &'tcx hir::ForeignItem) { + intravisit::walk_foreign_item(self, ni); + encode_info_for_foreign_item(self.rbml_w_for_visit_item, ni, self.index); + } + fn visit_ty(&mut self, ty: &'tcx hir::Ty) { + intravisit::walk_ty(self, ty); + encode_info_for_ty(ty, self.rbml_w_for_visit_item, self.index); + } +} + +fn encode_info_for_ty(ty: &hir::Ty, + rbml_w: &mut Encoder, + index: &mut IndexBuilder) { + let ecx = index.ecx(); + if let hir::TyImplTrait(_) = ty.node { + let def_id = ecx.tcx.map.local_def_id(ty.id); + let _task = index.record(def_id, rbml_w); + rbml_w.start_tag(tag_items_data_item); + encode_def_id_and_key(ecx, rbml_w, def_id); + encode_family(rbml_w, 'y'); + encode_bounds_and_type_for_item(rbml_w, ecx, index, ty.id); + rbml_w.end_tag(); + } +} + +fn encode_info_for_expr(expr: &hir::Expr, + rbml_w: &mut Encoder, + index: &mut IndexBuilder) { + let ecx = index.ecx(); + match expr.node { hir::ExprClosure(..) => { let def_id = ecx.tcx.map.local_def_id(expr.id); @@ -1313,42 +1354,7 @@ fn my_visit_expr(expr: &hir::Expr, } } -struct EncodeVisitor<'a, 'b:'a, 'c:'a, 'tcx:'c> { - rbml_w_for_visit_item: &'a mut Encoder<'b>, - ecx: &'a EncodeContext<'c, 'tcx>, - index: &'a mut IndexBuilder<'c, 'tcx>, -} - -impl<'a, 'b, 'c, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'b, 'c, 'tcx> { - fn visit_expr(&mut self, ex: &'tcx hir::Expr) { - intravisit::walk_expr(self, ex); - my_visit_expr(ex, self.rbml_w_for_visit_item, self.ecx, self.index); - } - fn visit_item(&mut self, i: &'tcx hir::Item) { - intravisit::walk_item(self, i); - encode_info_for_item(self.ecx, self.rbml_w_for_visit_item, i, self.index); - } - fn visit_foreign_item(&mut self, ni: &'tcx hir::ForeignItem) { - intravisit::walk_foreign_item(self, ni); - encode_info_for_foreign_item(self.ecx, self.rbml_w_for_visit_item, ni, self.index); - } - fn visit_ty(&mut self, ty: &'tcx hir::Ty) { - intravisit::walk_ty(self, ty); - - if let hir::TyImplTrait(_) = ty.node { - let rbml_w = &mut *self.rbml_w_for_visit_item; - let def_id = self.ecx.tcx.map.local_def_id(ty.id); - let _task = self.index.record(def_id, rbml_w); - rbml_w.start_tag(tag_items_data_item); - encode_def_id_and_key(self.ecx, rbml_w, def_id); - encode_family(rbml_w, 'y'); - encode_bounds_and_type_for_item(rbml_w, self.ecx, self.index, ty.id); - rbml_w.end_tag(); - } - } -} - -fn encode_info_for_items<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, +fn encode_info_for_items<'a, 'tcx>(ecx: &'a EncodeContext<'a, 'tcx>, rbml_w: &mut Encoder) -> IndexBuilder<'a, 'tcx> { let krate = ecx.tcx.map.krate(); @@ -1369,7 +1375,6 @@ fn encode_info_for_items<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, krate.visit_all_items(&mut EncodeVisitor { index: &mut index, - ecx: ecx, rbml_w_for_visit_item: &mut *rbml_w, }); diff --git a/src/librustc_metadata/index_builder.rs b/src/librustc_metadata/index_builder.rs index 0f52252c6a005..1e1ae06443643 100644 --- a/src/librustc_metadata/index_builder.rs +++ b/src/librustc_metadata/index_builder.rs @@ -11,12 +11,12 @@ use encoder::EncodeContext; use index::IndexData; use rbml::writer::Encoder; -use rustc::dep_graph::{DepGraph, DepNode, DepTask}; +use rustc::dep_graph::{DepNode, DepTask}; use rustc::hir::def_id::DefId; use rustc::ty; use rustc_data_structures::fnv::FnvHashMap; -pub struct IndexBuilder<'a, 'tcx> { +pub struct IndexBuilder<'a, 'tcx: 'a> { ecx: &'a EncodeContext<'a, 'tcx>, items: IndexData, xrefs: FnvHashMap, u32>, // sequentially-assigned @@ -27,7 +27,7 @@ pub struct IndexBuilder<'a, 'tcx> { pub enum XRef<'tcx> { Predicate(ty::Predicate<'tcx>) } impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { - pub fn new(ecx: &EncodeContext<'a, 'tcx>) -> Self { + pub fn new(ecx: &'a EncodeContext<'a, 'tcx>) -> Self { IndexBuilder { ecx: ecx, items: IndexData::new(ecx.tcx.map.num_local_def_ids()), @@ -35,7 +35,7 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { } } - pub fn ecx(&self) { + pub fn ecx(&self) -> &'a EncodeContext<'a, 'tcx> { self.ecx } From b2c7922d7f6cab865751c4c0977072942b78c287 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 10 Aug 2016 15:33:36 -0400 Subject: [PATCH 05/22] move free encode fns into methods of IndexBuilder --- src/librustc_metadata/encoder.rs | 1798 +++++++++++++++--------------- 1 file changed, 902 insertions(+), 896 deletions(-) diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 6f0ccf5af9963..f256d1269340c 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -132,24 +132,23 @@ fn encode_item_variances(rbml_w: &mut Encoder, rbml_w.end_tag(); } -fn encode_bounds_and_type_for_item<'a, 'tcx>(rbml_w: &mut Encoder, - ecx: &EncodeContext<'a, 'tcx>, - index: &mut IndexBuilder<'a, 'tcx>, - id: NodeId) { - encode_bounds_and_type(rbml_w, - ecx, - index, - &ecx.tcx.lookup_item_type(ecx.tcx.map.local_def_id(id)), - &ecx.tcx.lookup_predicates(ecx.tcx.map.local_def_id(id))); -} - -fn encode_bounds_and_type<'a, 'tcx>(rbml_w: &mut Encoder, - ecx: &EncodeContext<'a, 'tcx>, - index: &mut IndexBuilder<'a, 'tcx>, - scheme: &ty::TypeScheme<'tcx>, - predicates: &ty::GenericPredicates<'tcx>) { - encode_generics(rbml_w, ecx, index, &scheme.generics, &predicates); - encode_type(ecx, rbml_w, scheme.ty); +impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { + fn encode_bounds_and_type_for_item(&mut self, + rbml_w: &mut Encoder, + id: NodeId) { + let ecx = self.ecx(); + self.encode_bounds_and_type(rbml_w, + &ecx.tcx.lookup_item_type(ecx.tcx.map.local_def_id(id)), + &ecx.tcx.lookup_predicates(ecx.tcx.map.local_def_id(id))); + } + + fn encode_bounds_and_type(&mut self, + rbml_w: &mut Encoder, + scheme: &ty::TypeScheme<'tcx>, + predicates: &ty::GenericPredicates<'tcx>) { + self.encode_generics(rbml_w, &scheme.generics, &predicates); + self.encode_type(rbml_w, scheme.ty); + } } fn encode_variant_id(rbml_w: &mut Encoder, vid: DefId) { @@ -165,92 +164,95 @@ fn write_closure_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w.mark_stable_position(); } -fn encode_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, - rbml_w: &mut Encoder, - typ: Ty<'tcx>) { - rbml_w.start_tag(tag_items_data_item_type); - tyencode::enc_ty(rbml_w.writer, &ecx.ty_str_ctxt(), typ); - rbml_w.mark_stable_position(); - rbml_w.end_tag(); -} - -fn encode_disr_val(_: &EncodeContext, +impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { + fn encode_type(&mut self, rbml_w: &mut Encoder, - disr_val: ty::Disr) { - // convert to u64 so just the number is printed, without any type info - rbml_w.wr_tagged_str(tag_disr_val, &disr_val.to_u64_unchecked().to_string()); -} + typ: Ty<'tcx>) { + rbml_w.start_tag(tag_items_data_item_type); + tyencode::enc_ty(rbml_w.writer, &self.ecx().ty_str_ctxt(), typ); + rbml_w.mark_stable_position(); + rbml_w.end_tag(); + } -fn encode_parent_item(rbml_w: &mut Encoder, id: DefId) { - rbml_w.wr_tagged_u64(tag_items_data_parent_item, def_to_u64(id)); -} + fn encode_disr_val(&mut self, + rbml_w: &mut Encoder, + disr_val: ty::Disr) { + // convert to u64 so just the number is printed, without any type info + rbml_w.wr_tagged_str(tag_disr_val, &disr_val.to_u64_unchecked().to_string()); + } -fn encode_struct_fields(rbml_w: &mut Encoder, - variant: ty::VariantDef) { - for f in &variant.fields { - if variant.kind == ty::VariantKind::Tuple { - rbml_w.start_tag(tag_item_unnamed_field); - } else { - rbml_w.start_tag(tag_item_field); - encode_name(rbml_w, f.name); - } - encode_struct_field_family(rbml_w, f.vis); - encode_def_id(rbml_w, f.did); - rbml_w.end_tag(); + fn encode_parent_item(&mut self, rbml_w: &mut Encoder, id: DefId) { + rbml_w.wr_tagged_u64(tag_items_data_parent_item, def_to_u64(id)); } -} -fn encode_enum_variant_info<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, - rbml_w: &mut Encoder, - did: DefId, - vis: &hir::Visibility, - index: &mut IndexBuilder<'a, 'tcx>) { - debug!("encode_enum_variant_info(did={:?})", did); - let repr_hints = ecx.tcx.lookup_repr_hints(did); - let repr_type = ecx.tcx.enum_repr_type(repr_hints.get(0)); - let mut disr_val = repr_type.initial_discriminant(ecx.tcx); - let def = ecx.tcx.lookup_adt_def(did); - for variant in &def.variants { - let vid = variant.did; - let variant_node_id = ecx.local_id(vid); - - for field in &variant.fields { - encode_field(ecx, rbml_w, field, index); + fn encode_struct_fields(&mut self, + rbml_w: &mut Encoder, + variant: ty::VariantDef) { + for f in &variant.fields { + if variant.kind == ty::VariantKind::Tuple { + rbml_w.start_tag(tag_item_unnamed_field); + } else { + rbml_w.start_tag(tag_item_field); + encode_name(rbml_w, f.name); + } + self.encode_struct_field_family(rbml_w, f.vis); + encode_def_id(rbml_w, f.did); + rbml_w.end_tag(); } + } - let _task = index.record(vid, rbml_w); - rbml_w.start_tag(tag_items_data_item); - encode_def_id_and_key(ecx, rbml_w, vid); - encode_family(rbml_w, match variant.kind { - ty::VariantKind::Struct => 'V', - ty::VariantKind::Tuple => 'v', - ty::VariantKind::Unit => 'w', - }); - encode_name(rbml_w, variant.name); - encode_parent_item(rbml_w, did); - encode_visibility(rbml_w, vis); - - let attrs = ecx.tcx.get_attrs(vid); - encode_attributes(rbml_w, &attrs); - encode_repr_attrs(rbml_w, ecx, &attrs); + fn encode_enum_variant_info(&mut self, + rbml_w: &mut Encoder, + did: DefId, + vis: &hir::Visibility) { + debug!("encode_enum_variant_info(did={:?})", did); + let ecx = self.ecx(); + let repr_hints = ecx.tcx.lookup_repr_hints(did); + let repr_type = ecx.tcx.enum_repr_type(repr_hints.get(0)); + let mut disr_val = repr_type.initial_discriminant(ecx.tcx); + let def = ecx.tcx.lookup_adt_def(did); + for variant in &def.variants { + let vid = variant.did; + let variant_node_id = ecx.local_id(vid); + + for field in &variant.fields { + self.encode_field(rbml_w, field); + } - let stab = ecx.tcx.lookup_stability(vid); - let depr = ecx.tcx.lookup_deprecation(vid); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); + let _task = self.record(vid, rbml_w); + rbml_w.start_tag(tag_items_data_item); + encode_def_id_and_key(ecx, rbml_w, vid); + encode_family(rbml_w, match variant.kind { + ty::VariantKind::Struct => 'V', + ty::VariantKind::Tuple => 'v', + ty::VariantKind::Unit => 'w', + }); + encode_name(rbml_w, variant.name); + self.encode_parent_item(rbml_w, did); + self.encode_visibility(rbml_w, vis); + + let attrs = ecx.tcx.get_attrs(vid); + encode_attributes(rbml_w, &attrs); + self.encode_repr_attrs(rbml_w, &attrs); + + let stab = ecx.tcx.lookup_stability(vid); + let depr = ecx.tcx.lookup_deprecation(vid); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); - encode_struct_fields(rbml_w, variant); + self.encode_struct_fields(rbml_w, variant); - let specified_disr_val = variant.disr_val; - if specified_disr_val != disr_val { - encode_disr_val(ecx, rbml_w, specified_disr_val); - disr_val = specified_disr_val; - } - encode_bounds_and_type_for_item(rbml_w, ecx, index, variant_node_id); + let specified_disr_val = variant.disr_val; + if specified_disr_val != disr_val { + self.encode_disr_val(rbml_w, specified_disr_val); + disr_val = specified_disr_val; + } + self.encode_bounds_and_type_for_item(rbml_w, variant_node_id); - rbml_w.end_tag(); + rbml_w.end_tag(); - disr_val = disr_val.wrap_incr(); + disr_val = disr_val.wrap_incr(); + } } } @@ -300,57 +302,61 @@ fn encode_reexports(ecx: &EncodeContext, } } -fn encode_info_for_mod(ecx: &EncodeContext, - rbml_w: &mut Encoder, - md: &hir::Mod, - attrs: &[ast::Attribute], - id: NodeId, - name: Name, - vis: &hir::Visibility) { - rbml_w.start_tag(tag_items_data_item); - encode_def_id_and_key(ecx, rbml_w, ecx.tcx.map.local_def_id(id)); - encode_family(rbml_w, 'm'); - encode_name(rbml_w, name); - debug!("(encoding info for module) encoding info for module ID {}", id); - - // Encode info about all the module children. - for item_id in &md.item_ids { - rbml_w.wr_tagged_u64(tag_mod_child, - def_to_u64(ecx.tcx.map.local_def_id(item_id.id))); +impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { + fn encode_info_for_mod(&mut self, + rbml_w: &mut Encoder, + md: &hir::Mod, + attrs: &[ast::Attribute], + id: NodeId, + name: Name, + vis: &hir::Visibility) { + let ecx = self.ecx(); - let item = ecx.tcx.map.expect_item(item_id.id); - each_auxiliary_node_id(item, |auxiliary_node_id| { + rbml_w.start_tag(tag_items_data_item); + encode_def_id_and_key(ecx, rbml_w, ecx.tcx.map.local_def_id(id)); + encode_family(rbml_w, 'm'); + encode_name(rbml_w, name); + debug!("(encoding info for module) encoding info for module ID {}", id); + + // Encode info about all the module children. + for item_id in &md.item_ids { rbml_w.wr_tagged_u64(tag_mod_child, - def_to_u64(ecx.tcx.map.local_def_id(auxiliary_node_id))); - true - }); - } + def_to_u64(ecx.tcx.map.local_def_id(item_id.id))); + + let item = ecx.tcx.map.expect_item(item_id.id); + each_auxiliary_node_id(item, |auxiliary_node_id| { + rbml_w.wr_tagged_u64(tag_mod_child, + def_to_u64(ecx.tcx.map.local_def_id(auxiliary_node_id))); + true + }); + } - encode_visibility(rbml_w, vis); + self.encode_visibility(rbml_w, vis); - let stab = ecx.tcx.lookup_stability(ecx.tcx.map.local_def_id(id)); - let depr = ecx.tcx.lookup_deprecation(ecx.tcx.map.local_def_id(id)); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); + let stab = ecx.tcx.lookup_stability(ecx.tcx.map.local_def_id(id)); + let depr = ecx.tcx.lookup_deprecation(ecx.tcx.map.local_def_id(id)); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); - // Encode the reexports of this module, if this module is public. - if *vis == hir::Public { - debug!("(encoding info for module) encoding reexports for {}", id); - encode_reexports(ecx, rbml_w, id); - } - encode_attributes(rbml_w, attrs); + // Encode the reexports of this module, if this module is public. + if *vis == hir::Public { + debug!("(encoding info for module) encoding reexports for {}", id); + encode_reexports(ecx, rbml_w, id); + } + encode_attributes(rbml_w, attrs); - rbml_w.end_tag(); -} + rbml_w.end_tag(); + } -fn encode_struct_field_family(rbml_w: &mut Encoder, - visibility: ty::Visibility) { - encode_family(rbml_w, if visibility.is_public() { 'g' } else { 'N' }); -} + fn encode_struct_field_family(&mut self, rbml_w: &mut Encoder, + visibility: ty::Visibility) { + encode_family(rbml_w, if visibility.is_public() { 'g' } else { 'N' }); + } -fn encode_visibility(rbml_w: &mut Encoder, visibility: T) { - let ch = if visibility.is_public() { 'y' } else { 'i' }; - rbml_w.wr_tagged_u8(tag_items_data_item_visibility, ch as u8); + fn encode_visibility(&mut self, rbml_w: &mut Encoder, visibility: T) { + let ch = if visibility.is_public() { 'y' } else { 'i' }; + rbml_w.wr_tagged_u8(tag_items_data_item_visibility, ch as u8); + } } trait HasVisibility: Sized { @@ -421,281 +427,287 @@ fn encode_item_sort(rbml_w: &mut Encoder, sort: char) { rbml_w.wr_tagged_u8(tag_item_trait_item_sort, sort as u8); } -fn encode_field<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, - rbml_w: &mut Encoder, - field: ty::FieldDef<'tcx>, - index: &mut IndexBuilder<'a, 'tcx>) { - let nm = field.name; - let id = ecx.local_id(field.did); - - let _task = index.record(field.did, rbml_w); - rbml_w.start_tag(tag_items_data_item); - debug!("encode_field: encoding {} {}", nm, id); - encode_struct_field_family(rbml_w, field.vis); - encode_name(rbml_w, nm); - encode_bounds_and_type_for_item(rbml_w, ecx, index, id); - encode_def_id_and_key(ecx, rbml_w, field.did); - - let stab = ecx.tcx.lookup_stability(field.did); - let depr = ecx.tcx.lookup_deprecation(field.did); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); - - rbml_w.end_tag(); -} - -fn encode_info_for_struct_ctor<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, - rbml_w: &mut Encoder, - name: Name, - struct_def: &hir::VariantData, - index: &mut IndexBuilder<'a, 'tcx>, - struct_id: NodeId) { - let ctor_id = struct_def.id(); - let ctor_def_id = ecx.tcx.map.local_def_id(ctor_id); - - let _task = index.record(ctor_def_id, rbml_w); - rbml_w.start_tag(tag_items_data_item); - encode_def_id_and_key(ecx, rbml_w, ctor_def_id); - encode_family(rbml_w, match *struct_def { - hir::VariantData::Struct(..) => 'S', - hir::VariantData::Tuple(..) => 's', - hir::VariantData::Unit(..) => 'u', - }); - encode_bounds_and_type_for_item(rbml_w, ecx, index, ctor_id); - encode_name(rbml_w, name); - encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(struct_id)); +impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { + fn encode_field(&mut self, + rbml_w: &mut Encoder, + field: ty::FieldDef<'tcx>) { + let ecx = self.ecx(); - let stab = ecx.tcx.lookup_stability(ecx.tcx.map.local_def_id(ctor_id)); - let depr= ecx.tcx.lookup_deprecation(ecx.tcx.map.local_def_id(ctor_id)); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); + let nm = field.name; + let id = ecx.local_id(field.did); - // indicate that this is a tuple struct ctor, because downstream users will normally want - // the tuple struct definition, but without this there is no way for them to tell that - // they actually have a ctor rather than a normal function - rbml_w.wr_tagged_bytes(tag_items_data_item_is_tuple_struct_ctor, &[]); + let _task = self.record(field.did, rbml_w); + rbml_w.start_tag(tag_items_data_item); + debug!("encode_field: encoding {} {}", nm, id); + self.encode_struct_field_family(rbml_w, field.vis); + encode_name(rbml_w, nm); + self.encode_bounds_and_type_for_item(rbml_w, id); + encode_def_id_and_key(ecx, rbml_w, field.did); + + let stab = ecx.tcx.lookup_stability(field.did); + let depr = ecx.tcx.lookup_deprecation(field.did); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); - rbml_w.end_tag(); + rbml_w.end_tag(); + } } -fn encode_generics<'a, 'tcx>(rbml_w: &mut Encoder, - ecx: &EncodeContext<'a, 'tcx>, - index: &mut IndexBuilder<'a, 'tcx>, - generics: &ty::Generics<'tcx>, - predicates: &ty::GenericPredicates<'tcx>) -{ - rbml_w.start_tag(tag_item_generics); - tyencode::enc_generics(rbml_w.writer, &ecx.ty_str_ctxt(), generics); - rbml_w.mark_stable_position(); - rbml_w.end_tag(); +impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { + fn encode_info_for_struct_ctor(&mut self, + rbml_w: &mut Encoder, + name: Name, + struct_def: &hir::VariantData, + struct_id: NodeId) { + let ecx = self.ecx(); + let ctor_id = struct_def.id(); + let ctor_def_id = ecx.tcx.map.local_def_id(ctor_id); + + let _task = self.record(ctor_def_id, rbml_w); + rbml_w.start_tag(tag_items_data_item); + encode_def_id_and_key(ecx, rbml_w, ctor_def_id); + encode_family(rbml_w, match *struct_def { + hir::VariantData::Struct(..) => 'S', + hir::VariantData::Tuple(..) => 's', + hir::VariantData::Unit(..) => 'u', + }); + self.encode_bounds_and_type_for_item(rbml_w, ctor_id); + encode_name(rbml_w, name); + self.encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(struct_id)); - encode_predicates(rbml_w, index, predicates, tag_item_predicates); -} + let stab = ecx.tcx.lookup_stability(ecx.tcx.map.local_def_id(ctor_id)); + let depr = ecx.tcx.lookup_deprecation(ecx.tcx.map.local_def_id(ctor_id)); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); -fn encode_predicates<'a,'tcx>(rbml_w: &mut Encoder, - index: &mut IndexBuilder<'a, 'tcx>, - predicates: &ty::GenericPredicates<'tcx>, - tag: usize) -{ - rbml_w.start_tag(tag); - if let Some(def_id) = predicates.parent { - rbml_w.wr_tagged_u64(tag_items_data_parent_item, def_to_u64(def_id)); + // indicate that this is a tuple struct ctor, because downstream users will normally want + // the tuple struct definition, but without this there is no way for them to tell that + // they actually have a ctor rather than a normal function + rbml_w.wr_tagged_bytes(tag_items_data_item_is_tuple_struct_ctor, &[]); + + rbml_w.end_tag(); } - for predicate in &predicates.predicates { - rbml_w.wr_tagged_u32(tag_predicate, - index.add_xref(XRef::Predicate(predicate.clone()))); + + fn encode_generics(&mut self, + rbml_w: &mut Encoder, + generics: &ty::Generics<'tcx>, + predicates: &ty::GenericPredicates<'tcx>) + { + let ecx = self.ecx(); + rbml_w.start_tag(tag_item_generics); + tyencode::enc_generics(rbml_w.writer, &ecx.ty_str_ctxt(), generics); + rbml_w.mark_stable_position(); + rbml_w.end_tag(); + self.encode_predicates(rbml_w, predicates, tag_item_predicates); } - rbml_w.end_tag(); -} -fn encode_method_ty_fields<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, - rbml_w: &mut Encoder, - index: &mut IndexBuilder<'a, 'tcx>, - method_ty: &ty::Method<'tcx>) { - encode_def_id_and_key(ecx, rbml_w, method_ty.def_id); - encode_name(rbml_w, method_ty.name); - encode_generics(rbml_w, ecx, index, - &method_ty.generics, &method_ty.predicates); - encode_visibility(rbml_w, method_ty.vis); - encode_explicit_self(rbml_w, &method_ty.explicit_self); - match method_ty.explicit_self { - ty::ExplicitSelfCategory::Static => { - encode_family(rbml_w, STATIC_METHOD_FAMILY); + fn encode_predicates(&mut self, + rbml_w: &mut Encoder, + predicates: &ty::GenericPredicates<'tcx>, + tag: usize) { + rbml_w.start_tag(tag); + if let Some(def_id) = predicates.parent { + rbml_w.wr_tagged_u64(tag_items_data_parent_item, def_to_u64(def_id)); + } + for predicate in &predicates.predicates { + rbml_w.wr_tagged_u32(tag_predicate, + self.add_xref(XRef::Predicate(predicate.clone()))); } - _ => encode_family(rbml_w, METHOD_FAMILY) + rbml_w.end_tag(); } -} -fn encode_info_for_associated_const<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, - rbml_w: &mut Encoder, - index: &mut IndexBuilder<'a, 'tcx>, - associated_const: &ty::AssociatedConst, - parent_id: NodeId, - impl_item_opt: Option<&hir::ImplItem>) { - debug!("encode_info_for_associated_const({:?},{:?})", - associated_const.def_id, - associated_const.name); - - let _task = index.record(associated_const.def_id, rbml_w); - rbml_w.start_tag(tag_items_data_item); - - encode_def_id_and_key(ecx, rbml_w, associated_const.def_id); - encode_name(rbml_w, associated_const.name); - encode_visibility(rbml_w, associated_const.vis); - encode_family(rbml_w, 'C'); - - encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id)); - encode_item_sort(rbml_w, 'C'); - - encode_bounds_and_type_for_item(rbml_w, ecx, index, - ecx.local_id(associated_const.def_id)); - - let stab = ecx.tcx.lookup_stability(associated_const.def_id); - let depr = ecx.tcx.lookup_deprecation(associated_const.def_id); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); - - if let Some(ii) = impl_item_opt { - encode_attributes(rbml_w, &ii.attrs); - encode_defaultness(rbml_w, ii.defaultness); - encode_inlined_item(ecx, - rbml_w, - InlinedItemRef::ImplItem(ecx.tcx.map.local_def_id(parent_id), - ii)); - encode_mir(ecx, rbml_w, ii.id); + fn encode_method_ty_fields(&mut self, + rbml_w: &mut Encoder, + method_ty: &ty::Method<'tcx>) { + let ecx = self.ecx(); + encode_def_id_and_key(ecx, rbml_w, method_ty.def_id); + encode_name(rbml_w, method_ty.name); + self.encode_generics(rbml_w, &method_ty.generics, &method_ty.predicates); + self.encode_visibility(rbml_w, method_ty.vis); + encode_explicit_self(rbml_w, &method_ty.explicit_self); + match method_ty.explicit_self { + ty::ExplicitSelfCategory::Static => { + encode_family(rbml_w, STATIC_METHOD_FAMILY); + } + _ => encode_family(rbml_w, METHOD_FAMILY) + } } - rbml_w.end_tag(); -} + fn encode_info_for_associated_const(&mut self, + rbml_w: &mut Encoder, + associated_const: &ty::AssociatedConst, + parent_id: NodeId, + impl_item_opt: Option<&hir::ImplItem>) { + let ecx = self.ecx(); + debug!("encode_info_for_associated_const({:?},{:?})", + associated_const.def_id, + associated_const.name); + + let _task = self.record(associated_const.def_id, rbml_w); + rbml_w.start_tag(tag_items_data_item); -fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, - rbml_w: &mut Encoder, - index: &mut IndexBuilder<'a, 'tcx>, - m: &ty::Method<'tcx>, - is_default_impl: bool, - parent_id: NodeId, - impl_item_opt: Option<&hir::ImplItem>) { - - debug!("encode_info_for_method: {:?} {:?}", m.def_id, - m.name); - let _task = index.record(m.def_id, rbml_w); - rbml_w.start_tag(tag_items_data_item); - - encode_method_ty_fields(ecx, rbml_w, index, m); - encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id)); - encode_item_sort(rbml_w, 'r'); - - let stab = ecx.tcx.lookup_stability(m.def_id); - let depr = ecx.tcx.lookup_deprecation(m.def_id); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); - - let m_node_id = ecx.local_id(m.def_id); - encode_bounds_and_type_for_item(rbml_w, ecx, index, m_node_id); - - if let Some(impl_item) = impl_item_opt { - if let hir::ImplItemKind::Method(ref sig, _) = impl_item.node { - encode_attributes(rbml_w, &impl_item.attrs); - let generics = ecx.tcx.lookup_generics(m.def_id); - let types = generics.parent_types as usize + generics.types.len(); - let needs_inline = types > 0 || is_default_impl || - attr::requests_inline(&impl_item.attrs); - if needs_inline || sig.constness == hir::Constness::Const { - encode_inlined_item(ecx, - rbml_w, - InlinedItemRef::ImplItem(ecx.tcx.map.local_def_id(parent_id), - impl_item)); - encode_mir(ecx, rbml_w, impl_item.id); - } - encode_constness(rbml_w, sig.constness); - encode_defaultness(rbml_w, impl_item.defaultness); - encode_method_argument_names(rbml_w, &sig.decl); + encode_def_id_and_key(ecx, rbml_w, associated_const.def_id); + encode_name(rbml_w, associated_const.name); + self.encode_visibility(rbml_w, associated_const.vis); + encode_family(rbml_w, 'C'); + + self.encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id)); + encode_item_sort(rbml_w, 'C'); + + self.encode_bounds_and_type_for_item(rbml_w, ecx.local_id(associated_const.def_id)); + + let stab = ecx.tcx.lookup_stability(associated_const.def_id); + let depr = ecx.tcx.lookup_deprecation(associated_const.def_id); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); + + if let Some(ii) = impl_item_opt { + encode_attributes(rbml_w, &ii.attrs); + encode_defaultness(rbml_w, ii.defaultness); + encode_inlined_item(ecx, + rbml_w, + InlinedItemRef::ImplItem(ecx.tcx.map.local_def_id(parent_id), + ii)); + self.encode_mir(rbml_w, ii.id); } + + rbml_w.end_tag(); } - rbml_w.end_tag(); -} + fn encode_info_for_method(&mut self, + rbml_w: &mut Encoder, + m: &ty::Method<'tcx>, + is_default_impl: bool, + parent_id: NodeId, + impl_item_opt: Option<&hir::ImplItem>) { + let ecx = self.ecx(); + + debug!("encode_info_for_method: {:?} {:?}", m.def_id, + m.name); + let _task = self.record(m.def_id, rbml_w); + rbml_w.start_tag(tag_items_data_item); -fn encode_info_for_associated_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, - rbml_w: &mut Encoder, - index: &mut IndexBuilder<'a, 'tcx>, - associated_type: &ty::AssociatedType<'tcx>, - parent_id: NodeId, - impl_item_opt: Option<&hir::ImplItem>) { - debug!("encode_info_for_associated_type({:?},{:?})", - associated_type.def_id, - associated_type.name); - - let _task = index.record(associated_type.def_id, rbml_w); - rbml_w.start_tag(tag_items_data_item); - - encode_def_id_and_key(ecx, rbml_w, associated_type.def_id); - encode_name(rbml_w, associated_type.name); - encode_visibility(rbml_w, associated_type.vis); - encode_family(rbml_w, 'y'); - encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id)); - encode_item_sort(rbml_w, 't'); - - let stab = ecx.tcx.lookup_stability(associated_type.def_id); - let depr = ecx.tcx.lookup_deprecation(associated_type.def_id); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); - - if let Some(ii) = impl_item_opt { - encode_attributes(rbml_w, &ii.attrs); - encode_defaultness(rbml_w, ii.defaultness); - } else { - encode_predicates(rbml_w, index, - &ecx.tcx.lookup_predicates(associated_type.def_id), - tag_item_generics); - } + self.encode_method_ty_fields(rbml_w, m); + self.encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id)); + encode_item_sort(rbml_w, 'r'); + + let stab = ecx.tcx.lookup_stability(m.def_id); + let depr = ecx.tcx.lookup_deprecation(m.def_id); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); - if let Some(ty) = associated_type.ty { - encode_type(ecx, rbml_w, ty); + let m_node_id = ecx.local_id(m.def_id); + self.encode_bounds_and_type_for_item(rbml_w, m_node_id); + + if let Some(impl_item) = impl_item_opt { + if let hir::ImplItemKind::Method(ref sig, _) = impl_item.node { + encode_attributes(rbml_w, &impl_item.attrs); + let generics = ecx.tcx.lookup_generics(m.def_id); + let types = generics.parent_types as usize + generics.types.len(); + let needs_inline = types > 0 || is_default_impl || + attr::requests_inline(&impl_item.attrs); + if needs_inline || sig.constness == hir::Constness::Const { + encode_inlined_item( + ecx, + rbml_w, + InlinedItemRef::ImplItem(ecx.tcx.map.local_def_id(parent_id), + impl_item)); + self.encode_mir(rbml_w, impl_item.id); + } + encode_constness(rbml_w, sig.constness); + encode_defaultness(rbml_w, impl_item.defaultness); + self.encode_method_argument_names(rbml_w, &sig.decl); + } + } + + rbml_w.end_tag(); } - rbml_w.end_tag(); -} + fn encode_info_for_associated_type(&mut self, + rbml_w: &mut Encoder, + associated_type: &ty::AssociatedType<'tcx>, + parent_id: NodeId, + impl_item_opt: Option<&hir::ImplItem>) { + let ecx = self.ecx(); + debug!("encode_info_for_associated_type({:?},{:?})", + associated_type.def_id, + associated_type.name); + + let _task = self.record(associated_type.def_id, rbml_w); + rbml_w.start_tag(tag_items_data_item); + + encode_def_id_and_key(ecx, rbml_w, associated_type.def_id); + encode_name(rbml_w, associated_type.name); + self.encode_visibility(rbml_w, associated_type.vis); + encode_family(rbml_w, 'y'); + self.encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id)); + encode_item_sort(rbml_w, 't'); + + let stab = ecx.tcx.lookup_stability(associated_type.def_id); + let depr = ecx.tcx.lookup_deprecation(associated_type.def_id); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); -fn encode_method_argument_names(rbml_w: &mut Encoder, - decl: &hir::FnDecl) { - rbml_w.start_tag(tag_method_argument_names); - for arg in &decl.inputs { - let tag = tag_method_argument_name; - if let PatKind::Binding(_, ref path1, _) = arg.pat.node { - let name = path1.node.as_str(); - rbml_w.wr_tagged_bytes(tag, name.as_bytes()); + if let Some(ii) = impl_item_opt { + encode_attributes(rbml_w, &ii.attrs); + encode_defaultness(rbml_w, ii.defaultness); } else { - rbml_w.wr_tagged_bytes(tag, &[]); + // TODO this looks bogus and unnecessary + self.encode_predicates(rbml_w, + &ecx.tcx.lookup_predicates(associated_type.def_id), + tag_item_generics); } + + if let Some(ty) = associated_type.ty { + self.encode_type(rbml_w, ty); + } + + rbml_w.end_tag(); } - rbml_w.end_tag(); -} -fn encode_repr_attrs(rbml_w: &mut Encoder, - ecx: &EncodeContext, - attrs: &[ast::Attribute]) { - let mut repr_attrs = Vec::new(); - for attr in attrs { - repr_attrs.extend(attr::find_repr_attrs(ecx.tcx.sess.diagnostic(), - attr)); + fn encode_method_argument_names(&mut self, + rbml_w: &mut Encoder, + decl: &hir::FnDecl) { + rbml_w.start_tag(tag_method_argument_names); + for arg in &decl.inputs { + let tag = tag_method_argument_name; + if let PatKind::Binding(_, ref path1, _) = arg.pat.node { + let name = path1.node.as_str(); + rbml_w.wr_tagged_bytes(tag, name.as_bytes()); + } else { + rbml_w.wr_tagged_bytes(tag, &[]); + } + } + rbml_w.end_tag(); } - rbml_w.start_tag(tag_items_data_item_repr); - repr_attrs.encode(rbml_w); - rbml_w.end_tag(); -} -fn encode_mir(ecx: &EncodeContext, rbml_w: &mut Encoder, node_id: NodeId) { - let def_id = ecx.tcx.map.local_def_id(node_id); - if let Some(mir) = ecx.mir_map.map.get(&def_id) { - rbml_w.start_tag(tag_mir as usize); - rbml_w.emit_opaque(|opaque_encoder| { - tls::enter_encoding_context(ecx, opaque_encoder, |_, opaque_encoder| { - Encodable::encode(mir, opaque_encoder) - }) - }).unwrap(); + fn encode_repr_attrs(&mut self, + rbml_w: &mut Encoder, + attrs: &[ast::Attribute]) { + let ecx = self.ecx(); + let mut repr_attrs = Vec::new(); + for attr in attrs { + repr_attrs.extend(attr::find_repr_attrs(ecx.tcx.sess.diagnostic(), + attr)); + } + rbml_w.start_tag(tag_items_data_item_repr); + repr_attrs.encode(rbml_w); rbml_w.end_tag(); } + + fn encode_mir(&mut self, rbml_w: &mut Encoder, node_id: NodeId) { + let ecx = self.ecx(); + let def_id = ecx.tcx.map.local_def_id(node_id); + if let Some(mir) = ecx.mir_map.map.get(&def_id) { + rbml_w.start_tag(tag_mir as usize); + rbml_w.emit_opaque(|opaque_encoder| { + tls::enter_encoding_context(ecx, opaque_encoder, |_, opaque_encoder| { + Encodable::encode(mir, opaque_encoder) + }) + }).unwrap(); + rbml_w.end_tag(); + } + } } const FN_FAMILY: char = 'f'; @@ -762,544 +774,539 @@ fn encode_xrefs<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w.end_tag(); } -fn encode_info_for_item<'a, 'tcx>(rbml_w: &mut Encoder, - item: &hir::Item, - index: &mut IndexBuilder<'a, 'tcx>) { - let ecx = index.ecx(); - let tcx = ecx.tcx; - - debug!("encoding info for item at {}", - tcx.sess.codemap().span_to_string(item.span)); - - let vis = &item.vis; - let def_id = ecx.tcx.map.local_def_id(item.id); - - let (stab, depr) = tcx.dep_graph.with_task(DepNode::MetaData(def_id), || { - (tcx.lookup_stability(ecx.tcx.map.local_def_id(item.id)), - tcx.lookup_deprecation(ecx.tcx.map.local_def_id(item.id))) - }); - - match item.node { - hir::ItemStatic(_, m, _) => { - let _task = index.record(def_id, rbml_w); - rbml_w.start_tag(tag_items_data_item); - encode_def_id_and_key(ecx, rbml_w, def_id); - if m == hir::MutMutable { - encode_family(rbml_w, 'b'); - } else { - encode_family(rbml_w, 'c'); - } - encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id); - encode_name(rbml_w, item.name); - encode_visibility(rbml_w, vis); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); - encode_attributes(rbml_w, &item.attrs); - rbml_w.end_tag(); - } - hir::ItemConst(_, _) => { - let _task = index.record(def_id, rbml_w); - rbml_w.start_tag(tag_items_data_item); - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_family(rbml_w, 'C'); - encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id); - encode_name(rbml_w, item.name); - encode_attributes(rbml_w, &item.attrs); - encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(def_id, item)); - encode_mir(ecx, rbml_w, item.id); - encode_visibility(rbml_w, vis); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); - rbml_w.end_tag(); - } - hir::ItemFn(ref decl, _, constness, _, ref generics, _) => { - let _task = index.record(def_id, rbml_w); - rbml_w.start_tag(tag_items_data_item); - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_family(rbml_w, FN_FAMILY); - let tps_len = generics.ty_params.len(); - encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id); - encode_name(rbml_w, item.name); - encode_attributes(rbml_w, &item.attrs); - let needs_inline = tps_len > 0 || attr::requests_inline(&item.attrs); - if needs_inline || constness == hir::Constness::Const { - encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(def_id, item)); - encode_mir(ecx, rbml_w, item.id); - } - encode_constness(rbml_w, constness); - encode_visibility(rbml_w, vis); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); - encode_method_argument_names(rbml_w, &decl); - rbml_w.end_tag(); - } - hir::ItemMod(ref m) => { - let _task = index.record(def_id, rbml_w); - encode_info_for_mod(ecx, - rbml_w, - m, - &item.attrs, - item.id, - item.name, - &item.vis); - } - hir::ItemForeignMod(ref fm) => { - let _task = index.record(def_id, rbml_w); - rbml_w.start_tag(tag_items_data_item); - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_family(rbml_w, 'n'); - encode_name(rbml_w, item.name); - - // Encode all the items in this module. - for foreign_item in &fm.items { - rbml_w.wr_tagged_u64(tag_mod_child, - def_to_u64(ecx.tcx.map.local_def_id(foreign_item.id))); - } - encode_visibility(rbml_w, vis); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); - rbml_w.end_tag(); - } - hir::ItemTy(..) => { - let _task = index.record(def_id, rbml_w); - rbml_w.start_tag(tag_items_data_item); - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_family(rbml_w, 'y'); - encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id); - encode_name(rbml_w, item.name); - encode_visibility(rbml_w, vis); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); - rbml_w.end_tag(); - } - hir::ItemEnum(ref enum_definition, _) => { - let _task = index.record(def_id, rbml_w); - - rbml_w.start_tag(tag_items_data_item); - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_family(rbml_w, 't'); - encode_item_variances(rbml_w, ecx, item.id); - encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id); - encode_name(rbml_w, item.name); - encode_attributes(rbml_w, &item.attrs); - encode_repr_attrs(rbml_w, ecx, &item.attrs); - for v in &enum_definition.variants { - encode_variant_id(rbml_w, ecx.tcx.map.local_def_id(v.node.data.id())); - } - encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(def_id, item)); - encode_mir(ecx, rbml_w, item.id); - - // Encode inherent implementations for this enumeration. - encode_inherent_implementations(ecx, rbml_w, def_id); - - encode_visibility(rbml_w, vis); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); - rbml_w.end_tag(); +impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { + fn encode_info_for_item(&mut self, + rbml_w: &mut Encoder, + item: &hir::Item) { + let ecx = self.ecx(); + let tcx = ecx.tcx; - encode_enum_variant_info(ecx, - rbml_w, - def_id, - vis, - index); - } - hir::ItemStruct(ref struct_def, _) => { - /* Index the class*/ - let _task = index.record(def_id, rbml_w); + debug!("encoding info for item at {}", + tcx.sess.codemap().span_to_string(item.span)); - let def = ecx.tcx.lookup_adt_def(def_id); - let variant = def.struct_variant(); + let vis = &item.vis; + let def_id = ecx.tcx.map.local_def_id(item.id); - /* Now, make an item for the class itself */ - rbml_w.start_tag(tag_items_data_item); - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_family(rbml_w, match *struct_def { - hir::VariantData::Struct(..) => 'S', - hir::VariantData::Tuple(..) => 's', - hir::VariantData::Unit(..) => 'u', + let (stab, depr) = tcx.dep_graph.with_task(DepNode::MetaData(def_id), || { + (tcx.lookup_stability(ecx.tcx.map.local_def_id(item.id)), + tcx.lookup_deprecation(ecx.tcx.map.local_def_id(item.id))) }); - encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id); - - encode_item_variances(rbml_w, ecx, item.id); - encode_name(rbml_w, item.name); - encode_attributes(rbml_w, &item.attrs); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); - encode_visibility(rbml_w, vis); - encode_repr_attrs(rbml_w, ecx, &item.attrs); - - /* Encode def_ids for each field and method - for methods, write all the stuff get_trait_method - needs to know*/ - encode_struct_fields(rbml_w, variant); - encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(def_id, item)); - encode_mir(ecx, rbml_w, item.id); - - // Encode inherent implementations for this structure. - encode_inherent_implementations(ecx, rbml_w, def_id); - - if !struct_def.is_struct() { - let ctor_did = ecx.tcx.map.local_def_id(struct_def.id()); - rbml_w.wr_tagged_u64(tag_items_data_item_struct_ctor, - def_to_u64(ctor_did)); - } - - rbml_w.end_tag(); - - for field in &variant.fields { - encode_field(ecx, rbml_w, field, index); - } - - // If this is a tuple-like struct, encode the type of the constructor. - if !struct_def.is_struct() { - encode_info_for_struct_ctor(ecx, rbml_w, item.name, struct_def, index, item.id); - } - } - hir::ItemDefaultImpl(unsafety, _) => { - let _task = index.record(def_id, rbml_w); - rbml_w.start_tag(tag_items_data_item); - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_family(rbml_w, 'd'); - encode_name(rbml_w, item.name); - encode_unsafety(rbml_w, unsafety); - - let trait_ref = tcx.impl_trait_ref(ecx.tcx.map.local_def_id(item.id)).unwrap(); - encode_trait_ref(rbml_w, ecx, trait_ref, tag_item_trait_ref); - rbml_w.end_tag(); - } - hir::ItemImpl(unsafety, polarity, _, _, _, ref ast_items) => { - let _task = index.record(def_id, rbml_w); - - // We need to encode information about the default methods we - // have inherited, so we drive this based on the impl structure. - let impl_items = tcx.impl_items.borrow(); - let items = impl_items.get(&def_id).unwrap(); - - rbml_w.start_tag(tag_items_data_item); - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_family(rbml_w, 'i'); - encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id); - encode_name(rbml_w, item.name); - encode_attributes(rbml_w, &item.attrs); - encode_unsafety(rbml_w, unsafety); - encode_polarity(rbml_w, polarity); - - match tcx.custom_coerce_unsized_kinds.borrow().get(&ecx.tcx.map.local_def_id(item.id)) { - Some(&kind) => { - rbml_w.start_tag(tag_impl_coerce_unsized_kind); - kind.encode(rbml_w); + match item.node { + hir::ItemStatic(_, m, _) => { + let _task = self.record(def_id, rbml_w); + rbml_w.start_tag(tag_items_data_item); + encode_def_id_and_key(ecx, rbml_w, def_id); + if m == hir::MutMutable { + encode_family(rbml_w, 'b'); + } else { + encode_family(rbml_w, 'c'); + } + self.encode_bounds_and_type_for_item(rbml_w, item.id); + encode_name(rbml_w, item.name); + self.encode_visibility(rbml_w, vis); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); + encode_attributes(rbml_w, &item.attrs); rbml_w.end_tag(); } - None => {} - } - - for &item_def_id in items { - rbml_w.start_tag(tag_item_impl_item); - match item_def_id { - ty::ConstTraitItemId(item_def_id) => { - encode_def_id(rbml_w, item_def_id); - encode_item_sort(rbml_w, 'C'); + hir::ItemConst(_, _) => { + let _task = self.record(def_id, rbml_w); + rbml_w.start_tag(tag_items_data_item); + encode_def_id_and_key(ecx, rbml_w, def_id); + encode_family(rbml_w, 'C'); + self.encode_bounds_and_type_for_item(rbml_w, item.id); + encode_name(rbml_w, item.name); + encode_attributes(rbml_w, &item.attrs); + encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(def_id, item)); + self.encode_mir(rbml_w, item.id); + self.encode_visibility(rbml_w, vis); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); + rbml_w.end_tag(); + } + hir::ItemFn(ref decl, _, constness, _, ref generics, _) => { + let _task = self.record(def_id, rbml_w); + rbml_w.start_tag(tag_items_data_item); + encode_def_id_and_key(ecx, rbml_w, def_id); + encode_family(rbml_w, FN_FAMILY); + let tps_len = generics.ty_params.len(); + self.encode_bounds_and_type_for_item(rbml_w, item.id); + encode_name(rbml_w, item.name); + encode_attributes(rbml_w, &item.attrs); + let needs_inline = tps_len > 0 || attr::requests_inline(&item.attrs); + if needs_inline || constness == hir::Constness::Const { + encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(def_id, item)); + self.encode_mir(rbml_w, item.id); } - ty::MethodTraitItemId(item_def_id) => { - encode_def_id(rbml_w, item_def_id); - encode_item_sort(rbml_w, 'r'); + encode_constness(rbml_w, constness); + self.encode_visibility(rbml_w, vis); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); + self.encode_method_argument_names(rbml_w, &decl); + rbml_w.end_tag(); + } + hir::ItemMod(ref m) => { + let _task = self.record(def_id, rbml_w); + self.encode_info_for_mod(rbml_w, + m, + &item.attrs, + item.id, + item.name, + &item.vis); + } + hir::ItemForeignMod(ref fm) => { + let _task = self.record(def_id, rbml_w); + rbml_w.start_tag(tag_items_data_item); + encode_def_id_and_key(ecx, rbml_w, def_id); + encode_family(rbml_w, 'n'); + encode_name(rbml_w, item.name); + + // Encode all the items in this module. + for foreign_item in &fm.items { + rbml_w.wr_tagged_u64(tag_mod_child, + def_to_u64(ecx.tcx.map.local_def_id(foreign_item.id))); } - ty::TypeTraitItemId(item_def_id) => { - encode_def_id(rbml_w, item_def_id); - encode_item_sort(rbml_w, 't'); + self.encode_visibility(rbml_w, vis); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); + rbml_w.end_tag(); + } + hir::ItemTy(..) => { + let _task = self.record(def_id, rbml_w); + rbml_w.start_tag(tag_items_data_item); + encode_def_id_and_key(ecx, rbml_w, def_id); + encode_family(rbml_w, 'y'); + self.encode_bounds_and_type_for_item(rbml_w, item.id); + encode_name(rbml_w, item.name); + self.encode_visibility(rbml_w, vis); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); + rbml_w.end_tag(); + } + hir::ItemEnum(ref enum_definition, _) => { + let _task = self.record(def_id, rbml_w); + + rbml_w.start_tag(tag_items_data_item); + encode_def_id_and_key(ecx, rbml_w, def_id); + encode_family(rbml_w, 't'); + encode_item_variances(rbml_w, ecx, item.id); + self.encode_bounds_and_type_for_item(rbml_w, item.id); + encode_name(rbml_w, item.name); + encode_attributes(rbml_w, &item.attrs); + self.encode_repr_attrs(rbml_w, &item.attrs); + for v in &enum_definition.variants { + encode_variant_id(rbml_w, ecx.tcx.map.local_def_id(v.node.data.id())); } + encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(def_id, item)); + self.encode_mir(rbml_w, item.id); + + // Encode inherent implementations for this enumeration. + encode_inherent_implementations(ecx, rbml_w, def_id); + + self.encode_visibility(rbml_w, vis); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); + rbml_w.end_tag(); + + self.encode_enum_variant_info(rbml_w, + def_id, + vis); } - rbml_w.end_tag(); - } - let did = ecx.tcx.map.local_def_id(item.id); - if let Some(trait_ref) = tcx.impl_trait_ref(did) { - encode_trait_ref(rbml_w, ecx, trait_ref, tag_item_trait_ref); - - let trait_def = tcx.lookup_trait_def(trait_ref.def_id); - let parent = trait_def.ancestors(did) - .skip(1) - .next() - .and_then(|node| match node { - specialization_graph::Node::Impl(parent) => Some(parent), - _ => None, + hir::ItemStruct(ref struct_def, _) => { + /* Index the class*/ + let _task = self.record(def_id, rbml_w); + + let def = ecx.tcx.lookup_adt_def(def_id); + let variant = def.struct_variant(); + + /* Now, make an item for the class itself */ + rbml_w.start_tag(tag_items_data_item); + encode_def_id_and_key(ecx, rbml_w, def_id); + encode_family(rbml_w, match *struct_def { + hir::VariantData::Struct(..) => 'S', + hir::VariantData::Tuple(..) => 's', + hir::VariantData::Unit(..) => 'u', }); - encode_parent_impl(rbml_w, parent); - } - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); - rbml_w.end_tag(); - - // Iterate down the trait items, emitting them. We rely on the - // assumption that all of the actually implemented trait items - // appear first in the impl structure, in the same order they do - // in the ast. This is a little sketchy. - let num_implemented_methods = ast_items.len(); - for (i, &trait_item_def_id) in items.iter().enumerate() { - let ast_item = if i < num_implemented_methods { - Some(&ast_items[i]) - } else { - None - }; - - match tcx.impl_or_trait_item(trait_item_def_id.def_id()) { - ty::ConstTraitItem(ref associated_const) => { - encode_info_for_associated_const(ecx, - rbml_w, - index, - &associated_const, - item.id, - ast_item) + self.encode_bounds_and_type_for_item(rbml_w, item.id); + + encode_item_variances(rbml_w, ecx, item.id); + encode_name(rbml_w, item.name); + encode_attributes(rbml_w, &item.attrs); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); + self.encode_visibility(rbml_w, vis); + self.encode_repr_attrs(rbml_w, &item.attrs); + + /* Encode def_ids for each field and method + for methods, write all the stuff get_trait_method + needs to know*/ + self.encode_struct_fields(rbml_w, variant); + + encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(def_id, item)); + self.encode_mir(rbml_w, item.id); + + // Encode inherent implementations for this structure. + encode_inherent_implementations(ecx, rbml_w, def_id); + + if !struct_def.is_struct() { + let ctor_did = ecx.tcx.map.local_def_id(struct_def.id()); + rbml_w.wr_tagged_u64(tag_items_data_item_struct_ctor, + def_to_u64(ctor_did)); } - ty::MethodTraitItem(ref method_type) => { - encode_info_for_method(ecx, - rbml_w, - index, - &method_type, - false, - item.id, - ast_item) + + rbml_w.end_tag(); + + for field in &variant.fields { + self.encode_field(rbml_w, field); } - ty::TypeTraitItem(ref associated_type) => { - encode_info_for_associated_type(ecx, - rbml_w, - index, - &associated_type, - item.id, - ast_item) + + // If this is a tuple-like struct, encode the type of the constructor. + if !struct_def.is_struct() { + self.encode_info_for_struct_ctor(rbml_w, item.name, struct_def, item.id); } } - } - } - hir::ItemTrait(_, _, _, ref ms) => { - let _task = index.record(def_id, rbml_w); - rbml_w.start_tag(tag_items_data_item); - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_family(rbml_w, 'I'); - encode_item_variances(rbml_w, ecx, item.id); - let trait_def = tcx.lookup_trait_def(def_id); - let trait_predicates = tcx.lookup_predicates(def_id); - encode_unsafety(rbml_w, trait_def.unsafety); - encode_paren_sugar(rbml_w, trait_def.paren_sugar); - encode_defaulted(rbml_w, tcx.trait_has_default_impl(def_id)); - encode_associated_type_names(rbml_w, &trait_def.associated_type_names); - encode_generics(rbml_w, ecx, index, - &trait_def.generics, &trait_predicates); - encode_predicates(rbml_w, index, - &tcx.lookup_super_predicates(def_id), - tag_item_super_predicates); - encode_trait_ref(rbml_w, ecx, trait_def.trait_ref, tag_item_trait_ref); - encode_name(rbml_w, item.name); - encode_attributes(rbml_w, &item.attrs); - encode_visibility(rbml_w, vis); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); - for &method_def_id in tcx.trait_item_def_ids(def_id).iter() { - rbml_w.start_tag(tag_item_trait_item); - match method_def_id { - ty::ConstTraitItemId(const_def_id) => { - encode_def_id(rbml_w, const_def_id); - encode_item_sort(rbml_w, 'C'); + hir::ItemDefaultImpl(unsafety, _) => { + let _task = self.record(def_id, rbml_w); + rbml_w.start_tag(tag_items_data_item); + encode_def_id_and_key(ecx, rbml_w, def_id); + encode_family(rbml_w, 'd'); + encode_name(rbml_w, item.name); + encode_unsafety(rbml_w, unsafety); + + let trait_ref = tcx.impl_trait_ref(ecx.tcx.map.local_def_id(item.id)).unwrap(); + encode_trait_ref(rbml_w, ecx, trait_ref, tag_item_trait_ref); + rbml_w.end_tag(); + } + hir::ItemImpl(unsafety, polarity, _, _, _, ref ast_items) => { + let _task = self.record(def_id, rbml_w); + + // We need to encode information about the default methods we + // have inherited, so we drive this based on the impl structure. + let impl_items = tcx.impl_items.borrow(); + let items = impl_items.get(&def_id).unwrap(); + + rbml_w.start_tag(tag_items_data_item); + encode_def_id_and_key(ecx, rbml_w, def_id); + encode_family(rbml_w, 'i'); + self.encode_bounds_and_type_for_item(rbml_w, item.id); + encode_name(rbml_w, item.name); + encode_attributes(rbml_w, &item.attrs); + encode_unsafety(rbml_w, unsafety); + encode_polarity(rbml_w, polarity); + + match tcx.custom_coerce_unsized_kinds + .borrow() + .get(&ecx.tcx.map.local_def_id(item.id)) { + Some(&kind) => { + rbml_w.start_tag(tag_impl_coerce_unsized_kind); + kind.encode(rbml_w); + rbml_w.end_tag(); + } + None => {} } - ty::MethodTraitItemId(method_def_id) => { - encode_def_id(rbml_w, method_def_id); - encode_item_sort(rbml_w, 'r'); + + for &item_def_id in items { + rbml_w.start_tag(tag_item_impl_item); + match item_def_id { + ty::ConstTraitItemId(item_def_id) => { + encode_def_id(rbml_w, item_def_id); + encode_item_sort(rbml_w, 'C'); + } + ty::MethodTraitItemId(item_def_id) => { + encode_def_id(rbml_w, item_def_id); + encode_item_sort(rbml_w, 'r'); + } + ty::TypeTraitItemId(item_def_id) => { + encode_def_id(rbml_w, item_def_id); + encode_item_sort(rbml_w, 't'); + } + } + rbml_w.end_tag(); } - ty::TypeTraitItemId(type_def_id) => { - encode_def_id(rbml_w, type_def_id); - encode_item_sort(rbml_w, 't'); + let did = ecx.tcx.map.local_def_id(item.id); + if let Some(trait_ref) = tcx.impl_trait_ref(did) { + encode_trait_ref(rbml_w, ecx, trait_ref, tag_item_trait_ref); + + let trait_def = tcx.lookup_trait_def(trait_ref.def_id); + let parent = trait_def.ancestors(did) + .skip(1) + .next() + .and_then(|node| match node { + specialization_graph::Node::Impl(parent) => + Some(parent), + _ => None, + }); + encode_parent_impl(rbml_w, parent); } - } - rbml_w.end_tag(); - - rbml_w.wr_tagged_u64(tag_mod_child, - def_to_u64(method_def_id.def_id())); - } + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); + rbml_w.end_tag(); - // Encode inherent implementations for this trait. - encode_inherent_implementations(ecx, rbml_w, def_id); + // Iterate down the trait items, emitting them. We rely on the + // assumption that all of the actually implemented trait items + // appear first in the impl structure, in the same order they do + // in the ast. This is a little sketchy. + let num_implemented_methods = ast_items.len(); + for (i, &trait_item_def_id) in items.iter().enumerate() { + let ast_item = if i < num_implemented_methods { + Some(&ast_items[i]) + } else { + None + }; + + match tcx.impl_or_trait_item(trait_item_def_id.def_id()) { + ty::ConstTraitItem(ref associated_const) => { + self.encode_info_for_associated_const(rbml_w, + &associated_const, + item.id, + ast_item) + } + ty::MethodTraitItem(ref method_type) => { + self.encode_info_for_method(rbml_w, + &method_type, + false, + item.id, + ast_item) + } + ty::TypeTraitItem(ref associated_type) => { + self.encode_info_for_associated_type(rbml_w, + &associated_type, + item.id, + ast_item) + } + } + } + } + hir::ItemTrait(_, _, _, ref ms) => { + let _task = self.record(def_id, rbml_w); + rbml_w.start_tag(tag_items_data_item); + encode_def_id_and_key(ecx, rbml_w, def_id); + encode_family(rbml_w, 'I'); + encode_item_variances(rbml_w, ecx, item.id); + let trait_def = tcx.lookup_trait_def(def_id); + let trait_predicates = tcx.lookup_predicates(def_id); + encode_unsafety(rbml_w, trait_def.unsafety); + encode_paren_sugar(rbml_w, trait_def.paren_sugar); + encode_defaulted(rbml_w, tcx.trait_has_default_impl(def_id)); + encode_associated_type_names(rbml_w, &trait_def.associated_type_names); + self.encode_generics(rbml_w, &trait_def.generics, &trait_predicates); + self.encode_predicates(rbml_w, &tcx.lookup_super_predicates(def_id), tag_item_super_predicates); + encode_trait_ref(rbml_w, ecx, trait_def.trait_ref, tag_item_trait_ref); + encode_name(rbml_w, item.name); + encode_attributes(rbml_w, &item.attrs); + self.encode_visibility(rbml_w, vis); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); + for &method_def_id in tcx.trait_item_def_ids(def_id).iter() { + rbml_w.start_tag(tag_item_trait_item); + match method_def_id { + ty::ConstTraitItemId(const_def_id) => { + encode_def_id(rbml_w, const_def_id); + encode_item_sort(rbml_w, 'C'); + } + ty::MethodTraitItemId(method_def_id) => { + encode_def_id(rbml_w, method_def_id); + encode_item_sort(rbml_w, 'r'); + } + ty::TypeTraitItemId(type_def_id) => { + encode_def_id(rbml_w, type_def_id); + encode_item_sort(rbml_w, 't'); + } + } + rbml_w.end_tag(); - rbml_w.end_tag(); + rbml_w.wr_tagged_u64(tag_mod_child, + def_to_u64(method_def_id.def_id())); + } - // Now output the trait item info for each trait item. - let r = tcx.trait_item_def_ids(def_id); - for (i, &item_def_id) in r.iter().enumerate() { - assert_eq!(item_def_id.def_id().krate, LOCAL_CRATE); + // Encode inherent implementations for this trait. + encode_inherent_implementations(ecx, rbml_w, def_id); - let _task = index.record(item_def_id.def_id(), rbml_w); - rbml_w.start_tag(tag_items_data_item); + rbml_w.end_tag(); - encode_parent_item(rbml_w, def_id); + // Now output the trait item info for each trait item. + let r = tcx.trait_item_def_ids(def_id); + for (i, &item_def_id) in r.iter().enumerate() { + assert_eq!(item_def_id.def_id().krate, LOCAL_CRATE); - let stab = tcx.lookup_stability(item_def_id.def_id()); - let depr = tcx.lookup_deprecation(item_def_id.def_id()); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); + let _task = self.record(item_def_id.def_id(), rbml_w); + rbml_w.start_tag(tag_items_data_item); - let trait_item_type = - tcx.impl_or_trait_item(item_def_id.def_id()); - let is_nonstatic_method; - match trait_item_type { - ty::ConstTraitItem(associated_const) => { - encode_name(rbml_w, associated_const.name); - encode_def_id_and_key(ecx, rbml_w, associated_const.def_id); - encode_visibility(rbml_w, associated_const.vis); + self.encode_parent_item(rbml_w, def_id); - encode_family(rbml_w, 'C'); + let stab = tcx.lookup_stability(item_def_id.def_id()); + let depr = tcx.lookup_deprecation(item_def_id.def_id()); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); - encode_bounds_and_type_for_item(rbml_w, ecx, index, - ecx.local_id(associated_const.def_id)); + let trait_item_type = + tcx.impl_or_trait_item(item_def_id.def_id()); + let is_nonstatic_method; + match trait_item_type { + ty::ConstTraitItem(associated_const) => { + encode_name(rbml_w, associated_const.name); + encode_def_id_and_key(ecx, rbml_w, associated_const.def_id); + self.encode_visibility(rbml_w, associated_const.vis); - is_nonstatic_method = false; - } - ty::MethodTraitItem(method_ty) => { - let method_def_id = item_def_id.def_id(); + encode_family(rbml_w, 'C'); - encode_method_ty_fields(ecx, rbml_w, index, &method_ty); + self.encode_bounds_and_type_for_item( + rbml_w, + ecx.local_id(associated_const.def_id)); - match method_ty.explicit_self { - ty::ExplicitSelfCategory::Static => { - encode_family(rbml_w, - STATIC_METHOD_FAMILY); + is_nonstatic_method = false; } - _ => { - encode_family(rbml_w, - METHOD_FAMILY); + ty::MethodTraitItem(method_ty) => { + let method_def_id = item_def_id.def_id(); + + self.encode_method_ty_fields(rbml_w, &method_ty); + + match method_ty.explicit_self { + ty::ExplicitSelfCategory::Static => { + encode_family(rbml_w, + STATIC_METHOD_FAMILY); + } + _ => { + encode_family(rbml_w, + METHOD_FAMILY); + } + } + self.encode_bounds_and_type_for_item(rbml_w, + ecx.local_id(method_def_id)); + + is_nonstatic_method = method_ty.explicit_self != + ty::ExplicitSelfCategory::Static; } - } - encode_bounds_and_type_for_item(rbml_w, ecx, index, - ecx.local_id(method_def_id)); - - is_nonstatic_method = method_ty.explicit_self != - ty::ExplicitSelfCategory::Static; - } - ty::TypeTraitItem(associated_type) => { - encode_name(rbml_w, associated_type.name); - encode_def_id_and_key(ecx, rbml_w, associated_type.def_id); - encode_item_sort(rbml_w, 't'); - encode_family(rbml_w, 'y'); - - if let Some(ty) = associated_type.ty { - encode_type(ecx, rbml_w, ty); - } + ty::TypeTraitItem(associated_type) => { + encode_name(rbml_w, associated_type.name); + encode_def_id_and_key(ecx, rbml_w, associated_type.def_id); + encode_item_sort(rbml_w, 't'); + encode_family(rbml_w, 'y'); - is_nonstatic_method = false; - } - } + if let Some(ty) = associated_type.ty { + self.encode_type(rbml_w, ty); + } - let trait_item = &ms[i]; - encode_attributes(rbml_w, &trait_item.attrs); - match trait_item.node { - hir::ConstTraitItem(_, ref default) => { - if default.is_some() { - encode_item_sort(rbml_w, 'C'); - } else { - encode_item_sort(rbml_w, 'c'); + is_nonstatic_method = false; + } } - encode_inlined_item(ecx, rbml_w, - InlinedItemRef::TraitItem(def_id, trait_item)); - encode_mir(ecx, rbml_w, trait_item.id); - } - hir::MethodTraitItem(ref sig, ref body) => { - // If this is a static method, we've already - // encoded this. - if is_nonstatic_method { - // FIXME: I feel like there is something funny - // going on. - encode_bounds_and_type_for_item(rbml_w, ecx, index, - ecx.local_id(item_def_id.def_id())); - } + let trait_item = &ms[i]; + encode_attributes(rbml_w, &trait_item.attrs); + match trait_item.node { + hir::ConstTraitItem(_, ref default) => { + if default.is_some() { + encode_item_sort(rbml_w, 'C'); + } else { + encode_item_sort(rbml_w, 'c'); + } + + encode_inlined_item(ecx, rbml_w, + InlinedItemRef::TraitItem(def_id, trait_item)); + self.encode_mir(rbml_w, trait_item.id); + } + hir::MethodTraitItem(ref sig, ref body) => { + // If this is a static method, we've already + // encoded this. + if is_nonstatic_method { + self.encode_bounds_and_type_for_item( + rbml_w, + ecx.local_id(item_def_id.def_id())); + } + + if body.is_some() { + encode_item_sort(rbml_w, 'p'); + encode_inlined_item(ecx, rbml_w, + InlinedItemRef::TraitItem(def_id, trait_item)); + self.encode_mir(rbml_w, trait_item.id); + } else { + encode_item_sort(rbml_w, 'r'); + } + self.encode_method_argument_names(rbml_w, &sig.decl); + } - if body.is_some() { - encode_item_sort(rbml_w, 'p'); - encode_inlined_item(ecx, rbml_w, - InlinedItemRef::TraitItem(def_id, trait_item)); - encode_mir(ecx, rbml_w, trait_item.id); - } else { - encode_item_sort(rbml_w, 'r'); + hir::TypeTraitItem(..) => {} } - encode_method_argument_names(rbml_w, &sig.decl); - } - hir::TypeTraitItem(..) => {} + rbml_w.end_tag(); + } + } + hir::ItemExternCrate(_) | hir::ItemUse(_) => { + // these are encoded separately } - - rbml_w.end_tag(); } - } - hir::ItemExternCrate(_) | hir::ItemUse(_) => { - // these are encoded separately - } } } -fn encode_info_for_foreign_item<'a, 'tcx>(rbml_w: &mut Encoder, - nitem: &hir::ForeignItem, - index: &mut IndexBuilder<'a, 'tcx>) { - let ecx = index.ecx(); - - debug!("writing foreign item {}", ecx.tcx.node_path_str(nitem.id)); - let def_id = ecx.tcx.map.local_def_id(nitem.id); - let abi = ecx.tcx.map.get_foreign_abi(nitem.id); - - let _task = index.record(def_id, rbml_w); - rbml_w.start_tag(tag_items_data_item); - encode_def_id_and_key(ecx, rbml_w, def_id); - let parent_id = ecx.tcx.map.get_parent(nitem.id); - encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id)); - encode_visibility(rbml_w, &nitem.vis); - match nitem.node { - hir::ForeignItemFn(ref fndecl, _) => { - encode_family(rbml_w, FN_FAMILY); - encode_bounds_and_type_for_item(rbml_w, ecx, index, nitem.id); - encode_name(rbml_w, nitem.name); - if abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic { - encode_inlined_item(ecx, rbml_w, InlinedItemRef::Foreign(def_id, nitem)); - encode_mir(ecx, rbml_w, nitem.id); - } - encode_attributes(rbml_w, &nitem.attrs); - let stab = ecx.tcx.lookup_stability(ecx.tcx.map.local_def_id(nitem.id)); - let depr = ecx.tcx.lookup_deprecation(ecx.tcx.map.local_def_id(nitem.id)); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); - encode_method_argument_names(rbml_w, &fndecl); - } - hir::ForeignItemStatic(_, mutbl) => { - if mutbl { - encode_family(rbml_w, 'b'); - } else { - encode_family(rbml_w, 'c'); +impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { + fn encode_info_for_foreign_item(&mut self, + rbml_w: &mut Encoder, + nitem: &hir::ForeignItem) { + let ecx = self.ecx(); + + debug!("writing foreign item {}", ecx.tcx.node_path_str(nitem.id)); + let def_id = ecx.tcx.map.local_def_id(nitem.id); + let abi = ecx.tcx.map.get_foreign_abi(nitem.id); + + let _task = self.record(def_id, rbml_w); + rbml_w.start_tag(tag_items_data_item); + encode_def_id_and_key(ecx, rbml_w, def_id); + let parent_id = ecx.tcx.map.get_parent(nitem.id); + self.encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id)); + self.encode_visibility(rbml_w, &nitem.vis); + match nitem.node { + hir::ForeignItemFn(ref fndecl, _) => { + encode_family(rbml_w, FN_FAMILY); + self.encode_bounds_and_type_for_item(rbml_w, nitem.id); + encode_name(rbml_w, nitem.name); + if abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic { + encode_inlined_item(ecx, rbml_w, InlinedItemRef::Foreign(def_id, nitem)); + self.encode_mir(rbml_w, nitem.id); + } + encode_attributes(rbml_w, &nitem.attrs); + let stab = ecx.tcx.lookup_stability(ecx.tcx.map.local_def_id(nitem.id)); + let depr = ecx.tcx.lookup_deprecation(ecx.tcx.map.local_def_id(nitem.id)); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); + self.encode_method_argument_names(rbml_w, &fndecl); + } + hir::ForeignItemStatic(_, mutbl) => { + if mutbl { + encode_family(rbml_w, 'b'); + } else { + encode_family(rbml_w, 'c'); + } + self.encode_bounds_and_type_for_item(rbml_w, nitem.id); + encode_attributes(rbml_w, &nitem.attrs); + let stab = ecx.tcx.lookup_stability(ecx.tcx.map.local_def_id(nitem.id)); + let depr = ecx.tcx.lookup_deprecation(ecx.tcx.map.local_def_id(nitem.id)); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); + encode_name(rbml_w, nitem.name); + } } - encode_bounds_and_type_for_item(rbml_w, ecx, index, nitem.id); - encode_attributes(rbml_w, &nitem.attrs); - let stab = ecx.tcx.lookup_stability(ecx.tcx.map.local_def_id(nitem.id)); - let depr = ecx.tcx.lookup_deprecation(ecx.tcx.map.local_def_id(nitem.id)); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); - encode_name(rbml_w, nitem.name); - } + rbml_w.end_tag(); } - rbml_w.end_tag(); } struct EncodeVisitor<'a, 'data:'a, 'ecx: 'a, 'tcx: 'ecx> { - rbml_w_for_visit_item: &'a mut Encoder<'data>, + rbml_w: &'a mut Encoder<'data>, index: &'a mut IndexBuilder<'ecx, 'tcx>, } impl<'a, 'data, 'ecx, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'data, 'ecx, 'tcx> { fn visit_expr(&mut self, ex: &'tcx hir::Expr) { intravisit::walk_expr(self, ex); - encode_info_for_expr(ex, self.rbml_w_for_visit_item, self.index); + self.index.encode_info_for_expr(ex, self.rbml_w); } fn visit_item(&mut self, i: &'tcx hir::Item) { intravisit::walk_item(self, i); - encode_info_for_item(self.rbml_w_for_visit_item, i, self.index); + self.index.encode_info_for_item(self.rbml_w, i); } fn visit_foreign_item(&mut self, ni: &'tcx hir::ForeignItem) { intravisit::walk_foreign_item(self, ni); - encode_info_for_foreign_item(self.rbml_w_for_visit_item, ni, self.index); + self.index.encode_info_for_foreign_item(self.rbml_w, ni); } fn visit_ty(&mut self, ty: &'tcx hir::Ty) { intravisit::walk_ty(self, ty); @@ -1307,50 +1314,50 @@ impl<'a, 'data, 'ecx, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'data, 'ecx, 'tc } } -fn encode_info_for_ty(ty: &hir::Ty, - rbml_w: &mut Encoder, - index: &mut IndexBuilder) { - let ecx = index.ecx(); - if let hir::TyImplTrait(_) = ty.node { - let def_id = ecx.tcx.map.local_def_id(ty.id); - let _task = index.record(def_id, rbml_w); - rbml_w.start_tag(tag_items_data_item); - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_family(rbml_w, 'y'); - encode_bounds_and_type_for_item(rbml_w, ecx, index, ty.id); - rbml_w.end_tag(); +impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { + fn encode_info_for_ty(&mut self, + ty: &hir::Ty, + rbml_w: &mut Encoder) { + let ecx = self.ecx(); + if let hir::TyImplTrait(_) = ty.node { + let def_id = ecx.tcx.map.local_def_id(ty.id); + let _task = self.record(def_id, rbml_w); + rbml_w.start_tag(tag_items_data_item); + encode_def_id_and_key(ecx, rbml_w, def_id); + encode_family(rbml_w, 'y'); + self.encode_bounds_and_type_for_item(rbml_w, ecx, ty.id); + rbml_w.end_tag(); + } } -} -fn encode_info_for_expr(expr: &hir::Expr, - rbml_w: &mut Encoder, - index: &mut IndexBuilder) { - let ecx = index.ecx(); + fn encode_info_for_expr(&mut self, expr: &hir::Expr, rbml_w: &mut Encoder) { + let ecx = self.ecx(); - match expr.node { - hir::ExprClosure(..) => { - let def_id = ecx.tcx.map.local_def_id(expr.id); + match expr.node { + hir::ExprClosure(..) => { + let def_id = ecx.tcx.map.local_def_id(expr.id); - let _task = index.record(def_id, rbml_w); + let _task = self.record(def_id, rbml_w); - rbml_w.start_tag(tag_items_data_item); - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_name(rbml_w, syntax::parse::token::intern("")); + rbml_w.start_tag(tag_items_data_item); + encode_def_id_and_key(ecx, rbml_w, def_id); + encode_name(rbml_w, syntax::parse::token::intern("")); - rbml_w.start_tag(tag_items_closure_ty); - write_closure_type(ecx, rbml_w, &ecx.tcx.tables.borrow().closure_tys[&def_id]); - rbml_w.end_tag(); + rbml_w.start_tag(tag_items_closure_ty); + write_closure_type(ecx, rbml_w, &ecx.tcx.tables.borrow().closure_tys[&def_id]); + rbml_w.end_tag(); - rbml_w.start_tag(tag_items_closure_kind); - ecx.tcx.closure_kind(def_id).encode(rbml_w).unwrap(); - rbml_w.end_tag(); + rbml_w.start_tag(tag_items_closure_kind); + ecx.tcx.closure_kind(def_id).encode(rbml_w).unwrap(); + rbml_w.end_tag(); - assert!(ecx.mir_map.map.contains_key(&def_id)); - encode_mir(ecx, rbml_w, expr.id); + assert!(ecx.mir_map.map.contains_key(&def_id)); + self.encode_mir(rbml_w, expr.id); - rbml_w.end_tag(); + rbml_w.end_tag(); + } + _ => { } } - _ => { } } } @@ -1364,18 +1371,17 @@ fn encode_info_for_items<'a, 'tcx>(ecx: &'a EncodeContext<'a, 'tcx>, { let _task = index.record(DefId::local(CRATE_DEF_INDEX), rbml_w); - encode_info_for_mod(ecx, - rbml_w, - &krate.module, - &[], - CRATE_NODE_ID, - syntax::parse::token::intern(&ecx.link_meta.crate_name), - &hir::Public); + index.encode_info_for_mod(rbml_w, + &krate.module, + &[], + CRATE_NODE_ID, + syntax::parse::token::intern(&ecx.link_meta.crate_name), + &hir::Public); } krate.visit_all_items(&mut EncodeVisitor { index: &mut index, - rbml_w_for_visit_item: &mut *rbml_w, + rbml_w: &mut *rbml_w, }); rbml_w.end_tag(); From 6b76932ba84958666d0866d5ae21703b3be14701 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 10 Aug 2016 17:29:24 -0400 Subject: [PATCH 06/22] 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 f256d1269340c..49bd861b131e4 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 1e1ae06443643..915bf98519c90 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 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.builder.xrefs) } +} - pub fn into_fields(self) -> (IndexData, FnvHashMap, u32>) { - (self.items, self.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) + } +} From baccdc01ae608920602fda8411f1ff8f127ebef2 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 10 Aug 2016 21:37:53 -0400 Subject: [PATCH 07/22] make record take a closure --- src/librustc_metadata/encoder.rs | 1049 ++++++++++++------------ src/librustc_metadata/index_builder.rs | 12 +- 2 files changed, 518 insertions(+), 543 deletions(-) diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 49bd861b131e4..87c7b36cf87e6 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -221,37 +221,35 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { self.encode_field(rbml_w, field); } - let _task = self.record(vid, rbml_w); - rbml_w.start_tag(tag_items_data_item); - encode_def_id_and_key(ecx, rbml_w, vid); - encode_family(rbml_w, match variant.kind { - ty::VariantKind::Struct => 'V', - ty::VariantKind::Tuple => 'v', - ty::VariantKind::Unit => 'w', - }); - encode_name(rbml_w, variant.name); - self.encode_parent_item(rbml_w, did); - self.encode_visibility(rbml_w, vis); - - let attrs = ecx.tcx.get_attrs(vid); - encode_attributes(rbml_w, &attrs); - self.encode_repr_attrs(rbml_w, &attrs); + self.record(vid, rbml_w, |this, rbml_w| { + encode_def_id_and_key(ecx, rbml_w, vid); + encode_family(rbml_w, match variant.kind { + ty::VariantKind::Struct => 'V', + ty::VariantKind::Tuple => 'v', + ty::VariantKind::Unit => 'w', + }); + encode_name(rbml_w, variant.name); + this.encode_parent_item(rbml_w, did); + this.encode_visibility(rbml_w, vis); - let stab = ecx.tcx.lookup_stability(vid); - let depr = ecx.tcx.lookup_deprecation(vid); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); + let attrs = ecx.tcx.get_attrs(vid); + encode_attributes(rbml_w, &attrs); + this.encode_repr_attrs(rbml_w, &attrs); - self.encode_struct_fields(rbml_w, variant); + let stab = ecx.tcx.lookup_stability(vid); + let depr = ecx.tcx.lookup_deprecation(vid); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); - let specified_disr_val = variant.disr_val; - if specified_disr_val != disr_val { - self.encode_disr_val(rbml_w, specified_disr_val); - disr_val = specified_disr_val; - } - self.encode_bounds_and_type_for_item(rbml_w, variant_node_id); + this.encode_struct_fields(rbml_w, variant); - rbml_w.end_tag(); + let specified_disr_val = variant.disr_val; + if specified_disr_val != disr_val { + this.encode_disr_val(rbml_w, specified_disr_val); + disr_val = specified_disr_val; + } + this.encode_bounds_and_type_for_item(rbml_w, variant_node_id); + }); disr_val = disr_val.wrap_incr(); } @@ -314,7 +312,6 @@ impl<'a, 'tcx> ItemContentBuilder<'a, 'tcx> { vis: &hir::Visibility) { let ecx = self.ecx(); - rbml_w.start_tag(tag_items_data_item); encode_def_id_and_key(ecx, rbml_w, ecx.tcx.map.local_def_id(id)); encode_family(rbml_w, 'm'); encode_name(rbml_w, name); @@ -346,8 +343,6 @@ impl<'a, 'tcx> ItemContentBuilder<'a, 'tcx> { encode_reexports(ecx, rbml_w, id); } encode_attributes(rbml_w, attrs); - - rbml_w.end_tag(); } fn encode_struct_field_family(&mut self, rbml_w: &mut Encoder, @@ -438,20 +433,18 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { let nm = field.name; let id = ecx.local_id(field.did); - let _task = self.record(field.did, rbml_w); - rbml_w.start_tag(tag_items_data_item); - debug!("encode_field: encoding {} {}", nm, id); - self.encode_struct_field_family(rbml_w, field.vis); - encode_name(rbml_w, nm); - self.encode_bounds_and_type_for_item(rbml_w, id); - encode_def_id_and_key(ecx, rbml_w, field.did); - - let stab = ecx.tcx.lookup_stability(field.did); - let depr = ecx.tcx.lookup_deprecation(field.did); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); + self.record(field.did, rbml_w, |this, rbml_w| { + debug!("encode_field: encoding {} {}", nm, id); + this.encode_struct_field_family(rbml_w, field.vis); + encode_name(rbml_w, nm); + this.encode_bounds_and_type_for_item(rbml_w, id); + encode_def_id_and_key(ecx, rbml_w, field.did); - rbml_w.end_tag(); + let stab = ecx.tcx.lookup_stability(field.did); + let depr = ecx.tcx.lookup_deprecation(field.did); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); + }); } } @@ -465,29 +458,29 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { let ctor_id = struct_def.id(); let ctor_def_id = ecx.tcx.map.local_def_id(ctor_id); - let _task = self.record(ctor_def_id, rbml_w); - rbml_w.start_tag(tag_items_data_item); - encode_def_id_and_key(ecx, rbml_w, ctor_def_id); - encode_family(rbml_w, match *struct_def { - hir::VariantData::Struct(..) => 'S', - hir::VariantData::Tuple(..) => 's', - hir::VariantData::Unit(..) => 'u', - }); - self.encode_bounds_and_type_for_item(rbml_w, ctor_id); - encode_name(rbml_w, name); - self.encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(struct_id)); - - let stab = ecx.tcx.lookup_stability(ecx.tcx.map.local_def_id(ctor_id)); - let depr = ecx.tcx.lookup_deprecation(ecx.tcx.map.local_def_id(ctor_id)); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); + self.record(ctor_def_id, rbml_w, |this, rbml_w| { + encode_def_id_and_key(ecx, rbml_w, ctor_def_id); + encode_family(rbml_w, match *struct_def { + hir::VariantData::Struct(..) => 'S', + hir::VariantData::Tuple(..) => 's', + hir::VariantData::Unit(..) => 'u', + }); + this.encode_bounds_and_type_for_item(rbml_w, ctor_id); + encode_name(rbml_w, name); + this.encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(struct_id)); - // indicate that this is a tuple struct ctor, because downstream users will normally want - // the tuple struct definition, but without this there is no way for them to tell that - // they actually have a ctor rather than a normal function - rbml_w.wr_tagged_bytes(tag_items_data_item_is_tuple_struct_ctor, &[]); + let stab = ecx.tcx.lookup_stability(ecx.tcx.map.local_def_id(ctor_id)); + let depr = ecx.tcx.lookup_deprecation(ecx.tcx.map.local_def_id(ctor_id)); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); - rbml_w.end_tag(); + // indicate that this is a tuple struct ctor, because + // downstream users will normally want the tuple struct + // definition, but without this there is no way for them + // to tell that they actually have a ctor rather than a + // normal function + rbml_w.wr_tagged_bytes(tag_items_data_item_is_tuple_struct_ctor, &[]); + }); } } @@ -549,35 +542,32 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { associated_const.def_id, associated_const.name); - let _task = self.record(associated_const.def_id, rbml_w); - rbml_w.start_tag(tag_items_data_item); - - encode_def_id_and_key(ecx, rbml_w, associated_const.def_id); - encode_name(rbml_w, associated_const.name); - self.encode_visibility(rbml_w, associated_const.vis); - encode_family(rbml_w, 'C'); - - self.encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id)); - encode_item_sort(rbml_w, 'C'); + self.record(associated_const.def_id, rbml_w, |this, rbml_w| { + encode_def_id_and_key(ecx, rbml_w, associated_const.def_id); + encode_name(rbml_w, associated_const.name); + this.encode_visibility(rbml_w, associated_const.vis); + encode_family(rbml_w, 'C'); - self.encode_bounds_and_type_for_item(rbml_w, ecx.local_id(associated_const.def_id)); + this.encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id)); + encode_item_sort(rbml_w, 'C'); - let stab = ecx.tcx.lookup_stability(associated_const.def_id); - let depr = ecx.tcx.lookup_deprecation(associated_const.def_id); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); + this.encode_bounds_and_type_for_item(rbml_w, ecx.local_id(associated_const.def_id)); - if let Some(ii) = impl_item_opt { - encode_attributes(rbml_w, &ii.attrs); - encode_defaultness(rbml_w, ii.defaultness); - encode_inlined_item(ecx, - rbml_w, - InlinedItemRef::ImplItem(ecx.tcx.map.local_def_id(parent_id), - ii)); - self.encode_mir(rbml_w, ii.id); - } + let stab = ecx.tcx.lookup_stability(associated_const.def_id); + let depr = ecx.tcx.lookup_deprecation(associated_const.def_id); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); - rbml_w.end_tag(); + if let Some(ii) = impl_item_opt { + encode_attributes(rbml_w, &ii.attrs); + encode_defaultness(rbml_w, ii.defaultness); + encode_inlined_item(ecx, + rbml_w, + InlinedItemRef::ImplItem(ecx.tcx.map.local_def_id(parent_id), + ii)); + this.encode_mir(rbml_w, ii.id); + } + }); } fn encode_info_for_method(&mut self, @@ -590,43 +580,40 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { debug!("encode_info_for_method: {:?} {:?}", m.def_id, m.name); - let _task = self.record(m.def_id, rbml_w); - rbml_w.start_tag(tag_items_data_item); - - self.encode_method_ty_fields(rbml_w, m); - self.encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id)); - encode_item_sort(rbml_w, 'r'); + self.record(m.def_id, rbml_w, |this, rbml_w| { + this.encode_method_ty_fields(rbml_w, m); + this.encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id)); + encode_item_sort(rbml_w, 'r'); - let stab = ecx.tcx.lookup_stability(m.def_id); - let depr = ecx.tcx.lookup_deprecation(m.def_id); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); + let stab = ecx.tcx.lookup_stability(m.def_id); + let depr = ecx.tcx.lookup_deprecation(m.def_id); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); - let m_node_id = ecx.local_id(m.def_id); - self.encode_bounds_and_type_for_item(rbml_w, m_node_id); - - if let Some(impl_item) = impl_item_opt { - if let hir::ImplItemKind::Method(ref sig, _) = impl_item.node { - encode_attributes(rbml_w, &impl_item.attrs); - let generics = ecx.tcx.lookup_generics(m.def_id); - let types = generics.parent_types as usize + generics.types.len(); - let needs_inline = types > 0 || is_default_impl || - attr::requests_inline(&impl_item.attrs); - if needs_inline || sig.constness == hir::Constness::Const { - encode_inlined_item( - ecx, - rbml_w, - InlinedItemRef::ImplItem(ecx.tcx.map.local_def_id(parent_id), - impl_item)); - self.encode_mir(rbml_w, impl_item.id); + let m_node_id = ecx.local_id(m.def_id); + this.encode_bounds_and_type_for_item(rbml_w, m_node_id); + + if let Some(impl_item) = impl_item_opt { + if let hir::ImplItemKind::Method(ref sig, _) = impl_item.node { + encode_attributes(rbml_w, &impl_item.attrs); + let generics = ecx.tcx.lookup_generics(m.def_id); + let types = generics.parent_types as usize + generics.types.len(); + let needs_inline = types > 0 || is_default_impl || + attr::requests_inline(&impl_item.attrs); + if needs_inline || sig.constness == hir::Constness::Const { + encode_inlined_item( + ecx, + rbml_w, + InlinedItemRef::ImplItem(ecx.tcx.map.local_def_id(parent_id), + impl_item)); + this.encode_mir(rbml_w, impl_item.id); + } + encode_constness(rbml_w, sig.constness); + encode_defaultness(rbml_w, impl_item.defaultness); + this.encode_method_argument_names(rbml_w, &sig.decl); } - encode_constness(rbml_w, sig.constness); - encode_defaultness(rbml_w, impl_item.defaultness); - self.encode_method_argument_names(rbml_w, &sig.decl); } - } - - rbml_w.end_tag(); + }); } fn encode_info_for_associated_type(&mut self, @@ -639,38 +626,37 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { associated_type.def_id, associated_type.name); - let _task = self.record(associated_type.def_id, rbml_w); - rbml_w.start_tag(tag_items_data_item); - - encode_def_id_and_key(ecx, rbml_w, associated_type.def_id); - encode_name(rbml_w, associated_type.name); - self.encode_visibility(rbml_w, associated_type.vis); - encode_family(rbml_w, 'y'); - self.encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id)); - encode_item_sort(rbml_w, 't'); - - let stab = ecx.tcx.lookup_stability(associated_type.def_id); - let depr = ecx.tcx.lookup_deprecation(associated_type.def_id); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); + self.record(associated_type.def_id, rbml_w, |this, rbml_w| { + encode_def_id_and_key(ecx, rbml_w, associated_type.def_id); + encode_name(rbml_w, associated_type.name); + this.encode_visibility(rbml_w, associated_type.vis); + encode_family(rbml_w, 'y'); + this.encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id)); + encode_item_sort(rbml_w, 't'); - if let Some(ii) = impl_item_opt { - encode_attributes(rbml_w, &ii.attrs); - encode_defaultness(rbml_w, ii.defaultness); - } else { - // TODO this looks bogus and unnecessary - self.encode_predicates(rbml_w, - &ecx.tcx.lookup_predicates(associated_type.def_id), - tag_item_generics); - } + let stab = ecx.tcx.lookup_stability(associated_type.def_id); + let depr = ecx.tcx.lookup_deprecation(associated_type.def_id); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); - if let Some(ty) = associated_type.ty { - self.encode_type(rbml_w, ty); - } + if let Some(ii) = impl_item_opt { + encode_attributes(rbml_w, &ii.attrs); + encode_defaultness(rbml_w, ii.defaultness); + } else { + // TODO this looks bogus and unnecessary + this.encode_predicates(rbml_w, + &ecx.tcx.lookup_predicates(associated_type.def_id), + tag_item_generics); + } - rbml_w.end_tag(); + if let Some(ty) = associated_type.ty { + this.encode_type(rbml_w, ty); + } + }); } +} +impl<'a, 'tcx> ItemContentBuilder<'a, 'tcx> { fn encode_method_argument_names(&mut self, rbml_w: &mut Encoder, decl: &hir::FnDecl) { @@ -686,9 +672,7 @@ 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]) { @@ -802,120 +786,114 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { match item.node { hir::ItemStatic(_, m, _) => { - let _task = self.record(def_id, rbml_w); - rbml_w.start_tag(tag_items_data_item); - encode_def_id_and_key(ecx, rbml_w, def_id); - if m == hir::MutMutable { - encode_family(rbml_w, 'b'); - } else { - encode_family(rbml_w, 'c'); - } - self.encode_bounds_and_type_for_item(rbml_w, item.id); - encode_name(rbml_w, item.name); - self.encode_visibility(rbml_w, vis); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); - encode_attributes(rbml_w, &item.attrs); - rbml_w.end_tag(); + self.record(def_id, rbml_w, |this, rbml_w| { + encode_def_id_and_key(ecx, rbml_w, def_id); + if m == hir::MutMutable { + encode_family(rbml_w, 'b'); + } else { + encode_family(rbml_w, 'c'); + } + this.encode_bounds_and_type_for_item(rbml_w, item.id); + encode_name(rbml_w, item.name); + this.encode_visibility(rbml_w, vis); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); + encode_attributes(rbml_w, &item.attrs); + }); } hir::ItemConst(_, _) => { - let _task = self.record(def_id, rbml_w); - rbml_w.start_tag(tag_items_data_item); - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_family(rbml_w, 'C'); - self.encode_bounds_and_type_for_item(rbml_w, item.id); - encode_name(rbml_w, item.name); - encode_attributes(rbml_w, &item.attrs); - encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(def_id, item)); - self.encode_mir(rbml_w, item.id); - self.encode_visibility(rbml_w, vis); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); - rbml_w.end_tag(); + self.record(def_id, rbml_w, |this, rbml_w| { + encode_def_id_and_key(ecx, rbml_w, def_id); + encode_family(rbml_w, 'C'); + this.encode_bounds_and_type_for_item(rbml_w, item.id); + encode_name(rbml_w, item.name); + encode_attributes(rbml_w, &item.attrs); + encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(def_id, item)); + this.encode_mir(rbml_w, item.id); + this.encode_visibility(rbml_w, vis); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); + }); } hir::ItemFn(ref decl, _, constness, _, ref generics, _) => { - let _task = self.record(def_id, rbml_w); - rbml_w.start_tag(tag_items_data_item); - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_family(rbml_w, FN_FAMILY); - let tps_len = generics.ty_params.len(); - self.encode_bounds_and_type_for_item(rbml_w, item.id); - encode_name(rbml_w, item.name); - encode_attributes(rbml_w, &item.attrs); - let needs_inline = tps_len > 0 || attr::requests_inline(&item.attrs); - if needs_inline || constness == hir::Constness::Const { - encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(def_id, item)); - self.encode_mir(rbml_w, item.id); - } - encode_constness(rbml_w, constness); - self.encode_visibility(rbml_w, vis); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); - self.encode_method_argument_names(rbml_w, &decl); - rbml_w.end_tag(); + self.record(def_id, rbml_w, |this, rbml_w| { + encode_def_id_and_key(ecx, rbml_w, def_id); + encode_family(rbml_w, FN_FAMILY); + let tps_len = generics.ty_params.len(); + this.encode_bounds_and_type_for_item(rbml_w, item.id); + encode_name(rbml_w, item.name); + encode_attributes(rbml_w, &item.attrs); + let needs_inline = tps_len > 0 || attr::requests_inline(&item.attrs); + if needs_inline || constness == hir::Constness::Const { + encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(def_id, item)); + this.encode_mir(rbml_w, item.id); + } + encode_constness(rbml_w, constness); + this.encode_visibility(rbml_w, vis); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); + this.encode_method_argument_names(rbml_w, &decl); + }); } hir::ItemMod(ref m) => { - let _task = self.record(def_id, rbml_w); - self.encode_info_for_mod(rbml_w, - m, - &item.attrs, - item.id, - item.name, - &item.vis); + self.record(def_id, rbml_w, |this, rbml_w| { + this.encode_info_for_mod(rbml_w, + m, + &item.attrs, + item.id, + item.name, + &item.vis); + }); } hir::ItemForeignMod(ref fm) => { - let _task = self.record(def_id, rbml_w); - rbml_w.start_tag(tag_items_data_item); - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_family(rbml_w, 'n'); - encode_name(rbml_w, item.name); - - // Encode all the items in this module. - for foreign_item in &fm.items { - rbml_w.wr_tagged_u64(tag_mod_child, - def_to_u64(ecx.tcx.map.local_def_id(foreign_item.id))); - } - self.encode_visibility(rbml_w, vis); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); - rbml_w.end_tag(); + self.record(def_id, rbml_w, |this, rbml_w| { + encode_def_id_and_key(ecx, rbml_w, def_id); + encode_family(rbml_w, 'n'); + encode_name(rbml_w, item.name); + + // Encode all the items in this module. + for foreign_item in &fm.items { + rbml_w.wr_tagged_u64(tag_mod_child, + def_to_u64(ecx.tcx.map.local_def_id(foreign_item.id))); + } + this.encode_visibility(rbml_w, vis); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); + }); } hir::ItemTy(..) => { - let _task = self.record(def_id, rbml_w); - rbml_w.start_tag(tag_items_data_item); - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_family(rbml_w, 'y'); - self.encode_bounds_and_type_for_item(rbml_w, item.id); - encode_name(rbml_w, item.name); - self.encode_visibility(rbml_w, vis); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); - rbml_w.end_tag(); + self.record(def_id, rbml_w, |this, rbml_w| { + encode_def_id_and_key(ecx, rbml_w, def_id); + encode_family(rbml_w, 'y'); + this.encode_bounds_and_type_for_item(rbml_w, item.id); + encode_name(rbml_w, item.name); + this.encode_visibility(rbml_w, vis); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); + }); } hir::ItemEnum(ref enum_definition, _) => { - let _task = self.record(def_id, rbml_w); - - rbml_w.start_tag(tag_items_data_item); - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_family(rbml_w, 't'); - encode_item_variances(rbml_w, ecx, item.id); - self.encode_bounds_and_type_for_item(rbml_w, item.id); - encode_name(rbml_w, item.name); - encode_attributes(rbml_w, &item.attrs); - self.encode_repr_attrs(rbml_w, &item.attrs); - for v in &enum_definition.variants { - encode_variant_id(rbml_w, ecx.tcx.map.local_def_id(v.node.data.id())); - } - encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(def_id, item)); - self.encode_mir(rbml_w, item.id); + self.record(def_id, rbml_w, |this, rbml_w| { + encode_def_id_and_key(ecx, rbml_w, def_id); + encode_family(rbml_w, 't'); + encode_item_variances(rbml_w, ecx, item.id); + this.encode_bounds_and_type_for_item(rbml_w, item.id); + encode_name(rbml_w, item.name); + encode_attributes(rbml_w, &item.attrs); + this.encode_repr_attrs(rbml_w, &item.attrs); + for v in &enum_definition.variants { + encode_variant_id(rbml_w, ecx.tcx.map.local_def_id(v.node.data.id())); + } + encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(def_id, item)); + this.encode_mir(rbml_w, item.id); - // Encode inherent implementations for this enumeration. - encode_inherent_implementations(ecx, rbml_w, def_id); + // Encode inherent implementations for this enumeration. + encode_inherent_implementations(ecx, rbml_w, def_id); - self.encode_visibility(rbml_w, vis); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); - rbml_w.end_tag(); + this.encode_visibility(rbml_w, vis); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); + }); self.encode_enum_variant_info(rbml_w, def_id, @@ -923,47 +901,44 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { } hir::ItemStruct(ref struct_def, _) => { /* Index the class*/ - let _task = self.record(def_id, rbml_w); - let def = ecx.tcx.lookup_adt_def(def_id); let variant = def.struct_variant(); - /* Now, make an item for the class itself */ - rbml_w.start_tag(tag_items_data_item); - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_family(rbml_w, match *struct_def { - hir::VariantData::Struct(..) => 'S', - hir::VariantData::Tuple(..) => 's', - hir::VariantData::Unit(..) => 'u', - }); - self.encode_bounds_and_type_for_item(rbml_w, item.id); - - encode_item_variances(rbml_w, ecx, item.id); - encode_name(rbml_w, item.name); - encode_attributes(rbml_w, &item.attrs); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); - self.encode_visibility(rbml_w, vis); - self.encode_repr_attrs(rbml_w, &item.attrs); - - /* Encode def_ids for each field and method - for methods, write all the stuff get_trait_method - needs to know*/ - self.encode_struct_fields(rbml_w, variant); + self.record(def_id, rbml_w, |this, rbml_w| { + /* Now, make an item for the class itself */ + encode_def_id_and_key(ecx, rbml_w, def_id); + encode_family(rbml_w, match *struct_def { + hir::VariantData::Struct(..) => 'S', + hir::VariantData::Tuple(..) => 's', + hir::VariantData::Unit(..) => 'u', + }); + this.encode_bounds_and_type_for_item(rbml_w, item.id); + + encode_item_variances(rbml_w, ecx, item.id); + encode_name(rbml_w, item.name); + encode_attributes(rbml_w, &item.attrs); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); + this.encode_visibility(rbml_w, vis); + this.encode_repr_attrs(rbml_w, &item.attrs); - encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(def_id, item)); - self.encode_mir(rbml_w, item.id); + /* Encode def_ids for each field and method + for methods, write all the stuff get_trait_method + needs to know*/ + this.encode_struct_fields(rbml_w, variant); - // Encode inherent implementations for this structure. - encode_inherent_implementations(ecx, rbml_w, def_id); + encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(def_id, item)); + this.encode_mir(rbml_w, item.id); - if !struct_def.is_struct() { - let ctor_did = ecx.tcx.map.local_def_id(struct_def.id()); - rbml_w.wr_tagged_u64(tag_items_data_item_struct_ctor, - def_to_u64(ctor_did)); - } + // Encode inherent implementations for this structure. + encode_inherent_implementations(ecx, rbml_w, def_id); - rbml_w.end_tag(); + if !struct_def.is_struct() { + let ctor_did = ecx.tcx.map.local_def_id(struct_def.id()); + rbml_w.wr_tagged_u64(tag_items_data_item_struct_ctor, + def_to_u64(ctor_did)); + } + }); for field in &variant.fields { self.encode_field(rbml_w, field); @@ -975,81 +950,81 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { } } hir::ItemDefaultImpl(unsafety, _) => { - let _task = self.record(def_id, rbml_w); - rbml_w.start_tag(tag_items_data_item); - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_family(rbml_w, 'd'); - encode_name(rbml_w, item.name); - encode_unsafety(rbml_w, unsafety); + self.record(def_id, rbml_w, |_this, rbml_w| { + encode_def_id_and_key(ecx, rbml_w, def_id); + encode_family(rbml_w, 'd'); + encode_name(rbml_w, item.name); + encode_unsafety(rbml_w, unsafety); - let trait_ref = tcx.impl_trait_ref(ecx.tcx.map.local_def_id(item.id)).unwrap(); - encode_trait_ref(rbml_w, ecx, trait_ref, tag_item_trait_ref); - rbml_w.end_tag(); + let trait_ref = tcx.impl_trait_ref(ecx.tcx.map.local_def_id(item.id)).unwrap(); + encode_trait_ref(rbml_w, ecx, trait_ref, tag_item_trait_ref); + }); } hir::ItemImpl(unsafety, polarity, _, _, _, ref ast_items) => { - let _task = self.record(def_id, rbml_w); - // We need to encode information about the default methods we // have inherited, so we drive this based on the impl structure. let impl_items = tcx.impl_items.borrow(); - let items = impl_items.get(&def_id).unwrap(); - - rbml_w.start_tag(tag_items_data_item); - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_family(rbml_w, 'i'); - self.encode_bounds_and_type_for_item(rbml_w, item.id); - encode_name(rbml_w, item.name); - encode_attributes(rbml_w, &item.attrs); - encode_unsafety(rbml_w, unsafety); - encode_polarity(rbml_w, polarity); - - match tcx.custom_coerce_unsized_kinds - .borrow() - .get(&ecx.tcx.map.local_def_id(item.id)) { - Some(&kind) => { - rbml_w.start_tag(tag_impl_coerce_unsized_kind); - kind.encode(rbml_w); - rbml_w.end_tag(); + let items = &impl_items[&def_id]; + + self.record(def_id, rbml_w, |this, rbml_w| { + encode_def_id_and_key(ecx, rbml_w, def_id); + encode_family(rbml_w, 'i'); + this.encode_bounds_and_type_for_item(rbml_w, item.id); + encode_name(rbml_w, item.name); + encode_attributes(rbml_w, &item.attrs); + encode_unsafety(rbml_w, unsafety); + encode_polarity(rbml_w, polarity); + + match + tcx.custom_coerce_unsized_kinds + .borrow() + .get(&ecx.tcx.map.local_def_id(item.id)) + { + Some(&kind) => { + rbml_w.start_tag(tag_impl_coerce_unsized_kind); + kind.encode(rbml_w); + rbml_w.end_tag(); + } + None => {} } - None => {} - } - for &item_def_id in items { - rbml_w.start_tag(tag_item_impl_item); - match item_def_id { - ty::ConstTraitItemId(item_def_id) => { - encode_def_id(rbml_w, item_def_id); - encode_item_sort(rbml_w, 'C'); - } - ty::MethodTraitItemId(item_def_id) => { - encode_def_id(rbml_w, item_def_id); - encode_item_sort(rbml_w, 'r'); - } - ty::TypeTraitItemId(item_def_id) => { - encode_def_id(rbml_w, item_def_id); - encode_item_sort(rbml_w, 't'); + for &item_def_id in items { + rbml_w.start_tag(tag_item_impl_item); + match item_def_id { + ty::ConstTraitItemId(item_def_id) => { + encode_def_id(rbml_w, item_def_id); + encode_item_sort(rbml_w, 'C'); + } + ty::MethodTraitItemId(item_def_id) => { + encode_def_id(rbml_w, item_def_id); + encode_item_sort(rbml_w, 'r'); + } + ty::TypeTraitItemId(item_def_id) => { + encode_def_id(rbml_w, item_def_id); + encode_item_sort(rbml_w, 't'); + } } + rbml_w.end_tag(); } - rbml_w.end_tag(); - } - let did = ecx.tcx.map.local_def_id(item.id); - if let Some(trait_ref) = tcx.impl_trait_ref(did) { - encode_trait_ref(rbml_w, ecx, trait_ref, tag_item_trait_ref); - let trait_def = tcx.lookup_trait_def(trait_ref.def_id); - let parent = trait_def.ancestors(did) - .skip(1) - .next() - .and_then(|node| match node { - specialization_graph::Node::Impl(parent) => - Some(parent), - _ => None, - }); - encode_parent_impl(rbml_w, parent); - } - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); - rbml_w.end_tag(); + let did = ecx.tcx.map.local_def_id(item.id); + if let Some(trait_ref) = tcx.impl_trait_ref(did) { + encode_trait_ref(rbml_w, ecx, trait_ref, tag_item_trait_ref); + + let trait_def = tcx.lookup_trait_def(trait_ref.def_id); + let parent = trait_def.ancestors(did) + .skip(1) + .next() + .and_then(|node| match node { + specialization_graph::Node::Impl(parent) => + Some(parent), + _ => None, + }); + encode_parent_impl(rbml_w, parent); + } + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); + }); // Iterate down the trait items, emitting them. We rely on the // assumption that all of the actually implemented trait items @@ -1087,157 +1062,157 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { } } hir::ItemTrait(_, _, _, ref ms) => { - let _task = self.record(def_id, rbml_w); - rbml_w.start_tag(tag_items_data_item); - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_family(rbml_w, 'I'); - encode_item_variances(rbml_w, ecx, item.id); - let trait_def = tcx.lookup_trait_def(def_id); - let trait_predicates = tcx.lookup_predicates(def_id); - encode_unsafety(rbml_w, trait_def.unsafety); - encode_paren_sugar(rbml_w, trait_def.paren_sugar); - encode_defaulted(rbml_w, tcx.trait_has_default_impl(def_id)); - encode_associated_type_names(rbml_w, &trait_def.associated_type_names); - self.encode_generics(rbml_w, &trait_def.generics, &trait_predicates); - self.encode_predicates(rbml_w, &tcx.lookup_super_predicates(def_id), tag_item_super_predicates); - encode_trait_ref(rbml_w, ecx, trait_def.trait_ref, tag_item_trait_ref); - encode_name(rbml_w, item.name); - encode_attributes(rbml_w, &item.attrs); - self.encode_visibility(rbml_w, vis); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); - for &method_def_id in tcx.trait_item_def_ids(def_id).iter() { - rbml_w.start_tag(tag_item_trait_item); - match method_def_id { - ty::ConstTraitItemId(const_def_id) => { - encode_def_id(rbml_w, const_def_id); - encode_item_sort(rbml_w, 'C'); - } - ty::MethodTraitItemId(method_def_id) => { - encode_def_id(rbml_w, method_def_id); - encode_item_sort(rbml_w, 'r'); - } - ty::TypeTraitItemId(type_def_id) => { - encode_def_id(rbml_w, type_def_id); - encode_item_sort(rbml_w, 't'); + self.record(def_id, rbml_w, |this, rbml_w| { + encode_def_id_and_key(ecx, rbml_w, def_id); + encode_family(rbml_w, 'I'); + encode_item_variances(rbml_w, ecx, item.id); + let trait_def = tcx.lookup_trait_def(def_id); + let trait_predicates = tcx.lookup_predicates(def_id); + encode_unsafety(rbml_w, trait_def.unsafety); + encode_paren_sugar(rbml_w, trait_def.paren_sugar); + encode_defaulted(rbml_w, tcx.trait_has_default_impl(def_id)); + encode_associated_type_names(rbml_w, &trait_def.associated_type_names); + this.encode_generics(rbml_w, &trait_def.generics, &trait_predicates); + this.encode_predicates(rbml_w, + &tcx.lookup_super_predicates(def_id), + tag_item_super_predicates); + encode_trait_ref(rbml_w, ecx, trait_def.trait_ref, tag_item_trait_ref); + encode_name(rbml_w, item.name); + encode_attributes(rbml_w, &item.attrs); + this.encode_visibility(rbml_w, vis); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); + for &method_def_id in tcx.trait_item_def_ids(def_id).iter() { + rbml_w.start_tag(tag_item_trait_item); + match method_def_id { + ty::ConstTraitItemId(const_def_id) => { + encode_def_id(rbml_w, const_def_id); + encode_item_sort(rbml_w, 'C'); + } + ty::MethodTraitItemId(method_def_id) => { + encode_def_id(rbml_w, method_def_id); + encode_item_sort(rbml_w, 'r'); + } + ty::TypeTraitItemId(type_def_id) => { + encode_def_id(rbml_w, type_def_id); + encode_item_sort(rbml_w, 't'); + } } - } - rbml_w.end_tag(); - - rbml_w.wr_tagged_u64(tag_mod_child, - def_to_u64(method_def_id.def_id())); - } + rbml_w.end_tag(); - // Encode inherent implementations for this trait. - encode_inherent_implementations(ecx, rbml_w, def_id); + rbml_w.wr_tagged_u64(tag_mod_child, + def_to_u64(method_def_id.def_id())); + } - rbml_w.end_tag(); + // Encode inherent implementations for this trait. + encode_inherent_implementations(ecx, rbml_w, def_id); + }); // Now output the trait item info for each trait item. let r = tcx.trait_item_def_ids(def_id); for (i, &item_def_id) in r.iter().enumerate() { assert_eq!(item_def_id.def_id().krate, LOCAL_CRATE); - let _task = self.record(item_def_id.def_id(), rbml_w); - rbml_w.start_tag(tag_items_data_item); + self.record(item_def_id.def_id(), rbml_w, |this, rbml_w| { + this.encode_parent_item(rbml_w, def_id); - self.encode_parent_item(rbml_w, def_id); + let stab = tcx.lookup_stability(item_def_id.def_id()); + let depr = tcx.lookup_deprecation(item_def_id.def_id()); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); - let stab = tcx.lookup_stability(item_def_id.def_id()); - let depr = tcx.lookup_deprecation(item_def_id.def_id()); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); - - let trait_item_type = - tcx.impl_or_trait_item(item_def_id.def_id()); - let is_nonstatic_method; - match trait_item_type { - ty::ConstTraitItem(associated_const) => { - encode_name(rbml_w, associated_const.name); - encode_def_id_and_key(ecx, rbml_w, associated_const.def_id); - self.encode_visibility(rbml_w, associated_const.vis); - - encode_family(rbml_w, 'C'); + let trait_item_type = + tcx.impl_or_trait_item(item_def_id.def_id()); + let is_nonstatic_method; + match trait_item_type { + ty::ConstTraitItem(associated_const) => { + encode_name(rbml_w, associated_const.name); + encode_def_id_and_key(ecx, rbml_w, associated_const.def_id); + this.encode_visibility(rbml_w, associated_const.vis); - self.encode_bounds_and_type_for_item( - rbml_w, - ecx.local_id(associated_const.def_id)); + encode_family(rbml_w, 'C'); - is_nonstatic_method = false; - } - ty::MethodTraitItem(method_ty) => { - let method_def_id = item_def_id.def_id(); - - self.encode_method_ty_fields(rbml_w, &method_ty); + this.encode_bounds_and_type_for_item( + rbml_w, + ecx.local_id(associated_const.def_id)); - match method_ty.explicit_self { - ty::ExplicitSelfCategory::Static => { - encode_family(rbml_w, - STATIC_METHOD_FAMILY); - } - _ => { - encode_family(rbml_w, - METHOD_FAMILY); - } + is_nonstatic_method = false; } - self.encode_bounds_and_type_for_item(rbml_w, - ecx.local_id(method_def_id)); + ty::MethodTraitItem(method_ty) => { + let method_def_id = item_def_id.def_id(); + + this.encode_method_ty_fields(rbml_w, &method_ty); + + match method_ty.explicit_self { + ty::ExplicitSelfCategory::Static => { + encode_family(rbml_w, + STATIC_METHOD_FAMILY); + } + _ => { + encode_family(rbml_w, + METHOD_FAMILY); + } + } + this.encode_bounds_and_type_for_item(rbml_w, + ecx.local_id(method_def_id)); - is_nonstatic_method = method_ty.explicit_self != - ty::ExplicitSelfCategory::Static; - } - ty::TypeTraitItem(associated_type) => { - encode_name(rbml_w, associated_type.name); - encode_def_id_and_key(ecx, rbml_w, associated_type.def_id); - encode_item_sort(rbml_w, 't'); - encode_family(rbml_w, 'y'); - - if let Some(ty) = associated_type.ty { - self.encode_type(rbml_w, ty); + is_nonstatic_method = method_ty.explicit_self != + ty::ExplicitSelfCategory::Static; } + ty::TypeTraitItem(associated_type) => { + encode_name(rbml_w, associated_type.name); + encode_def_id_and_key(ecx, rbml_w, associated_type.def_id); + encode_item_sort(rbml_w, 't'); + encode_family(rbml_w, 'y'); + + if let Some(ty) = associated_type.ty { + this.encode_type(rbml_w, ty); + } - is_nonstatic_method = false; - } - } - - let trait_item = &ms[i]; - encode_attributes(rbml_w, &trait_item.attrs); - match trait_item.node { - hir::ConstTraitItem(_, ref default) => { - if default.is_some() { - encode_item_sort(rbml_w, 'C'); - } else { - encode_item_sort(rbml_w, 'c'); + is_nonstatic_method = false; } - - encode_inlined_item(ecx, rbml_w, - InlinedItemRef::TraitItem(def_id, trait_item)); - self.encode_mir(rbml_w, trait_item.id); } - hir::MethodTraitItem(ref sig, ref body) => { - // If this is a static method, we've already - // encoded this. - if is_nonstatic_method { - self.encode_bounds_and_type_for_item( - rbml_w, - ecx.local_id(item_def_id.def_id())); - } - if body.is_some() { - encode_item_sort(rbml_w, 'p'); + let trait_item = &ms[i]; + encode_attributes(rbml_w, &trait_item.attrs); + match trait_item.node { + hir::ConstTraitItem(_, ref default) => { + if default.is_some() { + encode_item_sort(rbml_w, 'C'); + } else { + encode_item_sort(rbml_w, 'c'); + } + encode_inlined_item(ecx, rbml_w, InlinedItemRef::TraitItem(def_id, trait_item)); - self.encode_mir(rbml_w, trait_item.id); - } else { - encode_item_sort(rbml_w, 'r'); + this.encode_mir(rbml_w, trait_item.id); } - self.encode_method_argument_names(rbml_w, &sig.decl); - } + hir::MethodTraitItem(ref sig, ref body) => { + // If this is a static method, we've already + // encoded this. + if is_nonstatic_method { + this.encode_bounds_and_type_for_item( + rbml_w, + ecx.local_id(item_def_id.def_id())); + } - hir::TypeTraitItem(..) => {} - } + if body.is_some() { + encode_item_sort(rbml_w, 'p'); + encode_inlined_item(ecx, + rbml_w, + InlinedItemRef::TraitItem( + def_id, + trait_item)); + this.encode_mir(rbml_w, trait_item.id); + } else { + encode_item_sort(rbml_w, 'r'); + } + this.encode_method_argument_names(rbml_w, &sig.decl); + } - rbml_w.end_tag(); + hir::TypeTraitItem(..) => {} + } + }); } } hir::ItemExternCrate(_) | hir::ItemUse(_) => { @@ -1255,44 +1230,43 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { let def_id = ecx.tcx.map.local_def_id(nitem.id); let abi = ecx.tcx.map.get_foreign_abi(nitem.id); - let _task = self.record(def_id, rbml_w); - rbml_w.start_tag(tag_items_data_item); - encode_def_id_and_key(ecx, rbml_w, def_id); - let parent_id = ecx.tcx.map.get_parent(nitem.id); - self.encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id)); - self.encode_visibility(rbml_w, &nitem.vis); - match nitem.node { - hir::ForeignItemFn(ref fndecl, _) => { - encode_family(rbml_w, FN_FAMILY); - self.encode_bounds_and_type_for_item(rbml_w, nitem.id); - encode_name(rbml_w, nitem.name); - if abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic { - encode_inlined_item(ecx, rbml_w, InlinedItemRef::Foreign(def_id, nitem)); - self.encode_mir(rbml_w, nitem.id); + self.record(def_id, rbml_w, |this, rbml_w| { + encode_def_id_and_key(ecx, rbml_w, def_id); + let parent_id = ecx.tcx.map.get_parent(nitem.id); + this.encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id)); + this.encode_visibility(rbml_w, &nitem.vis); + match nitem.node { + hir::ForeignItemFn(ref fndecl, _) => { + encode_family(rbml_w, FN_FAMILY); + this.encode_bounds_and_type_for_item(rbml_w, nitem.id); + encode_name(rbml_w, nitem.name); + if abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic { + encode_inlined_item(ecx, rbml_w, InlinedItemRef::Foreign(def_id, nitem)); + this.encode_mir(rbml_w, nitem.id); + } + encode_attributes(rbml_w, &nitem.attrs); + let stab = ecx.tcx.lookup_stability(ecx.tcx.map.local_def_id(nitem.id)); + let depr = ecx.tcx.lookup_deprecation(ecx.tcx.map.local_def_id(nitem.id)); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); + this.encode_method_argument_names(rbml_w, &fndecl); } - encode_attributes(rbml_w, &nitem.attrs); - let stab = ecx.tcx.lookup_stability(ecx.tcx.map.local_def_id(nitem.id)); - let depr = ecx.tcx.lookup_deprecation(ecx.tcx.map.local_def_id(nitem.id)); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); - self.encode_method_argument_names(rbml_w, &fndecl); - } - hir::ForeignItemStatic(_, mutbl) => { - if mutbl { - encode_family(rbml_w, 'b'); - } else { - encode_family(rbml_w, 'c'); + hir::ForeignItemStatic(_, mutbl) => { + if mutbl { + encode_family(rbml_w, 'b'); + } else { + encode_family(rbml_w, 'c'); + } + this.encode_bounds_and_type_for_item(rbml_w, nitem.id); + encode_attributes(rbml_w, &nitem.attrs); + let stab = ecx.tcx.lookup_stability(ecx.tcx.map.local_def_id(nitem.id)); + let depr = ecx.tcx.lookup_deprecation(ecx.tcx.map.local_def_id(nitem.id)); + encode_stability(rbml_w, stab); + encode_deprecation(rbml_w, depr); + encode_name(rbml_w, nitem.name); } - self.encode_bounds_and_type_for_item(rbml_w, nitem.id); - encode_attributes(rbml_w, &nitem.attrs); - let stab = ecx.tcx.lookup_stability(ecx.tcx.map.local_def_id(nitem.id)); - let depr = ecx.tcx.lookup_deprecation(ecx.tcx.map.local_def_id(nitem.id)); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); - encode_name(rbml_w, nitem.name); } - } - rbml_w.end_tag(); + }); } } @@ -1316,7 +1290,7 @@ impl<'a, 'data, 'ecx, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'data, 'ecx, 'tc } fn visit_ty(&mut self, ty: &'tcx hir::Ty) { intravisit::walk_ty(self, ty); - encode_info_for_ty(ty, self.rbml_w_for_visit_item, self.index); + self.index.encode_info_for_ty(ty, self.rbml_w); } } @@ -1327,12 +1301,11 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { let ecx = self.ecx(); if let hir::TyImplTrait(_) = ty.node { let def_id = ecx.tcx.map.local_def_id(ty.id); - let _task = self.record(def_id, rbml_w); - rbml_w.start_tag(tag_items_data_item); - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_family(rbml_w, 'y'); - self.encode_bounds_and_type_for_item(rbml_w, ecx, ty.id); - rbml_w.end_tag(); + self.record(def_id, rbml_w, |this, rbml_w| { + encode_def_id_and_key(ecx, rbml_w, def_id); + encode_family(rbml_w, 'y'); + this.encode_bounds_and_type_for_item(rbml_w, ty.id); + }); } } @@ -1343,24 +1316,21 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { hir::ExprClosure(..) => { let def_id = ecx.tcx.map.local_def_id(expr.id); - let _task = self.record(def_id, rbml_w); - - rbml_w.start_tag(tag_items_data_item); - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_name(rbml_w, syntax::parse::token::intern("")); - - rbml_w.start_tag(tag_items_closure_ty); - write_closure_type(ecx, rbml_w, &ecx.tcx.tables.borrow().closure_tys[&def_id]); - rbml_w.end_tag(); + self.record(def_id, rbml_w, |this, rbml_w| { + encode_def_id_and_key(ecx, rbml_w, def_id); + encode_name(rbml_w, syntax::parse::token::intern("")); - rbml_w.start_tag(tag_items_closure_kind); - ecx.tcx.closure_kind(def_id).encode(rbml_w).unwrap(); - rbml_w.end_tag(); + rbml_w.start_tag(tag_items_closure_ty); + write_closure_type(ecx, rbml_w, &ecx.tcx.tables.borrow().closure_tys[&def_id]); + rbml_w.end_tag(); - assert!(ecx.mir_map.map.contains_key(&def_id)); - self.encode_mir(rbml_w, expr.id); + rbml_w.start_tag(tag_items_closure_kind); + ecx.tcx.closure_kind(def_id).encode(rbml_w).unwrap(); + rbml_w.end_tag(); - rbml_w.end_tag(); + assert!(ecx.mir_map.map.contains_key(&def_id)); + this.encode_mir(rbml_w, expr.id); + }); } _ => { } } @@ -1375,15 +1345,14 @@ fn encode_info_for_items<'a, 'tcx>(ecx: &'a EncodeContext<'a, 'tcx>, let mut index = IndexBuilder::new(ecx); rbml_w.start_tag(tag_items_data); - { - let _task = index.record(DefId::local(CRATE_DEF_INDEX), rbml_w); - index.encode_info_for_mod(rbml_w, - &krate.module, - &[], - CRATE_NODE_ID, - syntax::parse::token::intern(&ecx.link_meta.crate_name), - &hir::Public); - } + index.record(DefId::local(CRATE_DEF_INDEX), rbml_w, |this, rbml_w| { + this.encode_info_for_mod(rbml_w, + &krate.module, + &[], + CRATE_NODE_ID, + syntax::parse::token::intern(&ecx.link_meta.crate_name), + &hir::Public); + }); krate.visit_all_items(&mut EncodeVisitor { index: &mut index, diff --git a/src/librustc_metadata/index_builder.rs b/src/librustc_metadata/index_builder.rs index 915bf98519c90..2ccd1fd4254d7 100644 --- a/src/librustc_metadata/index_builder.rs +++ b/src/librustc_metadata/index_builder.rs @@ -8,10 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use common::tag_items_data_item; use encoder::EncodeContext; use index::IndexData; use rbml::writer::Encoder; -use rustc::dep_graph::{DepNode, DepTask}; +use rustc::dep_graph::DepNode; use rustc::hir::def_id::DefId; use rustc::ty; use rustc_data_structures::fnv::FnvHashMap; @@ -52,10 +53,15 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { /// /// Returns a dep-graph task that you should keep live as long as /// the data for this item is being emitted. - pub fn record(&mut self, id: DefId, rbml_w: &mut Encoder) -> DepTask<'a> { + pub fn record(&mut self, id: DefId, rbml_w: &mut Encoder, op: OP) + where OP: FnOnce(&mut ItemContentBuilder<'a, 'tcx>, &mut Encoder) + { let position = rbml_w.mark_stable_position(); self.items.record(id, position); - self.ecx.tcx.dep_graph.in_task(DepNode::MetaData(id)) + let _task = self.ecx.tcx.dep_graph.in_task(DepNode::MetaData(id)); + rbml_w.start_tag(tag_items_data_item).unwrap(); + op(self, rbml_w); + rbml_w.end_tag().unwrap(); } pub fn into_fields(self) -> (IndexData, FnvHashMap, u32>) { From d49e1a91912788b874bfb5cfc610bc8e3a845d7f Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 11 Aug 2016 21:55:22 -0400 Subject: [PATCH 08/22] move rbml_w into the self struct --- src/librustc_metadata/encoder.rs | 788 ++++++++++++------------- src/librustc_metadata/index_builder.rs | 37 +- 2 files changed, 400 insertions(+), 425 deletions(-) diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 87c7b36cf87e6..8b76dd62692fb 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -132,22 +132,19 @@ fn encode_item_variances(rbml_w: &mut Encoder, rbml_w.end_tag(); } -impl<'a, 'tcx> ItemContentBuilder<'a, 'tcx> { +impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { fn encode_bounds_and_type_for_item(&mut self, - rbml_w: &mut Encoder, id: NodeId) { let ecx = self.ecx(); - self.encode_bounds_and_type(rbml_w, - &ecx.tcx.lookup_item_type(ecx.tcx.map.local_def_id(id)), + self.encode_bounds_and_type(&ecx.tcx.lookup_item_type(ecx.tcx.map.local_def_id(id)), &ecx.tcx.lookup_predicates(ecx.tcx.map.local_def_id(id))); } fn encode_bounds_and_type(&mut self, - rbml_w: &mut Encoder, scheme: &ty::TypeScheme<'tcx>, predicates: &ty::GenericPredicates<'tcx>) { - self.encode_generics(rbml_w, &scheme.generics, &predicates); - self.encode_type(rbml_w, scheme.ty); + self.encode_generics(&scheme.generics, &predicates); + self.encode_type(scheme.ty); } } @@ -164,47 +161,44 @@ fn write_closure_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w.mark_stable_position(); } -impl<'a, 'tcx> ItemContentBuilder<'a, 'tcx> { +impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { fn encode_type(&mut self, - rbml_w: &mut Encoder, typ: Ty<'tcx>) { - rbml_w.start_tag(tag_items_data_item_type); - tyencode::enc_ty(rbml_w.writer, &self.ecx().ty_str_ctxt(), typ); - rbml_w.mark_stable_position(); - rbml_w.end_tag(); + let ecx = self.ecx; + self.rbml_w.start_tag(tag_items_data_item_type); + tyencode::enc_ty(self.rbml_w.writer, &ecx.ty_str_ctxt(), typ); + self.rbml_w.mark_stable_position(); + self.rbml_w.end_tag(); } fn encode_disr_val(&mut self, - rbml_w: &mut Encoder, disr_val: ty::Disr) { // convert to u64 so just the number is printed, without any type info - rbml_w.wr_tagged_str(tag_disr_val, &disr_val.to_u64_unchecked().to_string()); + self.rbml_w.wr_tagged_str(tag_disr_val, &disr_val.to_u64_unchecked().to_string()); } - fn encode_parent_item(&mut self, rbml_w: &mut Encoder, id: DefId) { - rbml_w.wr_tagged_u64(tag_items_data_parent_item, def_to_u64(id)); + fn encode_parent_item(&mut self, id: DefId) { + self.rbml_w.wr_tagged_u64(tag_items_data_parent_item, def_to_u64(id)); } fn encode_struct_fields(&mut self, - rbml_w: &mut Encoder, variant: ty::VariantDef) { for f in &variant.fields { if variant.kind == ty::VariantKind::Tuple { - rbml_w.start_tag(tag_item_unnamed_field); + self.rbml_w.start_tag(tag_item_unnamed_field); } else { - rbml_w.start_tag(tag_item_field); - encode_name(rbml_w, f.name); + self.rbml_w.start_tag(tag_item_field); + encode_name(self.rbml_w, f.name); } - self.encode_struct_field_family(rbml_w, f.vis); - encode_def_id(rbml_w, f.did); - rbml_w.end_tag(); + self.encode_struct_field_family(f.vis); + encode_def_id(self.rbml_w, f.did); + self.rbml_w.end_tag(); } } } -impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { +impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { fn encode_enum_variant_info(&mut self, - rbml_w: &mut Encoder, did: DefId, vis: &hir::Visibility) { debug!("encode_enum_variant_info(did={:?})", did); @@ -218,37 +212,37 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { let variant_node_id = ecx.local_id(vid); for field in &variant.fields { - self.encode_field(rbml_w, field); + self.encode_field(field); } - self.record(vid, rbml_w, |this, rbml_w| { - encode_def_id_and_key(ecx, rbml_w, vid); - encode_family(rbml_w, match variant.kind { + self.record(vid, |this| { + encode_def_id_and_key(ecx, this.rbml_w, vid); + encode_family(this.rbml_w, match variant.kind { ty::VariantKind::Struct => 'V', ty::VariantKind::Tuple => 'v', ty::VariantKind::Unit => 'w', }); - encode_name(rbml_w, variant.name); - this.encode_parent_item(rbml_w, did); - this.encode_visibility(rbml_w, vis); + encode_name(this.rbml_w, variant.name); + this.encode_parent_item(did); + this.encode_visibility(vis); let attrs = ecx.tcx.get_attrs(vid); - encode_attributes(rbml_w, &attrs); - this.encode_repr_attrs(rbml_w, &attrs); + encode_attributes(this.rbml_w, &attrs); + this.encode_repr_attrs(&attrs); let stab = ecx.tcx.lookup_stability(vid); let depr = ecx.tcx.lookup_deprecation(vid); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); + encode_stability(this.rbml_w, stab); + encode_deprecation(this.rbml_w, depr); - this.encode_struct_fields(rbml_w, variant); + this.encode_struct_fields(variant); let specified_disr_val = variant.disr_val; if specified_disr_val != disr_val { - this.encode_disr_val(rbml_w, specified_disr_val); + this.encode_disr_val(specified_disr_val); disr_val = specified_disr_val; } - this.encode_bounds_and_type_for_item(rbml_w, variant_node_id); + this.encode_bounds_and_type_for_item(variant_node_id); }); disr_val = disr_val.wrap_incr(); @@ -302,9 +296,8 @@ fn encode_reexports(ecx: &EncodeContext, } } -impl<'a, 'tcx> ItemContentBuilder<'a, 'tcx> { +impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { fn encode_info_for_mod(&mut self, - rbml_w: &mut Encoder, md: &hir::Mod, attrs: &[ast::Attribute], id: NodeId, @@ -312,47 +305,47 @@ impl<'a, 'tcx> ItemContentBuilder<'a, 'tcx> { vis: &hir::Visibility) { let ecx = self.ecx(); - encode_def_id_and_key(ecx, rbml_w, ecx.tcx.map.local_def_id(id)); - encode_family(rbml_w, 'm'); - encode_name(rbml_w, name); + encode_def_id_and_key(ecx, self.rbml_w, ecx.tcx.map.local_def_id(id)); + encode_family(self.rbml_w, 'm'); + encode_name(self.rbml_w, name); debug!("(encoding info for module) encoding info for module ID {}", id); // Encode info about all the module children. for item_id in &md.item_ids { - rbml_w.wr_tagged_u64(tag_mod_child, + self.rbml_w.wr_tagged_u64(tag_mod_child, def_to_u64(ecx.tcx.map.local_def_id(item_id.id))); let item = ecx.tcx.map.expect_item(item_id.id); each_auxiliary_node_id(item, |auxiliary_node_id| { - rbml_w.wr_tagged_u64(tag_mod_child, + self.rbml_w.wr_tagged_u64(tag_mod_child, def_to_u64(ecx.tcx.map.local_def_id(auxiliary_node_id))); true }); } - self.encode_visibility(rbml_w, vis); + self.encode_visibility(vis); let stab = ecx.tcx.lookup_stability(ecx.tcx.map.local_def_id(id)); let depr = ecx.tcx.lookup_deprecation(ecx.tcx.map.local_def_id(id)); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); + encode_stability(self.rbml_w, stab); + encode_deprecation(self.rbml_w, depr); // Encode the reexports of this module, if this module is public. if *vis == hir::Public { debug!("(encoding info for module) encoding reexports for {}", id); - encode_reexports(ecx, rbml_w, id); + encode_reexports(ecx, self.rbml_w, id); } - encode_attributes(rbml_w, attrs); + encode_attributes(self.rbml_w, attrs); } - fn encode_struct_field_family(&mut self, rbml_w: &mut Encoder, + fn encode_struct_field_family(&mut self, visibility: ty::Visibility) { - encode_family(rbml_w, if visibility.is_public() { 'g' } else { 'N' }); + encode_family(self.rbml_w, if visibility.is_public() { 'g' } else { 'N' }); } - fn encode_visibility(&mut self, rbml_w: &mut Encoder, visibility: T) { + fn encode_visibility(&mut self, visibility: T) { let ch = if visibility.is_public() { 'y' } else { 'i' }; - rbml_w.wr_tagged_u8(tag_items_data_item_visibility, ch as u8); + self.rbml_w.wr_tagged_u8(tag_items_data_item_visibility, ch as u8); } } @@ -424,33 +417,31 @@ fn encode_item_sort(rbml_w: &mut Encoder, sort: char) { rbml_w.wr_tagged_u8(tag_item_trait_item_sort, sort as u8); } -impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { +impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { fn encode_field(&mut self, - rbml_w: &mut Encoder, field: ty::FieldDef<'tcx>) { let ecx = self.ecx(); let nm = field.name; let id = ecx.local_id(field.did); - self.record(field.did, rbml_w, |this, rbml_w| { + self.record(field.did, |this| { debug!("encode_field: encoding {} {}", nm, id); - this.encode_struct_field_family(rbml_w, field.vis); - encode_name(rbml_w, nm); - this.encode_bounds_and_type_for_item(rbml_w, id); - encode_def_id_and_key(ecx, rbml_w, field.did); + this.encode_struct_field_family(field.vis); + encode_name(this.rbml_w, nm); + this.encode_bounds_and_type_for_item(id); + encode_def_id_and_key(ecx, this.rbml_w, field.did); let stab = ecx.tcx.lookup_stability(field.did); let depr = ecx.tcx.lookup_deprecation(field.did); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); + encode_stability(this.rbml_w, stab); + encode_deprecation(this.rbml_w, depr); }); } } -impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { +impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { fn encode_info_for_struct_ctor(&mut self, - rbml_w: &mut Encoder, name: Name, struct_def: &hir::VariantData, struct_id: NodeId) { @@ -458,82 +449,78 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { let ctor_id = struct_def.id(); let ctor_def_id = ecx.tcx.map.local_def_id(ctor_id); - self.record(ctor_def_id, rbml_w, |this, rbml_w| { - encode_def_id_and_key(ecx, rbml_w, ctor_def_id); - encode_family(rbml_w, match *struct_def { + self.record(ctor_def_id, |this| { + encode_def_id_and_key(ecx, this.rbml_w, ctor_def_id); + encode_family(this.rbml_w, match *struct_def { hir::VariantData::Struct(..) => 'S', hir::VariantData::Tuple(..) => 's', hir::VariantData::Unit(..) => 'u', }); - this.encode_bounds_and_type_for_item(rbml_w, ctor_id); - encode_name(rbml_w, name); - this.encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(struct_id)); + this.encode_bounds_and_type_for_item(ctor_id); + encode_name(this.rbml_w, name); + this.encode_parent_item(ecx.tcx.map.local_def_id(struct_id)); let stab = ecx.tcx.lookup_stability(ecx.tcx.map.local_def_id(ctor_id)); let depr = ecx.tcx.lookup_deprecation(ecx.tcx.map.local_def_id(ctor_id)); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); + encode_stability(this.rbml_w, stab); + encode_deprecation(this.rbml_w, depr); // indicate that this is a tuple struct ctor, because // downstream users will normally want the tuple struct // definition, but without this there is no way for them // to tell that they actually have a ctor rather than a // normal function - rbml_w.wr_tagged_bytes(tag_items_data_item_is_tuple_struct_ctor, &[]); + this.rbml_w.wr_tagged_bytes(tag_items_data_item_is_tuple_struct_ctor, &[]); }); } } -impl<'a, 'tcx> ItemContentBuilder<'a, 'tcx> { +impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { fn encode_generics(&mut self, - rbml_w: &mut Encoder, generics: &ty::Generics<'tcx>, predicates: &ty::GenericPredicates<'tcx>) { let ecx = self.ecx(); - rbml_w.start_tag(tag_item_generics); - tyencode::enc_generics(rbml_w.writer, &ecx.ty_str_ctxt(), generics); - rbml_w.mark_stable_position(); - rbml_w.end_tag(); - self.encode_predicates(rbml_w, predicates, tag_item_predicates); + self.rbml_w.start_tag(tag_item_generics); + tyencode::enc_generics(self.rbml_w.writer, &ecx.ty_str_ctxt(), generics); + self.rbml_w.mark_stable_position(); + self.rbml_w.end_tag(); + self.encode_predicates(predicates, tag_item_predicates); } fn encode_predicates(&mut self, - rbml_w: &mut Encoder, predicates: &ty::GenericPredicates<'tcx>, tag: usize) { - rbml_w.start_tag(tag); + self.rbml_w.start_tag(tag); if let Some(def_id) = predicates.parent { - rbml_w.wr_tagged_u64(tag_items_data_parent_item, def_to_u64(def_id)); + self.rbml_w.wr_tagged_u64(tag_items_data_parent_item, def_to_u64(def_id)); } for predicate in &predicates.predicates { - rbml_w.wr_tagged_u32(tag_predicate, - self.add_xref(XRef::Predicate(predicate.clone()))); + let xref = self.add_xref(XRef::Predicate(predicate.clone())); + self.rbml_w.wr_tagged_u32(tag_predicate, xref); } - rbml_w.end_tag(); + self.rbml_w.end_tag(); } fn encode_method_ty_fields(&mut self, - rbml_w: &mut Encoder, method_ty: &ty::Method<'tcx>) { let ecx = self.ecx(); - encode_def_id_and_key(ecx, rbml_w, method_ty.def_id); - encode_name(rbml_w, method_ty.name); - self.encode_generics(rbml_w, &method_ty.generics, &method_ty.predicates); - self.encode_visibility(rbml_w, method_ty.vis); - encode_explicit_self(rbml_w, &method_ty.explicit_self); + encode_def_id_and_key(ecx, self.rbml_w, method_ty.def_id); + encode_name(self.rbml_w, method_ty.name); + self.encode_generics(&method_ty.generics, &method_ty.predicates); + self.encode_visibility(method_ty.vis); + encode_explicit_self(self.rbml_w, &method_ty.explicit_self); match method_ty.explicit_self { ty::ExplicitSelfCategory::Static => { - encode_family(rbml_w, STATIC_METHOD_FAMILY); + encode_family(self.rbml_w, STATIC_METHOD_FAMILY); } - _ => encode_family(rbml_w, METHOD_FAMILY) + _ => encode_family(self.rbml_w, METHOD_FAMILY) } } } -impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { +impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { fn encode_info_for_associated_const(&mut self, - rbml_w: &mut Encoder, associated_const: &ty::AssociatedConst, parent_id: NodeId, impl_item_opt: Option<&hir::ImplItem>) { @@ -542,36 +529,35 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { associated_const.def_id, associated_const.name); - self.record(associated_const.def_id, rbml_w, |this, rbml_w| { - encode_def_id_and_key(ecx, rbml_w, associated_const.def_id); - encode_name(rbml_w, associated_const.name); - this.encode_visibility(rbml_w, associated_const.vis); - encode_family(rbml_w, 'C'); + self.record(associated_const.def_id, |this| { + encode_def_id_and_key(ecx, this.rbml_w, associated_const.def_id); + encode_name(this.rbml_w, associated_const.name); + this.encode_visibility(associated_const.vis); + encode_family(this.rbml_w, 'C'); - this.encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id)); - encode_item_sort(rbml_w, 'C'); + this.encode_parent_item(ecx.tcx.map.local_def_id(parent_id)); + encode_item_sort(this.rbml_w, 'C'); - this.encode_bounds_and_type_for_item(rbml_w, ecx.local_id(associated_const.def_id)); + this.encode_bounds_and_type_for_item(ecx.local_id(associated_const.def_id)); let stab = ecx.tcx.lookup_stability(associated_const.def_id); let depr = ecx.tcx.lookup_deprecation(associated_const.def_id); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); + encode_stability(this.rbml_w, stab); + encode_deprecation(this.rbml_w, depr); if let Some(ii) = impl_item_opt { - encode_attributes(rbml_w, &ii.attrs); - encode_defaultness(rbml_w, ii.defaultness); + encode_attributes(this.rbml_w, &ii.attrs); + encode_defaultness(this.rbml_w, ii.defaultness); encode_inlined_item(ecx, - rbml_w, + this.rbml_w, InlinedItemRef::ImplItem(ecx.tcx.map.local_def_id(parent_id), ii)); - this.encode_mir(rbml_w, ii.id); + this.encode_mir(ii.id); } }); } fn encode_info_for_method(&mut self, - rbml_w: &mut Encoder, m: &ty::Method<'tcx>, is_default_impl: bool, parent_id: NodeId, @@ -580,22 +566,22 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { debug!("encode_info_for_method: {:?} {:?}", m.def_id, m.name); - self.record(m.def_id, rbml_w, |this, rbml_w| { - this.encode_method_ty_fields(rbml_w, m); - this.encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id)); - encode_item_sort(rbml_w, 'r'); + self.record(m.def_id, |this| { + this.encode_method_ty_fields(m); + this.encode_parent_item(ecx.tcx.map.local_def_id(parent_id)); + encode_item_sort(this.rbml_w, 'r'); let stab = ecx.tcx.lookup_stability(m.def_id); let depr = ecx.tcx.lookup_deprecation(m.def_id); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); + encode_stability(this.rbml_w, stab); + encode_deprecation(this.rbml_w, depr); let m_node_id = ecx.local_id(m.def_id); - this.encode_bounds_and_type_for_item(rbml_w, m_node_id); + this.encode_bounds_and_type_for_item(m_node_id); if let Some(impl_item) = impl_item_opt { if let hir::ImplItemKind::Method(ref sig, _) = impl_item.node { - encode_attributes(rbml_w, &impl_item.attrs); + encode_attributes(this.rbml_w, &impl_item.attrs); let generics = ecx.tcx.lookup_generics(m.def_id); let types = generics.parent_types as usize + generics.types.len(); let needs_inline = types > 0 || is_default_impl || @@ -603,21 +589,20 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { if needs_inline || sig.constness == hir::Constness::Const { encode_inlined_item( ecx, - rbml_w, + this.rbml_w, InlinedItemRef::ImplItem(ecx.tcx.map.local_def_id(parent_id), impl_item)); - this.encode_mir(rbml_w, impl_item.id); + this.encode_mir(impl_item.id); } - encode_constness(rbml_w, sig.constness); - encode_defaultness(rbml_w, impl_item.defaultness); - this.encode_method_argument_names(rbml_w, &sig.decl); + encode_constness(this.rbml_w, sig.constness); + encode_defaultness(this.rbml_w, impl_item.defaultness); + this.encode_method_argument_names(&sig.decl); } } }); } fn encode_info_for_associated_type(&mut self, - rbml_w: &mut Encoder, associated_type: &ty::AssociatedType<'tcx>, parent_id: NodeId, impl_item_opt: Option<&hir::ImplItem>) { @@ -626,55 +611,52 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { associated_type.def_id, associated_type.name); - self.record(associated_type.def_id, rbml_w, |this, rbml_w| { - encode_def_id_and_key(ecx, rbml_w, associated_type.def_id); - encode_name(rbml_w, associated_type.name); - this.encode_visibility(rbml_w, associated_type.vis); - encode_family(rbml_w, 'y'); - this.encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id)); - encode_item_sort(rbml_w, 't'); + self.record(associated_type.def_id, |this| { + encode_def_id_and_key(ecx, this.rbml_w, associated_type.def_id); + encode_name(this.rbml_w, associated_type.name); + this.encode_visibility(associated_type.vis); + encode_family(this.rbml_w, 'y'); + this.encode_parent_item(ecx.tcx.map.local_def_id(parent_id)); + encode_item_sort(this.rbml_w, 't'); let stab = ecx.tcx.lookup_stability(associated_type.def_id); let depr = ecx.tcx.lookup_deprecation(associated_type.def_id); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); + encode_stability(this.rbml_w, stab); + encode_deprecation(this.rbml_w, depr); if let Some(ii) = impl_item_opt { - encode_attributes(rbml_w, &ii.attrs); - encode_defaultness(rbml_w, ii.defaultness); + encode_attributes(this.rbml_w, &ii.attrs); + encode_defaultness(this.rbml_w, ii.defaultness); } else { // TODO this looks bogus and unnecessary - this.encode_predicates(rbml_w, - &ecx.tcx.lookup_predicates(associated_type.def_id), + this.encode_predicates(&ecx.tcx.lookup_predicates(associated_type.def_id), tag_item_generics); } if let Some(ty) = associated_type.ty { - this.encode_type(rbml_w, ty); + this.encode_type(ty); } }); } } -impl<'a, 'tcx> ItemContentBuilder<'a, 'tcx> { +impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { fn encode_method_argument_names(&mut self, - rbml_w: &mut Encoder, decl: &hir::FnDecl) { - rbml_w.start_tag(tag_method_argument_names); + self.rbml_w.start_tag(tag_method_argument_names); for arg in &decl.inputs { let tag = tag_method_argument_name; if let PatKind::Binding(_, ref path1, _) = arg.pat.node { let name = path1.node.as_str(); - rbml_w.wr_tagged_bytes(tag, name.as_bytes()); + self.rbml_w.wr_tagged_bytes(tag, name.as_bytes()); } else { - rbml_w.wr_tagged_bytes(tag, &[]); + self.rbml_w.wr_tagged_bytes(tag, &[]); } } - rbml_w.end_tag(); + self.rbml_w.end_tag(); } fn encode_repr_attrs(&mut self, - rbml_w: &mut Encoder, attrs: &[ast::Attribute]) { let ecx = self.ecx(); let mut repr_attrs = Vec::new(); @@ -682,22 +664,22 @@ impl<'a, 'tcx> ItemContentBuilder<'a, 'tcx> { repr_attrs.extend(attr::find_repr_attrs(ecx.tcx.sess.diagnostic(), attr)); } - rbml_w.start_tag(tag_items_data_item_repr); - repr_attrs.encode(rbml_w); - rbml_w.end_tag(); + self.rbml_w.start_tag(tag_items_data_item_repr); + repr_attrs.encode(self.rbml_w); + self.rbml_w.end_tag(); } - fn encode_mir(&mut self, rbml_w: &mut Encoder, node_id: NodeId) { + fn encode_mir(&mut self, node_id: NodeId) { let ecx = self.ecx(); let def_id = ecx.tcx.map.local_def_id(node_id); if let Some(mir) = ecx.mir_map.map.get(&def_id) { - rbml_w.start_tag(tag_mir as usize); - rbml_w.emit_opaque(|opaque_encoder| { + self.rbml_w.start_tag(tag_mir as usize); + self.rbml_w.emit_opaque(|opaque_encoder| { tls::enter_encoding_context(ecx, opaque_encoder, |_, opaque_encoder| { Encodable::encode(mir, opaque_encoder) }) }).unwrap(); - rbml_w.end_tag(); + self.rbml_w.end_tag(); } } } @@ -766,9 +748,8 @@ fn encode_xrefs<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w.end_tag(); } -impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { +impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { fn encode_info_for_item(&mut self, - rbml_w: &mut Encoder, item: &hir::Item) { let ecx = self.ecx(); let tcx = ecx.tcx; @@ -786,59 +767,58 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { match item.node { hir::ItemStatic(_, m, _) => { - self.record(def_id, rbml_w, |this, rbml_w| { - encode_def_id_and_key(ecx, rbml_w, def_id); + self.record(def_id, |this| { + encode_def_id_and_key(ecx, this.rbml_w, def_id); if m == hir::MutMutable { - encode_family(rbml_w, 'b'); + encode_family(this.rbml_w, 'b'); } else { - encode_family(rbml_w, 'c'); + encode_family(this.rbml_w, 'c'); } - this.encode_bounds_and_type_for_item(rbml_w, item.id); - encode_name(rbml_w, item.name); - this.encode_visibility(rbml_w, vis); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); - encode_attributes(rbml_w, &item.attrs); + this.encode_bounds_and_type_for_item(item.id); + encode_name(this.rbml_w, item.name); + this.encode_visibility(vis); + encode_stability(this.rbml_w, stab); + encode_deprecation(this.rbml_w, depr); + encode_attributes(this.rbml_w, &item.attrs); }); } hir::ItemConst(_, _) => { - self.record(def_id, rbml_w, |this, rbml_w| { - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_family(rbml_w, 'C'); - this.encode_bounds_and_type_for_item(rbml_w, item.id); - encode_name(rbml_w, item.name); - encode_attributes(rbml_w, &item.attrs); - encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(def_id, item)); - this.encode_mir(rbml_w, item.id); - this.encode_visibility(rbml_w, vis); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); + self.record(def_id, |this| { + encode_def_id_and_key(ecx, this.rbml_w, def_id); + encode_family(this.rbml_w, 'C'); + this.encode_bounds_and_type_for_item(item.id); + encode_name(this.rbml_w, item.name); + encode_attributes(this.rbml_w, &item.attrs); + encode_inlined_item(ecx, this.rbml_w, InlinedItemRef::Item(def_id, item)); + this.encode_mir(item.id); + this.encode_visibility(vis); + encode_stability(this.rbml_w, stab); + encode_deprecation(this.rbml_w, depr); }); } hir::ItemFn(ref decl, _, constness, _, ref generics, _) => { - self.record(def_id, rbml_w, |this, rbml_w| { - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_family(rbml_w, FN_FAMILY); + self.record(def_id, |this| { + encode_def_id_and_key(ecx, this.rbml_w, def_id); + encode_family(this.rbml_w, FN_FAMILY); let tps_len = generics.ty_params.len(); - this.encode_bounds_and_type_for_item(rbml_w, item.id); - encode_name(rbml_w, item.name); - encode_attributes(rbml_w, &item.attrs); + this.encode_bounds_and_type_for_item(item.id); + encode_name(this.rbml_w, item.name); + encode_attributes(this.rbml_w, &item.attrs); let needs_inline = tps_len > 0 || attr::requests_inline(&item.attrs); if needs_inline || constness == hir::Constness::Const { - encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(def_id, item)); - this.encode_mir(rbml_w, item.id); + encode_inlined_item(ecx, this.rbml_w, InlinedItemRef::Item(def_id, item)); + this.encode_mir(item.id); } - encode_constness(rbml_w, constness); - this.encode_visibility(rbml_w, vis); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); - this.encode_method_argument_names(rbml_w, &decl); + encode_constness(this.rbml_w, constness); + this.encode_visibility(vis); + encode_stability(this.rbml_w, stab); + encode_deprecation(this.rbml_w, depr); + this.encode_method_argument_names(&decl); }); } hir::ItemMod(ref m) => { - self.record(def_id, rbml_w, |this, rbml_w| { - this.encode_info_for_mod(rbml_w, - m, + self.record(def_id, |this| { + this.encode_info_for_mod(m, &item.attrs, item.id, item.name, @@ -846,118 +826,116 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { }); } hir::ItemForeignMod(ref fm) => { - self.record(def_id, rbml_w, |this, rbml_w| { - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_family(rbml_w, 'n'); - encode_name(rbml_w, item.name); + self.record(def_id, |this| { + encode_def_id_and_key(ecx, this.rbml_w, def_id); + encode_family(this.rbml_w, 'n'); + encode_name(this.rbml_w, item.name); // Encode all the items in this module. for foreign_item in &fm.items { - rbml_w.wr_tagged_u64(tag_mod_child, + this.rbml_w.wr_tagged_u64(tag_mod_child, def_to_u64(ecx.tcx.map.local_def_id(foreign_item.id))); } - this.encode_visibility(rbml_w, vis); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); + this.encode_visibility(vis); + encode_stability(this.rbml_w, stab); + encode_deprecation(this.rbml_w, depr); }); } hir::ItemTy(..) => { - self.record(def_id, rbml_w, |this, rbml_w| { - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_family(rbml_w, 'y'); - this.encode_bounds_and_type_for_item(rbml_w, item.id); - encode_name(rbml_w, item.name); - this.encode_visibility(rbml_w, vis); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); + self.record(def_id, |this| { + encode_def_id_and_key(ecx, this.rbml_w, def_id); + encode_family(this.rbml_w, 'y'); + this.encode_bounds_and_type_for_item(item.id); + encode_name(this.rbml_w, item.name); + this.encode_visibility(vis); + encode_stability(this.rbml_w, stab); + encode_deprecation(this.rbml_w, depr); }); } hir::ItemEnum(ref enum_definition, _) => { - self.record(def_id, rbml_w, |this, rbml_w| { - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_family(rbml_w, 't'); - encode_item_variances(rbml_w, ecx, item.id); - this.encode_bounds_and_type_for_item(rbml_w, item.id); - encode_name(rbml_w, item.name); - encode_attributes(rbml_w, &item.attrs); - this.encode_repr_attrs(rbml_w, &item.attrs); + self.record(def_id, |this| { + encode_def_id_and_key(ecx, this.rbml_w, def_id); + encode_family(this.rbml_w, 't'); + encode_item_variances(this.rbml_w, ecx, item.id); + this.encode_bounds_and_type_for_item(item.id); + encode_name(this.rbml_w, item.name); + encode_attributes(this.rbml_w, &item.attrs); + this.encode_repr_attrs(&item.attrs); for v in &enum_definition.variants { - encode_variant_id(rbml_w, ecx.tcx.map.local_def_id(v.node.data.id())); + encode_variant_id(this.rbml_w, ecx.tcx.map.local_def_id(v.node.data.id())); } - encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(def_id, item)); - this.encode_mir(rbml_w, item.id); + encode_inlined_item(ecx, this.rbml_w, InlinedItemRef::Item(def_id, item)); + this.encode_mir(item.id); // Encode inherent implementations for this enumeration. - encode_inherent_implementations(ecx, rbml_w, def_id); + encode_inherent_implementations(ecx, this.rbml_w, def_id); - this.encode_visibility(rbml_w, vis); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); + this.encode_visibility(vis); + encode_stability(this.rbml_w, stab); + encode_deprecation(this.rbml_w, depr); }); - self.encode_enum_variant_info(rbml_w, - def_id, - vis); + self.encode_enum_variant_info(def_id, vis); } hir::ItemStruct(ref struct_def, _) => { /* Index the class*/ let def = ecx.tcx.lookup_adt_def(def_id); let variant = def.struct_variant(); - self.record(def_id, rbml_w, |this, rbml_w| { + self.record(def_id, |this| { /* Now, make an item for the class itself */ - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_family(rbml_w, match *struct_def { + encode_def_id_and_key(ecx, this.rbml_w, def_id); + encode_family(this.rbml_w, match *struct_def { hir::VariantData::Struct(..) => 'S', hir::VariantData::Tuple(..) => 's', hir::VariantData::Unit(..) => 'u', }); - this.encode_bounds_and_type_for_item(rbml_w, item.id); + this.encode_bounds_and_type_for_item(item.id); - encode_item_variances(rbml_w, ecx, item.id); - encode_name(rbml_w, item.name); - encode_attributes(rbml_w, &item.attrs); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); - this.encode_visibility(rbml_w, vis); - this.encode_repr_attrs(rbml_w, &item.attrs); + encode_item_variances(this.rbml_w, ecx, item.id); + encode_name(this.rbml_w, item.name); + encode_attributes(this.rbml_w, &item.attrs); + encode_stability(this.rbml_w, stab); + encode_deprecation(this.rbml_w, depr); + this.encode_visibility(vis); + this.encode_repr_attrs(&item.attrs); /* Encode def_ids for each field and method for methods, write all the stuff get_trait_method needs to know*/ - this.encode_struct_fields(rbml_w, variant); + this.encode_struct_fields(variant); - encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(def_id, item)); - this.encode_mir(rbml_w, item.id); + encode_inlined_item(ecx, this.rbml_w, InlinedItemRef::Item(def_id, item)); + this.encode_mir(item.id); // Encode inherent implementations for this structure. - encode_inherent_implementations(ecx, rbml_w, def_id); + encode_inherent_implementations(ecx, this.rbml_w, def_id); if !struct_def.is_struct() { let ctor_did = ecx.tcx.map.local_def_id(struct_def.id()); - rbml_w.wr_tagged_u64(tag_items_data_item_struct_ctor, + this.rbml_w.wr_tagged_u64(tag_items_data_item_struct_ctor, def_to_u64(ctor_did)); } }); for field in &variant.fields { - self.encode_field(rbml_w, field); + self.encode_field(field); } // If this is a tuple-like struct, encode the type of the constructor. if !struct_def.is_struct() { - self.encode_info_for_struct_ctor(rbml_w, item.name, struct_def, item.id); + self.encode_info_for_struct_ctor(item.name, struct_def, item.id); } } hir::ItemDefaultImpl(unsafety, _) => { - self.record(def_id, rbml_w, |_this, rbml_w| { - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_family(rbml_w, 'd'); - encode_name(rbml_w, item.name); - encode_unsafety(rbml_w, unsafety); + self.record(def_id, |this| { + encode_def_id_and_key(ecx, this.rbml_w, def_id); + encode_family(this.rbml_w, 'd'); + encode_name(this.rbml_w, item.name); + encode_unsafety(this.rbml_w, unsafety); let trait_ref = tcx.impl_trait_ref(ecx.tcx.map.local_def_id(item.id)).unwrap(); - encode_trait_ref(rbml_w, ecx, trait_ref, tag_item_trait_ref); + encode_trait_ref(this.rbml_w, ecx, trait_ref, tag_item_trait_ref); }); } hir::ItemImpl(unsafety, polarity, _, _, _, ref ast_items) => { @@ -966,14 +944,14 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { let impl_items = tcx.impl_items.borrow(); let items = &impl_items[&def_id]; - self.record(def_id, rbml_w, |this, rbml_w| { - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_family(rbml_w, 'i'); - this.encode_bounds_and_type_for_item(rbml_w, item.id); - encode_name(rbml_w, item.name); - encode_attributes(rbml_w, &item.attrs); - encode_unsafety(rbml_w, unsafety); - encode_polarity(rbml_w, polarity); + self.record(def_id, |this| { + encode_def_id_and_key(ecx, this.rbml_w, def_id); + encode_family(this.rbml_w, 'i'); + this.encode_bounds_and_type_for_item(item.id); + encode_name(this.rbml_w, item.name); + encode_attributes(this.rbml_w, &item.attrs); + encode_unsafety(this.rbml_w, unsafety); + encode_polarity(this.rbml_w, polarity); match tcx.custom_coerce_unsized_kinds @@ -981,35 +959,35 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { .get(&ecx.tcx.map.local_def_id(item.id)) { Some(&kind) => { - rbml_w.start_tag(tag_impl_coerce_unsized_kind); - kind.encode(rbml_w); - rbml_w.end_tag(); + this.rbml_w.start_tag(tag_impl_coerce_unsized_kind); + kind.encode(this.rbml_w); + this.rbml_w.end_tag(); } None => {} } for &item_def_id in items { - rbml_w.start_tag(tag_item_impl_item); + this.rbml_w.start_tag(tag_item_impl_item); match item_def_id { ty::ConstTraitItemId(item_def_id) => { - encode_def_id(rbml_w, item_def_id); - encode_item_sort(rbml_w, 'C'); + encode_def_id(this.rbml_w, item_def_id); + encode_item_sort(this.rbml_w, 'C'); } ty::MethodTraitItemId(item_def_id) => { - encode_def_id(rbml_w, item_def_id); - encode_item_sort(rbml_w, 'r'); + encode_def_id(this.rbml_w, item_def_id); + encode_item_sort(this.rbml_w, 'r'); } ty::TypeTraitItemId(item_def_id) => { - encode_def_id(rbml_w, item_def_id); - encode_item_sort(rbml_w, 't'); + encode_def_id(this.rbml_w, item_def_id); + encode_item_sort(this.rbml_w, 't'); } } - rbml_w.end_tag(); + this.rbml_w.end_tag(); } let did = ecx.tcx.map.local_def_id(item.id); if let Some(trait_ref) = tcx.impl_trait_ref(did) { - encode_trait_ref(rbml_w, ecx, trait_ref, tag_item_trait_ref); + encode_trait_ref(this.rbml_w, ecx, trait_ref, tag_item_trait_ref); let trait_def = tcx.lookup_trait_def(trait_ref.def_id); let parent = trait_def.ancestors(did) @@ -1020,10 +998,10 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { Some(parent), _ => None, }); - encode_parent_impl(rbml_w, parent); + encode_parent_impl(this.rbml_w, parent); } - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); + encode_stability(this.rbml_w, stab); + encode_deprecation(this.rbml_w, depr); }); // Iterate down the trait items, emitting them. We rely on the @@ -1040,21 +1018,18 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { match tcx.impl_or_trait_item(trait_item_def_id.def_id()) { ty::ConstTraitItem(ref associated_const) => { - self.encode_info_for_associated_const(rbml_w, - &associated_const, - item.id, - ast_item) + self.encode_info_for_associated_const(&associated_const, + item.id, + ast_item) } ty::MethodTraitItem(ref method_type) => { - self.encode_info_for_method(rbml_w, - &method_type, + self.encode_info_for_method(&method_type, false, item.id, ast_item) } ty::TypeTraitItem(ref associated_type) => { - self.encode_info_for_associated_type(rbml_w, - &associated_type, + self.encode_info_for_associated_type(&associated_type, item.id, ast_item) } @@ -1062,50 +1037,49 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { } } hir::ItemTrait(_, _, _, ref ms) => { - self.record(def_id, rbml_w, |this, rbml_w| { - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_family(rbml_w, 'I'); - encode_item_variances(rbml_w, ecx, item.id); + self.record(def_id, |this| { + encode_def_id_and_key(ecx, this.rbml_w, def_id); + encode_family(this.rbml_w, 'I'); + encode_item_variances(this.rbml_w, ecx, item.id); let trait_def = tcx.lookup_trait_def(def_id); let trait_predicates = tcx.lookup_predicates(def_id); - encode_unsafety(rbml_w, trait_def.unsafety); - encode_paren_sugar(rbml_w, trait_def.paren_sugar); - encode_defaulted(rbml_w, tcx.trait_has_default_impl(def_id)); - encode_associated_type_names(rbml_w, &trait_def.associated_type_names); - this.encode_generics(rbml_w, &trait_def.generics, &trait_predicates); - this.encode_predicates(rbml_w, - &tcx.lookup_super_predicates(def_id), + encode_unsafety(this.rbml_w, trait_def.unsafety); + encode_paren_sugar(this.rbml_w, trait_def.paren_sugar); + encode_defaulted(this.rbml_w, tcx.trait_has_default_impl(def_id)); + encode_associated_type_names(this.rbml_w, &trait_def.associated_type_names); + this.encode_generics(&trait_def.generics, &trait_predicates); + this.encode_predicates(&tcx.lookup_super_predicates(def_id), tag_item_super_predicates); - encode_trait_ref(rbml_w, ecx, trait_def.trait_ref, tag_item_trait_ref); - encode_name(rbml_w, item.name); - encode_attributes(rbml_w, &item.attrs); - this.encode_visibility(rbml_w, vis); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); + encode_trait_ref(this.rbml_w, ecx, trait_def.trait_ref, tag_item_trait_ref); + encode_name(this.rbml_w, item.name); + encode_attributes(this.rbml_w, &item.attrs); + this.encode_visibility(vis); + encode_stability(this.rbml_w, stab); + encode_deprecation(this.rbml_w, depr); for &method_def_id in tcx.trait_item_def_ids(def_id).iter() { - rbml_w.start_tag(tag_item_trait_item); + this.rbml_w.start_tag(tag_item_trait_item); match method_def_id { ty::ConstTraitItemId(const_def_id) => { - encode_def_id(rbml_w, const_def_id); - encode_item_sort(rbml_w, 'C'); + encode_def_id(this.rbml_w, const_def_id); + encode_item_sort(this.rbml_w, 'C'); } ty::MethodTraitItemId(method_def_id) => { - encode_def_id(rbml_w, method_def_id); - encode_item_sort(rbml_w, 'r'); + encode_def_id(this.rbml_w, method_def_id); + encode_item_sort(this.rbml_w, 'r'); } ty::TypeTraitItemId(type_def_id) => { - encode_def_id(rbml_w, type_def_id); - encode_item_sort(rbml_w, 't'); + encode_def_id(this.rbml_w, type_def_id); + encode_item_sort(this.rbml_w, 't'); } } - rbml_w.end_tag(); + this.rbml_w.end_tag(); - rbml_w.wr_tagged_u64(tag_mod_child, + this.rbml_w.wr_tagged_u64(tag_mod_child, def_to_u64(method_def_id.def_id())); } // Encode inherent implementations for this trait. - encode_inherent_implementations(ecx, rbml_w, def_id); + encode_inherent_implementations(ecx, this.rbml_w, def_id); }); // Now output the trait item info for each trait item. @@ -1113,27 +1087,26 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { for (i, &item_def_id) in r.iter().enumerate() { assert_eq!(item_def_id.def_id().krate, LOCAL_CRATE); - self.record(item_def_id.def_id(), rbml_w, |this, rbml_w| { - this.encode_parent_item(rbml_w, def_id); + self.record(item_def_id.def_id(), |this| { + this.encode_parent_item(def_id); let stab = tcx.lookup_stability(item_def_id.def_id()); let depr = tcx.lookup_deprecation(item_def_id.def_id()); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); + encode_stability(this.rbml_w, stab); + encode_deprecation(this.rbml_w, depr); let trait_item_type = tcx.impl_or_trait_item(item_def_id.def_id()); let is_nonstatic_method; match trait_item_type { ty::ConstTraitItem(associated_const) => { - encode_name(rbml_w, associated_const.name); - encode_def_id_and_key(ecx, rbml_w, associated_const.def_id); - this.encode_visibility(rbml_w, associated_const.vis); + encode_name(this.rbml_w, associated_const.name); + encode_def_id_and_key(ecx, this.rbml_w, associated_const.def_id); + this.encode_visibility(associated_const.vis); - encode_family(rbml_w, 'C'); + encode_family(this.rbml_w, 'C'); this.encode_bounds_and_type_for_item( - rbml_w, ecx.local_id(associated_const.def_id)); is_nonstatic_method = false; @@ -1141,32 +1114,31 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { ty::MethodTraitItem(method_ty) => { let method_def_id = item_def_id.def_id(); - this.encode_method_ty_fields(rbml_w, &method_ty); + this.encode_method_ty_fields(&method_ty); match method_ty.explicit_self { ty::ExplicitSelfCategory::Static => { - encode_family(rbml_w, + encode_family(this.rbml_w, STATIC_METHOD_FAMILY); } _ => { - encode_family(rbml_w, + encode_family(this.rbml_w, METHOD_FAMILY); } } - this.encode_bounds_and_type_for_item(rbml_w, - ecx.local_id(method_def_id)); + this.encode_bounds_and_type_for_item(ecx.local_id(method_def_id)); is_nonstatic_method = method_ty.explicit_self != ty::ExplicitSelfCategory::Static; } ty::TypeTraitItem(associated_type) => { - encode_name(rbml_w, associated_type.name); - encode_def_id_and_key(ecx, rbml_w, associated_type.def_id); - encode_item_sort(rbml_w, 't'); - encode_family(rbml_w, 'y'); + encode_name(this.rbml_w, associated_type.name); + encode_def_id_and_key(ecx, this.rbml_w, associated_type.def_id); + encode_item_sort(this.rbml_w, 't'); + encode_family(this.rbml_w, 'y'); if let Some(ty) = associated_type.ty { - this.encode_type(rbml_w, ty); + this.encode_type(ty); } is_nonstatic_method = false; @@ -1174,40 +1146,39 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { } let trait_item = &ms[i]; - encode_attributes(rbml_w, &trait_item.attrs); + encode_attributes(this.rbml_w, &trait_item.attrs); match trait_item.node { hir::ConstTraitItem(_, ref default) => { if default.is_some() { - encode_item_sort(rbml_w, 'C'); + encode_item_sort(this.rbml_w, 'C'); } else { - encode_item_sort(rbml_w, 'c'); + encode_item_sort(this.rbml_w, 'c'); } - encode_inlined_item(ecx, rbml_w, + encode_inlined_item(ecx, this.rbml_w, InlinedItemRef::TraitItem(def_id, trait_item)); - this.encode_mir(rbml_w, trait_item.id); + this.encode_mir(trait_item.id); } hir::MethodTraitItem(ref sig, ref body) => { // If this is a static method, we've already // encoded this. if is_nonstatic_method { this.encode_bounds_and_type_for_item( - rbml_w, ecx.local_id(item_def_id.def_id())); } if body.is_some() { - encode_item_sort(rbml_w, 'p'); + encode_item_sort(this.rbml_w, 'p'); encode_inlined_item(ecx, - rbml_w, + this.rbml_w, InlinedItemRef::TraitItem( def_id, trait_item)); - this.encode_mir(rbml_w, trait_item.id); + this.encode_mir(trait_item.id); } else { - encode_item_sort(rbml_w, 'r'); + encode_item_sort(this.rbml_w, 'r'); } - this.encode_method_argument_names(rbml_w, &sig.decl); + this.encode_method_argument_names(&sig.decl); } hir::TypeTraitItem(..) => {} @@ -1222,7 +1193,6 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { } fn encode_info_for_foreign_item(&mut self, - rbml_w: &mut Encoder, nitem: &hir::ForeignItem) { let ecx = self.ecx(); @@ -1230,106 +1200,107 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { let def_id = ecx.tcx.map.local_def_id(nitem.id); let abi = ecx.tcx.map.get_foreign_abi(nitem.id); - self.record(def_id, rbml_w, |this, rbml_w| { - encode_def_id_and_key(ecx, rbml_w, def_id); + self.record(def_id, |this| { + encode_def_id_and_key(ecx, this.rbml_w, def_id); let parent_id = ecx.tcx.map.get_parent(nitem.id); - this.encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id)); - this.encode_visibility(rbml_w, &nitem.vis); + this.encode_parent_item(ecx.tcx.map.local_def_id(parent_id)); + this.encode_visibility(&nitem.vis); match nitem.node { hir::ForeignItemFn(ref fndecl, _) => { - encode_family(rbml_w, FN_FAMILY); - this.encode_bounds_and_type_for_item(rbml_w, nitem.id); - encode_name(rbml_w, nitem.name); + encode_family(this.rbml_w, FN_FAMILY); + this.encode_bounds_and_type_for_item(nitem.id); + encode_name(this.rbml_w, nitem.name); if abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic { - encode_inlined_item(ecx, rbml_w, InlinedItemRef::Foreign(def_id, nitem)); - this.encode_mir(rbml_w, nitem.id); + encode_inlined_item(ecx, + this.rbml_w, + InlinedItemRef::Foreign(def_id, nitem)); + this.encode_mir(nitem.id); } - encode_attributes(rbml_w, &nitem.attrs); + encode_attributes(this.rbml_w, &nitem.attrs); let stab = ecx.tcx.lookup_stability(ecx.tcx.map.local_def_id(nitem.id)); let depr = ecx.tcx.lookup_deprecation(ecx.tcx.map.local_def_id(nitem.id)); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); - this.encode_method_argument_names(rbml_w, &fndecl); + encode_stability(this.rbml_w, stab); + encode_deprecation(this.rbml_w, depr); + this.encode_method_argument_names(&fndecl); } hir::ForeignItemStatic(_, mutbl) => { if mutbl { - encode_family(rbml_w, 'b'); + encode_family(this.rbml_w, 'b'); } else { - encode_family(rbml_w, 'c'); + encode_family(this.rbml_w, 'c'); } - this.encode_bounds_and_type_for_item(rbml_w, nitem.id); - encode_attributes(rbml_w, &nitem.attrs); + this.encode_bounds_and_type_for_item(nitem.id); + encode_attributes(this.rbml_w, &nitem.attrs); let stab = ecx.tcx.lookup_stability(ecx.tcx.map.local_def_id(nitem.id)); let depr = ecx.tcx.lookup_deprecation(ecx.tcx.map.local_def_id(nitem.id)); - encode_stability(rbml_w, stab); - encode_deprecation(rbml_w, depr); - encode_name(rbml_w, nitem.name); + encode_stability(this.rbml_w, stab); + encode_deprecation(this.rbml_w, depr); + encode_name(this.rbml_w, nitem.name); } } }); } } -struct EncodeVisitor<'a, 'data:'a, 'ecx: 'a, 'tcx: 'ecx> { - rbml_w: &'a mut Encoder<'data>, - index: &'a mut IndexBuilder<'ecx, 'tcx>, +struct EncodeVisitor<'a, 'ecx: 'a, 'tcx: 'ecx, 'encoder: 'ecx> { + index: &'a mut IndexBuilder<'ecx, 'tcx, 'encoder>, } -impl<'a, 'data, 'ecx, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'data, 'ecx, 'tcx> { +impl<'a, 'ecx, 'tcx, 'encoder> Visitor<'tcx> for EncodeVisitor<'a, 'ecx, 'tcx, 'encoder> { fn visit_expr(&mut self, ex: &'tcx hir::Expr) { intravisit::walk_expr(self, ex); - self.index.encode_info_for_expr(ex, self.rbml_w); + self.index.encode_info_for_expr(ex); } fn visit_item(&mut self, i: &'tcx hir::Item) { intravisit::walk_item(self, i); - self.index.encode_info_for_item(self.rbml_w, i); + self.index.encode_info_for_item(i); } fn visit_foreign_item(&mut self, ni: &'tcx hir::ForeignItem) { intravisit::walk_foreign_item(self, ni); - self.index.encode_info_for_foreign_item(self.rbml_w, ni); + self.index.encode_info_for_foreign_item(ni); } fn visit_ty(&mut self, ty: &'tcx hir::Ty) { intravisit::walk_ty(self, ty); - self.index.encode_info_for_ty(ty, self.rbml_w); + self.index.encode_info_for_ty(ty); } } -impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { - fn encode_info_for_ty(&mut self, - ty: &hir::Ty, - rbml_w: &mut Encoder) { +impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { + fn encode_info_for_ty(&mut self, ty: &hir::Ty) { let ecx = self.ecx(); if let hir::TyImplTrait(_) = ty.node { let def_id = ecx.tcx.map.local_def_id(ty.id); - self.record(def_id, rbml_w, |this, rbml_w| { - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_family(rbml_w, 'y'); - this.encode_bounds_and_type_for_item(rbml_w, ty.id); + self.record(def_id, |this| { + encode_def_id_and_key(ecx, this.rbml_w, def_id); + encode_family(this.rbml_w, 'y'); + this.encode_bounds_and_type_for_item(ty.id); }); } } - fn encode_info_for_expr(&mut self, expr: &hir::Expr, rbml_w: &mut Encoder) { + fn encode_info_for_expr(&mut self, expr: &hir::Expr) { let ecx = self.ecx(); match expr.node { hir::ExprClosure(..) => { let def_id = ecx.tcx.map.local_def_id(expr.id); - self.record(def_id, rbml_w, |this, rbml_w| { - encode_def_id_and_key(ecx, rbml_w, def_id); - encode_name(rbml_w, syntax::parse::token::intern("")); + self.record(def_id, |this| { + encode_def_id_and_key(ecx, this.rbml_w, def_id); + encode_name(this.rbml_w, syntax::parse::token::intern("")); - rbml_w.start_tag(tag_items_closure_ty); - write_closure_type(ecx, rbml_w, &ecx.tcx.tables.borrow().closure_tys[&def_id]); - rbml_w.end_tag(); + this.rbml_w.start_tag(tag_items_closure_ty); + write_closure_type(ecx, + this.rbml_w, + &ecx.tcx.tables.borrow().closure_tys[&def_id]); + this.rbml_w.end_tag(); - rbml_w.start_tag(tag_items_closure_kind); - ecx.tcx.closure_kind(def_id).encode(rbml_w).unwrap(); - rbml_w.end_tag(); + this.rbml_w.start_tag(tag_items_closure_kind); + ecx.tcx.closure_kind(def_id).encode(this.rbml_w).unwrap(); + this.rbml_w.end_tag(); assert!(ecx.mir_map.map.contains_key(&def_id)); - this.encode_mir(rbml_w, expr.id); + this.encode_mir(expr.id); }); } _ => { } @@ -1337,30 +1308,31 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { } } -fn encode_info_for_items<'a, 'tcx>(ecx: &'a EncodeContext<'a, 'tcx>, +fn encode_info_for_items<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w: &mut Encoder) - -> IndexBuilder<'a, 'tcx> { + -> (IndexData, FnvHashMap, u32>) { let krate = ecx.tcx.map.krate(); - let mut index = IndexBuilder::new(ecx); rbml_w.start_tag(tag_items_data); - index.record(DefId::local(CRATE_DEF_INDEX), rbml_w, |this, rbml_w| { - this.encode_info_for_mod(rbml_w, - &krate.module, - &[], - CRATE_NODE_ID, - syntax::parse::token::intern(&ecx.link_meta.crate_name), - &hir::Public); - }); - - krate.visit_all_items(&mut EncodeVisitor { - index: &mut index, - rbml_w: &mut *rbml_w, - }); + let fields = { + let mut index = IndexBuilder::new(ecx, rbml_w); + index.record(DefId::local(CRATE_DEF_INDEX), |this| { + this.encode_info_for_mod(&krate.module, + &[], + CRATE_NODE_ID, + syntax::parse::token::intern(&ecx.link_meta.crate_name), + &hir::Public); + }); + krate.visit_all_items(&mut EncodeVisitor { + index: &mut index, + }); + index.into_fields() + }; rbml_w.end_tag(); - index + + fields } fn encode_item_index(rbml_w: &mut Encoder, index: IndexData) { @@ -1880,12 +1852,10 @@ fn encode_metadata_inner(rbml_w: &mut Encoder, // Encode and index the items. rbml_w.start_tag(tag_items); i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap(); - let index = encode_info_for_items(&ecx, rbml_w); + let (items, xrefs) = encode_info_for_items(&ecx, rbml_w); stats.item_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i; rbml_w.end_tag(); - let (items, xrefs) = index.into_fields(); - i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap(); encode_item_index(rbml_w, items); stats.index_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i; diff --git a/src/librustc_metadata/index_builder.rs b/src/librustc_metadata/index_builder.rs index 2ccd1fd4254d7..b591e0a92688b 100644 --- a/src/librustc_metadata/index_builder.rs +++ b/src/librustc_metadata/index_builder.rs @@ -20,29 +20,33 @@ 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> { +pub struct IndexBuilder<'a, 'tcx: 'a, 'encoder: 'a> { items: IndexData, - builder: ItemContentBuilder<'a, 'tcx>, + builder: ItemContentBuilder<'a, 'tcx, 'encoder>, } /// 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> { +pub struct ItemContentBuilder<'a, 'tcx: 'a, 'encoder: 'a> { xrefs: FnvHashMap, u32>, // sequentially-assigned - ecx: &'a EncodeContext<'a, 'tcx>, + pub ecx: &'a EncodeContext<'a, 'tcx>, + pub rbml_w: &'a mut Encoder<'encoder>, } /// "interned" entries referenced by id #[derive(PartialEq, Eq, Hash)] pub enum XRef<'tcx> { Predicate(ty::Predicate<'tcx>) } -impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { - pub fn new(ecx: &'a EncodeContext<'a, 'tcx>) -> Self { +impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { + pub fn new(ecx: &'a EncodeContext<'a, 'tcx>, + rbml_w: &'a mut Encoder<'encoder>) + -> Self { IndexBuilder { items: IndexData::new(ecx.tcx.map.num_local_def_ids()), builder: ItemContentBuilder { ecx: ecx, xrefs: FnvHashMap(), + rbml_w: rbml_w, }, } } @@ -53,15 +57,15 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { /// /// Returns a dep-graph task that you should keep live as long as /// the data for this item is being emitted. - pub fn record(&mut self, id: DefId, rbml_w: &mut Encoder, op: OP) - where OP: FnOnce(&mut ItemContentBuilder<'a, 'tcx>, &mut Encoder) + pub fn record(&mut self, id: DefId, op: OP) + where OP: FnOnce(&mut ItemContentBuilder<'a, 'tcx, 'encoder>) { - let position = rbml_w.mark_stable_position(); + let position = self.rbml_w.mark_stable_position(); self.items.record(id, position); let _task = self.ecx.tcx.dep_graph.in_task(DepNode::MetaData(id)); - rbml_w.start_tag(tag_items_data_item).unwrap(); - op(self, rbml_w); - rbml_w.end_tag().unwrap(); + self.rbml_w.start_tag(tag_items_data_item).unwrap(); + op(self); + self.rbml_w.end_tag().unwrap(); } pub fn into_fields(self) -> (IndexData, FnvHashMap, u32>) { @@ -69,21 +73,21 @@ impl<'a, 'tcx> IndexBuilder<'a, 'tcx> { } } -impl<'a, 'tcx> Deref for IndexBuilder<'a, 'tcx> { - type Target = ItemContentBuilder<'a, 'tcx>; +impl<'a, 'tcx, 'encoder> Deref for IndexBuilder<'a, 'tcx, 'encoder> { + type Target = ItemContentBuilder<'a, 'tcx, 'encoder>; fn deref(&self) -> &Self::Target { &self.builder } } -impl<'a, 'tcx> DerefMut for IndexBuilder<'a, 'tcx> { +impl<'a, 'tcx, 'encoder> DerefMut for IndexBuilder<'a, 'tcx, 'encoder> { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.builder } } -impl<'a, 'tcx> ItemContentBuilder<'a, 'tcx> { +impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { pub fn ecx(&self) -> &'a EncodeContext<'a, 'tcx> { self.ecx } @@ -93,3 +97,4 @@ impl<'a, 'tcx> ItemContentBuilder<'a, 'tcx> { *self.xrefs.entry(xref).or_insert(old_len) } } + From 6277b1fef617610c32b36dba1b06f937488ca5a9 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 12 Aug 2016 14:18:59 -0400 Subject: [PATCH 09/22] separate main items from addl items in metadata --- src/librustc_metadata/encoder.rs | 374 ++++++++++++++++++------------- 1 file changed, 220 insertions(+), 154 deletions(-) diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 8b76dd62692fb..8611e744bc468 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -443,18 +443,18 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { fn encode_info_for_struct_ctor(&mut self, name: Name, - struct_def: &hir::VariantData, + ctor_id: ast::NodeId, + variant: ty::VariantDef<'tcx>, struct_id: NodeId) { let ecx = self.ecx(); - let ctor_id = struct_def.id(); let ctor_def_id = ecx.tcx.map.local_def_id(ctor_id); self.record(ctor_def_id, |this| { encode_def_id_and_key(ecx, this.rbml_w, ctor_def_id); - encode_family(this.rbml_w, match *struct_def { - hir::VariantData::Struct(..) => 'S', - hir::VariantData::Tuple(..) => 's', - hir::VariantData::Unit(..) => 'u', + encode_family(this.rbml_w, match variant.kind { + ty::VariantKind::Struct => 'S', + ty::VariantKind::Tuple => 's', + ty::VariantKind::Unit => 'u', }); this.encode_bounds_and_type_for_item(ctor_id); encode_name(this.rbml_w, name); @@ -874,15 +874,13 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { encode_stability(this.rbml_w, stab); encode_deprecation(this.rbml_w, depr); }); - - self.encode_enum_variant_info(def_id, vis); } hir::ItemStruct(ref struct_def, _) => { /* Index the class*/ - let def = ecx.tcx.lookup_adt_def(def_id); - let variant = def.struct_variant(); - self.record(def_id, |this| { + let def = ecx.tcx.lookup_adt_def(def_id); + let variant = def.struct_variant(); + /* Now, make an item for the class itself */ encode_def_id_and_key(ecx, this.rbml_w, def_id); encode_family(this.rbml_w, match *struct_def { @@ -917,15 +915,6 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { def_to_u64(ctor_did)); } }); - - for field in &variant.fields { - self.encode_field(field); - } - - // If this is a tuple-like struct, encode the type of the constructor. - if !struct_def.is_struct() { - self.encode_info_for_struct_ctor(item.name, struct_def, item.id); - } } hir::ItemDefaultImpl(unsafety, _) => { self.record(def_id, |this| { @@ -938,13 +927,13 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { encode_trait_ref(this.rbml_w, ecx, trait_ref, tag_item_trait_ref); }); } - hir::ItemImpl(unsafety, polarity, _, _, _, ref ast_items) => { - // We need to encode information about the default methods we - // have inherited, so we drive this based on the impl structure. - let impl_items = tcx.impl_items.borrow(); - let items = &impl_items[&def_id]; - + hir::ItemImpl(unsafety, polarity, _, _, _, _) => { self.record(def_id, |this| { + // We need to encode information about the default methods we + // have inherited, so we drive this based on the impl structure. + let impl_items = tcx.impl_items.borrow(); + let items = &impl_items[&def_id]; + encode_def_id_and_key(ecx, this.rbml_w, def_id); encode_family(this.rbml_w, 'i'); this.encode_bounds_and_type_for_item(item.id); @@ -1003,40 +992,8 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { encode_stability(this.rbml_w, stab); encode_deprecation(this.rbml_w, depr); }); - - // Iterate down the trait items, emitting them. We rely on the - // assumption that all of the actually implemented trait items - // appear first in the impl structure, in the same order they do - // in the ast. This is a little sketchy. - let num_implemented_methods = ast_items.len(); - for (i, &trait_item_def_id) in items.iter().enumerate() { - let ast_item = if i < num_implemented_methods { - Some(&ast_items[i]) - } else { - None - }; - - match tcx.impl_or_trait_item(trait_item_def_id.def_id()) { - ty::ConstTraitItem(ref associated_const) => { - self.encode_info_for_associated_const(&associated_const, - item.id, - ast_item) - } - ty::MethodTraitItem(ref method_type) => { - self.encode_info_for_method(&method_type, - false, - item.id, - ast_item) - } - ty::TypeTraitItem(ref associated_type) => { - self.encode_info_for_associated_type(&associated_type, - item.id, - ast_item) - } - } - } } - hir::ItemTrait(_, _, _, ref ms) => { + hir::ItemTrait(_, _, _, _) => { self.record(def_id, |this| { encode_def_id_and_key(ecx, this.rbml_w, def_id); encode_family(this.rbml_w, 'I'); @@ -1081,114 +1038,222 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { // Encode inherent implementations for this trait. encode_inherent_implementations(ecx, this.rbml_w, def_id); }); + } + hir::ItemExternCrate(_) | hir::ItemUse(_) => { + // these are encoded separately + } + } + } - // Now output the trait item info for each trait item. - let r = tcx.trait_item_def_ids(def_id); - for (i, &item_def_id) in r.iter().enumerate() { - assert_eq!(item_def_id.def_id().krate, LOCAL_CRATE); + /// In some cases, along with the item itself, we also + /// encode some sub-items. Usually we want some info from the item + /// so it's easier to do that here then to wait until we would encounter + /// normally in the visitor walk. + fn encode_addl_info_for_item(&mut self, + item: &hir::Item) { + let def_id = self.ecx.tcx.map.local_def_id(item.id); + match item.node { + hir::ItemStatic(..) | + hir::ItemConst(..) | + hir::ItemFn(..) | + hir::ItemMod(..) | + hir::ItemForeignMod(..) | + hir::ItemExternCrate(..) | + hir::ItemUse(..) | + hir::ItemDefaultImpl(..) | + hir::ItemTy(..) => { + // no sub-item recording needed in these cases + } + hir::ItemEnum(..) => { + self.encode_enum_variant_info(def_id, &item.vis); + } + hir::ItemStruct(ref struct_def, _) => { + self.encode_addl_struct_info(def_id, struct_def.id(), item); + } + hir::ItemImpl(_, _, _, _, _, ref ast_items) => { + self.encode_addl_impl_info(def_id, item.id, ast_items); + } + hir::ItemTrait(_, _, _, ref trait_items) => { + self.encode_addl_trait_info(def_id, trait_items); + } + } + } - self.record(item_def_id.def_id(), |this| { - this.encode_parent_item(def_id); + fn encode_addl_struct_info(&mut self, + def_id: DefId, + struct_def_id: ast::NodeId, + item: &hir::Item) { + let ecx = self.ecx; + let def = ecx.tcx.lookup_adt_def(def_id); + let variant = def.struct_variant(); - let stab = tcx.lookup_stability(item_def_id.def_id()); - let depr = tcx.lookup_deprecation(item_def_id.def_id()); - encode_stability(this.rbml_w, stab); - encode_deprecation(this.rbml_w, depr); + for field in &variant.fields { + self.encode_field(field); + } - let trait_item_type = - tcx.impl_or_trait_item(item_def_id.def_id()); - let is_nonstatic_method; - match trait_item_type { - ty::ConstTraitItem(associated_const) => { - encode_name(this.rbml_w, associated_const.name); - encode_def_id_and_key(ecx, this.rbml_w, associated_const.def_id); - this.encode_visibility(associated_const.vis); + // If this is a tuple-like struct, encode the type of the constructor. + match variant.kind { + ty::VariantKind::Struct => { + // no value for structs like struct Foo { ... } + } + ty::VariantKind::Tuple | ty::VariantKind::Unit => { + // there is a value for structs like `struct + // Foo()` and `struct Foo` + self.encode_info_for_struct_ctor(item.name, + struct_def_id, + variant, + item.id); + } + } + } - encode_family(this.rbml_w, 'C'); + fn encode_addl_impl_info(&mut self, + def_id: DefId, + impl_id: ast::NodeId, + ast_items: &[hir::ImplItem]) { + let ecx = self.ecx; + let impl_items = ecx.tcx.impl_items.borrow(); + let items = &impl_items[&def_id]; + + // Iterate down the trait items, emitting them. We rely on the + // assumption that all of the actually implemented trait items + // appear first in the impl structure, in the same order they do + // in the ast. This is a little sketchy. + let num_implemented_methods = ast_items.len(); + for (i, &trait_item_def_id) in items.iter().enumerate() { + let ast_item = if i < num_implemented_methods { + Some(&ast_items[i]) + } else { + None + }; + + match self.ecx.tcx.impl_or_trait_item(trait_item_def_id.def_id()) { + ty::ConstTraitItem(ref associated_const) => { + self.encode_info_for_associated_const(&associated_const, + impl_id, + ast_item) + } + ty::MethodTraitItem(ref method_type) => { + self.encode_info_for_method(&method_type, + false, + impl_id, + ast_item) + } + ty::TypeTraitItem(ref associated_type) => { + self.encode_info_for_associated_type(&associated_type, + impl_id, + ast_item) + } + } + } + } - this.encode_bounds_and_type_for_item( - ecx.local_id(associated_const.def_id)); + fn encode_addl_trait_info(&mut self, + def_id: DefId, + trait_items: &[hir::TraitItem]) { + // Now output the trait item info for each trait item. + let ecx = self.ecx; + let tcx = self.ecx.tcx; + let r = tcx.trait_item_def_ids(def_id); + for (&item_def_id, trait_item) in r.iter().zip(trait_items) { + assert_eq!(item_def_id.def_id().krate, LOCAL_CRATE); - is_nonstatic_method = false; + self.record(item_def_id.def_id(), |this| { + this.encode_parent_item(def_id); + + let stab = tcx.lookup_stability(item_def_id.def_id()); + let depr = tcx.lookup_deprecation(item_def_id.def_id()); + encode_stability(this.rbml_w, stab); + encode_deprecation(this.rbml_w, depr); + + let trait_item_type = + tcx.impl_or_trait_item(item_def_id.def_id()); + let is_nonstatic_method; + match trait_item_type { + ty::ConstTraitItem(associated_const) => { + encode_name(this.rbml_w, associated_const.name); + encode_def_id_and_key(ecx, this.rbml_w, associated_const.def_id); + this.encode_visibility(associated_const.vis); + + encode_family(this.rbml_w, 'C'); + + this.encode_bounds_and_type_for_item( + ecx.local_id(associated_const.def_id)); + + is_nonstatic_method = false; + } + ty::MethodTraitItem(method_ty) => { + let method_def_id = item_def_id.def_id(); + + this.encode_method_ty_fields(&method_ty); + + match method_ty.explicit_self { + ty::ExplicitSelfCategory::Static => { + encode_family(this.rbml_w, + STATIC_METHOD_FAMILY); } - ty::MethodTraitItem(method_ty) => { - let method_def_id = item_def_id.def_id(); - - this.encode_method_ty_fields(&method_ty); - - match method_ty.explicit_self { - ty::ExplicitSelfCategory::Static => { - encode_family(this.rbml_w, - STATIC_METHOD_FAMILY); - } - _ => { - encode_family(this.rbml_w, - METHOD_FAMILY); - } - } - this.encode_bounds_and_type_for_item(ecx.local_id(method_def_id)); - - is_nonstatic_method = method_ty.explicit_self != - ty::ExplicitSelfCategory::Static; + _ => { + encode_family(this.rbml_w, + METHOD_FAMILY); } - ty::TypeTraitItem(associated_type) => { - encode_name(this.rbml_w, associated_type.name); - encode_def_id_and_key(ecx, this.rbml_w, associated_type.def_id); - encode_item_sort(this.rbml_w, 't'); - encode_family(this.rbml_w, 'y'); + } + this.encode_bounds_and_type_for_item(ecx.local_id(method_def_id)); - if let Some(ty) = associated_type.ty { - this.encode_type(ty); - } + is_nonstatic_method = method_ty.explicit_self != + ty::ExplicitSelfCategory::Static; + } + ty::TypeTraitItem(associated_type) => { + encode_name(this.rbml_w, associated_type.name); + encode_def_id_and_key(ecx, this.rbml_w, associated_type.def_id); + encode_item_sort(this.rbml_w, 't'); + encode_family(this.rbml_w, 'y'); + + if let Some(ty) = associated_type.ty { + this.encode_type(ty); + } - is_nonstatic_method = false; - } + is_nonstatic_method = false; + } + } + + encode_attributes(this.rbml_w, &trait_item.attrs); + match trait_item.node { + hir::ConstTraitItem(_, ref default) => { + if default.is_some() { + encode_item_sort(this.rbml_w, 'C'); + } else { + encode_item_sort(this.rbml_w, 'c'); } - let trait_item = &ms[i]; - encode_attributes(this.rbml_w, &trait_item.attrs); - match trait_item.node { - hir::ConstTraitItem(_, ref default) => { - if default.is_some() { - encode_item_sort(this.rbml_w, 'C'); - } else { - encode_item_sort(this.rbml_w, 'c'); - } - - encode_inlined_item(ecx, this.rbml_w, - InlinedItemRef::TraitItem(def_id, trait_item)); - this.encode_mir(trait_item.id); - } - hir::MethodTraitItem(ref sig, ref body) => { - // If this is a static method, we've already - // encoded this. - if is_nonstatic_method { - this.encode_bounds_and_type_for_item( - ecx.local_id(item_def_id.def_id())); - } - - if body.is_some() { - encode_item_sort(this.rbml_w, 'p'); - encode_inlined_item(ecx, - this.rbml_w, - InlinedItemRef::TraitItem( - def_id, - trait_item)); - this.encode_mir(trait_item.id); - } else { - encode_item_sort(this.rbml_w, 'r'); - } - this.encode_method_argument_names(&sig.decl); - } + encode_inlined_item(ecx, this.rbml_w, + InlinedItemRef::TraitItem(def_id, trait_item)); + this.encode_mir(trait_item.id); + } + hir::MethodTraitItem(ref sig, ref body) => { + // If this is a static method, we've already + // encoded this. + if is_nonstatic_method { + this.encode_bounds_and_type_for_item( + ecx.local_id(item_def_id.def_id())); + } - hir::TypeTraitItem(..) => {} + if body.is_some() { + encode_item_sort(this.rbml_w, 'p'); + encode_inlined_item(ecx, + this.rbml_w, + InlinedItemRef::TraitItem( + def_id, + trait_item)); + this.encode_mir(trait_item.id); + } else { + encode_item_sort(this.rbml_w, 'r'); } - }); + this.encode_method_argument_names(&sig.decl); + } + + hir::TypeTraitItem(..) => {} } - } - hir::ItemExternCrate(_) | hir::ItemUse(_) => { - // these are encoded separately - } + }); } } @@ -1251,9 +1316,10 @@ impl<'a, 'ecx, 'tcx, 'encoder> Visitor<'tcx> for EncodeVisitor<'a, 'ecx, 'tcx, ' intravisit::walk_expr(self, ex); self.index.encode_info_for_expr(ex); } - fn visit_item(&mut self, i: &'tcx hir::Item) { - intravisit::walk_item(self, i); - self.index.encode_info_for_item(i); + fn visit_item(&mut self, item: &'tcx hir::Item) { + intravisit::walk_item(self, item); + self.index.encode_info_for_item(item); + self.index.encode_addl_info_for_item(item); } fn visit_foreign_item(&mut self, ni: &'tcx hir::ForeignItem) { intravisit::walk_foreign_item(self, ni); From 5166682583a95a8e498c27d12154ddc1d9dda406 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 12 Aug 2016 14:54:46 -0400 Subject: [PATCH 10/22] pull out the record call for encode_info_for_item --- src/librustc_metadata/encoder.rs | 468 +++++++++++++++---------------- 1 file changed, 226 insertions(+), 242 deletions(-) diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 8611e744bc468..25b705b0d3a77 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -748,8 +748,9 @@ fn encode_xrefs<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w.end_tag(); } -impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { +impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { fn encode_info_for_item(&mut self, + def_id: DefId, item: &hir::Item) { let ecx = self.ecx(); let tcx = ecx.tcx; @@ -758,7 +759,6 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { tcx.sess.codemap().span_to_string(item.span)); let vis = &item.vis; - let def_id = ecx.tcx.map.local_def_id(item.id); let (stab, depr) = tcx.dep_graph.with_task(DepNode::MetaData(def_id), || { (tcx.lookup_stability(ecx.tcx.map.local_def_id(item.id)), @@ -767,284 +767,264 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { match item.node { hir::ItemStatic(_, m, _) => { - self.record(def_id, |this| { - encode_def_id_and_key(ecx, this.rbml_w, def_id); - if m == hir::MutMutable { - encode_family(this.rbml_w, 'b'); - } else { - encode_family(this.rbml_w, 'c'); - } - this.encode_bounds_and_type_for_item(item.id); - encode_name(this.rbml_w, item.name); - this.encode_visibility(vis); - encode_stability(this.rbml_w, stab); - encode_deprecation(this.rbml_w, depr); - encode_attributes(this.rbml_w, &item.attrs); - }); + encode_def_id_and_key(ecx, self.rbml_w, def_id); + if m == hir::MutMutable { + encode_family(self.rbml_w, 'b'); + } else { + encode_family(self.rbml_w, 'c'); + } + self.encode_bounds_and_type_for_item(item.id); + encode_name(self.rbml_w, item.name); + self.encode_visibility(vis); + encode_stability(self.rbml_w, stab); + encode_deprecation(self.rbml_w, depr); + encode_attributes(self.rbml_w, &item.attrs); } hir::ItemConst(_, _) => { - self.record(def_id, |this| { - encode_def_id_and_key(ecx, this.rbml_w, def_id); - encode_family(this.rbml_w, 'C'); - this.encode_bounds_and_type_for_item(item.id); - encode_name(this.rbml_w, item.name); - encode_attributes(this.rbml_w, &item.attrs); - encode_inlined_item(ecx, this.rbml_w, InlinedItemRef::Item(def_id, item)); - this.encode_mir(item.id); - this.encode_visibility(vis); - encode_stability(this.rbml_w, stab); - encode_deprecation(this.rbml_w, depr); - }); + encode_def_id_and_key(ecx, self.rbml_w, def_id); + encode_family(self.rbml_w, 'C'); + self.encode_bounds_and_type_for_item(item.id); + encode_name(self.rbml_w, item.name); + encode_attributes(self.rbml_w, &item.attrs); + encode_inlined_item(ecx, self.rbml_w, InlinedItemRef::Item(def_id, item)); + self.encode_mir(item.id); + self.encode_visibility(vis); + encode_stability(self.rbml_w, stab); + encode_deprecation(self.rbml_w, depr); } hir::ItemFn(ref decl, _, constness, _, ref generics, _) => { - self.record(def_id, |this| { - encode_def_id_and_key(ecx, this.rbml_w, def_id); - encode_family(this.rbml_w, FN_FAMILY); - let tps_len = generics.ty_params.len(); - this.encode_bounds_and_type_for_item(item.id); - encode_name(this.rbml_w, item.name); - encode_attributes(this.rbml_w, &item.attrs); - let needs_inline = tps_len > 0 || attr::requests_inline(&item.attrs); - if needs_inline || constness == hir::Constness::Const { - encode_inlined_item(ecx, this.rbml_w, InlinedItemRef::Item(def_id, item)); - this.encode_mir(item.id); - } - encode_constness(this.rbml_w, constness); - this.encode_visibility(vis); - encode_stability(this.rbml_w, stab); - encode_deprecation(this.rbml_w, depr); - this.encode_method_argument_names(&decl); - }); + encode_def_id_and_key(ecx, self.rbml_w, def_id); + encode_family(self.rbml_w, FN_FAMILY); + let tps_len = generics.ty_params.len(); + self.encode_bounds_and_type_for_item(item.id); + encode_name(self.rbml_w, item.name); + encode_attributes(self.rbml_w, &item.attrs); + let needs_inline = tps_len > 0 || attr::requests_inline(&item.attrs); + if needs_inline || constness == hir::Constness::Const { + encode_inlined_item(ecx, self.rbml_w, InlinedItemRef::Item(def_id, item)); + self.encode_mir(item.id); + } + encode_constness(self.rbml_w, constness); + self.encode_visibility(vis); + encode_stability(self.rbml_w, stab); + encode_deprecation(self.rbml_w, depr); + self.encode_method_argument_names(&decl); } hir::ItemMod(ref m) => { - self.record(def_id, |this| { - this.encode_info_for_mod(m, - &item.attrs, - item.id, - item.name, - &item.vis); - }); + self.encode_info_for_mod(m, + &item.attrs, + item.id, + item.name, + &item.vis); } hir::ItemForeignMod(ref fm) => { - self.record(def_id, |this| { - encode_def_id_and_key(ecx, this.rbml_w, def_id); - encode_family(this.rbml_w, 'n'); - encode_name(this.rbml_w, item.name); - - // Encode all the items in this module. - for foreign_item in &fm.items { - this.rbml_w.wr_tagged_u64(tag_mod_child, - def_to_u64(ecx.tcx.map.local_def_id(foreign_item.id))); - } - this.encode_visibility(vis); - encode_stability(this.rbml_w, stab); - encode_deprecation(this.rbml_w, depr); - }); + encode_def_id_and_key(ecx, self.rbml_w, def_id); + encode_family(self.rbml_w, 'n'); + encode_name(self.rbml_w, item.name); + + // Encode all the items in self module. + for foreign_item in &fm.items { + self.rbml_w.wr_tagged_u64(tag_mod_child, + def_to_u64(ecx.tcx.map.local_def_id(foreign_item.id))); + } + self.encode_visibility(vis); + encode_stability(self.rbml_w, stab); + encode_deprecation(self.rbml_w, depr); } hir::ItemTy(..) => { - self.record(def_id, |this| { - encode_def_id_and_key(ecx, this.rbml_w, def_id); - encode_family(this.rbml_w, 'y'); - this.encode_bounds_and_type_for_item(item.id); - encode_name(this.rbml_w, item.name); - this.encode_visibility(vis); - encode_stability(this.rbml_w, stab); - encode_deprecation(this.rbml_w, depr); - }); + encode_def_id_and_key(ecx, self.rbml_w, def_id); + encode_family(self.rbml_w, 'y'); + self.encode_bounds_and_type_for_item(item.id); + encode_name(self.rbml_w, item.name); + self.encode_visibility(vis); + encode_stability(self.rbml_w, stab); + encode_deprecation(self.rbml_w, depr); } hir::ItemEnum(ref enum_definition, _) => { - self.record(def_id, |this| { - encode_def_id_and_key(ecx, this.rbml_w, def_id); - encode_family(this.rbml_w, 't'); - encode_item_variances(this.rbml_w, ecx, item.id); - this.encode_bounds_and_type_for_item(item.id); - encode_name(this.rbml_w, item.name); - encode_attributes(this.rbml_w, &item.attrs); - this.encode_repr_attrs(&item.attrs); - for v in &enum_definition.variants { - encode_variant_id(this.rbml_w, ecx.tcx.map.local_def_id(v.node.data.id())); - } - encode_inlined_item(ecx, this.rbml_w, InlinedItemRef::Item(def_id, item)); - this.encode_mir(item.id); + encode_def_id_and_key(ecx, self.rbml_w, def_id); + encode_family(self.rbml_w, 't'); + encode_item_variances(self.rbml_w, ecx, item.id); + self.encode_bounds_and_type_for_item(item.id); + encode_name(self.rbml_w, item.name); + encode_attributes(self.rbml_w, &item.attrs); + self.encode_repr_attrs(&item.attrs); + for v in &enum_definition.variants { + encode_variant_id(self.rbml_w, ecx.tcx.map.local_def_id(v.node.data.id())); + } + encode_inlined_item(ecx, self.rbml_w, InlinedItemRef::Item(def_id, item)); + self.encode_mir(item.id); - // Encode inherent implementations for this enumeration. - encode_inherent_implementations(ecx, this.rbml_w, def_id); + // Encode inherent implementations for self enumeration. + encode_inherent_implementations(ecx, self.rbml_w, def_id); - this.encode_visibility(vis); - encode_stability(this.rbml_w, stab); - encode_deprecation(this.rbml_w, depr); - }); + self.encode_visibility(vis); + encode_stability(self.rbml_w, stab); + encode_deprecation(self.rbml_w, depr); } hir::ItemStruct(ref struct_def, _) => { /* Index the class*/ - self.record(def_id, |this| { - let def = ecx.tcx.lookup_adt_def(def_id); - let variant = def.struct_variant(); - - /* Now, make an item for the class itself */ - encode_def_id_and_key(ecx, this.rbml_w, def_id); - encode_family(this.rbml_w, match *struct_def { - hir::VariantData::Struct(..) => 'S', - hir::VariantData::Tuple(..) => 's', - hir::VariantData::Unit(..) => 'u', - }); - this.encode_bounds_and_type_for_item(item.id); - - encode_item_variances(this.rbml_w, ecx, item.id); - encode_name(this.rbml_w, item.name); - encode_attributes(this.rbml_w, &item.attrs); - encode_stability(this.rbml_w, stab); - encode_deprecation(this.rbml_w, depr); - this.encode_visibility(vis); - this.encode_repr_attrs(&item.attrs); - - /* Encode def_ids for each field and method - for methods, write all the stuff get_trait_method - needs to know*/ - this.encode_struct_fields(variant); - - encode_inlined_item(ecx, this.rbml_w, InlinedItemRef::Item(def_id, item)); - this.encode_mir(item.id); - - // Encode inherent implementations for this structure. - encode_inherent_implementations(ecx, this.rbml_w, def_id); - - if !struct_def.is_struct() { - let ctor_did = ecx.tcx.map.local_def_id(struct_def.id()); - this.rbml_w.wr_tagged_u64(tag_items_data_item_struct_ctor, - def_to_u64(ctor_did)); - } + let def = ecx.tcx.lookup_adt_def(def_id); + let variant = def.struct_variant(); + + /* Now, make an item for the class itself */ + encode_def_id_and_key(ecx, self.rbml_w, def_id); + encode_family(self.rbml_w, match *struct_def { + hir::VariantData::Struct(..) => 'S', + hir::VariantData::Tuple(..) => 's', + hir::VariantData::Unit(..) => 'u', }); + self.encode_bounds_and_type_for_item(item.id); + + encode_item_variances(self.rbml_w, ecx, item.id); + encode_name(self.rbml_w, item.name); + encode_attributes(self.rbml_w, &item.attrs); + encode_stability(self.rbml_w, stab); + encode_deprecation(self.rbml_w, depr); + self.encode_visibility(vis); + self.encode_repr_attrs(&item.attrs); + + /* Encode def_ids for each field and method + for methods, write all the stuff get_trait_method + needs to know*/ + self.encode_struct_fields(variant); + + encode_inlined_item(ecx, self.rbml_w, InlinedItemRef::Item(def_id, item)); + self.encode_mir(item.id); + + // Encode inherent implementations for self structure. + encode_inherent_implementations(ecx, self.rbml_w, def_id); + + if !struct_def.is_struct() { + let ctor_did = ecx.tcx.map.local_def_id(struct_def.id()); + self.rbml_w.wr_tagged_u64(tag_items_data_item_struct_ctor, + def_to_u64(ctor_did)); + } } hir::ItemDefaultImpl(unsafety, _) => { - self.record(def_id, |this| { - encode_def_id_and_key(ecx, this.rbml_w, def_id); - encode_family(this.rbml_w, 'd'); - encode_name(this.rbml_w, item.name); - encode_unsafety(this.rbml_w, unsafety); + encode_def_id_and_key(ecx, self.rbml_w, def_id); + encode_family(self.rbml_w, 'd'); + encode_name(self.rbml_w, item.name); + encode_unsafety(self.rbml_w, unsafety); - let trait_ref = tcx.impl_trait_ref(ecx.tcx.map.local_def_id(item.id)).unwrap(); - encode_trait_ref(this.rbml_w, ecx, trait_ref, tag_item_trait_ref); - }); + let trait_ref = tcx.impl_trait_ref(ecx.tcx.map.local_def_id(item.id)).unwrap(); + encode_trait_ref(self.rbml_w, ecx, trait_ref, tag_item_trait_ref); } hir::ItemImpl(unsafety, polarity, _, _, _, _) => { - self.record(def_id, |this| { - // We need to encode information about the default methods we - // have inherited, so we drive this based on the impl structure. - let impl_items = tcx.impl_items.borrow(); - let items = &impl_items[&def_id]; - - encode_def_id_and_key(ecx, this.rbml_w, def_id); - encode_family(this.rbml_w, 'i'); - this.encode_bounds_and_type_for_item(item.id); - encode_name(this.rbml_w, item.name); - encode_attributes(this.rbml_w, &item.attrs); - encode_unsafety(this.rbml_w, unsafety); - encode_polarity(this.rbml_w, polarity); - - match - tcx.custom_coerce_unsized_kinds - .borrow() - .get(&ecx.tcx.map.local_def_id(item.id)) - { - Some(&kind) => { - this.rbml_w.start_tag(tag_impl_coerce_unsized_kind); - kind.encode(this.rbml_w); - this.rbml_w.end_tag(); - } - None => {} + // We need to encode information about the default methods we + // have inherited, so we drive self based on the impl structure. + let impl_items = tcx.impl_items.borrow(); + let items = &impl_items[&def_id]; + + encode_def_id_and_key(ecx, self.rbml_w, def_id); + encode_family(self.rbml_w, 'i'); + self.encode_bounds_and_type_for_item(item.id); + encode_name(self.rbml_w, item.name); + encode_attributes(self.rbml_w, &item.attrs); + encode_unsafety(self.rbml_w, unsafety); + encode_polarity(self.rbml_w, polarity); + + match + tcx.custom_coerce_unsized_kinds + .borrow() + .get(&ecx.tcx.map.local_def_id(item.id)) + { + Some(&kind) => { + self.rbml_w.start_tag(tag_impl_coerce_unsized_kind); + kind.encode(self.rbml_w); + self.rbml_w.end_tag(); } + None => {} + } - for &item_def_id in items { - this.rbml_w.start_tag(tag_item_impl_item); - match item_def_id { - ty::ConstTraitItemId(item_def_id) => { - encode_def_id(this.rbml_w, item_def_id); - encode_item_sort(this.rbml_w, 'C'); - } - ty::MethodTraitItemId(item_def_id) => { - encode_def_id(this.rbml_w, item_def_id); - encode_item_sort(this.rbml_w, 'r'); - } - ty::TypeTraitItemId(item_def_id) => { - encode_def_id(this.rbml_w, item_def_id); - encode_item_sort(this.rbml_w, 't'); - } + for &item_def_id in items { + self.rbml_w.start_tag(tag_item_impl_item); + match item_def_id { + ty::ConstTraitItemId(item_def_id) => { + encode_def_id(self.rbml_w, item_def_id); + encode_item_sort(self.rbml_w, 'C'); + } + ty::MethodTraitItemId(item_def_id) => { + encode_def_id(self.rbml_w, item_def_id); + encode_item_sort(self.rbml_w, 'r'); + } + ty::TypeTraitItemId(item_def_id) => { + encode_def_id(self.rbml_w, item_def_id); + encode_item_sort(self.rbml_w, 't'); } - this.rbml_w.end_tag(); } + self.rbml_w.end_tag(); + } - let did = ecx.tcx.map.local_def_id(item.id); - if let Some(trait_ref) = tcx.impl_trait_ref(did) { - encode_trait_ref(this.rbml_w, ecx, trait_ref, tag_item_trait_ref); - - let trait_def = tcx.lookup_trait_def(trait_ref.def_id); - let parent = trait_def.ancestors(did) - .skip(1) - .next() - .and_then(|node| match node { - specialization_graph::Node::Impl(parent) => - Some(parent), - _ => None, - }); - encode_parent_impl(this.rbml_w, parent); - } - encode_stability(this.rbml_w, stab); - encode_deprecation(this.rbml_w, depr); - }); + let did = ecx.tcx.map.local_def_id(item.id); + if let Some(trait_ref) = tcx.impl_trait_ref(did) { + encode_trait_ref(self.rbml_w, ecx, trait_ref, tag_item_trait_ref); + + let trait_def = tcx.lookup_trait_def(trait_ref.def_id); + let parent = trait_def.ancestors(did) + .skip(1) + .next() + .and_then(|node| match node { + specialization_graph::Node::Impl(parent) => + Some(parent), + _ => None, + }); + encode_parent_impl(self.rbml_w, parent); + } + encode_stability(self.rbml_w, stab); + encode_deprecation(self.rbml_w, depr); } hir::ItemTrait(_, _, _, _) => { - self.record(def_id, |this| { - encode_def_id_and_key(ecx, this.rbml_w, def_id); - encode_family(this.rbml_w, 'I'); - encode_item_variances(this.rbml_w, ecx, item.id); - let trait_def = tcx.lookup_trait_def(def_id); - let trait_predicates = tcx.lookup_predicates(def_id); - encode_unsafety(this.rbml_w, trait_def.unsafety); - encode_paren_sugar(this.rbml_w, trait_def.paren_sugar); - encode_defaulted(this.rbml_w, tcx.trait_has_default_impl(def_id)); - encode_associated_type_names(this.rbml_w, &trait_def.associated_type_names); - this.encode_generics(&trait_def.generics, &trait_predicates); - this.encode_predicates(&tcx.lookup_super_predicates(def_id), - tag_item_super_predicates); - encode_trait_ref(this.rbml_w, ecx, trait_def.trait_ref, tag_item_trait_ref); - encode_name(this.rbml_w, item.name); - encode_attributes(this.rbml_w, &item.attrs); - this.encode_visibility(vis); - encode_stability(this.rbml_w, stab); - encode_deprecation(this.rbml_w, depr); - for &method_def_id in tcx.trait_item_def_ids(def_id).iter() { - this.rbml_w.start_tag(tag_item_trait_item); - match method_def_id { - ty::ConstTraitItemId(const_def_id) => { - encode_def_id(this.rbml_w, const_def_id); - encode_item_sort(this.rbml_w, 'C'); - } - ty::MethodTraitItemId(method_def_id) => { - encode_def_id(this.rbml_w, method_def_id); - encode_item_sort(this.rbml_w, 'r'); - } - ty::TypeTraitItemId(type_def_id) => { - encode_def_id(this.rbml_w, type_def_id); - encode_item_sort(this.rbml_w, 't'); - } + encode_def_id_and_key(ecx, self.rbml_w, def_id); + encode_family(self.rbml_w, 'I'); + encode_item_variances(self.rbml_w, ecx, item.id); + let trait_def = tcx.lookup_trait_def(def_id); + let trait_predicates = tcx.lookup_predicates(def_id); + encode_unsafety(self.rbml_w, trait_def.unsafety); + encode_paren_sugar(self.rbml_w, trait_def.paren_sugar); + encode_defaulted(self.rbml_w, tcx.trait_has_default_impl(def_id)); + encode_associated_type_names(self.rbml_w, &trait_def.associated_type_names); + self.encode_generics(&trait_def.generics, &trait_predicates); + self.encode_predicates(&tcx.lookup_super_predicates(def_id), + tag_item_super_predicates); + encode_trait_ref(self.rbml_w, ecx, trait_def.trait_ref, tag_item_trait_ref); + encode_name(self.rbml_w, item.name); + encode_attributes(self.rbml_w, &item.attrs); + self.encode_visibility(vis); + encode_stability(self.rbml_w, stab); + encode_deprecation(self.rbml_w, depr); + for &method_def_id in tcx.trait_item_def_ids(def_id).iter() { + self.rbml_w.start_tag(tag_item_trait_item); + match method_def_id { + ty::ConstTraitItemId(const_def_id) => { + encode_def_id(self.rbml_w, const_def_id); + encode_item_sort(self.rbml_w, 'C'); + } + ty::MethodTraitItemId(method_def_id) => { + encode_def_id(self.rbml_w, method_def_id); + encode_item_sort(self.rbml_w, 'r'); + } + ty::TypeTraitItemId(type_def_id) => { + encode_def_id(self.rbml_w, type_def_id); + encode_item_sort(self.rbml_w, 't'); } - this.rbml_w.end_tag(); - - this.rbml_w.wr_tagged_u64(tag_mod_child, - def_to_u64(method_def_id.def_id())); } + self.rbml_w.end_tag(); - // Encode inherent implementations for this trait. - encode_inherent_implementations(ecx, this.rbml_w, def_id); - }); + self.rbml_w.wr_tagged_u64(tag_mod_child, + def_to_u64(method_def_id.def_id())); + } + + // Encode inherent implementations for self trait. + encode_inherent_implementations(ecx, self.rbml_w, def_id); } hir::ItemExternCrate(_) | hir::ItemUse(_) => { - // these are encoded separately + bug!("cannot encode info for item {:?}", item) } } } +} +impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { /// In some cases, along with the item itself, we also /// encode some sub-items. Usually we want some info from the item /// so it's easier to do that here then to wait until we would encounter @@ -1318,7 +1298,11 @@ impl<'a, 'ecx, 'tcx, 'encoder> Visitor<'tcx> for EncodeVisitor<'a, 'ecx, 'tcx, ' } fn visit_item(&mut self, item: &'tcx hir::Item) { intravisit::walk_item(self, item); - self.index.encode_info_for_item(item); + let def_id = self.index.ecx.tcx.map.local_def_id(item.id); + match item.node { + hir::ItemExternCrate(_) | hir::ItemUse(_) => (), // ignore these + _ => self.index.record(def_id, |index| index.encode_info_for_item(def_id, item)), + } self.index.encode_addl_info_for_item(item); } fn visit_foreign_item(&mut self, ni: &'tcx hir::ForeignItem) { From f35196326d09a9a632ad54efb9716f254dea5a3c Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 12 Aug 2016 15:59:53 -0400 Subject: [PATCH 11/22] pull out code for encoding enum variants --- src/librustc_metadata/decoder.rs | 18 ++----- src/librustc_metadata/encoder.rs | 83 +++++++++++++++----------------- 2 files changed, 45 insertions(+), 56 deletions(-) diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 5488f114db32f..d63e0866a9d6b 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -240,11 +240,10 @@ fn reexports<'a>(d: rbml::Doc<'a>) -> reader::TaggedDocsIterator<'a> { reader::tagged_docs(d, tag_items_data_item_reexport) } -fn variant_disr_val(d: rbml::Doc) -> Option { - reader::maybe_get_doc(d, tag_disr_val).and_then(|val_doc| { - reader::with_doc_data(val_doc, |data| { - str::from_utf8(data).ok().and_then(|s| s.parse().ok()) - }) +fn variant_disr_val(d: rbml::Doc) -> u64 { + let val_doc = reader::get_doc(d, tag_disr_val); + reader::with_doc_data(val_doc, |data| { + str::from_utf8(data).unwrap().parse().unwrap() }) } @@ -402,17 +401,10 @@ pub fn get_adt_def<'a, 'tcx>(cdata: Cmd, } } fn get_enum_variants<'tcx>(cdata: Cmd, doc: rbml::Doc) -> Vec> { - let mut disr_val = 0; reader::tagged_docs(doc, tag_items_data_item_variant).map(|p| { let did = translated_def_id(cdata, p); let item = cdata.lookup_item(did.index); - - if let Some(disr) = variant_disr_val(item) { - disr_val = disr; - } - let disr = disr_val; - disr_val = disr_val.wrapping_add(1); - + let disr = variant_disr_val(item); ty::VariantDefData { did: did, name: item_name(item), diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 25b705b0d3a77..8c1e551d030d0 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -28,7 +28,6 @@ use middle::dependency_format::Linkage; use rustc::dep_graph::DepNode; use rustc::traits::specialization_graph; use rustc::ty::{self, Ty, TyCtxt}; -use rustc::ty::util::IntTypeExt; use rustc::hir::svh::Svh; use rustc::mir::mir_map::MirMap; @@ -198,55 +197,53 @@ impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { } impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { - fn encode_enum_variant_info(&mut self, - did: DefId, - vis: &hir::Visibility) { - debug!("encode_enum_variant_info(did={:?})", did); + fn encode_enum_variant_infos(&mut self, + enum_did: DefId, + vis: &hir::Visibility) { + debug!("encode_enum_variant_info(enum_did={:?})", enum_did); let ecx = self.ecx(); - let repr_hints = ecx.tcx.lookup_repr_hints(did); - let repr_type = ecx.tcx.enum_repr_type(repr_hints.get(0)); - let mut disr_val = repr_type.initial_discriminant(ecx.tcx); - let def = ecx.tcx.lookup_adt_def(did); - for variant in &def.variants { - let vid = variant.did; - let variant_node_id = ecx.local_id(vid); - + let def = ecx.tcx.lookup_adt_def(enum_did); + for (i, variant) in def.variants.iter().enumerate() { for field in &variant.fields { self.encode_field(field); } + self.record(variant.did, |this| this.encode_enum_variant_info(enum_did, i, vis)); + } + } +} - self.record(vid, |this| { - encode_def_id_and_key(ecx, this.rbml_w, vid); - encode_family(this.rbml_w, match variant.kind { - ty::VariantKind::Struct => 'V', - ty::VariantKind::Tuple => 'v', - ty::VariantKind::Unit => 'w', - }); - encode_name(this.rbml_w, variant.name); - this.encode_parent_item(did); - this.encode_visibility(vis); - - let attrs = ecx.tcx.get_attrs(vid); - encode_attributes(this.rbml_w, &attrs); - this.encode_repr_attrs(&attrs); - - let stab = ecx.tcx.lookup_stability(vid); - let depr = ecx.tcx.lookup_deprecation(vid); - encode_stability(this.rbml_w, stab); - encode_deprecation(this.rbml_w, depr); +impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { + fn encode_enum_variant_info(&mut self, + enum_did: DefId, // enum def-id + index: usize, // variant index + vis: &hir::Visibility) { + let ecx = self.ecx; + let def = ecx.tcx.lookup_adt_def(enum_did); + let variant = &def.variants[index]; + let vid = variant.did; + let variant_node_id = ecx.local_id(vid); + encode_def_id_and_key(ecx, self.rbml_w, vid); + encode_family(self.rbml_w, match variant.kind { + ty::VariantKind::Struct => 'V', + ty::VariantKind::Tuple => 'v', + ty::VariantKind::Unit => 'w', + }); + encode_name(self.rbml_w, variant.name); + self.encode_parent_item(enum_did); + self.encode_visibility(vis); - this.encode_struct_fields(variant); + let attrs = ecx.tcx.get_attrs(vid); + encode_attributes(self.rbml_w, &attrs); + self.encode_repr_attrs(&attrs); - let specified_disr_val = variant.disr_val; - if specified_disr_val != disr_val { - this.encode_disr_val(specified_disr_val); - disr_val = specified_disr_val; - } - this.encode_bounds_and_type_for_item(variant_node_id); - }); + let stab = ecx.tcx.lookup_stability(vid); + let depr = ecx.tcx.lookup_deprecation(vid); + encode_stability(self.rbml_w, stab); + encode_deprecation(self.rbml_w, depr); - disr_val = disr_val.wrap_incr(); - } + self.encode_struct_fields(variant); + self.encode_disr_val(variant.disr_val); + self.encode_bounds_and_type_for_item(variant_node_id); } } @@ -1045,7 +1042,7 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { // no sub-item recording needed in these cases } hir::ItemEnum(..) => { - self.encode_enum_variant_info(def_id, &item.vis); + self.encode_enum_variant_infos(def_id, &item.vis); } hir::ItemStruct(ref struct_def, _) => { self.encode_addl_struct_info(def_id, struct_def.id(), item); From c716ad8af5cb78595cc410536f0e03e03a216b2d Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 12 Aug 2016 16:18:22 -0400 Subject: [PATCH 12/22] pull out encode_field --- src/librustc_metadata/encoder.rs | 49 ++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 8c1e551d030d0..f17613cddefdb 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -203,10 +203,8 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { debug!("encode_enum_variant_info(enum_did={:?})", enum_did); let ecx = self.ecx(); let def = ecx.tcx.lookup_adt_def(enum_did); + self.encode_fields(enum_did); for (i, variant) in def.variants.iter().enumerate() { - for field in &variant.fields { - self.encode_field(field); - } self.record(variant.did, |this| this.encode_enum_variant_info(enum_did, i, vis)); } } @@ -415,25 +413,42 @@ fn encode_item_sort(rbml_w: &mut Encoder, sort: char) { } impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { + fn encode_fields(&mut self, + adt_def_id: DefId) { + let def = self.ecx.tcx.lookup_adt_def(adt_def_id); + for (variant_index, variant) in def.variants.iter().enumerate() { + for (field_index, field) in variant.fields.iter().enumerate() { + self.record(field.did, |this| this.encode_field(adt_def_id, + variant_index, + field_index)); + } + } + } +} + +impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { fn encode_field(&mut self, - field: ty::FieldDef<'tcx>) { + adt_def_id: DefId, + variant_index: usize, + field_index: usize) { let ecx = self.ecx(); + let def = ecx.tcx.lookup_adt_def(adt_def_id); + let variant = &def.variants[variant_index]; + let field = &variant.fields[field_index]; let nm = field.name; let id = ecx.local_id(field.did); + debug!("encode_field: encoding {} {}", nm, id); - self.record(field.did, |this| { - debug!("encode_field: encoding {} {}", nm, id); - this.encode_struct_field_family(field.vis); - encode_name(this.rbml_w, nm); - this.encode_bounds_and_type_for_item(id); - encode_def_id_and_key(ecx, this.rbml_w, field.did); + self.encode_struct_field_family(field.vis); + encode_name(self.rbml_w, nm); + self.encode_bounds_and_type_for_item(id); + encode_def_id_and_key(ecx, self.rbml_w, field.did); - let stab = ecx.tcx.lookup_stability(field.did); - let depr = ecx.tcx.lookup_deprecation(field.did); - encode_stability(this.rbml_w, stab); - encode_deprecation(this.rbml_w, depr); - }); + let stab = ecx.tcx.lookup_stability(field.did); + let depr = ecx.tcx.lookup_deprecation(field.did); + encode_stability(self.rbml_w, stab); + encode_deprecation(self.rbml_w, depr); } } @@ -1064,9 +1079,7 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { let def = ecx.tcx.lookup_adt_def(def_id); let variant = def.struct_variant(); - for field in &variant.fields { - self.encode_field(field); - } + self.encode_fields(def_id); // If this is a tuple-like struct, encode the type of the constructor. match variant.kind { From 9afcd7724694e2078ffc9b6c6b73b178ebf3e379 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sun, 14 Aug 2016 18:10:13 -0400 Subject: [PATCH 13/22] don't pass extra state fo encode_struct_ctor --- src/librustc_metadata/encoder.rs | 67 ++++++++++++++++---------------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index f17613cddefdb..4848eb8fb4ce4 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -452,38 +452,37 @@ impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { } } -impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { - fn encode_info_for_struct_ctor(&mut self, - name: Name, - ctor_id: ast::NodeId, - variant: ty::VariantDef<'tcx>, - struct_id: NodeId) { +impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { + fn encode_struct_ctor(&mut self, + struct_def_id: DefId, + struct_node_id: ast::NodeId, + ctor_node_id: ast::NodeId) { let ecx = self.ecx(); - let ctor_def_id = ecx.tcx.map.local_def_id(ctor_id); - - self.record(ctor_def_id, |this| { - encode_def_id_and_key(ecx, this.rbml_w, ctor_def_id); - encode_family(this.rbml_w, match variant.kind { - ty::VariantKind::Struct => 'S', - ty::VariantKind::Tuple => 's', - ty::VariantKind::Unit => 'u', - }); - this.encode_bounds_and_type_for_item(ctor_id); - encode_name(this.rbml_w, name); - this.encode_parent_item(ecx.tcx.map.local_def_id(struct_id)); + let def = ecx.tcx.lookup_adt_def(struct_def_id); + let variant = def.struct_variant(); + let item = ecx.tcx.map.expect_item(struct_node_id); + let ctor_def_id = ecx.tcx.map.local_def_id(ctor_node_id); + encode_def_id_and_key(ecx, self.rbml_w, ctor_def_id); + encode_family(self.rbml_w, match variant.kind { + ty::VariantKind::Struct => 'S', + ty::VariantKind::Tuple => 's', + ty::VariantKind::Unit => 'u', + }); + self.encode_bounds_and_type_for_item(ctor_node_id); + encode_name(self.rbml_w, item.name); + self.encode_parent_item(struct_def_id); - let stab = ecx.tcx.lookup_stability(ecx.tcx.map.local_def_id(ctor_id)); - let depr = ecx.tcx.lookup_deprecation(ecx.tcx.map.local_def_id(ctor_id)); - encode_stability(this.rbml_w, stab); - encode_deprecation(this.rbml_w, depr); + let stab = ecx.tcx.lookup_stability(ctor_def_id); + let depr = ecx.tcx.lookup_deprecation(ctor_def_id); + encode_stability(self.rbml_w, stab); + encode_deprecation(self.rbml_w, depr); - // indicate that this is a tuple struct ctor, because - // downstream users will normally want the tuple struct - // definition, but without this there is no way for them - // to tell that they actually have a ctor rather than a - // normal function - this.rbml_w.wr_tagged_bytes(tag_items_data_item_is_tuple_struct_ctor, &[]); - }); + // indicate that this is a tuple struct ctor, because + // downstream users will normally want the tuple struct + // definition, but without this there is no way for them + // to tell that they actually have a ctor rather than a + // normal function + self.rbml_w.wr_tagged_bytes(tag_items_data_item_is_tuple_struct_ctor, &[]); } } @@ -1073,7 +1072,7 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { fn encode_addl_struct_info(&mut self, def_id: DefId, - struct_def_id: ast::NodeId, + struct_node_id: ast::NodeId, item: &hir::Item) { let ecx = self.ecx; let def = ecx.tcx.lookup_adt_def(def_id); @@ -1089,10 +1088,10 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { ty::VariantKind::Tuple | ty::VariantKind::Unit => { // there is a value for structs like `struct // Foo()` and `struct Foo` - self.encode_info_for_struct_ctor(item.name, - struct_def_id, - variant, - item.id); + let ctor_def_id = ecx.tcx.map.local_def_id(struct_node_id); + self.record(ctor_def_id, |this| this.encode_struct_ctor(def_id, + item.id, + struct_node_id)); } } } From 8dc8151b495b3237f06821a0b6fd6f0c89b5d438 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sun, 14 Aug 2016 18:27:57 -0400 Subject: [PATCH 14/22] pull out call to `record` for impl items --- src/librustc_metadata/encoder.rs | 202 ++++++++++++++++--------------- 1 file changed, 103 insertions(+), 99 deletions(-) diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 4848eb8fb4ce4..e662c444413e7 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -530,7 +530,31 @@ impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { } } -impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { +impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { + fn encode_info_for_impl_item(&mut self, + impl_id: NodeId, + impl_item_def_id: DefId, + ast_item: Option<&hir::ImplItem>) { + match self.ecx.tcx.impl_or_trait_item(impl_item_def_id) { + ty::ConstTraitItem(ref associated_const) => { + self.encode_info_for_associated_const(&associated_const, + impl_id, + ast_item) + } + ty::MethodTraitItem(ref method_type) => { + self.encode_info_for_method(&method_type, + false, + impl_id, + ast_item) + } + ty::TypeTraitItem(ref associated_type) => { + self.encode_info_for_associated_type(&associated_type, + impl_id, + ast_item) + } + } + } + fn encode_info_for_associated_const(&mut self, associated_const: &ty::AssociatedConst, parent_id: NodeId, @@ -540,32 +564,30 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { associated_const.def_id, associated_const.name); - self.record(associated_const.def_id, |this| { - encode_def_id_and_key(ecx, this.rbml_w, associated_const.def_id); - encode_name(this.rbml_w, associated_const.name); - this.encode_visibility(associated_const.vis); - encode_family(this.rbml_w, 'C'); + encode_def_id_and_key(ecx, self.rbml_w, associated_const.def_id); + encode_name(self.rbml_w, associated_const.name); + self.encode_visibility(associated_const.vis); + encode_family(self.rbml_w, 'C'); - this.encode_parent_item(ecx.tcx.map.local_def_id(parent_id)); - encode_item_sort(this.rbml_w, 'C'); - - this.encode_bounds_and_type_for_item(ecx.local_id(associated_const.def_id)); - - let stab = ecx.tcx.lookup_stability(associated_const.def_id); - let depr = ecx.tcx.lookup_deprecation(associated_const.def_id); - encode_stability(this.rbml_w, stab); - encode_deprecation(this.rbml_w, depr); - - if let Some(ii) = impl_item_opt { - encode_attributes(this.rbml_w, &ii.attrs); - encode_defaultness(this.rbml_w, ii.defaultness); - encode_inlined_item(ecx, - this.rbml_w, - InlinedItemRef::ImplItem(ecx.tcx.map.local_def_id(parent_id), - ii)); - this.encode_mir(ii.id); - } - }); + self.encode_parent_item(ecx.tcx.map.local_def_id(parent_id)); + encode_item_sort(self.rbml_w, 'C'); + + self.encode_bounds_and_type_for_item(ecx.local_id(associated_const.def_id)); + + let stab = ecx.tcx.lookup_stability(associated_const.def_id); + let depr = ecx.tcx.lookup_deprecation(associated_const.def_id); + encode_stability(self.rbml_w, stab); + encode_deprecation(self.rbml_w, depr); + + if let Some(ii) = impl_item_opt { + encode_attributes(self.rbml_w, &ii.attrs); + encode_defaultness(self.rbml_w, ii.defaultness); + encode_inlined_item(ecx, + self.rbml_w, + InlinedItemRef::ImplItem(ecx.tcx.map.local_def_id(parent_id), + ii)); + self.encode_mir(ii.id); + } } fn encode_info_for_method(&mut self, @@ -577,40 +599,38 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { debug!("encode_info_for_method: {:?} {:?}", m.def_id, m.name); - self.record(m.def_id, |this| { - this.encode_method_ty_fields(m); - this.encode_parent_item(ecx.tcx.map.local_def_id(parent_id)); - encode_item_sort(this.rbml_w, 'r'); - - let stab = ecx.tcx.lookup_stability(m.def_id); - let depr = ecx.tcx.lookup_deprecation(m.def_id); - encode_stability(this.rbml_w, stab); - encode_deprecation(this.rbml_w, depr); - - let m_node_id = ecx.local_id(m.def_id); - this.encode_bounds_and_type_for_item(m_node_id); - - if let Some(impl_item) = impl_item_opt { - if let hir::ImplItemKind::Method(ref sig, _) = impl_item.node { - encode_attributes(this.rbml_w, &impl_item.attrs); - let generics = ecx.tcx.lookup_generics(m.def_id); - let types = generics.parent_types as usize + generics.types.len(); - let needs_inline = types > 0 || is_default_impl || - attr::requests_inline(&impl_item.attrs); - if needs_inline || sig.constness == hir::Constness::Const { - encode_inlined_item( - ecx, - this.rbml_w, - InlinedItemRef::ImplItem(ecx.tcx.map.local_def_id(parent_id), - impl_item)); - this.encode_mir(impl_item.id); - } - encode_constness(this.rbml_w, sig.constness); - encode_defaultness(this.rbml_w, impl_item.defaultness); - this.encode_method_argument_names(&sig.decl); + self.encode_method_ty_fields(m); + self.encode_parent_item(ecx.tcx.map.local_def_id(parent_id)); + encode_item_sort(self.rbml_w, 'r'); + + let stab = ecx.tcx.lookup_stability(m.def_id); + let depr = ecx.tcx.lookup_deprecation(m.def_id); + encode_stability(self.rbml_w, stab); + encode_deprecation(self.rbml_w, depr); + + let m_node_id = ecx.local_id(m.def_id); + self.encode_bounds_and_type_for_item(m_node_id); + + if let Some(impl_item) = impl_item_opt { + if let hir::ImplItemKind::Method(ref sig, _) = impl_item.node { + encode_attributes(self.rbml_w, &impl_item.attrs); + let generics = ecx.tcx.lookup_generics(m.def_id); + let types = generics.parent_types as usize + generics.types.len(); + let needs_inline = types > 0 || is_default_impl || + attr::requests_inline(&impl_item.attrs); + if needs_inline || sig.constness == hir::Constness::Const { + encode_inlined_item( + ecx, + self.rbml_w, + InlinedItemRef::ImplItem(ecx.tcx.map.local_def_id(parent_id), + impl_item)); + self.encode_mir(impl_item.id); } + encode_constness(self.rbml_w, sig.constness); + encode_defaultness(self.rbml_w, impl_item.defaultness); + self.encode_method_argument_names(&sig.decl); } - }); + } } fn encode_info_for_associated_type(&mut self, @@ -622,32 +642,30 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { associated_type.def_id, associated_type.name); - self.record(associated_type.def_id, |this| { - encode_def_id_and_key(ecx, this.rbml_w, associated_type.def_id); - encode_name(this.rbml_w, associated_type.name); - this.encode_visibility(associated_type.vis); - encode_family(this.rbml_w, 'y'); - this.encode_parent_item(ecx.tcx.map.local_def_id(parent_id)); - encode_item_sort(this.rbml_w, 't'); + encode_def_id_and_key(ecx, self.rbml_w, associated_type.def_id); + encode_name(self.rbml_w, associated_type.name); + self.encode_visibility(associated_type.vis); + encode_family(self.rbml_w, 'y'); + self.encode_parent_item(ecx.tcx.map.local_def_id(parent_id)); + encode_item_sort(self.rbml_w, 't'); - let stab = ecx.tcx.lookup_stability(associated_type.def_id); - let depr = ecx.tcx.lookup_deprecation(associated_type.def_id); - encode_stability(this.rbml_w, stab); - encode_deprecation(this.rbml_w, depr); + let stab = ecx.tcx.lookup_stability(associated_type.def_id); + let depr = ecx.tcx.lookup_deprecation(associated_type.def_id); + encode_stability(self.rbml_w, stab); + encode_deprecation(self.rbml_w, depr); - if let Some(ii) = impl_item_opt { - encode_attributes(this.rbml_w, &ii.attrs); - encode_defaultness(this.rbml_w, ii.defaultness); - } else { - // TODO this looks bogus and unnecessary - this.encode_predicates(&ecx.tcx.lookup_predicates(associated_type.def_id), - tag_item_generics); - } + if let Some(ii) = impl_item_opt { + encode_attributes(self.rbml_w, &ii.attrs); + encode_defaultness(self.rbml_w, ii.defaultness); + } else { + // TODO this looks bogus and unnecessary + self.encode_predicates(&ecx.tcx.lookup_predicates(associated_type.def_id), + tag_item_generics); + } - if let Some(ty) = associated_type.ty { - this.encode_type(ty); - } - }); + if let Some(ty) = associated_type.ty { + self.encode_type(ty); + } } } @@ -1116,24 +1134,10 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { None }; - match self.ecx.tcx.impl_or_trait_item(trait_item_def_id.def_id()) { - ty::ConstTraitItem(ref associated_const) => { - self.encode_info_for_associated_const(&associated_const, - impl_id, - ast_item) - } - ty::MethodTraitItem(ref method_type) => { - self.encode_info_for_method(&method_type, - false, - impl_id, - ast_item) - } - ty::TypeTraitItem(ref associated_type) => { - self.encode_info_for_associated_type(&associated_type, - impl_id, - ast_item) - } - } + let trait_item_def_id = trait_item_def_id.def_id(); + self.record(trait_item_def_id, |this| { + this.encode_info_for_impl_item(impl_id, trait_item_def_id, ast_item) + }); } } From 8c4a2245898af11c7e4484370e42ff8d6f9214f1 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sun, 14 Aug 2016 18:38:42 -0400 Subject: [PATCH 15/22] extract encode_info_for_trait_item into method --- src/librustc_metadata/encoder.rs | 209 ++++++++++++++++--------------- 1 file changed, 109 insertions(+), 100 deletions(-) diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index e662c444413e7..cc9b2e213b9f4 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -21,7 +21,7 @@ use def_key; use tyencode; use index::{self, IndexData}; -use middle::cstore::{LOCAL_CRATE, InlinedItemRef, LinkMeta, tls}; +use middle::cstore::{InlinedItemRef, LinkMeta, tls}; use rustc::hir::def; use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId}; use middle::dependency_format::Linkage; @@ -531,6 +531,109 @@ impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { } impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { + fn encode_info_for_trait_item(&mut self, + trait_def_id: DefId, + item_def_id: DefId, + trait_item: &hir::TraitItem) { + let ecx = self.ecx; + let tcx = ecx.tcx; + + self.encode_parent_item(trait_def_id); + + let stab = tcx.lookup_stability(item_def_id); + let depr = tcx.lookup_deprecation(item_def_id); + encode_stability(self.rbml_w, stab); + encode_deprecation(self.rbml_w, depr); + + let trait_item_type = + tcx.impl_or_trait_item(item_def_id); + let is_nonstatic_method; + match trait_item_type { + ty::ConstTraitItem(associated_const) => { + encode_name(self.rbml_w, associated_const.name); + encode_def_id_and_key(ecx, self.rbml_w, associated_const.def_id); + self.encode_visibility(associated_const.vis); + + encode_family(self.rbml_w, 'C'); + + self.encode_bounds_and_type_for_item( + ecx.local_id(associated_const.def_id)); + + is_nonstatic_method = false; + } + ty::MethodTraitItem(method_ty) => { + let method_def_id = item_def_id; + + self.encode_method_ty_fields(&method_ty); + + match method_ty.explicit_self { + ty::ExplicitSelfCategory::Static => { + encode_family(self.rbml_w, + STATIC_METHOD_FAMILY); + } + _ => { + encode_family(self.rbml_w, + METHOD_FAMILY); + } + } + self.encode_bounds_and_type_for_item(ecx.local_id(method_def_id)); + + is_nonstatic_method = method_ty.explicit_self != + ty::ExplicitSelfCategory::Static; + } + ty::TypeTraitItem(associated_type) => { + encode_name(self.rbml_w, associated_type.name); + encode_def_id_and_key(ecx, self.rbml_w, associated_type.def_id); + encode_item_sort(self.rbml_w, 't'); + encode_family(self.rbml_w, 'y'); + + if let Some(ty) = associated_type.ty { + self.encode_type(ty); + } + + is_nonstatic_method = false; + } + } + + encode_attributes(self.rbml_w, &trait_item.attrs); + match trait_item.node { + hir::ConstTraitItem(_, ref default) => { + if default.is_some() { + encode_item_sort(self.rbml_w, 'C'); + } else { + encode_item_sort(self.rbml_w, 'c'); + } + + encode_inlined_item(ecx, self.rbml_w, + InlinedItemRef::TraitItem(trait_def_id, trait_item)); + self.encode_mir(trait_item.id); + } + hir::MethodTraitItem(ref sig, ref body) => { + // If this is a static method, we've already + // encoded self. + if is_nonstatic_method { + self.encode_bounds_and_type_for_item( + ecx.local_id(item_def_id)); + } + + if body.is_some() { + encode_item_sort(self.rbml_w, 'p'); + encode_inlined_item(ecx, + self.rbml_w, + InlinedItemRef::TraitItem( + trait_def_id, + trait_item)); + self.encode_mir(trait_item.id); + } else { + encode_item_sort(self.rbml_w, 'r'); + } + self.encode_method_argument_names(&sig.decl); + } + + hir::TypeTraitItem(..) => {} + } + } + fn encode_info_for_impl_item(&mut self, impl_id: NodeId, impl_item_def_id: DefId, @@ -1145,107 +1248,13 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { def_id: DefId, trait_items: &[hir::TraitItem]) { // Now output the trait item info for each trait item. - let ecx = self.ecx; let tcx = self.ecx.tcx; let r = tcx.trait_item_def_ids(def_id); - for (&item_def_id, trait_item) in r.iter().zip(trait_items) { - assert_eq!(item_def_id.def_id().krate, LOCAL_CRATE); - - self.record(item_def_id.def_id(), |this| { - this.encode_parent_item(def_id); - - let stab = tcx.lookup_stability(item_def_id.def_id()); - let depr = tcx.lookup_deprecation(item_def_id.def_id()); - encode_stability(this.rbml_w, stab); - encode_deprecation(this.rbml_w, depr); - - let trait_item_type = - tcx.impl_or_trait_item(item_def_id.def_id()); - let is_nonstatic_method; - match trait_item_type { - ty::ConstTraitItem(associated_const) => { - encode_name(this.rbml_w, associated_const.name); - encode_def_id_and_key(ecx, this.rbml_w, associated_const.def_id); - this.encode_visibility(associated_const.vis); - - encode_family(this.rbml_w, 'C'); - - this.encode_bounds_and_type_for_item( - ecx.local_id(associated_const.def_id)); - - is_nonstatic_method = false; - } - ty::MethodTraitItem(method_ty) => { - let method_def_id = item_def_id.def_id(); - - this.encode_method_ty_fields(&method_ty); - - match method_ty.explicit_self { - ty::ExplicitSelfCategory::Static => { - encode_family(this.rbml_w, - STATIC_METHOD_FAMILY); - } - _ => { - encode_family(this.rbml_w, - METHOD_FAMILY); - } - } - this.encode_bounds_and_type_for_item(ecx.local_id(method_def_id)); - - is_nonstatic_method = method_ty.explicit_self != - ty::ExplicitSelfCategory::Static; - } - ty::TypeTraitItem(associated_type) => { - encode_name(this.rbml_w, associated_type.name); - encode_def_id_and_key(ecx, this.rbml_w, associated_type.def_id); - encode_item_sort(this.rbml_w, 't'); - encode_family(this.rbml_w, 'y'); - - if let Some(ty) = associated_type.ty { - this.encode_type(ty); - } - - is_nonstatic_method = false; - } - } - - encode_attributes(this.rbml_w, &trait_item.attrs); - match trait_item.node { - hir::ConstTraitItem(_, ref default) => { - if default.is_some() { - encode_item_sort(this.rbml_w, 'C'); - } else { - encode_item_sort(this.rbml_w, 'c'); - } - - encode_inlined_item(ecx, this.rbml_w, - InlinedItemRef::TraitItem(def_id, trait_item)); - this.encode_mir(trait_item.id); - } - hir::MethodTraitItem(ref sig, ref body) => { - // If this is a static method, we've already - // encoded this. - if is_nonstatic_method { - this.encode_bounds_and_type_for_item( - ecx.local_id(item_def_id.def_id())); - } - - if body.is_some() { - encode_item_sort(this.rbml_w, 'p'); - encode_inlined_item(ecx, - this.rbml_w, - InlinedItemRef::TraitItem( - def_id, - trait_item)); - this.encode_mir(trait_item.id); - } else { - encode_item_sort(this.rbml_w, 'r'); - } - this.encode_method_argument_names(&sig.decl); - } - - hir::TypeTraitItem(..) => {} - } + for (item_def_id, trait_item) in r.iter().zip(trait_items) { + let item_def_id = item_def_id.def_id(); + assert!(item_def_id.is_local()); + self.record(item_def_id, |this| { + this.encode_info_for_trait_item(def_id, item_def_id, trait_item) }); } } From c0c8ab9cd2728de9789ea76d8520b2be92bc1eb2 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sun, 14 Aug 2016 18:50:53 -0400 Subject: [PATCH 16/22] extract two more record calls --- src/librustc_metadata/encoder.rs | 116 ++++++++++++++++--------------- 1 file changed, 61 insertions(+), 55 deletions(-) diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index cc9b2e213b9f4..9855eeeb97070 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -1258,54 +1258,54 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { }); } } +} +impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { fn encode_info_for_foreign_item(&mut self, + def_id: DefId, nitem: &hir::ForeignItem) { let ecx = self.ecx(); debug!("writing foreign item {}", ecx.tcx.node_path_str(nitem.id)); - let def_id = ecx.tcx.map.local_def_id(nitem.id); let abi = ecx.tcx.map.get_foreign_abi(nitem.id); - self.record(def_id, |this| { - encode_def_id_and_key(ecx, this.rbml_w, def_id); - let parent_id = ecx.tcx.map.get_parent(nitem.id); - this.encode_parent_item(ecx.tcx.map.local_def_id(parent_id)); - this.encode_visibility(&nitem.vis); - match nitem.node { - hir::ForeignItemFn(ref fndecl, _) => { - encode_family(this.rbml_w, FN_FAMILY); - this.encode_bounds_and_type_for_item(nitem.id); - encode_name(this.rbml_w, nitem.name); - if abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic { - encode_inlined_item(ecx, - this.rbml_w, - InlinedItemRef::Foreign(def_id, nitem)); - this.encode_mir(nitem.id); - } - encode_attributes(this.rbml_w, &nitem.attrs); - let stab = ecx.tcx.lookup_stability(ecx.tcx.map.local_def_id(nitem.id)); - let depr = ecx.tcx.lookup_deprecation(ecx.tcx.map.local_def_id(nitem.id)); - encode_stability(this.rbml_w, stab); - encode_deprecation(this.rbml_w, depr); - this.encode_method_argument_names(&fndecl); + encode_def_id_and_key(ecx, self.rbml_w, def_id); + let parent_id = ecx.tcx.map.get_parent(nitem.id); + self.encode_parent_item(ecx.tcx.map.local_def_id(parent_id)); + self.encode_visibility(&nitem.vis); + match nitem.node { + hir::ForeignItemFn(ref fndecl, _) => { + encode_family(self.rbml_w, FN_FAMILY); + self.encode_bounds_and_type_for_item(nitem.id); + encode_name(self.rbml_w, nitem.name); + if abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic { + encode_inlined_item(ecx, + self.rbml_w, + InlinedItemRef::Foreign(def_id, nitem)); + self.encode_mir(nitem.id); } - hir::ForeignItemStatic(_, mutbl) => { - if mutbl { - encode_family(this.rbml_w, 'b'); - } else { - encode_family(this.rbml_w, 'c'); - } - this.encode_bounds_and_type_for_item(nitem.id); - encode_attributes(this.rbml_w, &nitem.attrs); - let stab = ecx.tcx.lookup_stability(ecx.tcx.map.local_def_id(nitem.id)); - let depr = ecx.tcx.lookup_deprecation(ecx.tcx.map.local_def_id(nitem.id)); - encode_stability(this.rbml_w, stab); - encode_deprecation(this.rbml_w, depr); - encode_name(this.rbml_w, nitem.name); + encode_attributes(self.rbml_w, &nitem.attrs); + let stab = ecx.tcx.lookup_stability(ecx.tcx.map.local_def_id(nitem.id)); + let depr = ecx.tcx.lookup_deprecation(ecx.tcx.map.local_def_id(nitem.id)); + encode_stability(self.rbml_w, stab); + encode_deprecation(self.rbml_w, depr); + self.encode_method_argument_names(&fndecl); + } + hir::ForeignItemStatic(_, mutbl) => { + if mutbl { + encode_family(self.rbml_w, 'b'); + } else { + encode_family(self.rbml_w, 'c'); } + self.encode_bounds_and_type_for_item(nitem.id); + encode_attributes(self.rbml_w, &nitem.attrs); + let stab = ecx.tcx.lookup_stability(ecx.tcx.map.local_def_id(nitem.id)); + let depr = ecx.tcx.lookup_deprecation(ecx.tcx.map.local_def_id(nitem.id)); + encode_stability(self.rbml_w, stab); + encode_deprecation(self.rbml_w, depr); + encode_name(self.rbml_w, nitem.name); } - }); + } } } @@ -1329,7 +1329,8 @@ impl<'a, 'ecx, 'tcx, 'encoder> Visitor<'tcx> for EncodeVisitor<'a, 'ecx, 'tcx, ' } fn visit_foreign_item(&mut self, ni: &'tcx hir::ForeignItem) { intravisit::walk_foreign_item(self, ni); - self.index.encode_info_for_foreign_item(ni); + let def_id = self.index.ecx.tcx.map.local_def_id(ni.id); + self.index.record(def_id, |index| index.encode_info_for_foreign_item(def_id, ni)); } fn visit_ty(&mut self, ty: &'tcx hir::Ty) { intravisit::walk_ty(self, ty); @@ -1357,29 +1358,34 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { hir::ExprClosure(..) => { let def_id = ecx.tcx.map.local_def_id(expr.id); - self.record(def_id, |this| { - encode_def_id_and_key(ecx, this.rbml_w, def_id); - encode_name(this.rbml_w, syntax::parse::token::intern("")); - - this.rbml_w.start_tag(tag_items_closure_ty); - write_closure_type(ecx, - this.rbml_w, - &ecx.tcx.tables.borrow().closure_tys[&def_id]); - this.rbml_w.end_tag(); - - this.rbml_w.start_tag(tag_items_closure_kind); - ecx.tcx.closure_kind(def_id).encode(this.rbml_w).unwrap(); - this.rbml_w.end_tag(); - - assert!(ecx.mir_map.map.contains_key(&def_id)); - this.encode_mir(expr.id); - }); + self.record(def_id, |this| this.encode_info_for_closure(def_id, expr.id)); } _ => { } } } } +impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { + fn encode_info_for_closure(&mut self, def_id: DefId, expr_id: NodeId) { + let ecx = self.ecx; + encode_def_id_and_key(ecx, self.rbml_w, def_id); + encode_name(self.rbml_w, syntax::parse::token::intern("")); + + self.rbml_w.start_tag(tag_items_closure_ty); + write_closure_type(ecx, + self.rbml_w, + &ecx.tcx.tables.borrow().closure_tys[&def_id]); + self.rbml_w.end_tag(); + + self.rbml_w.start_tag(tag_items_closure_kind); + ecx.tcx.closure_kind(def_id).encode(self.rbml_w).unwrap(); + self.rbml_w.end_tag(); + + assert!(ecx.mir_map.map.contains_key(&def_id)); + self.encode_mir(expr_id); + } +} + fn encode_info_for_items<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w: &mut Encoder) -> (IndexData, FnvHashMap, u32>) { From 00e699faf3ec39715477b8386fba9deab2e2c925 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sun, 14 Aug 2016 20:25:00 -0400 Subject: [PATCH 17/22] change callback for expr/type to a fn pointer The idea is that, this way, we can cleanly isolate ALL state that is being passed, since it goes as an argument to the fn pointer. --- src/librustc_metadata/encoder.rs | 116 ++++++++++++------------- src/librustc_metadata/index_builder.rs | 8 +- 2 files changed, 62 insertions(+), 62 deletions(-) diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 9855eeeb97070..309347a5e5a7a 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -205,16 +205,17 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { let def = ecx.tcx.lookup_adt_def(enum_did); self.encode_fields(enum_did); for (i, variant) in def.variants.iter().enumerate() { - self.record(variant.did, |this| this.encode_enum_variant_info(enum_did, i, vis)); + self.record(variant.did, + ItemContentBuilder::encode_enum_variant_info, + (enum_did, i, vis)); } } } impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { fn encode_enum_variant_info(&mut self, - enum_did: DefId, // enum def-id - index: usize, // variant index - vis: &hir::Visibility) { + (enum_did, index, vis): + (DefId, usize, &hir::Visibility)) { let ecx = self.ecx; let def = ecx.tcx.lookup_adt_def(enum_did); let variant = &def.variants[index]; @@ -293,11 +294,8 @@ fn encode_reexports(ecx: &EncodeContext, impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { fn encode_info_for_mod(&mut self, - md: &hir::Mod, - attrs: &[ast::Attribute], - id: NodeId, - name: Name, - vis: &hir::Visibility) { + (md, attrs, id, name, vis): + (&hir::Mod, &[ast::Attribute], NodeId, Name, &hir::Visibility)) { let ecx = self.ecx(); encode_def_id_and_key(ecx, self.rbml_w, ecx.tcx.map.local_def_id(id)); @@ -418,9 +416,9 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { let def = self.ecx.tcx.lookup_adt_def(adt_def_id); for (variant_index, variant) in def.variants.iter().enumerate() { for (field_index, field) in variant.fields.iter().enumerate() { - self.record(field.did, |this| this.encode_field(adt_def_id, - variant_index, - field_index)); + self.record(field.did, + ItemContentBuilder::encode_field, + (adt_def_id, variant_index, field_index)); } } } @@ -428,9 +426,8 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { fn encode_field(&mut self, - adt_def_id: DefId, - variant_index: usize, - field_index: usize) { + (adt_def_id, variant_index, field_index): + (DefId, usize, usize)) { let ecx = self.ecx(); let def = ecx.tcx.lookup_adt_def(adt_def_id); let variant = &def.variants[variant_index]; @@ -454,9 +451,8 @@ impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { fn encode_struct_ctor(&mut self, - struct_def_id: DefId, - struct_node_id: ast::NodeId, - ctor_node_id: ast::NodeId) { + (struct_def_id, struct_node_id, ctor_node_id): + (DefId, ast::NodeId, ast::NodeId)) { let ecx = self.ecx(); let def = ecx.tcx.lookup_adt_def(struct_def_id); let variant = def.struct_variant(); @@ -532,9 +528,8 @@ impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { fn encode_info_for_trait_item(&mut self, - trait_def_id: DefId, - item_def_id: DefId, - trait_item: &hir::TraitItem) { + (trait_def_id, item_def_id, trait_item): + (DefId, DefId, &hir::TraitItem)) { let ecx = self.ecx; let tcx = ecx.tcx; @@ -635,9 +630,8 @@ impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { } fn encode_info_for_impl_item(&mut self, - impl_id: NodeId, - impl_item_def_id: DefId, - ast_item: Option<&hir::ImplItem>) { + (impl_id, impl_item_def_id, ast_item): + (NodeId, DefId, Option<&hir::ImplItem>)) { match self.ecx.tcx.impl_or_trait_item(impl_item_def_id) { ty::ConstTraitItem(ref associated_const) => { self.encode_info_for_associated_const(&associated_const, @@ -882,8 +876,7 @@ fn encode_xrefs<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { fn encode_info_for_item(&mut self, - def_id: DefId, - item: &hir::Item) { + (def_id, item): (DefId, &hir::Item)) { let ecx = self.ecx(); let tcx = ecx.tcx; @@ -943,11 +936,7 @@ impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { self.encode_method_argument_names(&decl); } hir::ItemMod(ref m) => { - self.encode_info_for_mod(m, - &item.attrs, - item.id, - item.name, - &item.vis); + self.encode_info_for_mod((m, &item.attrs, item.id, item.name, &item.vis)); } hir::ItemForeignMod(ref fm) => { encode_def_id_and_key(ecx, self.rbml_w, def_id); @@ -1210,9 +1199,9 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { // there is a value for structs like `struct // Foo()` and `struct Foo` let ctor_def_id = ecx.tcx.map.local_def_id(struct_node_id); - self.record(ctor_def_id, |this| this.encode_struct_ctor(def_id, - item.id, - struct_node_id)); + self.record(ctor_def_id, + ItemContentBuilder::encode_struct_ctor, + (def_id, item.id, struct_node_id)); } } } @@ -1238,9 +1227,9 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { }; let trait_item_def_id = trait_item_def_id.def_id(); - self.record(trait_item_def_id, |this| { - this.encode_info_for_impl_item(impl_id, trait_item_def_id, ast_item) - }); + self.record(trait_item_def_id, + ItemContentBuilder::encode_info_for_impl_item, + (impl_id, trait_item_def_id, ast_item)); } } @@ -1253,17 +1242,16 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { for (item_def_id, trait_item) in r.iter().zip(trait_items) { let item_def_id = item_def_id.def_id(); assert!(item_def_id.is_local()); - self.record(item_def_id, |this| { - this.encode_info_for_trait_item(def_id, item_def_id, trait_item) - }); + self.record(item_def_id, + ItemContentBuilder::encode_info_for_trait_item, + (def_id, item_def_id, trait_item)); } } } impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { fn encode_info_for_foreign_item(&mut self, - def_id: DefId, - nitem: &hir::ForeignItem) { + (def_id, nitem): (DefId, &hir::ForeignItem)) { let ecx = self.ecx(); debug!("writing foreign item {}", ecx.tcx.node_path_str(nitem.id)); @@ -1323,14 +1311,18 @@ impl<'a, 'ecx, 'tcx, 'encoder> Visitor<'tcx> for EncodeVisitor<'a, 'ecx, 'tcx, ' let def_id = self.index.ecx.tcx.map.local_def_id(item.id); match item.node { hir::ItemExternCrate(_) | hir::ItemUse(_) => (), // ignore these - _ => self.index.record(def_id, |index| index.encode_info_for_item(def_id, item)), + _ => self.index.record(def_id, + ItemContentBuilder::encode_info_for_item, + (def_id, item)), } self.index.encode_addl_info_for_item(item); } fn visit_foreign_item(&mut self, ni: &'tcx hir::ForeignItem) { intravisit::walk_foreign_item(self, ni); let def_id = self.index.ecx.tcx.map.local_def_id(ni.id); - self.index.record(def_id, |index| index.encode_info_for_foreign_item(def_id, ni)); + self.index.record(def_id, + ItemContentBuilder::encode_info_for_foreign_item, + (def_id, ni)); } fn visit_ty(&mut self, ty: &'tcx hir::Ty) { intravisit::walk_ty(self, ty); @@ -1343,11 +1335,9 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { let ecx = self.ecx(); if let hir::TyImplTrait(_) = ty.node { let def_id = ecx.tcx.map.local_def_id(ty.id); - self.record(def_id, |this| { - encode_def_id_and_key(ecx, this.rbml_w, def_id); - encode_family(this.rbml_w, 'y'); - this.encode_bounds_and_type_for_item(ty.id); - }); + self.record(def_id, + ItemContentBuilder::encode_info_for_anon_ty, + (def_id, ty.id)); } } @@ -1357,8 +1347,9 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { match expr.node { hir::ExprClosure(..) => { let def_id = ecx.tcx.map.local_def_id(expr.id); - - self.record(def_id, |this| this.encode_info_for_closure(def_id, expr.id)); + self.record(def_id, + ItemContentBuilder::encode_info_for_closure, + (def_id, expr.id)); } _ => { } } @@ -1366,7 +1357,14 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { } impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { - fn encode_info_for_closure(&mut self, def_id: DefId, expr_id: NodeId) { + fn encode_info_for_anon_ty(&mut self, (def_id, ty_id): (DefId, NodeId)) { + let ecx = self.ecx; + encode_def_id_and_key(ecx, self.rbml_w, def_id); + encode_family(self.rbml_w, 'y'); + self.encode_bounds_and_type_for_item(ty_id); + } + + fn encode_info_for_closure(&mut self, (def_id, expr_id): (DefId, NodeId)) { let ecx = self.ecx; encode_def_id_and_key(ecx, self.rbml_w, def_id); encode_name(self.rbml_w, syntax::parse::token::intern("")); @@ -1395,13 +1393,13 @@ fn encode_info_for_items<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, let fields = { let mut index = IndexBuilder::new(ecx, rbml_w); - index.record(DefId::local(CRATE_DEF_INDEX), |this| { - this.encode_info_for_mod(&krate.module, - &[], - CRATE_NODE_ID, - syntax::parse::token::intern(&ecx.link_meta.crate_name), - &hir::Public); - }); + index.record(DefId::local(CRATE_DEF_INDEX), + ItemContentBuilder::encode_info_for_mod, + (&krate.module, + &[], + CRATE_NODE_ID, + syntax::parse::token::intern(&ecx.link_meta.crate_name), + &hir::Public)); krate.visit_all_items(&mut EncodeVisitor { index: &mut index, }); diff --git a/src/librustc_metadata/index_builder.rs b/src/librustc_metadata/index_builder.rs index b591e0a92688b..a971c618a2120 100644 --- a/src/librustc_metadata/index_builder.rs +++ b/src/librustc_metadata/index_builder.rs @@ -57,14 +57,16 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { /// /// Returns a dep-graph task that you should keep live as long as /// the data for this item is being emitted. - pub fn record(&mut self, id: DefId, op: OP) - where OP: FnOnce(&mut ItemContentBuilder<'a, 'tcx, 'encoder>) + pub fn record(&mut self, + id: DefId, + op: fn(&mut ItemContentBuilder<'a, 'tcx, 'encoder>, DATA), + data: DATA) { let position = self.rbml_w.mark_stable_position(); self.items.record(id, position); let _task = self.ecx.tcx.dep_graph.in_task(DepNode::MetaData(id)); self.rbml_w.start_tag(tag_items_data_item).unwrap(); - op(self); + op(self, data); self.rbml_w.end_tag().unwrap(); } From f3990feb2e411d0826dfb83aa7078468da5d1907 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sun, 14 Aug 2016 21:16:16 -0400 Subject: [PATCH 18/22] create a trait to ensure that data is tracked Also write a comment explaining the system. --- src/librustc_metadata/encoder.rs | 33 ++++---- src/librustc_metadata/index_builder.rs | 106 +++++++++++++++++++++++-- 2 files changed, 117 insertions(+), 22 deletions(-) diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 309347a5e5a7a..494699af7ba1a 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -53,7 +53,7 @@ use rustc::hir::intravisit::Visitor; use rustc::hir::intravisit; use rustc::hir::map::DefKey; -use super::index_builder::{IndexBuilder, ItemContentBuilder, XRef}; +use super::index_builder::{FromId, IndexBuilder, ItemContentBuilder, XRef}; pub struct EncodeContext<'a, 'tcx: 'a> { pub diag: &'a Handler, @@ -198,8 +198,7 @@ impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { fn encode_enum_variant_infos(&mut self, - enum_did: DefId, - vis: &hir::Visibility) { + enum_did: DefId) { debug!("encode_enum_variant_info(enum_did={:?})", enum_did); let ecx = self.ecx(); let def = ecx.tcx.lookup_adt_def(enum_did); @@ -207,15 +206,15 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { for (i, variant) in def.variants.iter().enumerate() { self.record(variant.did, ItemContentBuilder::encode_enum_variant_info, - (enum_did, i, vis)); + (enum_did, i)); } } } impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { fn encode_enum_variant_info(&mut self, - (enum_did, index, vis): - (DefId, usize, &hir::Visibility)) { + (enum_did, index): + (DefId, usize)) { let ecx = self.ecx; let def = ecx.tcx.lookup_adt_def(enum_did); let variant = &def.variants[index]; @@ -229,7 +228,10 @@ impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { }); encode_name(self.rbml_w, variant.name); self.encode_parent_item(enum_did); - self.encode_visibility(vis); + + let enum_id = ecx.tcx.map.as_local_node_id(enum_did).unwrap(); + let enum_vis = &ecx.tcx.map.expect_item(enum_id).vis; + self.encode_visibility(enum_vis); let attrs = ecx.tcx.get_attrs(vid); encode_attributes(self.rbml_w, &attrs); @@ -294,8 +296,8 @@ fn encode_reexports(ecx: &EncodeContext, impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { fn encode_info_for_mod(&mut self, - (md, attrs, id, name, vis): - (&hir::Mod, &[ast::Attribute], NodeId, Name, &hir::Visibility)) { + FromId(id, (md, attrs, name, vis)): + FromId<(&hir::Mod, &[ast::Attribute], Name, &hir::Visibility)>) { let ecx = self.ecx(); encode_def_id_and_key(ecx, self.rbml_w, ecx.tcx.map.local_def_id(id)); @@ -936,7 +938,7 @@ impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { self.encode_method_argument_names(&decl); } hir::ItemMod(ref m) => { - self.encode_info_for_mod((m, &item.attrs, item.id, item.name, &item.vis)); + self.encode_info_for_mod(FromId(item.id, (m, &item.attrs, item.name, &item.vis))); } hir::ItemForeignMod(ref fm) => { encode_def_id_and_key(ecx, self.rbml_w, def_id); @@ -1166,7 +1168,7 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { // no sub-item recording needed in these cases } hir::ItemEnum(..) => { - self.encode_enum_variant_infos(def_id, &item.vis); + self.encode_enum_variant_infos(def_id); } hir::ItemStruct(ref struct_def, _) => { self.encode_addl_struct_info(def_id, struct_def.id(), item); @@ -1395,11 +1397,10 @@ fn encode_info_for_items<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, let mut index = IndexBuilder::new(ecx, rbml_w); index.record(DefId::local(CRATE_DEF_INDEX), ItemContentBuilder::encode_info_for_mod, - (&krate.module, - &[], - CRATE_NODE_ID, - syntax::parse::token::intern(&ecx.link_meta.crate_name), - &hir::Public)); + FromId(CRATE_NODE_ID, (&krate.module, + &[], + syntax::parse::token::intern(&ecx.link_meta.crate_name), + &hir::Public))); krate.visit_all_items(&mut EncodeVisitor { index: &mut index, }); diff --git a/src/librustc_metadata/index_builder.rs b/src/librustc_metadata/index_builder.rs index a971c618a2120..c7ee3efaa81d3 100644 --- a/src/librustc_metadata/index_builder.rs +++ b/src/librustc_metadata/index_builder.rs @@ -13,9 +13,11 @@ use encoder::EncodeContext; use index::IndexData; use rbml::writer::Encoder; use rustc::dep_graph::DepNode; +use rustc::hir; use rustc::hir::def_id::DefId; -use rustc::ty; +use rustc::ty::{self, TyCtxt}; use rustc_data_structures::fnv::FnvHashMap; +use syntax::ast; use std::ops::{Deref, DerefMut}; /// Builder that can encode new items, adding them into the index. @@ -51,21 +53,34 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { } } - /// 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. + /// Emit the data for a def-id to the metadata. The function to + /// emit the data is `op`, and it will be given `data` as + /// arguments. This `record` function will start/end an RBML tag + /// and record the current offset for use in the index, calling + /// `op` to generate the data in the RBML tag. /// - /// Returns a dep-graph task that you should keep live as long as - /// the data for this item is being emitted. + /// In addition, it will setup a dep-graph task to track what data + /// `op` accesses to generate the metadata, which is later used by + /// incremental compilation to compute a hash for the metadata and + /// track changes. + /// + /// The reason that `op` is a function pointer, and not a closure, + /// is that we want to be able to completely track all data it has + /// access to, so that we can be sure that `DATA: DepGraphRead` + /// holds, and that it is therefore not gaining "secret" access to + /// bits of HIR or other state that would not be trackd by the + /// content system. pub fn record(&mut self, id: DefId, op: fn(&mut ItemContentBuilder<'a, 'tcx, 'encoder>, DATA), data: DATA) + where DATA: DepGraphRead { let position = self.rbml_w.mark_stable_position(); self.items.record(id, position); let _task = self.ecx.tcx.dep_graph.in_task(DepNode::MetaData(id)); self.rbml_w.start_tag(tag_items_data_item).unwrap(); + data.read(self.ecx.tcx); op(self, data); self.rbml_w.end_tag().unwrap(); } @@ -100,3 +115,82 @@ impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { } } +/// Trait that registers reads for types that are tracked in the +/// dep-graph. Mostly it is implemented for indices like DefId etc +/// which do not need to register a read. +pub trait DepGraphRead { + fn read(&self, tcx: TyCtxt); +} + +impl DepGraphRead for usize { + fn read(&self, _tcx: TyCtxt) { } +} + +impl DepGraphRead for DefId { + fn read(&self, _tcx: TyCtxt) { } +} + +impl DepGraphRead for ast::NodeId { + fn read(&self, _tcx: TyCtxt) { } +} + +impl DepGraphRead for Option + where T: DepGraphRead +{ + fn read(&self, tcx: TyCtxt) { + match *self { + Some(ref v) => v.read(tcx), + None => (), + } + } +} + +impl DepGraphRead for [T] + where T: DepGraphRead +{ + fn read(&self, tcx: TyCtxt) { + for i in self { + i.read(tcx); + } + } +} + +macro_rules! read_tuple { + ($($name:ident),*) => { + impl<$($name),*> DepGraphRead for ($($name),*) + where $($name: DepGraphRead),* + { + #[allow(non_snake_case)] + fn read(&self, tcx: TyCtxt) { + let &($(ref $name),*) = self; + $($name.read(tcx);)* + } + } + } +} +read_tuple!(A,B); +read_tuple!(A,B,C); + +macro_rules! read_hir { + ($t:ty) => { + impl<'tcx> DepGraphRead for &'tcx $t { + fn read(&self, tcx: TyCtxt) { + tcx.map.read(self.id); + } + } + } +} +read_hir!(hir::Item); +read_hir!(hir::ImplItem); +read_hir!(hir::TraitItem); +read_hir!(hir::ForeignItem); + +/// You can use `FromId(X, ...)` to indicate that `...` came from node +/// `X`; so we will add a read from the suitable `Hir` node. +pub struct FromId(pub ast::NodeId, pub T); + +impl DepGraphRead for FromId { + fn read(&self, tcx: TyCtxt) { + tcx.map.read(self.0); + } +} From 1a91e67614b7f4a93bb128ca4f25889b25e22b99 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 15 Aug 2016 10:19:58 -0400 Subject: [PATCH 19/22] pacify the mercilous tidy --- src/librustc_metadata/encoder.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 494699af7ba1a..11a1aab7b5b95 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -947,8 +947,9 @@ impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { // Encode all the items in self module. for foreign_item in &fm.items { - self.rbml_w.wr_tagged_u64(tag_mod_child, - def_to_u64(ecx.tcx.map.local_def_id(foreign_item.id))); + self.rbml_w.wr_tagged_u64( + tag_mod_child, + def_to_u64(ecx.tcx.map.local_def_id(foreign_item.id))); } self.encode_visibility(vis); encode_stability(self.rbml_w, stab); From 9daea5b6393af6706dd50a48d4bf8e6eeaff9860 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 15 Aug 2016 11:04:21 -0400 Subject: [PATCH 20/22] Add a comment, remove Deref/DerefMut The comment explains the `index-builder` pattern. We no longer need the `Deref/DerefMut` relationship, and it seems nicer without it. --- src/librustc_metadata/encoder.rs | 14 ++-- src/librustc_metadata/index_builder.rs | 98 +++++++++++++++++++------- 2 files changed, 79 insertions(+), 33 deletions(-) diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 11a1aab7b5b95..7f7b87fb880b4 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -415,7 +415,7 @@ fn encode_item_sort(rbml_w: &mut Encoder, sort: char) { impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { fn encode_fields(&mut self, adt_def_id: DefId) { - let def = self.ecx.tcx.lookup_adt_def(adt_def_id); + let def = self.ecx().tcx.lookup_adt_def(adt_def_id); for (variant_index, variant) in def.variants.iter().enumerate() { for (field_index, field) in variant.fields.iter().enumerate() { self.record(field.did, @@ -1155,7 +1155,7 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { /// normally in the visitor walk. fn encode_addl_info_for_item(&mut self, item: &hir::Item) { - let def_id = self.ecx.tcx.map.local_def_id(item.id); + let def_id = self.ecx().tcx.map.local_def_id(item.id); match item.node { hir::ItemStatic(..) | hir::ItemConst(..) | @@ -1187,7 +1187,7 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { def_id: DefId, struct_node_id: ast::NodeId, item: &hir::Item) { - let ecx = self.ecx; + let ecx = self.ecx(); let def = ecx.tcx.lookup_adt_def(def_id); let variant = def.struct_variant(); @@ -1213,7 +1213,7 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { def_id: DefId, impl_id: ast::NodeId, ast_items: &[hir::ImplItem]) { - let ecx = self.ecx; + let ecx = self.ecx(); let impl_items = ecx.tcx.impl_items.borrow(); let items = &impl_items[&def_id]; @@ -1240,7 +1240,7 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { def_id: DefId, trait_items: &[hir::TraitItem]) { // Now output the trait item info for each trait item. - let tcx = self.ecx.tcx; + let tcx = self.ecx().tcx; let r = tcx.trait_item_def_ids(def_id); for (item_def_id, trait_item) in r.iter().zip(trait_items) { let item_def_id = item_def_id.def_id(); @@ -1311,7 +1311,7 @@ impl<'a, 'ecx, 'tcx, 'encoder> Visitor<'tcx> for EncodeVisitor<'a, 'ecx, 'tcx, ' } fn visit_item(&mut self, item: &'tcx hir::Item) { intravisit::walk_item(self, item); - let def_id = self.index.ecx.tcx.map.local_def_id(item.id); + let def_id = self.index.ecx().tcx.map.local_def_id(item.id); match item.node { hir::ItemExternCrate(_) | hir::ItemUse(_) => (), // ignore these _ => self.index.record(def_id, @@ -1322,7 +1322,7 @@ impl<'a, 'ecx, 'tcx, 'encoder> Visitor<'tcx> for EncodeVisitor<'a, 'ecx, 'tcx, ' } fn visit_foreign_item(&mut self, ni: &'tcx hir::ForeignItem) { intravisit::walk_foreign_item(self, ni); - let def_id = self.index.ecx.tcx.map.local_def_id(ni.id); + let def_id = self.index.ecx().tcx.map.local_def_id(ni.id); self.index.record(def_id, ItemContentBuilder::encode_info_for_foreign_item, (def_id, ni)); diff --git a/src/librustc_metadata/index_builder.rs b/src/librustc_metadata/index_builder.rs index c7ee3efaa81d3..37f29696808ef 100644 --- a/src/librustc_metadata/index_builder.rs +++ b/src/librustc_metadata/index_builder.rs @@ -8,6 +8,60 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +//! Builder types for generating the "item data" section of the +//! metadata. This section winds up looking like this: +//! +//! ``` +//! // big list of item-like things... +//! // ...for most def-ids, there is an entry. +//! +//! +//! ``` +//! +//! As we generate this listing, we collect the offset of each +//! `data_item` entry and store it in an index. Then, when we load the +//! metadata, we can skip right to the metadata for a particular item. +//! +//! In addition to the offset, we need to track the data that was used +//! to generate the contents of each `data_item`. This is so that we +//! can figure out which HIR nodes contributors to that data for +//! incremental compilation purposes. +//! +//! The `IndexBuilder` facilitates with both of these. It is created +//! with an RBML encoder isntance (`rbml_w`) along with an +//! `EncodingContext` (`ecx`), which it encapsulates. It has one main +//! method, `record()`. You invoke `record` like so to create a new +//! `data_item` element in the list: +//! +//! ``` +//! index.record(some_def_id, callback_fn, data) +//! ``` +//! +//! What record will do is to (a) record the current offset, (b) emit +//! the `common::data_item` tag, and then call `callback_fn` with the +//! given data as well as an `ItemContentBuilder`. Once `callback_fn` +//! returns, the `common::data_item` tag will be closed. +//! +//! The `ItemContentBuilder` is another type that just offers access +//! to the `ecx` and `rbml_w` that were given in, as well as +//! maintaining a list of `xref` instances, which are used to extract +//! common data so it is not re-serialized. +//! +//! `ItemContentBuilder` is a distinct type which does not offer the +//! `record` method, so that we can ensure that `common::data_item` elements +//! are never nested. +//! +//! In addition, while the `callback_fn` is executing, we will push a +//! task `MetaData(some_def_id)`, which can then observe the +//! reads/writes that occur in the task. For this reason, the `data` +//! argument that is given to the `callback_fn` must implement the +//! trait `DepGraphRead`, which indicates how to register reads on the +//! data in this new task (note that many types of data, such as +//! `DefId`, do not currently require any reads to be registered, +//! since they are not derived from a HIR node). This is also why we +//! give a callback fn, rather than taking a closure: it allows us to +//! easily control precisely what data is given to that fn. + use common::tag_items_data_item; use encoder::EncodeContext; use index::IndexData; @@ -18,7 +72,6 @@ use rustc::hir::def_id::DefId; use rustc::ty::{self, TyCtxt}; use rustc_data_structures::fnv::FnvHashMap; use syntax::ast; -use std::ops::{Deref, DerefMut}; /// Builder that can encode new items, adding them into the index. /// Item encoding cannot be nested. @@ -53,6 +106,10 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { } } + pub fn ecx(&self) -> &'a EncodeContext<'a, 'tcx> { + self.builder.ecx() + } + /// Emit the data for a def-id to the metadata. The function to /// emit the data is `op`, and it will be given `data` as /// arguments. This `record` function will start/end an RBML tag @@ -76,13 +133,13 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { data: DATA) where DATA: DepGraphRead { - let position = self.rbml_w.mark_stable_position(); + let position = self.builder.rbml_w.mark_stable_position(); self.items.record(id, position); - let _task = self.ecx.tcx.dep_graph.in_task(DepNode::MetaData(id)); - self.rbml_w.start_tag(tag_items_data_item).unwrap(); - data.read(self.ecx.tcx); - op(self, data); - self.rbml_w.end_tag().unwrap(); + let _task = self.ecx().tcx.dep_graph.in_task(DepNode::MetaData(id)); + self.builder.rbml_w.start_tag(tag_items_data_item).unwrap(); + data.read(self.ecx().tcx); + op(&mut self.builder, data); + self.builder.rbml_w.end_tag().unwrap(); } pub fn into_fields(self) -> (IndexData, FnvHashMap, u32>) { @@ -90,20 +147,6 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { } } -impl<'a, 'tcx, 'encoder> Deref for IndexBuilder<'a, 'tcx, 'encoder> { - type Target = ItemContentBuilder<'a, 'tcx, 'encoder>; - - fn deref(&self) -> &Self::Target { - &self.builder - } -} - -impl<'a, 'tcx, 'encoder> DerefMut for IndexBuilder<'a, 'tcx, 'encoder> { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.builder - } -} - impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { pub fn ecx(&self) -> &'a EncodeContext<'a, 'tcx> { self.ecx @@ -115,9 +158,10 @@ impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { } } -/// Trait that registers reads for types that are tracked in the -/// dep-graph. Mostly it is implemented for indices like DefId etc -/// which do not need to register a read. +/// Trait used for data that can be passed from outside a dep-graph +/// task. The data must either be of some safe type, such as a +/// `DefId` index, or implement the `read` method so that it can add +/// a read of whatever dep-graph nodes are appropriate. pub trait DepGraphRead { fn read(&self, tcx: TyCtxt); } @@ -185,8 +229,10 @@ read_hir!(hir::ImplItem); read_hir!(hir::TraitItem); read_hir!(hir::ForeignItem); -/// You can use `FromId(X, ...)` to indicate that `...` came from node -/// `X`; so we will add a read from the suitable `Hir` node. +/// Newtype that can be used to package up misc data extracted from a +/// HIR node that doesn't carry its own id. This will allow an +/// arbitrary `T` to be passed in, but register a read on the given +/// node-id. pub struct FromId(pub ast::NodeId, pub T); impl DepGraphRead for FromId { From 6b33f47514f47267d9e07bebbf4c97b2404fa58c Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 16 Aug 2016 11:42:30 -0400 Subject: [PATCH 21/22] remove `usize: DepGraphRead` and add `Untracked` The idea is that a `usize` is sort of ambiguous: in this case, it represents indices that do not need tracking, but it could as easily be some data read out from a tracked location, and hence represent tracked data. Therefore, we add an `Untracked` type that lets user assert that value is not tracked. Also correct various typos. --- src/librustc_metadata/encoder.rs | 25 ++++++++++++++++++------- src/librustc_metadata/index_builder.rs | 23 +++++++++++++++++------ 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 7f7b87fb880b4..791d090273ffc 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -53,7 +53,7 @@ use rustc::hir::intravisit::Visitor; use rustc::hir::intravisit; use rustc::hir::map::DefKey; -use super::index_builder::{FromId, IndexBuilder, ItemContentBuilder, XRef}; +use super::index_builder::{FromId, IndexBuilder, ItemContentBuilder, Untracked, XRef}; pub struct EncodeContext<'a, 'tcx: 'a> { pub diag: &'a Handler, @@ -206,15 +206,20 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { for (i, variant) in def.variants.iter().enumerate() { self.record(variant.did, ItemContentBuilder::encode_enum_variant_info, - (enum_did, i)); + (enum_did, Untracked(i))); } } } impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { + /// Encode data for the given variant of the given ADT. The + /// index of the variant is untracked: this is ok because we + /// will have to lookup the adt-def by its id, and that gives us + /// the right to access any information in the adt-def (including, + /// e.g., the length of the various vectors). fn encode_enum_variant_info(&mut self, - (enum_did, index): - (DefId, usize)) { + (enum_did, Untracked(index)): + (DefId, Untracked)) { let ecx = self.ecx; let def = ecx.tcx.lookup_adt_def(enum_did); let variant = &def.variants[index]; @@ -420,16 +425,22 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> { for (field_index, field) in variant.fields.iter().enumerate() { self.record(field.did, ItemContentBuilder::encode_field, - (adt_def_id, variant_index, field_index)); + (adt_def_id, Untracked((variant_index, field_index)))); } } } } impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { + /// Encode data for the given field of the given variant of the + /// given ADT. The indices of the variant/field are untracked: + /// this is ok because we will have to lookup the adt-def by its + /// id, and that gives us the right to access any information in + /// the adt-def (including, e.g., the length of the various + /// vectors). fn encode_field(&mut self, - (adt_def_id, variant_index, field_index): - (DefId, usize, usize)) { + (adt_def_id, Untracked((variant_index, field_index))): + (DefId, Untracked<(usize, usize)>)) { let ecx = self.ecx(); let def = ecx.tcx.lookup_adt_def(adt_def_id); let variant = &def.variants[variant_index]; diff --git a/src/librustc_metadata/index_builder.rs b/src/librustc_metadata/index_builder.rs index 37f29696808ef..1d3d09d6bc2d7 100644 --- a/src/librustc_metadata/index_builder.rs +++ b/src/librustc_metadata/index_builder.rs @@ -24,10 +24,10 @@ //! //! In addition to the offset, we need to track the data that was used //! to generate the contents of each `data_item`. This is so that we -//! can figure out which HIR nodes contributors to that data for +//! can figure out which HIR nodes contributed to that data for //! incremental compilation purposes. //! -//! The `IndexBuilder` facilitates with both of these. It is created +//! The `IndexBuilder` facilitates both of these. It is created //! with an RBML encoder isntance (`rbml_w`) along with an //! `EncodingContext` (`ecx`), which it encapsulates. It has one main //! method, `record()`. You invoke `record` like so to create a new @@ -166,10 +166,6 @@ pub trait DepGraphRead { fn read(&self, tcx: TyCtxt); } -impl DepGraphRead for usize { - fn read(&self, _tcx: TyCtxt) { } -} - impl DepGraphRead for DefId { fn read(&self, _tcx: TyCtxt) { } } @@ -229,6 +225,21 @@ read_hir!(hir::ImplItem); read_hir!(hir::TraitItem); read_hir!(hir::ForeignItem); +/// Leaks access to a value of type T without any tracking. This is +/// suitable for ambiguous types like `usize`, which *could* represent +/// tracked data (e.g., if you read it out of a HIR node) or might not +/// (e.g., if it's an index). Adding in an `Untracked` is an +/// assertion, essentially, that the data does not need to be tracked +/// (or that read edges will be added by some other way). +/// +/// A good idea is to add to each use of `Untracked` an explanation of +/// why this value is ok. +pub struct Untracked(pub T); + +impl DepGraphRead for Untracked { + fn read(&self, _tcx: TyCtxt) { } +} + /// Newtype that can be used to package up misc data extracted from a /// HIR node that doesn't carry its own id. This will allow an /// arbitrary `T` to be passed in, but register a read on the given From 37d974f35327516e337f83be4f38579217660313 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 17 Aug 2016 15:14:08 -0400 Subject: [PATCH 22/22] remove seemingly unnecessary call to encode_predicates --- src/librustc_metadata/encoder.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 791d090273ffc..420dfbc58bf19 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -767,10 +767,6 @@ impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> { if let Some(ii) = impl_item_opt { encode_attributes(self.rbml_w, &ii.attrs); encode_defaultness(self.rbml_w, ii.defaultness); - } else { - // TODO this looks bogus and unnecessary - self.encode_predicates(&ecx.tcx.lookup_predicates(associated_type.def_id), - tag_item_generics); } if let Some(ty) = associated_type.ty {