From 8a6118b74840727e17ec42b0aa6d7a215d57d2df Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 13 Aug 2015 10:57:34 -0400 Subject: [PATCH 1/7] move InlinedItem into librustc, where it belongs --- src/librustc/ast_map/mod.rs | 32 ++++++++------- src/librustc/metadata/csearch.rs | 5 ++- src/librustc/metadata/decoder.rs | 3 +- src/librustc/metadata/encoder.rs | 30 +++++--------- src/librustc/metadata/inline.rs | 64 ++++++++++++++++++++++++++++++ src/librustc/metadata/mod.rs | 1 + src/librustc/middle/astencode.rs | 61 ++++++++++++++-------------- src/librustc/middle/const_eval.rs | 13 +++--- src/librustc/middle/region.rs | 7 ++-- src/librustc_trans/trans/inline.rs | 11 ++--- src/libsyntax/ast.rs | 12 ------ src/libsyntax/ast_util.rs | 33 +++++---------- src/libsyntax/visit.rs | 11 ----- 13 files changed, 157 insertions(+), 126 deletions(-) create mode 100644 src/librustc/metadata/inline.rs diff --git a/src/librustc/ast_map/mod.rs b/src/librustc/ast_map/mod.rs index a193ffcc731d6..b38c15d0f6a1e 100644 --- a/src/librustc/ast_map/mod.rs +++ b/src/librustc/ast_map/mod.rs @@ -12,6 +12,8 @@ pub use self::Node::*; pub use self::PathElem::*; use self::MapEntry::*; +use metadata::inline::InlinedItem; +use metadata::inline::InlinedItem as II; use syntax::abi; use syntax::ast::*; use syntax::ast_util; @@ -374,8 +376,8 @@ impl<'ast> Map<'ast> { pub fn get_parent_did(&self, id: NodeId) -> DefId { let parent = self.get_parent(id); match self.find_entry(parent) { - Some(RootInlinedParent(&InlinedParent {ii: IITraitItem(did, _), ..})) => did, - Some(RootInlinedParent(&InlinedParent {ii: IIImplItem(did, _), ..})) => did, + Some(RootInlinedParent(&InlinedParent {ii: II::TraitItem(did, _), ..})) => did, + Some(RootInlinedParent(&InlinedParent {ii: II::ImplItem(did, _), ..})) => did, _ => ast_util::local_def(parent) } } @@ -967,16 +969,16 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, -> &'ast InlinedItem { let mut fld = IdAndSpanUpdater { fold_ops: fold_ops }; let ii = match ii { - IIItem(i) => IIItem(fld.fold_item(i).expect_one("expected one item")), - IITraitItem(d, ti) => { - IITraitItem(fld.fold_ops.new_def_id(d), - fld.fold_trait_item(ti).expect_one("expected one trait item")) + II::Item(i) => II::Item(fld.fold_item(i).expect_one("expected one item")), + II::TraitItem(d, ti) => { + II::TraitItem(fld.fold_ops.new_def_id(d), + fld.fold_trait_item(ti).expect_one("expected one trait item")) } - IIImplItem(d, ii) => { - IIImplItem(fld.fold_ops.new_def_id(d), - fld.fold_impl_item(ii).expect_one("expected one impl item")) + II::ImplItem(d, ii) => { + II::ImplItem(fld.fold_ops.new_def_id(d), + fld.fold_impl_item(ii).expect_one("expected one impl item")) } - IIForeign(i) => IIForeign(fld.fold_foreign_item(i)) + II::Foreign(i) => II::Foreign(fld.fold_foreign_item(i)) }; let ii_parent = map.forest.inlined_items.alloc(InlinedParent { @@ -990,20 +992,20 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, parent_node: ii_parent_id, }; collector.insert_entry(ii_parent_id, RootInlinedParent(ii_parent)); - visit::walk_inlined_item(&mut collector, &ii_parent.ii); + ii_parent.ii.visit(&mut collector); // Methods get added to the AST map when their impl is visited. Since we // don't decode and instantiate the impl, but just the method, we have to // add it to the table now. Likewise with foreign items. match ii_parent.ii { - IIItem(_) => {} - IITraitItem(_, ref ti) => { + II::Item(_) => {} + II::TraitItem(_, ref ti) => { collector.insert(ti.id, NodeTraitItem(ti)); } - IIImplItem(_, ref ii) => { + II::ImplItem(_, ref ii) => { collector.insert(ii.id, NodeImplItem(ii)); } - IIForeign(ref i) => { + II::Foreign(ref i) => { collector.insert(i.id, NodeForeignItem(i)); } } diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index 2ade251018f26..d33b163c9725a 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -14,6 +14,7 @@ use ast_map; use metadata::common::*; use metadata::cstore; use metadata::decoder; +use metadata::inline::InlinedItem; use middle::lang_items; use middle::ty; @@ -96,8 +97,8 @@ pub fn get_item_path(tcx: &ty::ctxt, def: ast::DefId) -> Vec } pub enum FoundAst<'ast> { - Found(&'ast ast::InlinedItem), - FoundParent(ast::DefId, &'ast ast::InlinedItem), + Found(&'ast InlinedItem), + FoundParent(ast::DefId, &'ast InlinedItem), NotFound, } diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index c6c18fa14a340..11a5cc8c9d737 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -23,6 +23,7 @@ use metadata::csearch::MethodInfo; use metadata::csearch; use metadata::cstore; use metadata::encoder::def_to_u64; +use metadata::inline::InlinedItem; use metadata::tydecode::{parse_ty_data, parse_region_data, parse_type_param_def_data, parse_bare_fn_ty_data, parse_trait_ref_data, parse_predicate_data}; @@ -776,7 +777,7 @@ pub type DecodeInlinedItem<'a> = &ty::ctxt<'tcx>, Vec, rbml::Doc) - -> Result<&'tcx ast::InlinedItem, Vec> + 'a>; + -> Result<&'tcx InlinedItem, Vec> + 'a>; pub fn maybe_get_item_ast<'tcx>(cdata: Cmd, tcx: &ty::ctxt<'tcx>, id: ast::NodeId, mut decode_inlined_item: DecodeInlinedItem) diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index e0f35b6817b4f..03f5f477bd817 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -13,8 +13,6 @@ #![allow(unused_must_use)] // everything is just a MemWriter, can't fail #![allow(non_camel_case_types)] -pub use self::InlinedItemRef::*; - use ast_map::{self, LinkedPath, PathElem, PathElems}; use back::svh::Svh; use session::config; @@ -22,6 +20,7 @@ use metadata::common::*; use metadata::cstore; use metadata::decoder; use metadata::tyencode; +use metadata::inline::InlinedItemRef; use middle::def; use middle::ty::{self, Ty}; use middle::stability; @@ -46,14 +45,6 @@ use syntax::visit; use syntax; use rbml::writer::Encoder; -/// A borrowed version of `ast::InlinedItem`. -pub enum InlinedItemRef<'a> { - IIItemRef(&'a ast::Item), - IITraitItemRef(DefId, &'a ast::TraitItem), - IIImplItemRef(DefId, &'a ast::ImplItem), - IIForeignRef(&'a ast::ForeignItem) -} - pub type EncodeInlinedItem<'a> = Box; @@ -830,7 +821,7 @@ fn encode_info_for_associated_const(ecx: &EncodeContext, if let Some(ii) = impl_item_opt { encode_attributes(rbml_w, &ii.attrs); - encode_inlined_item(ecx, rbml_w, IIImplItemRef(local_def(parent_id), ii)); + encode_inlined_item(ecx, rbml_w, InlinedItemRef::ImplItem(local_def(parent_id), ii)); } rbml_w.end_tag(); @@ -868,7 +859,7 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, let needs_inline = any_types || is_default_impl || attr::requests_inline(&impl_item.attrs); if needs_inline || sig.constness == ast::Constness::Const { - encode_inlined_item(ecx, rbml_w, IIImplItemRef(local_def(parent_id), + encode_inlined_item(ecx, rbml_w, InlinedItemRef::ImplItem(local_def(parent_id), impl_item)); } encode_constness(rbml_w, sig.constness); @@ -1050,7 +1041,7 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_name(rbml_w, item.ident.name); encode_path(rbml_w, path); encode_attributes(rbml_w, &item.attrs); - encode_inlined_item(ecx, rbml_w, IIItemRef(item)); + encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(item)); encode_visibility(rbml_w, vis); encode_stability(rbml_w, stab); rbml_w.end_tag(); @@ -1067,7 +1058,7 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_attributes(rbml_w, &item.attrs); let needs_inline = tps_len > 0 || attr::requests_inline(&item.attrs); if needs_inline || constness == ast::Constness::Const { - encode_inlined_item(ecx, rbml_w, IIItemRef(item)); + encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(item)); } if tps_len == 0 { encode_symbol(ecx, rbml_w, item.id); @@ -1132,7 +1123,7 @@ fn encode_info_for_item(ecx: &EncodeContext, for v in &enum_definition.variants { encode_variant_id(rbml_w, local_def(v.node.id)); } - encode_inlined_item(ecx, rbml_w, IIItemRef(item)); + encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(item)); encode_path(rbml_w, path); // Encode inherent implementations for this enumeration. @@ -1180,7 +1171,7 @@ fn encode_info_for_item(ecx: &EncodeContext, needs to know*/ encode_struct_fields(rbml_w, variant, def_id); - encode_inlined_item(ecx, rbml_w, IIItemRef(item)); + encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(item)); // Encode inherent implementations for this structure. encode_inherent_implementations(ecx, rbml_w, def_id); @@ -1455,7 +1446,7 @@ fn encode_info_for_item(ecx: &EncodeContext, match trait_item.node { ast::ConstTraitItem(_, _) => { encode_inlined_item(ecx, rbml_w, - IITraitItemRef(def_id, trait_item)); + InlinedItemRef::TraitItem(def_id, trait_item)); } ast::MethodTraitItem(ref sig, ref body) => { // If this is a static method, we've already @@ -1469,7 +1460,8 @@ fn encode_info_for_item(ecx: &EncodeContext, if body.is_some() { encode_item_sort(rbml_w, 'p'); - encode_inlined_item(ecx, rbml_w, IITraitItemRef(def_id, trait_item)); + encode_inlined_item(ecx, rbml_w, + InlinedItemRef::TraitItem(def_id, trait_item)); } else { encode_item_sort(rbml_w, 'r'); } @@ -1508,7 +1500,7 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext, encode_bounds_and_type_for_item(rbml_w, ecx, nitem.id); encode_name(rbml_w, nitem.ident.name); if abi == abi::RustIntrinsic { - encode_inlined_item(ecx, rbml_w, IIForeignRef(nitem)); + encode_inlined_item(ecx, rbml_w, InlinedItemRef::Foreign(nitem)); } encode_attributes(rbml_w, &*nitem.attrs); let stab = stability::lookup(ecx.tcx, ast_util::local_def(nitem.id)); diff --git a/src/librustc/metadata/inline.rs b/src/librustc/metadata/inline.rs new file mode 100644 index 0000000000000..ba09e173fd80d --- /dev/null +++ b/src/librustc/metadata/inline.rs @@ -0,0 +1,64 @@ +// 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 syntax::ast; +use syntax::ast_util::{IdRange, IdRangeComputingVisitor, + IdVisitor, IdVisitingOperation}; +use syntax::ptr::P; +use syntax::visit::Visitor; +use self::InlinedItem::*; + +/// The data we save and restore about an inlined item or method. This is not +/// part of the AST that we parse from a file, but it becomes part of the tree +/// that we trans. +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub enum InlinedItem { + Item(P), + TraitItem(ast::DefId /* impl id */, P), + ImplItem(ast::DefId /* impl id */, P), + Foreign(P), +} + +/// A borrowed version of `ast::InlinedItem`. +pub enum InlinedItemRef<'a> { + Item(&'a ast::Item), + TraitItem(ast::DefId, &'a ast::TraitItem), + ImplItem(ast::DefId, &'a ast::ImplItem), + Foreign(&'a ast::ForeignItem) +} + +impl InlinedItem { + pub fn visit<'ast,V>(&'ast self, visitor: &mut V) + where V: Visitor<'ast> + { + match *self { + Item(ref i) => visitor.visit_item(&**i), + Foreign(ref i) => visitor.visit_foreign_item(&**i), + TraitItem(_, ref ti) => visitor.visit_trait_item(ti), + ImplItem(_, ref ii) => visitor.visit_impl_item(ii), + } + } + + pub fn visit_ids(&self, operation: &mut O) { + let mut id_visitor = IdVisitor { + operation: operation, + pass_through_items: true, + visited_outermost: false, + }; + self.visit(&mut id_visitor); + } + + pub fn compute_id_range(&self) -> IdRange { + let mut visitor = IdRangeComputingVisitor::new(); + self.visit_ids(&mut visitor); + visitor.result() + } +} + diff --git a/src/librustc/metadata/mod.rs b/src/librustc/metadata/mod.rs index 0bf1e6d198fa2..44901eb054791 100644 --- a/src/librustc/metadata/mod.rs +++ b/src/librustc/metadata/mod.rs @@ -19,3 +19,4 @@ pub mod csearch; pub mod loader; pub mod filesearch; pub mod macro_import; +pub mod inline; diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index c064b31173f98..a07b849b400aa 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -17,16 +17,17 @@ use metadata::common as c; use metadata::cstore as cstore; use session::Session; use metadata::decoder; -use middle::def; use metadata::encoder as e; -use middle::region; +use metadata::inline::{InlinedItem, InlinedItemRef}; use metadata::tydecode; use metadata::tydecode::{DefIdSource, NominalType, TypeWithId}; use metadata::tydecode::{RegionParameter, ClosureSource}; use metadata::tyencode; use middle::cast; use middle::check_const::ConstQualif; +use middle::def; use middle::privacy::{AllPublic, LastMod}; +use middle::region; use middle::subst; use middle::subst::VecPerParamSpace; use middle::ty::{self, Ty}; @@ -75,12 +76,12 @@ trait tr_intern { pub fn encode_inlined_item(ecx: &e::EncodeContext, rbml_w: &mut Encoder, - ii: e::InlinedItemRef) { + ii: InlinedItemRef) { let id = match ii { - e::IIItemRef(i) => i.id, - e::IIForeignRef(i) => i.id, - e::IITraitItemRef(_, ti) => ti.id, - e::IIImplItemRef(_, ii) => ii.id, + InlinedItemRef::Item(i) => i.id, + InlinedItemRef::Foreign(i) => i.id, + InlinedItemRef::TraitItem(_, ti) => ti.id, + InlinedItemRef::ImplItem(_, ii) => ii.id, }; debug!("> Encoding inlined item: {} ({:?})", ecx.tcx.map.path_to_string(id), @@ -88,7 +89,7 @@ pub fn encode_inlined_item(ecx: &e::EncodeContext, // Folding could be avoided with a smarter encoder. let ii = simplify_ast(ii); - let id_range = ast_util::compute_id_range_for_inlined_item(&ii); + let id_range = ii.compute_id_range(); rbml_w.start_tag(c::tag_ast as usize); id_range.encode(rbml_w); @@ -124,7 +125,7 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata, tcx: &ty::ctxt<'tcx>, path: Vec, par_doc: rbml::Doc) - -> Result<&'tcx ast::InlinedItem, Vec> { + -> Result<&'tcx InlinedItem, Vec> { match par_doc.opt_child(c::tag_ast) { None => Err(path), Some(ast_doc) => { @@ -150,10 +151,10 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata, let ii = ast_map::map_decoded_item(&dcx.tcx.map, path, raw_ii, dcx); let ident = match *ii { - ast::IIItem(ref i) => i.ident, - ast::IIForeign(ref i) => i.ident, - ast::IITraitItem(_, ref ti) => ti.ident, - ast::IIImplItem(_, ref ii) => ii.ident + InlinedItem::Item(ref i) => i.ident, + InlinedItem::Foreign(ref i) => i.ident, + InlinedItem::TraitItem(_, ref ti) => ti.ident, + InlinedItem::ImplItem(_, ref ii) => ii.ident }; debug!("Fn named: {}", ident); debug!("< Decoded inlined fn: {}::{}", @@ -162,7 +163,7 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata, region::resolve_inlined_item(&tcx.sess, &tcx.region_maps, ii); decode_side_tables(dcx, ast_doc); match *ii { - ast::IIItem(ref i) => { + InlinedItem::Item(ref i) => { debug!(">>> DECODED ITEM >>>\n{}\n<<< DECODED ITEM <<<", syntax::print::pprust::item_to_string(&**i)); } @@ -349,7 +350,7 @@ impl def_id_decoder_helpers for D // We also have to adjust the spans: for now we just insert a dummy span, // but eventually we should add entries to the local codemap as required. -fn encode_ast(rbml_w: &mut Encoder, item: &ast::InlinedItem) { +fn encode_ast(rbml_w: &mut Encoder, item: &InlinedItem) { rbml_w.start_tag(c::tag_tree as usize); item.encode(rbml_w); rbml_w.end_tag(); @@ -399,34 +400,34 @@ impl Folder for NestedItemsDropper { // As it happens, trans relies on the fact that we do not export // nested items, as otherwise it would get confused when translating // inlined items. -fn simplify_ast(ii: e::InlinedItemRef) -> ast::InlinedItem { +fn simplify_ast(ii: InlinedItemRef) -> InlinedItem { let mut fld = NestedItemsDropper; match ii { // HACK we're not dropping items. - e::IIItemRef(i) => { - ast::IIItem(fold::noop_fold_item(P(i.clone()), &mut fld) + InlinedItemRef::Item(i) => { + InlinedItem::Item(fold::noop_fold_item(P(i.clone()), &mut fld) .expect_one("expected one item")) } - e::IITraitItemRef(d, ti) => { - ast::IITraitItem(d, + InlinedItemRef::TraitItem(d, ti) => { + InlinedItem::TraitItem(d, fold::noop_fold_trait_item(P(ti.clone()), &mut fld) .expect_one("noop_fold_trait_item must produce \ exactly one trait item")) } - e::IIImplItemRef(d, ii) => { - ast::IIImplItem(d, + InlinedItemRef::ImplItem(d, ii) => { + InlinedItem::ImplItem(d, fold::noop_fold_impl_item(P(ii.clone()), &mut fld) .expect_one("noop_fold_impl_item must produce \ exactly one impl item")) } - e::IIForeignRef(i) => { - ast::IIForeign(fold::noop_fold_foreign_item(P(i.clone()), &mut fld)) + InlinedItemRef::Foreign(i) => { + InlinedItem::Foreign(fold::noop_fold_foreign_item(P(i.clone()), &mut fld)) } } } -fn decode_ast(par_doc: rbml::Doc) -> ast::InlinedItem { +fn decode_ast(par_doc: rbml::Doc) -> InlinedItem { let chi_doc = par_doc.get(c::tag_tree as usize); let mut d = reader::Decoder::new(chi_doc); Decodable::decode(&mut d).unwrap() @@ -920,9 +921,9 @@ impl<'a, 'b, 'c, 'tcx> ast_util::IdVisitingOperation for fn encode_side_tables_for_ii(ecx: &e::EncodeContext, rbml_w: &mut Encoder, - ii: &ast::InlinedItem) { + ii: &InlinedItem) { rbml_w.start_tag(c::tag_table as usize); - ast_util::visit_ids_for_inlined_item(ii, &mut SideTableEncodingIdVisitor { + ii.visit_ids(&mut SideTableEncodingIdVisitor { ecx: ecx, rbml_w: rbml_w }); @@ -1644,15 +1645,15 @@ fn test_simplification() { return alist {eq_fn: eq_int, data: Vec::new()}; } ).unwrap(); - let item_in = e::IIItemRef(&*item); + let item_in = InlinedItemRef::Item(&*item); let item_out = simplify_ast(item_in); - let item_exp = ast::IIItem(quote_item!(&cx, + let item_exp = InlinedItem::Item(quote_item!(&cx, fn new_int_alist() -> alist { return alist {eq_fn: eq_int, data: Vec::new()}; } ).unwrap()); match (item_out, item_exp) { - (ast::IIItem(item_out), ast::IIItem(item_exp)) => { + (InlinedItem::Item(item_out), InlinedItem::Item(item_exp)) => { assert!(pprust::item_to_string(&*item_out) == pprust::item_to_string(&*item_exp)); } diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index fd1c8d4892a10..a1327df224a97 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -17,6 +17,7 @@ use self::EvalHint::*; use ast_map; use ast_map::blocks::FnLikeNode; use metadata::csearch; +use metadata::inline::InlinedItem; use middle::{astencode, def, infer, subst, traits}; use middle::pat_util::def_to_path; use middle::ty::{self, Ty}; @@ -86,7 +87,7 @@ fn lookup_variant_by_id<'a>(tcx: &'a ty::ctxt, } let expr_id = match csearch::maybe_get_item_ast(tcx, enum_def, Box::new(|a, b, c, d| astencode::decode_inlined_item(a, b, c, d))) { - csearch::FoundAst::Found(&ast::IIItem(ref item)) => match item.node { + csearch::FoundAst::Found(&InlinedItem::Item(ref item)) => match item.node { ast::ItemEnum(ast::EnumDef { ref variants }, _) => { // NOTE this doesn't do the right thing, it compares inlined // NodeId's to the original variant_def's NodeId, but they @@ -161,11 +162,11 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>, let mut used_ref_id = false; let expr_id = match csearch::maybe_get_item_ast(tcx, def_id, Box::new(|a, b, c, d| astencode::decode_inlined_item(a, b, c, d))) { - csearch::FoundAst::Found(&ast::IIItem(ref item)) => match item.node { + csearch::FoundAst::Found(&InlinedItem::Item(ref item)) => match item.node { ast::ItemConst(_, ref const_expr) => Some(const_expr.id), _ => None }, - csearch::FoundAst::Found(&ast::IITraitItem(trait_id, ref ti)) => match ti.node { + csearch::FoundAst::Found(&InlinedItem::TraitItem(trait_id, ref ti)) => match ti.node { ast::ConstTraitItem(_, _) => { used_ref_id = true; match maybe_ref_id { @@ -184,7 +185,7 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>, } _ => None }, - csearch::FoundAst::Found(&ast::IIImplItem(_, ref ii)) => match ii.node { + csearch::FoundAst::Found(&InlinedItem::ImplItem(_, ref ii)) => match ii.node { ast::ConstImplItem(_, ref expr) => Some(expr.id), _ => None }, @@ -217,8 +218,8 @@ fn inline_const_fn_from_external_crate(tcx: &ty::ctxt, def_id: ast::DefId) let fn_id = match csearch::maybe_get_item_ast(tcx, def_id, box |a, b, c, d| astencode::decode_inlined_item(a, b, c, d)) { - csearch::FoundAst::Found(&ast::IIItem(ref item)) => Some(item.id), - csearch::FoundAst::Found(&ast::IIImplItem(_, ref item)) => Some(item.id), + csearch::FoundAst::Found(&InlinedItem::Item(ref item)) => Some(item.id), + csearch::FoundAst::Found(&InlinedItem::ImplItem(_, ref item)) => Some(item.id), _ => None }; tcx.extern_const_fns.borrow_mut().insert(def_id, diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 2a033d36a4777..dafc1e900f3f9 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -17,8 +17,9 @@ //! `middle/typeck/infer/region_inference.rs` use ast_map; -use session::Session; +use metadata::inline::InlinedItem; use middle::ty::{self, Ty}; +use session::Session; use util::nodemap::{FnvHashMap, FnvHashSet, NodeMap}; use std::cell::RefCell; @@ -1231,7 +1232,7 @@ pub fn resolve_crate(sess: &Session, krate: &ast::Crate) -> RegionMaps { pub fn resolve_inlined_item(sess: &Session, region_maps: &RegionMaps, - item: &ast::InlinedItem) { + item: &InlinedItem) { let mut visitor = RegionResolutionVisitor { sess: sess, region_maps: region_maps, @@ -1241,5 +1242,5 @@ pub fn resolve_inlined_item(sess: &Session, var_parent: InnermostDeclaringBlock::None } }; - visit::walk_inlined_item(&mut visitor, item); + item.visit(&mut visitor); } diff --git a/src/librustc_trans/trans/inline.rs b/src/librustc_trans/trans/inline.rs index 01bfc51a5c0de..c6450d06eb66c 100644 --- a/src/librustc_trans/trans/inline.rs +++ b/src/librustc_trans/trans/inline.rs @@ -10,6 +10,7 @@ use llvm::{AvailableExternallyLinkage, InternalLinkage, SetLinkage}; use metadata::csearch; +use metadata::inline::InlinedItem; use middle::astencode; use middle::subst::Substs; use trans::base::{push_ctxt, trans_item, get_item_val, trans_fn}; @@ -48,7 +49,7 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId) ccx.external().borrow_mut().insert(fn_id, None); return None; } - csearch::FoundAst::Found(&ast::IIItem(ref item)) => { + csearch::FoundAst::Found(&InlinedItem::Item(ref item)) => { ccx.external().borrow_mut().insert(fn_id, Some(item.id)); ccx.external_srcs().borrow_mut().insert(item.id, fn_id); @@ -91,12 +92,12 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId) item.id } - csearch::FoundAst::Found(&ast::IIForeign(ref item)) => { + csearch::FoundAst::Found(&InlinedItem::Foreign(ref item)) => { ccx.external().borrow_mut().insert(fn_id, Some(item.id)); ccx.external_srcs().borrow_mut().insert(item.id, fn_id); item.id } - csearch::FoundAst::FoundParent(parent_id, &ast::IIItem(ref item)) => { + csearch::FoundAst::FoundParent(parent_id, &InlinedItem::Item(ref item)) => { ccx.external().borrow_mut().insert(parent_id, Some(item.id)); ccx.external_srcs().borrow_mut().insert(item.id, parent_id); @@ -131,7 +132,7 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId) ccx.sess().bug("maybe_get_item_ast returned a FoundParent \ with a non-item parent"); } - csearch::FoundAst::Found(&ast::IITraitItem(_, ref trait_item)) => { + csearch::FoundAst::Found(&InlinedItem::TraitItem(_, ref trait_item)) => { ccx.external().borrow_mut().insert(fn_id, Some(trait_item.id)); ccx.external_srcs().borrow_mut().insert(trait_item.id, fn_id); @@ -150,7 +151,7 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId) // don't. trait_item.id } - csearch::FoundAst::Found(&ast::IIImplItem(impl_did, ref impl_item)) => { + csearch::FoundAst::Found(&InlinedItem::ImplItem(impl_did, ref impl_item)) => { ccx.external().borrow_mut().insert(fn_id, Some(impl_item.id)); ccx.external_srcs().borrow_mut().insert(impl_item.id, fn_id); diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 08c6dcc7f872a..0bcd97cfe873f 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -23,7 +23,6 @@ pub use self::FloatTy::*; pub use self::FunctionRetTy::*; pub use self::ForeignItem_::*; pub use self::ImplItem_::*; -pub use self::InlinedItem::*; pub use self::IntTy::*; pub use self::Item_::*; pub use self::KleeneOp::*; @@ -1925,17 +1924,6 @@ impl ForeignItem_ { } } -/// The data we save and restore about an inlined item or method. This is not -/// part of the AST that we parse from a file, but it becomes part of the tree -/// that we trans. -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum InlinedItem { - IIItem(P), - IITraitItem(DefId /* impl id */, P), - IIImplItem(DefId /* impl id */, P), - IIForeign(P), -} - /// A macro definition, in this crate or imported from another. /// /// Not parsed directly, but created on macro import or `macro_rules!` expansion. diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 83d3c9c4ec5ea..7aff92ecb7090 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -503,19 +503,18 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> { } } -pub fn visit_ids_for_inlined_item(item: &InlinedItem, - operation: &mut O) { - let mut id_visitor = IdVisitor { - operation: operation, - pass_through_items: true, - visited_outermost: false, - }; - - visit::walk_inlined_item(&mut id_visitor, item); +pub struct IdRangeComputingVisitor { + result: IdRange, } -struct IdRangeComputingVisitor { - result: IdRange, +impl IdRangeComputingVisitor { + pub fn new() -> IdRangeComputingVisitor { + IdRangeComputingVisitor { result: IdRange::max() } + } + + pub fn result(&self) -> IdRange { + self.result + } } impl IdVisitingOperation for IdRangeComputingVisitor { @@ -524,14 +523,6 @@ impl IdVisitingOperation for IdRangeComputingVisitor { } } -pub fn compute_id_range_for_inlined_item(item: &InlinedItem) -> IdRange { - let mut visitor = IdRangeComputingVisitor { - result: IdRange::max() - }; - visit_ids_for_inlined_item(item, &mut visitor); - visitor.result -} - /// Computes the id range for a single fn body, ignoring nested items. pub fn compute_id_range_for_fn_body(fk: visit::FnKind, decl: &FnDecl, @@ -540,9 +531,7 @@ pub fn compute_id_range_for_fn_body(fk: visit::FnKind, id: NodeId) -> IdRange { - let mut visitor = IdRangeComputingVisitor { - result: IdRange::max() - }; + let mut visitor = IdRangeComputingVisitor::new(); let mut id_visitor = IdVisitor { operation: &mut visitor, pass_through_items: false, diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index ad144d6033bd1..259564337a21b 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -142,17 +142,6 @@ pub trait Visitor<'v> : Sized { fn visit_attribute(&mut self, _attr: &'v Attribute) {} } -pub fn walk_inlined_item<'v,V>(visitor: &mut V, item: &'v InlinedItem) - where V: Visitor<'v> { - match *item { - IIItem(ref i) => visitor.visit_item(&**i), - IIForeign(ref i) => visitor.visit_foreign_item(&**i), - IITraitItem(_, ref ti) => visitor.visit_trait_item(ti), - IIImplItem(_, ref ii) => visitor.visit_impl_item(ii), - } -} - - pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate) { visitor.visit_mod(&krate.module, krate.span, CRATE_NODE_ID); for attr in &krate.attrs { From c9bb5a68f866a11a7507ccd4994978ad6d080eb0 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 14 Aug 2015 04:56:07 -0400 Subject: [PATCH 2/7] convert tydecode to use a closure for def-id conversion and to store the closure in the PSState struct --- src/librustc/metadata/tydecode.rs | 401 +++++++++++------------------- 1 file changed, 142 insertions(+), 259 deletions(-) diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index a8b22846b786d..bdeae1c4bc96c 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -57,13 +57,14 @@ pub enum DefIdSource { ClosureSource } -// type conv_did = impl FnMut(DefIdSource, ast::DefId) -> ast::DefId; +pub type DefIdConvert<'a> = &'a mut FnMut(DefIdSource, ast::DefId) -> ast::DefId; pub struct PState<'a, 'tcx: 'a> { data: &'a [u8], krate: ast::CrateNum, pos: usize, - tcx: &'a ty::ctxt<'tcx> + tcx: &'a ty::ctxt<'tcx>, + conv_def_id: DefIdConvert<'a>, } fn peek(st: &PState) -> char { @@ -82,9 +83,8 @@ fn next_byte(st: &mut PState) -> u8 { return b; } -fn scan(st: &mut PState, mut is_last: F, op: G) -> R where +fn scan<'a, 'tcx, F>(st: &mut PState<'a,'tcx>, mut is_last: F) -> &'a [u8] where F: FnMut(char) -> bool, - G: FnOnce(&[u8]) -> R, { let start_pos = st.pos; debug!("scan: '{}' (start)", st.data[st.pos] as char); @@ -94,30 +94,27 @@ fn scan(st: &mut PState, mut is_last: F, op: G) -> R where } let end_pos = st.pos; st.pos += 1; - return op(&st.data[start_pos..end_pos]); + return &st.data[start_pos..end_pos]; } pub fn parse_name(st: &mut PState, last: char) -> ast::Name { fn is_last(b: char, c: char) -> bool { return c == b; } - parse_name_(st, |a| is_last(last, a) ) + let bytes = scan(st, |a| is_last(last, a)); + token::intern(str::from_utf8(bytes).unwrap()) } -fn parse_name_(st: &mut PState, is_last: F) -> ast::Name where - F: FnMut(char) -> bool, -{ - scan(st, is_last, |bytes| { - token::intern(str::from_utf8(bytes).unwrap()) - }) -} - -pub fn parse_state_from_data<'a, 'tcx>(data: &'a [u8], crate_num: ast::CrateNum, - pos: usize, tcx: &'a ty::ctxt<'tcx>) +pub fn parse_state_from_data<'a, 'tcx>(data: &'a [u8], + crate_num: ast::CrateNum, + pos: usize, + tcx: &'a ty::ctxt<'tcx>, + conv: DefIdConvert<'a>) -> PState<'a, 'tcx> { PState { data: data, krate: crate_num, pos: pos, - tcx: tcx + tcx: tcx, + conv_def_id: conv, } } @@ -140,77 +137,77 @@ pub fn parse_ty_closure_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: usize, tcx: &ty::ctxt<'tcx>, - conv: F) + mut conv: F) -> ty::ClosureTy<'tcx> where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, { - let mut st = parse_state_from_data(data, crate_num, pos, tcx); - parse_closure_ty(&mut st, conv) + let mut st = parse_state_from_data(data, crate_num, pos, tcx, &mut conv); + parse_closure_ty(&mut st) } pub fn parse_ty_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: usize, - tcx: &ty::ctxt<'tcx>, conv: F) -> Ty<'tcx> where + tcx: &ty::ctxt<'tcx>, mut conv: F) -> Ty<'tcx> where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, { debug!("parse_ty_data {}", data_log_string(data, pos)); - let mut st = parse_state_from_data(data, crate_num, pos, tcx); - parse_ty(&mut st, conv) + let mut st = parse_state_from_data(data, crate_num, pos, tcx, &mut conv); + parse_ty(&mut st) } pub fn parse_region_data(data: &[u8], crate_num: ast::CrateNum, pos: usize, tcx: &ty::ctxt, - conv: F) -> ty::Region where + mut conv: F) -> ty::Region where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, { debug!("parse_region_data {}", data_log_string(data, pos)); - let mut st = parse_state_from_data(data, crate_num, pos, tcx); - parse_region(&mut st, conv) + let mut st = parse_state_from_data(data, crate_num, pos, tcx, &mut conv); + parse_region(&mut st) } pub fn parse_bare_fn_ty_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: usize, - tcx: &ty::ctxt<'tcx>, conv: F) + tcx: &ty::ctxt<'tcx>, mut conv: F) -> ty::BareFnTy<'tcx> where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, { debug!("parse_bare_fn_ty_data {}", data_log_string(data, pos)); - let mut st = parse_state_from_data(data, crate_num, pos, tcx); - parse_bare_fn_ty(&mut st, conv) + let mut st = parse_state_from_data(data, crate_num, pos, tcx, &mut conv); + parse_bare_fn_ty(&mut st) } pub fn parse_trait_ref_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: usize, - tcx: &ty::ctxt<'tcx>, conv: F) + tcx: &ty::ctxt<'tcx>, mut conv: F) -> ty::TraitRef<'tcx> where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, { debug!("parse_trait_ref_data {}", data_log_string(data, pos)); - let mut st = parse_state_from_data(data, crate_num, pos, tcx); - parse_trait_ref(&mut st, conv) + let mut st = parse_state_from_data(data, crate_num, pos, tcx, &mut conv); + parse_trait_ref(&mut st) } pub fn parse_substs_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: usize, - tcx: &ty::ctxt<'tcx>, conv: F) -> subst::Substs<'tcx> where + tcx: &ty::ctxt<'tcx>, mut conv: F) -> subst::Substs<'tcx> where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, { debug!("parse_substs_data{}", data_log_string(data, pos)); - let mut st = parse_state_from_data(data, crate_num, pos, tcx); - parse_substs(&mut st, conv) + let mut st = parse_state_from_data(data, crate_num, pos, tcx, &mut conv); + parse_substs(&mut st) } pub fn parse_existential_bounds_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, - pos: usize, tcx: &ty::ctxt<'tcx>, conv: F) + pos: usize, tcx: &ty::ctxt<'tcx>, mut conv: F) -> ty::ExistentialBounds<'tcx> where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, { - let mut st = parse_state_from_data(data, crate_num, pos, tcx); - parse_existential_bounds(&mut st, conv) + let mut st = parse_state_from_data(data, crate_num, pos, tcx, &mut conv); + parse_existential_bounds(&mut st) } pub fn parse_builtin_bounds_data(data: &[u8], crate_num: ast::CrateNum, - pos: usize, tcx: &ty::ctxt, conv: F) + pos: usize, tcx: &ty::ctxt, mut conv: F) -> ty::BuiltinBounds where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, { - let mut st = parse_state_from_data(data, crate_num, pos, tcx); - parse_builtin_bounds(&mut st, conv) + let mut st = parse_state_from_data(data, crate_num, pos, tcx, &mut conv); + parse_builtin_bounds(&mut st) } fn parse_size(st: &mut PState) -> Option { @@ -242,44 +239,25 @@ fn parse_vec_per_param_space<'a, 'tcx, T, F>(st: &mut PState<'a, 'tcx>, r } -fn parse_substs<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, - mut conv: F) -> subst::Substs<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - parse_substs_(st, &mut conv) +fn parse_substs<'a, 'tcx>(st: &mut PState<'a, 'tcx>) -> subst::Substs<'tcx> { + let regions = parse_region_substs(st); + let types = parse_vec_per_param_space(st, |st| parse_ty(st)); + subst::Substs { types: types, regions: regions } } -fn parse_substs_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, - conv: &mut F) -> subst::Substs<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - let regions = - parse_region_substs_(st, conv); - - let types = - parse_vec_per_param_space(st, |st| parse_ty_(st, conv)); - - subst::Substs { types: types, - regions: regions } -} - -fn parse_region_substs_(st: &mut PState, conv: &mut F) -> subst::RegionSubsts where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ +fn parse_region_substs(st: &mut PState) -> subst::RegionSubsts { match next(st) { 'e' => subst::ErasedRegions, 'n' => { subst::NonerasedRegions( parse_vec_per_param_space( - st, |st| parse_region_(st, conv))) + st, |st| parse_region(st))) } _ => panic!("parse_bound_region: bad input") } } -fn parse_bound_region_(st: &mut PState, conv: &mut F) -> ty::BoundRegion where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ +fn parse_bound_region(st: &mut PState) -> ty::BoundRegion { match next(st) { 'a' => { let id = parse_u32(st); @@ -287,7 +265,7 @@ fn parse_bound_region_(st: &mut PState, conv: &mut F) -> ty::BoundRegion wher ty::BrAnon(id) } '[' => { - let def = parse_def_(st, RegionParameter, conv); + let def = parse_def(st, RegionParameter); let ident = token::str_to_ident(&parse_str(st, ']')); ty::BrNamed(def, ident.name) } @@ -301,21 +279,13 @@ fn parse_bound_region_(st: &mut PState, conv: &mut F) -> ty::BoundRegion wher } } -fn parse_region(st: &mut PState, mut conv: F) -> ty::Region where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - parse_region_(st, &mut conv) -} - -fn parse_region_(st: &mut PState, conv: &mut F) -> ty::Region where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ +fn parse_region(st: &mut PState) -> ty::Region { match next(st) { 'b' => { assert_eq!(next(st), '['); let id = ty::DebruijnIndex::new(parse_u32(st)); assert_eq!(next(st), '|'); - let br = parse_bound_region_(st, conv); + let br = parse_bound_region(st); assert_eq!(next(st), ']'); ty::ReLateBound(id, br) } @@ -339,7 +309,7 @@ fn parse_region_(st: &mut PState, conv: &mut F) -> ty::Region where assert_eq!(next(st), '['); let scope = parse_destruction_scope_data(st); assert_eq!(next(st), '|'); - let br = parse_bound_region_(st, conv); + let br = parse_bound_region(st); assert_eq!(next(st), ']'); ty::ReFree(ty::FreeRegion { scope: scope, bound_region: br}) @@ -420,31 +390,13 @@ fn parse_str(st: &mut PState, term: char) -> String { result } -fn parse_trait_ref<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, mut conv: F) - -> ty::TraitRef<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - parse_trait_ref_(st, &mut conv) -} - -fn parse_trait_ref_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) - -> ty::TraitRef<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - let def = parse_def_(st, NominalType, conv); - let substs = st.tcx.mk_substs(parse_substs_(st, conv)); +fn parse_trait_ref<'a, 'tcx>(st: &mut PState<'a, 'tcx>) -> ty::TraitRef<'tcx> { + let def = parse_def(st, NominalType); + let substs = st.tcx.mk_substs(parse_substs(st)); ty::TraitRef {def_id: def, substs: substs} } -fn parse_ty<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, mut conv: F) -> Ty<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - parse_ty_(st, &mut conv) -} - -fn parse_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> Ty<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ +fn parse_ty<'a, 'tcx>(st: &mut PState<'a, 'tcx>) -> Ty<'tcx> { let tcx = st.tcx; match next(st) { 'b' => return tcx.types.bool, @@ -468,16 +420,16 @@ fn parse_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> Ty<'tcx> w 'c' => return tcx.types.char, 't' => { assert_eq!(next(st), '['); - let did = parse_def_(st, NominalType, conv); - let substs = parse_substs_(st, conv); + let did = parse_def(st, NominalType); + let substs = parse_substs(st); assert_eq!(next(st), ']'); let def = st.tcx.lookup_adt_def(did); return tcx.mk_enum(def, st.tcx.mk_substs(substs)); } 'x' => { assert_eq!(next(st), '['); - let trait_ref = ty::Binder(parse_trait_ref_(st, conv)); - let bounds = parse_existential_bounds_(st, conv); + let trait_ref = ty::Binder(parse_trait_ref(st)); + let bounds = parse_existential_bounds(st); assert_eq!(next(st), ']'); return tcx.mk_trait(trait_ref, bounds); } @@ -490,15 +442,15 @@ fn parse_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> Ty<'tcx> w let name = token::intern(&parse_str(st, ']')); return tcx.mk_param(space, index, name); } - '~' => return tcx.mk_box(parse_ty_(st, conv)), - '*' => return tcx.mk_ptr(parse_mt_(st, conv)), + '~' => return tcx.mk_box(parse_ty(st)), + '*' => return tcx.mk_ptr(parse_mt(st)), '&' => { - let r = parse_region_(st, conv); - let mt = parse_mt_(st, conv); + let r = parse_region(st); + let mt = parse_mt(st); return tcx.mk_ref(tcx.mk_region(r), mt); } 'V' => { - let t = parse_ty_(st, conv); + let t = parse_ty(st); return match parse_size(st) { Some(n) => tcx.mk_array(t, n), None => tcx.mk_slice(t) @@ -510,26 +462,31 @@ fn parse_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> Ty<'tcx> w 'T' => { assert_eq!(next(st), '['); let mut params = Vec::new(); - while peek(st) != ']' { params.push(parse_ty_(st, conv)); } + while peek(st) != ']' { params.push(parse_ty(st)); } st.pos = st.pos + 1; return tcx.mk_tup(params); } 'F' => { - let def_id = parse_def_(st, NominalType, conv); - return tcx.mk_fn(Some(def_id), tcx.mk_bare_fn(parse_bare_fn_ty_(st, conv))); + let def_id = parse_def(st, NominalType); + return tcx.mk_fn(Some(def_id), tcx.mk_bare_fn(parse_bare_fn_ty(st))); } 'G' => { - return tcx.mk_fn(None, tcx.mk_bare_fn(parse_bare_fn_ty_(st, conv))); + return tcx.mk_fn(None, tcx.mk_bare_fn(parse_bare_fn_ty(st))); } '#' => { + // This is a hacky little caching scheme. The idea is that if we encode + // the same type twice, the second (and third, and fourth...) time we will + // just write `#123`, where `123` is the offset in the metadata of the + // first appearance. Now when we are *decoding*, if we see a `#123`, we + // can first check a cache (`tcx.rcache`) for that offset. If we find something, + // we return it (modulo closure types, see below). But if not, then we + // jump to offset 123 and read the type from there. + let pos = parse_hex(st); assert_eq!(next(st), ':'); let len = parse_hex(st); assert_eq!(next(st), '#'); - let key = ty::CReaderCacheKey {cnum: st.krate, - pos: pos, - len: len }; - + let key = ty::CReaderCacheKey {cnum: st.krate, pos: pos, len: len }; match tcx.rcache.borrow().get(&key).cloned() { Some(tt) => { // If there is a closure buried in the type some where, then we @@ -541,34 +498,39 @@ fn parse_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> Ty<'tcx> w } None => {} } + let mut ps = PState { pos: pos, - .. *st + conv_def_id: st.conv_def_id, // -+ Have to call out these fields specifically, + tcx: st.tcx, // | rather than writing `..*st`, so that we + data: st.data, // | trigger reborrow coercions. Suboptimal, + krate: st.krate, // -+ I suppose. }; - let tt = parse_ty_(&mut ps, conv); + + let tt = parse_ty(&mut ps); tcx.rcache.borrow_mut().insert(key, tt); return tt; } '\"' => { - let _ = parse_def_(st, TypeWithId, conv); - let inner = parse_ty_(st, conv); + let _ = parse_def(st, TypeWithId); + let inner = parse_ty(st); inner } 'a' => { assert_eq!(next(st), '['); - let did = parse_def_(st, NominalType, conv); - let substs = parse_substs_(st, conv); + let did = parse_def(st, NominalType); + let substs = parse_substs(st); assert_eq!(next(st), ']'); let def = st.tcx.lookup_adt_def(did); return st.tcx.mk_struct(def, st.tcx.mk_substs(substs)); } 'k' => { assert_eq!(next(st), '['); - let did = parse_def_(st, ClosureSource, conv); - let substs = parse_substs_(st, conv); + let did = parse_def(st, ClosureSource); + let substs = parse_substs(st); let mut tys = vec![]; while peek(st) != '.' { - tys.push(parse_ty_(st, conv)); + tys.push(parse_ty(st)); } assert_eq!(next(st), '.'); assert_eq!(next(st), ']'); @@ -576,7 +538,7 @@ fn parse_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> Ty<'tcx> w } 'P' => { assert_eq!(next(st), '['); - let trait_ref = parse_trait_ref_(st, conv); + let trait_ref = parse_trait_ref(st); let name = token::intern(&parse_str(st, ']')); return tcx.mk_projection(trait_ref, name); } @@ -594,17 +556,14 @@ fn parse_mutability(st: &mut PState) -> ast::Mutability { } } -fn parse_mt_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> ty::TypeAndMut<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ +fn parse_mt<'a, 'tcx>(st: &mut PState<'a, 'tcx>) -> ty::TypeAndMut<'tcx> { let m = parse_mutability(st); - ty::TypeAndMut { ty: parse_ty_(st, conv), mutbl: m } + ty::TypeAndMut { ty: parse_ty(st), mutbl: m } } -fn parse_def_(st: &mut PState, source: DefIdSource, conv: &mut F) -> ast::DefId where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - return (*conv)(source, scan(st, |c| { c == '|' }, parse_def_id)); +fn parse_def(st: &mut PState, source: DefIdSource) -> ast::DefId { + let def_id = parse_defid(scan(st, |c| c == '|')); + return (st.conv_def_id)(source, def_id); } fn parse_uint(st: &mut PState) -> usize { @@ -652,25 +611,14 @@ fn parse_unsafety(c: char) -> ast::Unsafety { fn parse_abi_set(st: &mut PState) -> abi::Abi { assert_eq!(next(st), '['); - scan(st, |c| c == ']', |bytes| { - let abi_str = str::from_utf8(bytes).unwrap(); - abi::lookup(&abi_str[..]).expect(abi_str) - }) + let bytes = scan(st, |c| c == ']'); + let abi_str = str::from_utf8(bytes).unwrap(); + abi::lookup(&abi_str[..]).expect(abi_str) } -fn parse_closure_ty<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, - mut conv: F) -> ty::ClosureTy<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - parse_closure_ty_(st, &mut conv) -} - -fn parse_closure_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, - conv: &mut F) -> ty::ClosureTy<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ +fn parse_closure_ty<'a, 'tcx>(st: &mut PState<'a, 'tcx>) -> ty::ClosureTy<'tcx> { let unsafety = parse_unsafety(next(st)); - let sig = parse_sig_(st, conv); + let sig = parse_sig(st); let abi = parse_abi_set(st); ty::ClosureTy { unsafety: unsafety, @@ -679,20 +627,10 @@ fn parse_closure_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, } } -fn parse_bare_fn_ty<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, - mut conv: F) -> ty::BareFnTy<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - parse_bare_fn_ty_(st, &mut conv) -} - -fn parse_bare_fn_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, - conv: &mut F) -> ty::BareFnTy<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ +fn parse_bare_fn_ty<'a, 'tcx>(st: &mut PState<'a, 'tcx>) -> ty::BareFnTy<'tcx> { let unsafety = parse_unsafety(next(st)); let abi = parse_abi_set(st); - let sig = parse_sig_(st, conv); + let sig = parse_sig(st); ty::BareFnTy { unsafety: unsafety, abi: abi, @@ -700,13 +638,11 @@ fn parse_bare_fn_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, } } -fn parse_sig_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> ty::PolyFnSig<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ +fn parse_sig<'a, 'tcx>(st: &mut PState<'a, 'tcx>) -> ty::PolyFnSig<'tcx> { assert_eq!(next(st), '['); let mut inputs = Vec::new(); while peek(st) != ']' { - inputs.push(parse_ty_(st, conv)); + inputs.push(parse_ty(st)); } st.pos += 1; // eat the ']' let variadic = match next(st) { @@ -719,15 +655,15 @@ fn parse_sig_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> ty::PolyF st.pos += 1; ty::FnDiverging } - _ => ty::FnConverging(parse_ty_(st, conv)) + _ => ty::FnConverging(parse_ty(st)) }; ty::Binder(ty::FnSig {inputs: inputs, - output: output, - variadic: variadic}) + output: output, + variadic: variadic}) } // Rust metadata parsing -pub fn parse_def_id(buf: &[u8]) -> ast::DefId { +pub fn parse_defid(buf: &[u8]) -> ast::DefId { let mut colon_idx = 0; let len = buf.len(); while colon_idx < len && buf[colon_idx] != ':' as u8 { colon_idx += 1; } @@ -743,14 +679,14 @@ pub fn parse_def_id(buf: &[u8]) -> ast::DefId { s.parse::().ok() }) { Some(cn) => cn as ast::CrateNum, - None => panic!("internal error: parse_def_id: crate number expected, found {:?}", + None => panic!("internal error: parse_defid: crate number expected, found {:?}", crate_part) }; let def_num = match str::from_utf8(def_part).ok().and_then(|s| { s.parse::().ok() }) { Some(dn) => dn as ast::NodeId, - None => panic!("internal error: parse_def_id: id expected, found {:?}", + None => panic!("internal error: parse_defid: id expected, found {:?}", def_part) }; ast::DefId { krate: crate_num, node: def_num } @@ -760,39 +696,27 @@ pub fn parse_predicate_data<'tcx, F>(data: &[u8], start: usize, crate_num: ast::CrateNum, tcx: &ty::ctxt<'tcx>, - conv: F) + mut conv: F) -> ty::Predicate<'tcx> where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, { - let mut st = parse_state_from_data(data, crate_num, start, tcx); - parse_predicate(&mut st, conv) -} - -pub fn parse_predicate<'a,'tcx, F>(st: &mut PState<'a, 'tcx>, - mut conv: F) - -> ty::Predicate<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - parse_predicate_(st, &mut conv) + let mut st = parse_state_from_data(data, crate_num, start, tcx, &mut conv); + parse_predicate(&mut st) } -fn parse_predicate_<'a,'tcx, F>(st: &mut PState<'a, 'tcx>, - conv: &mut F) - -> ty::Predicate<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ +pub fn parse_predicate<'a,'tcx>(st: &mut PState<'a, 'tcx>) -> ty::Predicate<'tcx> { match next(st) { - 't' => ty::Binder(parse_trait_ref_(st, conv)).to_predicate(), - 'e' => ty::Binder(ty::EquatePredicate(parse_ty_(st, conv), - parse_ty_(st, conv))).to_predicate(), - 'r' => ty::Binder(ty::OutlivesPredicate(parse_region_(st, conv), - parse_region_(st, conv))).to_predicate(), - 'o' => ty::Binder(ty::OutlivesPredicate(parse_ty_(st, conv), - parse_region_(st, conv))).to_predicate(), - 'p' => ty::Binder(parse_projection_predicate_(st, conv)).to_predicate(), - 'w' => ty::Predicate::WellFormed(parse_ty_(st, conv)), + 't' => ty::Binder(parse_trait_ref(st)).to_predicate(), + 'e' => ty::Binder(ty::EquatePredicate(parse_ty(st), + parse_ty(st))).to_predicate(), + 'r' => ty::Binder(ty::OutlivesPredicate(parse_region(st), + parse_region(st))).to_predicate(), + 'o' => ty::Binder(ty::OutlivesPredicate(parse_ty(st), + parse_region(st))).to_predicate(), + 'p' => ty::Binder(parse_projection_predicate(st)).to_predicate(), + 'w' => ty::Predicate::WellFormed(parse_ty(st)), 'O' => { - let def_id = parse_def_(st, NominalType, conv); + let def_id = parse_def(st, NominalType); assert_eq!(next(st), '|'); ty::Predicate::ObjectSafe(def_id) } @@ -800,50 +724,35 @@ fn parse_predicate_<'a,'tcx, F>(st: &mut PState<'a, 'tcx>, } } -fn parse_projection_predicate_<'a,'tcx, F>( - st: &mut PState<'a, 'tcx>, - conv: &mut F, -) -> ty::ProjectionPredicate<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ +fn parse_projection_predicate<'a,'tcx>(st: &mut PState<'a, 'tcx>) -> ty::ProjectionPredicate<'tcx> { ty::ProjectionPredicate { projection_ty: ty::ProjectionTy { - trait_ref: parse_trait_ref_(st, conv), + trait_ref: parse_trait_ref(st), item_name: token::str_to_ident(&parse_str(st, '|')).name, }, - ty: parse_ty_(st, conv), + ty: parse_ty(st), } } pub fn parse_type_param_def_data<'tcx, F>(data: &[u8], start: usize, crate_num: ast::CrateNum, tcx: &ty::ctxt<'tcx>, - conv: F) -> ty::TypeParameterDef<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - let mut st = parse_state_from_data(data, crate_num, start, tcx); - parse_type_param_def(&mut st, conv) -} - -fn parse_type_param_def<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, mut conv: F) - -> ty::TypeParameterDef<'tcx> where + mut conv: F) -> ty::TypeParameterDef<'tcx> where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, { - parse_type_param_def_(st, &mut conv) + let mut st = parse_state_from_data(data, crate_num, start, tcx, &mut conv); + parse_type_param_def(&mut st) } -fn parse_type_param_def_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) - -> ty::TypeParameterDef<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ +fn parse_type_param_def<'a, 'tcx>(st: &mut PState<'a, 'tcx>) -> ty::TypeParameterDef<'tcx> { let name = parse_name(st, ':'); - let def_id = parse_def_(st, NominalType, conv); + let def_id = parse_def(st, NominalType); let space = parse_param_space(st); assert_eq!(next(st), '|'); let index = parse_u32(st); assert_eq!(next(st), '|'); - let default_def_id = parse_def_(st, NominalType, conv); - let default = parse_opt(st, |st| parse_ty_(st, conv)); - let object_lifetime_default = parse_object_lifetime_default(st, conv); + let default_def_id = parse_def(st, NominalType); + let default = parse_opt(st, |st| parse_ty(st)); + let object_lifetime_default = parse_object_lifetime_default(st); ty::TypeParameterDef { name: name, @@ -856,44 +765,27 @@ fn parse_type_param_def_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) } } -fn parse_object_lifetime_default<'a,'tcx, F>(st: &mut PState<'a,'tcx>, - conv: &mut F) - -> ty::ObjectLifetimeDefault - where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ +fn parse_object_lifetime_default<'a,'tcx>(st: &mut PState<'a,'tcx>) -> ty::ObjectLifetimeDefault { match next(st) { 'a' => ty::ObjectLifetimeDefault::Ambiguous, 'b' => ty::ObjectLifetimeDefault::BaseDefault, 's' => { - let region = parse_region_(st, conv); + let region = parse_region(st); ty::ObjectLifetimeDefault::Specific(region) } _ => panic!("parse_object_lifetime_default: bad input") } } -fn parse_existential_bounds<'a,'tcx, F>(st: &mut PState<'a,'tcx>, - mut conv: F) - -> ty::ExistentialBounds<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - parse_existential_bounds_(st, &mut conv) -} - -fn parse_existential_bounds_<'a,'tcx, F>(st: &mut PState<'a,'tcx>, - conv: &mut F) - -> ty::ExistentialBounds<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - let builtin_bounds = parse_builtin_bounds_(st, conv); - let region_bound = parse_region_(st, conv); +fn parse_existential_bounds<'a,'tcx>(st: &mut PState<'a,'tcx>) -> ty::ExistentialBounds<'tcx> { + let builtin_bounds = parse_builtin_bounds(st); + let region_bound = parse_region(st); let mut projection_bounds = Vec::new(); loop { match next(st) { 'P' => { - projection_bounds.push( - ty::Binder(parse_projection_predicate_(st, conv))); + projection_bounds.push(ty::Binder(parse_projection_predicate(st))); } '.' => { break; } c => { @@ -907,17 +799,8 @@ fn parse_existential_bounds_<'a,'tcx, F>(st: &mut PState<'a,'tcx>, projection_bounds: projection_bounds }; } -fn parse_builtin_bounds(st: &mut PState, mut _conv: F) -> ty::BuiltinBounds where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - parse_builtin_bounds_(st, &mut _conv) -} - -fn parse_builtin_bounds_(st: &mut PState, _conv: &mut F) -> ty::BuiltinBounds where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ +fn parse_builtin_bounds(st: &mut PState) -> ty::BuiltinBounds { let mut builtin_bounds = ty::BuiltinBounds::empty(); - loop { match next(st) { 'S' => { From 2a53744aaacb7bdaba2a20b49f7bf484222f5813 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 14 Aug 2015 05:11:54 -0400 Subject: [PATCH 3/7] convert tydecode to use an impl, eliminating a lot of boilerplate --- src/librustc/metadata/tydecode.rs | 1239 ++++++++++++++--------------- 1 file changed, 618 insertions(+), 621 deletions(-) diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index bdeae1c4bc96c..2ddb0697c171b 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -57,82 +57,6 @@ pub enum DefIdSource { ClosureSource } -pub type DefIdConvert<'a> = &'a mut FnMut(DefIdSource, ast::DefId) -> ast::DefId; - -pub struct PState<'a, 'tcx: 'a> { - data: &'a [u8], - krate: ast::CrateNum, - pos: usize, - tcx: &'a ty::ctxt<'tcx>, - conv_def_id: DefIdConvert<'a>, -} - -fn peek(st: &PState) -> char { - st.data[st.pos] as char -} - -fn next(st: &mut PState) -> char { - let ch = st.data[st.pos] as char; - st.pos = st.pos + 1; - return ch; -} - -fn next_byte(st: &mut PState) -> u8 { - let b = st.data[st.pos]; - st.pos = st.pos + 1; - return b; -} - -fn scan<'a, 'tcx, F>(st: &mut PState<'a,'tcx>, mut is_last: F) -> &'a [u8] where - F: FnMut(char) -> bool, -{ - let start_pos = st.pos; - debug!("scan: '{}' (start)", st.data[st.pos] as char); - while !is_last(st.data[st.pos] as char) { - st.pos += 1; - debug!("scan: '{}'", st.data[st.pos] as char); - } - let end_pos = st.pos; - st.pos += 1; - return &st.data[start_pos..end_pos]; -} - -pub fn parse_name(st: &mut PState, last: char) -> ast::Name { - fn is_last(b: char, c: char) -> bool { return c == b; } - let bytes = scan(st, |a| is_last(last, a)); - token::intern(str::from_utf8(bytes).unwrap()) -} - -pub fn parse_state_from_data<'a, 'tcx>(data: &'a [u8], - crate_num: ast::CrateNum, - pos: usize, - tcx: &'a ty::ctxt<'tcx>, - conv: DefIdConvert<'a>) - -> PState<'a, 'tcx> { - PState { - data: data, - krate: crate_num, - pos: pos, - tcx: tcx, - conv_def_id: conv, - } -} - -fn data_log_string(data: &[u8], pos: usize) -> String { - let mut buf = String::new(); - buf.push_str("<<"); - for i in pos..data.len() { - let c = data[i]; - if c > 0x20 && c <= 0x7F { - buf.push(c as char); - } else { - buf.push('.'); - } - } - buf.push_str(">>"); - buf -} - pub fn parse_ty_closure_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: usize, @@ -141,8 +65,8 @@ pub fn parse_ty_closure_data<'tcx, F>(data: &[u8], -> ty::ClosureTy<'tcx> where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, { - let mut st = parse_state_from_data(data, crate_num, pos, tcx, &mut conv); - parse_closure_ty(&mut st) + let mut st = PState::new(data, crate_num, pos, tcx, &mut conv); + st.parse_closure_ty() } pub fn parse_ty_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: usize, @@ -150,8 +74,8 @@ pub fn parse_ty_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: usize, F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, { debug!("parse_ty_data {}", data_log_string(data, pos)); - let mut st = parse_state_from_data(data, crate_num, pos, tcx, &mut conv); - parse_ty(&mut st) + let mut st = PState::new(data, crate_num, pos, tcx, &mut conv); + st.parse_ty() } pub fn parse_region_data(data: &[u8], crate_num: ast::CrateNum, pos: usize, tcx: &ty::ctxt, @@ -159,8 +83,8 @@ pub fn parse_region_data(data: &[u8], crate_num: ast::CrateNum, pos: usize, t F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, { debug!("parse_region_data {}", data_log_string(data, pos)); - let mut st = parse_state_from_data(data, crate_num, pos, tcx, &mut conv); - parse_region(&mut st) + let mut st = PState::new(data, crate_num, pos, tcx, &mut conv); + st.parse_region() } pub fn parse_bare_fn_ty_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: usize, @@ -169,8 +93,8 @@ pub fn parse_bare_fn_ty_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, { debug!("parse_bare_fn_ty_data {}", data_log_string(data, pos)); - let mut st = parse_state_from_data(data, crate_num, pos, tcx, &mut conv); - parse_bare_fn_ty(&mut st) + let mut st = PState::new(data, crate_num, pos, tcx, &mut conv); + st.parse_bare_fn_ty() } pub fn parse_trait_ref_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: usize, @@ -179,8 +103,8 @@ pub fn parse_trait_ref_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, { debug!("parse_trait_ref_data {}", data_log_string(data, pos)); - let mut st = parse_state_from_data(data, crate_num, pos, tcx, &mut conv); - parse_trait_ref(&mut st) + let mut st = PState::new(data, crate_num, pos, tcx, &mut conv); + st.parse_trait_ref() } pub fn parse_substs_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: usize, @@ -188,8 +112,8 @@ pub fn parse_substs_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: us F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, { debug!("parse_substs_data{}", data_log_string(data, pos)); - let mut st = parse_state_from_data(data, crate_num, pos, tcx, &mut conv); - parse_substs(&mut st) + let mut st = PState::new(data, crate_num, pos, tcx, &mut conv); + st.parse_substs() } pub fn parse_existential_bounds_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, @@ -197,8 +121,8 @@ pub fn parse_existential_bounds_data<'tcx, F>(data: &[u8], crate_num: ast::Crate -> ty::ExistentialBounds<'tcx> where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, { - let mut st = parse_state_from_data(data, crate_num, pos, tcx, &mut conv); - parse_existential_bounds(&mut st) + let mut st = PState::new(data, crate_num, pos, tcx, &mut conv); + st.parse_existential_bounds() } pub fn parse_builtin_bounds_data(data: &[u8], crate_num: ast::CrateNum, @@ -206,460 +130,657 @@ pub fn parse_builtin_bounds_data(data: &[u8], crate_num: ast::CrateNum, -> ty::BuiltinBounds where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, { - let mut st = parse_state_from_data(data, crate_num, pos, tcx, &mut conv); - parse_builtin_bounds(&mut st) + let mut st = PState::new(data, crate_num, pos, tcx, &mut conv); + st.parse_builtin_bounds() } -fn parse_size(st: &mut PState) -> Option { - assert_eq!(next(st), '/'); - - if peek(st) == '|' { - assert_eq!(next(st), '|'); - None - } else { - let n = parse_uint(st); - assert_eq!(next(st), '|'); - Some(n) - } +pub fn parse_type_param_def_data<'tcx, F>(data: &[u8], start: usize, + crate_num: ast::CrateNum, tcx: &ty::ctxt<'tcx>, + mut conv: F) -> ty::TypeParameterDef<'tcx> where + F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, +{ + let mut st = PState::new(data, crate_num, start, tcx, &mut conv); + st.parse_type_param_def() } -fn parse_vec_per_param_space<'a, 'tcx, T, F>(st: &mut PState<'a, 'tcx>, - mut f: F) - -> VecPerParamSpace where - F: FnMut(&mut PState<'a, 'tcx>) -> T, +pub fn parse_predicate_data<'tcx, F>(data: &[u8], + start: usize, + crate_num: ast::CrateNum, + tcx: &ty::ctxt<'tcx>, + mut conv: F) + -> ty::Predicate<'tcx> where + F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, { - let mut r = VecPerParamSpace::empty(); - for &space in &subst::ParamSpace::all() { - assert_eq!(next(st), '['); - while peek(st) != ']' { - r.push(space, f(st)); - } - assert_eq!(next(st), ']'); - } - r + let mut st = PState::new(data, crate_num, start, tcx, &mut conv); + st.parse_predicate() } -fn parse_substs<'a, 'tcx>(st: &mut PState<'a, 'tcx>) -> subst::Substs<'tcx> { - let regions = parse_region_substs(st); - let types = parse_vec_per_param_space(st, |st| parse_ty(st)); - subst::Substs { types: types, regions: regions } +pub type DefIdConvert<'a> = &'a mut FnMut(DefIdSource, ast::DefId) -> ast::DefId; + +pub struct PState<'a, 'tcx: 'a> { + data: &'a [u8], + krate: ast::CrateNum, + pos: usize, + tcx: &'a ty::ctxt<'tcx>, + conv_def_id: DefIdConvert<'a>, } -fn parse_region_substs(st: &mut PState) -> subst::RegionSubsts { - match next(st) { - 'e' => subst::ErasedRegions, - 'n' => { - subst::NonerasedRegions( - parse_vec_per_param_space( - st, |st| parse_region(st))) +impl<'a,'tcx> PState<'a,'tcx> { + pub fn new(data: &'a [u8], + crate_num: ast::CrateNum, + pos: usize, + tcx: &'a ty::ctxt<'tcx>, + conv: DefIdConvert<'a>) + -> PState<'a, 'tcx> { + PState { + data: data, + krate: crate_num, + pos: pos, + tcx: tcx, + conv_def_id: conv, } - _ => panic!("parse_bound_region: bad input") } -} -fn parse_bound_region(st: &mut PState) -> ty::BoundRegion { - match next(st) { - 'a' => { - let id = parse_u32(st); - assert_eq!(next(st), '|'); - ty::BrAnon(id) + fn peek(&self) -> char { + self.data[self.pos] as char + } + + fn next(&mut self) -> char { + let ch = self.data[self.pos] as char; + self.pos = self.pos + 1; + return ch; + } + + fn next_byte(&mut self) -> u8 { + let b = self.data[self.pos]; + self.pos = self.pos + 1; + return b; + } + + fn scan(&mut self, mut is_last: F) -> &'a [u8] + where F: FnMut(char) -> bool, + { + let start_pos = self.pos; + debug!("scan: '{}' (start)", self.data[self.pos] as char); + while !is_last(self.data[self.pos] as char) { + self.pos += 1; + debug!("scan: '{}'", self.data[self.pos] as char); } - '[' => { - let def = parse_def(st, RegionParameter); - let ident = token::str_to_ident(&parse_str(st, ']')); - ty::BrNamed(def, ident.name) + let end_pos = self.pos; + self.pos += 1; + return &self.data[start_pos..end_pos]; + } + + pub fn parse_name(&mut self, last: char) -> ast::Name { + fn is_last(b: char, c: char) -> bool { return c == b; } + let bytes = self.scan(|a| is_last(last, a)); + token::intern(str::from_utf8(bytes).unwrap()) + } + + fn parse_size(&mut self) -> Option { + assert_eq!(self.next(), '/'); + + if self.peek() == '|' { + assert_eq!(self.next(), '|'); + None + } else { + let n = self.parse_uint(); + assert_eq!(self.next(), '|'); + Some(n) } - 'f' => { - let id = parse_u32(st); - assert_eq!(next(st), '|'); - ty::BrFresh(id) + } + + fn parse_vec_per_param_space(&mut self, mut f: F) -> VecPerParamSpace where + F: FnMut(&mut PState<'a, 'tcx>) -> T, + { + let mut r = VecPerParamSpace::empty(); + for &space in &subst::ParamSpace::all() { + assert_eq!(self.next(), '['); + while self.peek() != ']' { + r.push(space, f(self)); + } + assert_eq!(self.next(), ']'); } - 'e' => ty::BrEnv, - _ => panic!("parse_bound_region: bad input") + r } -} -fn parse_region(st: &mut PState) -> ty::Region { - match next(st) { - 'b' => { - assert_eq!(next(st), '['); - let id = ty::DebruijnIndex::new(parse_u32(st)); - assert_eq!(next(st), '|'); - let br = parse_bound_region(st); - assert_eq!(next(st), ']'); - ty::ReLateBound(id, br) - } - 'B' => { - assert_eq!(next(st), '['); - let node_id = parse_uint(st) as ast::NodeId; - assert_eq!(next(st), '|'); - let space = parse_param_space(st); - assert_eq!(next(st), '|'); - let index = parse_u32(st); - assert_eq!(next(st), '|'); - let nm = token::str_to_ident(&parse_str(st, ']')); - ty::ReEarlyBound(ty::EarlyBoundRegion { - param_id: node_id, - space: space, - index: index, - name: nm.name - }) - } - 'f' => { - assert_eq!(next(st), '['); - let scope = parse_destruction_scope_data(st); - assert_eq!(next(st), '|'); - let br = parse_bound_region(st); - assert_eq!(next(st), ']'); - ty::ReFree(ty::FreeRegion { scope: scope, - bound_region: br}) - } - 's' => { - let scope = parse_scope(st); - assert_eq!(next(st), '|'); - ty::ReScope(scope) - } - 't' => { - ty::ReStatic - } - 'e' => { - ty::ReStatic - } - _ => panic!("parse_region: bad input") + fn parse_substs(&mut self) -> subst::Substs<'tcx> { + let regions = self.parse_region_substs(); + let types = self.parse_vec_per_param_space(|this| this.parse_ty()); + subst::Substs { types: types, regions: regions } } -} -fn parse_scope(st: &mut PState) -> region::CodeExtent { - match next(st) { - 'P' => { - assert_eq!(next(st), '['); - let fn_id = parse_uint(st) as ast::NodeId; - assert_eq!(next(st), '|'); - let body_id = parse_uint(st) as ast::NodeId; - assert_eq!(next(st), ']'); - region::CodeExtent::ParameterScope { - fn_id: fn_id, body_id: body_id + fn parse_region_substs(&mut self) -> subst::RegionSubsts { + match self.next() { + 'e' => subst::ErasedRegions, + 'n' => { + subst::NonerasedRegions( + self.parse_vec_per_param_space(|this| this.parse_region())) } + _ => panic!("parse_bound_region: bad input") } - 'M' => { - let node_id = parse_uint(st) as ast::NodeId; - region::CodeExtent::Misc(node_id) + } + + fn parse_bound_region(&mut self) -> ty::BoundRegion { + match self.next() { + 'a' => { + let id = self.parse_u32(); + assert_eq!(self.next(), '|'); + ty::BrAnon(id) + } + '[' => { + let def = self.parse_def(RegionParameter); + let ident = token::str_to_ident(&self.parse_str(']')); + ty::BrNamed(def, ident.name) + } + 'f' => { + let id = self.parse_u32(); + assert_eq!(self.next(), '|'); + ty::BrFresh(id) + } + 'e' => ty::BrEnv, + _ => panic!("parse_bound_region: bad input") } - 'D' => { - let node_id = parse_uint(st) as ast::NodeId; - region::CodeExtent::DestructionScope(node_id) + } + + fn parse_region(&mut self) -> ty::Region { + match self.next() { + 'b' => { + assert_eq!(self.next(), '['); + let id = ty::DebruijnIndex::new(self.parse_u32()); + assert_eq!(self.next(), '|'); + let br = self.parse_bound_region(); + assert_eq!(self.next(), ']'); + ty::ReLateBound(id, br) + } + 'B' => { + assert_eq!(self.next(), '['); + let node_id = self.parse_uint() as ast::NodeId; + assert_eq!(self.next(), '|'); + let space = self.parse_param_space(); + assert_eq!(self.next(), '|'); + let index = self.parse_u32(); + assert_eq!(self.next(), '|'); + let nm = token::str_to_ident(&self.parse_str(']')); + ty::ReEarlyBound(ty::EarlyBoundRegion { + param_id: node_id, + space: space, + index: index, + name: nm.name + }) + } + 'f' => { + assert_eq!(self.next(), '['); + let scope = self.parse_destruction_scope_data(); + assert_eq!(self.next(), '|'); + let br = self.parse_bound_region(); + assert_eq!(self.next(), ']'); + ty::ReFree(ty::FreeRegion { scope: scope, + bound_region: br}) + } + 's' => { + let scope = self.parse_scope(); + assert_eq!(self.next(), '|'); + ty::ReScope(scope) + } + 't' => { + ty::ReStatic + } + 'e' => { + ty::ReStatic + } + _ => panic!("parse_region: bad input") } - 'B' => { - assert_eq!(next(st), '['); - let node_id = parse_uint(st) as ast::NodeId; - assert_eq!(next(st), '|'); - let first_stmt_index = parse_uint(st); - assert_eq!(next(st), ']'); - let block_remainder = region::BlockRemainder { - block: node_id, first_statement_index: first_stmt_index, - }; - region::CodeExtent::Remainder(block_remainder) + } + + fn parse_scope(&mut self) -> region::CodeExtent { + match self.next() { + 'P' => { + assert_eq!(self.next(), '['); + let fn_id = self.parse_uint() as ast::NodeId; + assert_eq!(self.next(), '|'); + let body_id = self.parse_uint() as ast::NodeId; + assert_eq!(self.next(), ']'); + region::CodeExtent::ParameterScope { + fn_id: fn_id, body_id: body_id + } + } + 'M' => { + let node_id = self.parse_uint() as ast::NodeId; + region::CodeExtent::Misc(node_id) + } + 'D' => { + let node_id = self.parse_uint() as ast::NodeId; + region::CodeExtent::DestructionScope(node_id) + } + 'B' => { + assert_eq!(self.next(), '['); + let node_id = self.parse_uint() as ast::NodeId; + assert_eq!(self.next(), '|'); + let first_stmt_index = self.parse_uint(); + assert_eq!(self.next(), ']'); + let block_remainder = region::BlockRemainder { + block: node_id, first_statement_index: first_stmt_index, + }; + region::CodeExtent::Remainder(block_remainder) + } + _ => panic!("parse_scope: bad input") } - _ => panic!("parse_scope: bad input") } -} -fn parse_destruction_scope_data(st: &mut PState) -> region::DestructionScopeData { - let node_id = parse_uint(st) as ast::NodeId; - region::DestructionScopeData::new(node_id) -} + fn parse_destruction_scope_data(&mut self) -> region::DestructionScopeData { + let node_id = self.parse_uint() as ast::NodeId; + region::DestructionScopeData::new(node_id) + } -fn parse_opt<'a, 'tcx, T, F>(st: &mut PState<'a, 'tcx>, f: F) -> Option where - F: FnOnce(&mut PState<'a, 'tcx>) -> T, -{ - match next(st) { - 'n' => None, - 's' => Some(f(st)), - _ => panic!("parse_opt: bad input") + fn parse_opt(&mut self, f: F) -> Option + where F: FnOnce(&mut PState<'a, 'tcx>) -> T, + { + match self.next() { + 'n' => None, + 's' => Some(f(self)), + _ => panic!("parse_opt: bad input") + } } -} -fn parse_str(st: &mut PState, term: char) -> String { - let mut result = String::new(); - while peek(st) != term { - unsafe { - result.as_mut_vec().push_all(&[next_byte(st)]) + fn parse_str(&mut self, term: char) -> String { + let mut result = String::new(); + while self.peek() != term { + unsafe { + result.as_mut_vec().push_all(&[self.next_byte()]) + } } + self.next(); + result } - next(st); - result -} -fn parse_trait_ref<'a, 'tcx>(st: &mut PState<'a, 'tcx>) -> ty::TraitRef<'tcx> { - let def = parse_def(st, NominalType); - let substs = st.tcx.mk_substs(parse_substs(st)); - ty::TraitRef {def_id: def, substs: substs} -} + fn parse_trait_ref(&mut self) -> ty::TraitRef<'tcx> { + let def = self.parse_def(NominalType); + let substs = self.tcx.mk_substs(self.parse_substs()); + ty::TraitRef {def_id: def, substs: substs} + } -fn parse_ty<'a, 'tcx>(st: &mut PState<'a, 'tcx>) -> Ty<'tcx> { - let tcx = st.tcx; - match next(st) { - 'b' => return tcx.types.bool, - 'i' => { /* eat the s of is */ next(st); return tcx.types.isize }, - 'u' => { /* eat the s of us */ next(st); return tcx.types.usize }, - 'M' => { - match next(st) { - 'b' => return tcx.types.u8, - 'w' => return tcx.types.u16, - 'l' => return tcx.types.u32, - 'd' => return tcx.types.u64, - 'B' => return tcx.types.i8, - 'W' => return tcx.types.i16, - 'L' => return tcx.types.i32, - 'D' => return tcx.types.i64, - 'f' => return tcx.types.f32, - 'F' => return tcx.types.f64, - _ => panic!("parse_ty: bad numeric type") - } - } - 'c' => return tcx.types.char, - 't' => { - assert_eq!(next(st), '['); - let did = parse_def(st, NominalType); - let substs = parse_substs(st); - assert_eq!(next(st), ']'); - let def = st.tcx.lookup_adt_def(did); - return tcx.mk_enum(def, st.tcx.mk_substs(substs)); - } - 'x' => { - assert_eq!(next(st), '['); - let trait_ref = ty::Binder(parse_trait_ref(st)); - let bounds = parse_existential_bounds(st); - assert_eq!(next(st), ']'); - return tcx.mk_trait(trait_ref, bounds); - } - 'p' => { - assert_eq!(next(st), '['); - let index = parse_u32(st); - assert_eq!(next(st), '|'); - let space = parse_param_space(st); - assert_eq!(next(st), '|'); - let name = token::intern(&parse_str(st, ']')); - return tcx.mk_param(space, index, name); - } - '~' => return tcx.mk_box(parse_ty(st)), - '*' => return tcx.mk_ptr(parse_mt(st)), - '&' => { - let r = parse_region(st); - let mt = parse_mt(st); - return tcx.mk_ref(tcx.mk_region(r), mt); - } - 'V' => { - let t = parse_ty(st); - return match parse_size(st) { - Some(n) => tcx.mk_array(t, n), - None => tcx.mk_slice(t) - }; - } - 'v' => { - return tcx.mk_str(); - } - 'T' => { - assert_eq!(next(st), '['); - let mut params = Vec::new(); - while peek(st) != ']' { params.push(parse_ty(st)); } - st.pos = st.pos + 1; - return tcx.mk_tup(params); - } - 'F' => { - let def_id = parse_def(st, NominalType); - return tcx.mk_fn(Some(def_id), tcx.mk_bare_fn(parse_bare_fn_ty(st))); - } - 'G' => { - return tcx.mk_fn(None, tcx.mk_bare_fn(parse_bare_fn_ty(st))); - } - '#' => { - // This is a hacky little caching scheme. The idea is that if we encode - // the same type twice, the second (and third, and fourth...) time we will - // just write `#123`, where `123` is the offset in the metadata of the - // first appearance. Now when we are *decoding*, if we see a `#123`, we - // can first check a cache (`tcx.rcache`) for that offset. If we find something, - // we return it (modulo closure types, see below). But if not, then we - // jump to offset 123 and read the type from there. - - let pos = parse_hex(st); - assert_eq!(next(st), ':'); - let len = parse_hex(st); - assert_eq!(next(st), '#'); - let key = ty::CReaderCacheKey {cnum: st.krate, pos: pos, len: len }; - match tcx.rcache.borrow().get(&key).cloned() { - Some(tt) => { - // If there is a closure buried in the type some where, then we - // need to re-convert any def ids (see case 'k', below). That means - // we can't reuse the cached version. - if !tt.has_closure_types() { + fn parse_ty(&mut self) -> Ty<'tcx> { + let tcx = self.tcx; + match self.next() { + 'b' => return tcx.types.bool, + 'i' => { /* eat the s of is */ self.next(); return tcx.types.isize }, + 'u' => { /* eat the s of us */ self.next(); return tcx.types.usize }, + 'M' => { + match self.next() { + 'b' => return tcx.types.u8, + 'w' => return tcx.types.u16, + 'l' => return tcx.types.u32, + 'd' => return tcx.types.u64, + 'B' => return tcx.types.i8, + 'W' => return tcx.types.i16, + 'L' => return tcx.types.i32, + 'D' => return tcx.types.i64, + 'f' => return tcx.types.f32, + 'F' => return tcx.types.f64, + _ => panic!("parse_ty: bad numeric type") + } + } + 'c' => return tcx.types.char, + 't' => { + assert_eq!(self.next(), '['); + let did = self.parse_def(NominalType); + let substs = self.parse_substs(); + assert_eq!(self.next(), ']'); + let def = self.tcx.lookup_adt_def(did); + return tcx.mk_enum(def, self.tcx.mk_substs(substs)); + } + 'x' => { + assert_eq!(self.next(), '['); + let trait_ref = ty::Binder(self.parse_trait_ref()); + let bounds = self.parse_existential_bounds(); + assert_eq!(self.next(), ']'); + return tcx.mk_trait(trait_ref, bounds); + } + 'p' => { + assert_eq!(self.next(), '['); + let index = self.parse_u32(); + assert_eq!(self.next(), '|'); + let space = self.parse_param_space(); + assert_eq!(self.next(), '|'); + let name = token::intern(&self.parse_str(']')); + return tcx.mk_param(space, index, name); + } + '~' => return tcx.mk_box(self.parse_ty()), + '*' => return tcx.mk_ptr(self.parse_mt()), + '&' => { + let r = self.parse_region(); + let mt = self.parse_mt(); + return tcx.mk_ref(tcx.mk_region(r), mt); + } + 'V' => { + let t = self.parse_ty(); + return match self.parse_size() { + Some(n) => tcx.mk_array(t, n), + None => tcx.mk_slice(t) + }; + } + 'v' => { + return tcx.mk_str(); + } + 'T' => { + assert_eq!(self.next(), '['); + let mut params = Vec::new(); + while self.peek() != ']' { params.push(self.parse_ty()); } + self.pos = self.pos + 1; + return tcx.mk_tup(params); + } + 'F' => { + let def_id = self.parse_def(NominalType); + return tcx.mk_fn(Some(def_id), tcx.mk_bare_fn(self.parse_bare_fn_ty())); + } + 'G' => { + return tcx.mk_fn(None, tcx.mk_bare_fn(self.parse_bare_fn_ty())); + } + '#' => { + // This is a hacky little caching scheme. The idea is that if we encode + // the same type twice, the second (and third, and fourth...) time we will + // just write `#123`, where `123` is the offset in the metadata of the + // first appearance. Now when we are *decoding*, if we see a `#123`, we + // can first check a cache (`tcx.rcache`) for that offset. If we find something, + // we return it (modulo closure types, see below). But if not, then we + // jump to offset 123 and read the type from there. + + let pos = self.parse_hex(); + assert_eq!(self.next(), ':'); + let len = self.parse_hex(); + assert_eq!(self.next(), '#'); + let key = ty::CReaderCacheKey {cnum: self.krate, pos: pos, len: len }; + match tcx.rcache.borrow().get(&key).cloned() { + Some(tt) => { + // If there is a closure buried in the type some where, then we + // need to re-convert any def ids (see case 'k', below). That means + // we can't reuse the cached version. + if !tt.has_closure_types() { + return tt; + } + } + None => {} + } + + let mut substate = PState::new(self.data, + self.krate, + pos, + self.tcx, + self.conv_def_id); + let tt = substate.parse_ty(); + tcx.rcache.borrow_mut().insert(key, tt); return tt; } - } - None => {} + '\"' => { + let _ = self.parse_def(TypeWithId); + let inner = self.parse_ty(); + inner + } + 'a' => { + assert_eq!(self.next(), '['); + let did = self.parse_def(NominalType); + let substs = self.parse_substs(); + assert_eq!(self.next(), ']'); + let def = self.tcx.lookup_adt_def(did); + return self.tcx.mk_struct(def, self.tcx.mk_substs(substs)); + } + 'k' => { + assert_eq!(self.next(), '['); + let did = self.parse_def(ClosureSource); + let substs = self.parse_substs(); + let mut tys = vec![]; + while self.peek() != '.' { + tys.push(self.parse_ty()); + } + assert_eq!(self.next(), '.'); + assert_eq!(self.next(), ']'); + return self.tcx.mk_closure(did, self.tcx.mk_substs(substs), tys); + } + 'P' => { + assert_eq!(self.next(), '['); + let trait_ref = self.parse_trait_ref(); + let name = token::intern(&self.parse_str(']')); + return tcx.mk_projection(trait_ref, name); + } + 'e' => { + return tcx.types.err; + } + c => { panic!("unexpected char in type string: {}", c);} } + } - let mut ps = PState { - pos: pos, - conv_def_id: st.conv_def_id, // -+ Have to call out these fields specifically, - tcx: st.tcx, // | rather than writing `..*st`, so that we - data: st.data, // | trigger reborrow coercions. Suboptimal, - krate: st.krate, // -+ I suppose. + fn parse_mutability(&mut self) -> ast::Mutability { + match self.peek() { + 'm' => { self.next(); ast::MutMutable } + _ => { ast::MutImmutable } + } + } + + fn parse_mt(&mut self) -> ty::TypeAndMut<'tcx> { + let m = self.parse_mutability(); + ty::TypeAndMut { ty: self.parse_ty(), mutbl: m } + } + + fn parse_def(&mut self, source: DefIdSource) -> ast::DefId { + let def_id = parse_defid(self.scan(|c| c == '|')); + return (self.conv_def_id)(source, def_id); + } + + fn parse_uint(&mut self) -> usize { + let mut n = 0; + loop { + let cur = self.peek(); + if cur < '0' || cur > '9' { return n; } + self.pos = self.pos + 1; + n *= 10; + n += (cur as usize) - ('0' as usize); }; + } - let tt = parse_ty(&mut ps); - tcx.rcache.borrow_mut().insert(key, tt); - return tt; - } - '\"' => { - let _ = parse_def(st, TypeWithId); - let inner = parse_ty(st); - inner - } - 'a' => { - assert_eq!(next(st), '['); - let did = parse_def(st, NominalType); - let substs = parse_substs(st); - assert_eq!(next(st), ']'); - let def = st.tcx.lookup_adt_def(did); - return st.tcx.mk_struct(def, st.tcx.mk_substs(substs)); - } - 'k' => { - assert_eq!(next(st), '['); - let did = parse_def(st, ClosureSource); - let substs = parse_substs(st); - let mut tys = vec![]; - while peek(st) != '.' { - tys.push(parse_ty(st)); - } - assert_eq!(next(st), '.'); - assert_eq!(next(st), ']'); - return st.tcx.mk_closure(did, st.tcx.mk_substs(substs), tys); - } - 'P' => { - assert_eq!(next(st), '['); - let trait_ref = parse_trait_ref(st); - let name = token::intern(&parse_str(st, ']')); - return tcx.mk_projection(trait_ref, name); - } - 'e' => { - return tcx.types.err; - } - c => { panic!("unexpected char in type string: {}", c);} + fn parse_u32(&mut self) -> u32 { + let n = self.parse_uint(); + let m = n as u32; + assert_eq!(m as usize, n); + m } -} -fn parse_mutability(st: &mut PState) -> ast::Mutability { - match peek(st) { - 'm' => { next(st); ast::MutMutable } - _ => { ast::MutImmutable } + fn parse_param_space(&mut self) -> subst::ParamSpace { + subst::ParamSpace::from_uint(self.parse_uint()) } -} -fn parse_mt<'a, 'tcx>(st: &mut PState<'a, 'tcx>) -> ty::TypeAndMut<'tcx> { - let m = parse_mutability(st); - ty::TypeAndMut { ty: parse_ty(st), mutbl: m } -} + fn parse_hex(&mut self) -> usize { + let mut n = 0; + loop { + let cur = self.peek(); + if (cur < '0' || cur > '9') && (cur < 'a' || cur > 'f') { return n; } + self.pos = self.pos + 1; + n *= 16; + if '0' <= cur && cur <= '9' { + n += (cur as usize) - ('0' as usize); + } else { n += 10 + (cur as usize) - ('a' as usize); } + }; + } -fn parse_def(st: &mut PState, source: DefIdSource) -> ast::DefId { - let def_id = parse_defid(scan(st, |c| c == '|')); - return (st.conv_def_id)(source, def_id); -} + fn parse_abi_set(&mut self) -> abi::Abi { + assert_eq!(self.next(), '['); + let bytes = self.scan(|c| c == ']'); + let abi_str = str::from_utf8(bytes).unwrap(); + abi::lookup(&abi_str[..]).expect(abi_str) + } -fn parse_uint(st: &mut PState) -> usize { - let mut n = 0; - loop { - let cur = peek(st); - if cur < '0' || cur > '9' { return n; } - st.pos = st.pos + 1; - n *= 10; - n += (cur as usize) - ('0' as usize); - }; -} + fn parse_closure_ty(&mut self) -> ty::ClosureTy<'tcx> { + let unsafety = parse_unsafety(self.next()); + let sig = self.parse_sig(); + let abi = self.parse_abi_set(); + ty::ClosureTy { + unsafety: unsafety, + sig: sig, + abi: abi, + } + } -fn parse_u32(st: &mut PState) -> u32 { - let n = parse_uint(st); - let m = n as u32; - assert_eq!(m as usize, n); - m -} + fn parse_bare_fn_ty(&mut self) -> ty::BareFnTy<'tcx> { + let unsafety = parse_unsafety(self.next()); + let abi = self.parse_abi_set(); + let sig = self.parse_sig(); + ty::BareFnTy { + unsafety: unsafety, + abi: abi, + sig: sig + } + } -fn parse_param_space(st: &mut PState) -> subst::ParamSpace { - subst::ParamSpace::from_uint(parse_uint(st)) -} + fn parse_sig(&mut self) -> ty::PolyFnSig<'tcx> { + assert_eq!(self.next(), '['); + let mut inputs = Vec::new(); + while self.peek() != ']' { + inputs.push(self.parse_ty()); + } + self.pos += 1; // eat the ']' + let variadic = match self.next() { + 'V' => true, + 'N' => false, + r => panic!(format!("bad variadic: {}", r)), + }; + let output = match self.peek() { + 'z' => { + self.pos += 1; + ty::FnDiverging + } + _ => ty::FnConverging(self.parse_ty()) + }; + ty::Binder(ty::FnSig {inputs: inputs, + output: output, + variadic: variadic}) + } -fn parse_hex(st: &mut PState) -> usize { - let mut n = 0; - loop { - let cur = peek(st); - if (cur < '0' || cur > '9') && (cur < 'a' || cur > 'f') { return n; } - st.pos = st.pos + 1; - n *= 16; - if '0' <= cur && cur <= '9' { - n += (cur as usize) - ('0' as usize); - } else { n += 10 + (cur as usize) - ('a' as usize); } - }; -} + pub fn parse_predicate(&mut self) -> ty::Predicate<'tcx> { + match self.next() { + 't' => ty::Binder(self.parse_trait_ref()).to_predicate(), + 'e' => ty::Binder(ty::EquatePredicate(self.parse_ty(), + self.parse_ty())).to_predicate(), + 'r' => ty::Binder(ty::OutlivesPredicate(self.parse_region(), + self.parse_region())).to_predicate(), + 'o' => ty::Binder(ty::OutlivesPredicate(self.parse_ty(), + self.parse_region())).to_predicate(), + 'p' => ty::Binder(self.parse_projection_predicate()).to_predicate(), + 'w' => ty::Predicate::WellFormed(self.parse_ty()), + 'O' => { + let def_id = self.parse_def(NominalType); + assert_eq!(self.next(), '|'); + ty::Predicate::ObjectSafe(def_id) + } + c => panic!("Encountered invalid character in metadata: {}", c) + } + } -fn parse_unsafety(c: char) -> ast::Unsafety { - match c { - 'u' => ast::Unsafety::Unsafe, - 'n' => ast::Unsafety::Normal, - _ => panic!("parse_unsafety: bad unsafety {}", c) + fn parse_projection_predicate(&mut self) -> ty::ProjectionPredicate<'tcx> { + ty::ProjectionPredicate { + projection_ty: ty::ProjectionTy { + trait_ref: self.parse_trait_ref(), + item_name: token::str_to_ident(&self.parse_str('|')).name, + }, + ty: self.parse_ty(), + } } -} -fn parse_abi_set(st: &mut PState) -> abi::Abi { - assert_eq!(next(st), '['); - let bytes = scan(st, |c| c == ']'); - let abi_str = str::from_utf8(bytes).unwrap(); - abi::lookup(&abi_str[..]).expect(abi_str) -} + fn parse_type_param_def(&mut self) -> ty::TypeParameterDef<'tcx> { + let name = self.parse_name(':'); + let def_id = self.parse_def(NominalType); + let space = self.parse_param_space(); + assert_eq!(self.next(), '|'); + let index = self.parse_u32(); + assert_eq!(self.next(), '|'); + let default_def_id = self.parse_def(NominalType); + let default = self.parse_opt(|this| this.parse_ty()); + let object_lifetime_default = self.parse_object_lifetime_default(); + + ty::TypeParameterDef { + name: name, + def_id: def_id, + space: space, + index: index, + default_def_id: default_def_id, + default: default, + object_lifetime_default: object_lifetime_default, + } + } + + fn parse_object_lifetime_default(&mut self) -> ty::ObjectLifetimeDefault { + match self.next() { + 'a' => ty::ObjectLifetimeDefault::Ambiguous, + 'b' => ty::ObjectLifetimeDefault::BaseDefault, + 's' => { + let region = self.parse_region(); + ty::ObjectLifetimeDefault::Specific(region) + } + _ => panic!("parse_object_lifetime_default: bad input") + } + } + + fn parse_existential_bounds(&mut self) -> ty::ExistentialBounds<'tcx> { + let builtin_bounds = self.parse_builtin_bounds(); + let region_bound = self.parse_region(); + let mut projection_bounds = Vec::new(); + + loop { + match self.next() { + 'P' => { + projection_bounds.push(ty::Binder(self.parse_projection_predicate())); + } + '.' => { break; } + c => { + panic!("parse_bounds: bad bounds ('{}')", c) + } + } + } -fn parse_closure_ty<'a, 'tcx>(st: &mut PState<'a, 'tcx>) -> ty::ClosureTy<'tcx> { - let unsafety = parse_unsafety(next(st)); - let sig = parse_sig(st); - let abi = parse_abi_set(st); - ty::ClosureTy { - unsafety: unsafety, - sig: sig, - abi: abi, + return ty::ExistentialBounds { region_bound: region_bound, + builtin_bounds: builtin_bounds, + projection_bounds: projection_bounds }; } -} -fn parse_bare_fn_ty<'a, 'tcx>(st: &mut PState<'a, 'tcx>) -> ty::BareFnTy<'tcx> { - let unsafety = parse_unsafety(next(st)); - let abi = parse_abi_set(st); - let sig = parse_sig(st); - ty::BareFnTy { - unsafety: unsafety, - abi: abi, - sig: sig + fn parse_builtin_bounds(&mut self) -> ty::BuiltinBounds { + let mut builtin_bounds = ty::BuiltinBounds::empty(); + loop { + match self.next() { + 'S' => { + builtin_bounds.insert(ty::BoundSend); + } + 'Z' => { + builtin_bounds.insert(ty::BoundSized); + } + 'P' => { + builtin_bounds.insert(ty::BoundCopy); + } + 'T' => { + builtin_bounds.insert(ty::BoundSync); + } + '.' => { + return builtin_bounds; + } + c => { + panic!("parse_bounds: bad builtin bounds ('{}')", c) + } + } + } } } -fn parse_sig<'a, 'tcx>(st: &mut PState<'a, 'tcx>) -> ty::PolyFnSig<'tcx> { - assert_eq!(next(st), '['); - let mut inputs = Vec::new(); - while peek(st) != ']' { - inputs.push(parse_ty(st)); - } - st.pos += 1; // eat the ']' - let variadic = match next(st) { - 'V' => true, - 'N' => false, - r => panic!(format!("bad variadic: {}", r)), - }; - let output = match peek(st) { - 'z' => { - st.pos += 1; - ty::FnDiverging +fn data_log_string(data: &[u8], pos: usize) -> String { + let mut buf = String::new(); + buf.push_str("<<"); + for i in pos..data.len() { + let c = data[i]; + if c > 0x20 && c <= 0x7F { + buf.push(c as char); + } else { + buf.push('.'); } - _ => ty::FnConverging(parse_ty(st)) - }; - ty::Binder(ty::FnSig {inputs: inputs, - output: output, - variadic: variadic}) + } + buf.push_str(">>"); + buf } // Rust metadata parsing @@ -678,149 +799,25 @@ pub fn parse_defid(buf: &[u8]) -> ast::DefId { let crate_num = match str::from_utf8(crate_part).ok().and_then(|s| { s.parse::().ok() }) { - Some(cn) => cn as ast::CrateNum, - None => panic!("internal error: parse_defid: crate number expected, found {:?}", - crate_part) + Some(cn) => cn as ast::CrateNum, + None => panic!("internal error: parse_defid: crate number expected, found {:?}", + crate_part) }; let def_num = match str::from_utf8(def_part).ok().and_then(|s| { s.parse::().ok() }) { - Some(dn) => dn as ast::NodeId, - None => panic!("internal error: parse_defid: id expected, found {:?}", - def_part) + Some(dn) => dn as ast::NodeId, + None => panic!("internal error: parse_defid: id expected, found {:?}", + def_part) }; ast::DefId { krate: crate_num, node: def_num } } -pub fn parse_predicate_data<'tcx, F>(data: &[u8], - start: usize, - crate_num: ast::CrateNum, - tcx: &ty::ctxt<'tcx>, - mut conv: F) - -> ty::Predicate<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - let mut st = parse_state_from_data(data, crate_num, start, tcx, &mut conv); - parse_predicate(&mut st) -} - -pub fn parse_predicate<'a,'tcx>(st: &mut PState<'a, 'tcx>) -> ty::Predicate<'tcx> { - match next(st) { - 't' => ty::Binder(parse_trait_ref(st)).to_predicate(), - 'e' => ty::Binder(ty::EquatePredicate(parse_ty(st), - parse_ty(st))).to_predicate(), - 'r' => ty::Binder(ty::OutlivesPredicate(parse_region(st), - parse_region(st))).to_predicate(), - 'o' => ty::Binder(ty::OutlivesPredicate(parse_ty(st), - parse_region(st))).to_predicate(), - 'p' => ty::Binder(parse_projection_predicate(st)).to_predicate(), - 'w' => ty::Predicate::WellFormed(parse_ty(st)), - 'O' => { - let def_id = parse_def(st, NominalType); - assert_eq!(next(st), '|'); - ty::Predicate::ObjectSafe(def_id) - } - c => panic!("Encountered invalid character in metadata: {}", c) - } -} - -fn parse_projection_predicate<'a,'tcx>(st: &mut PState<'a, 'tcx>) -> ty::ProjectionPredicate<'tcx> { - ty::ProjectionPredicate { - projection_ty: ty::ProjectionTy { - trait_ref: parse_trait_ref(st), - item_name: token::str_to_ident(&parse_str(st, '|')).name, - }, - ty: parse_ty(st), - } -} - -pub fn parse_type_param_def_data<'tcx, F>(data: &[u8], start: usize, - crate_num: ast::CrateNum, tcx: &ty::ctxt<'tcx>, - mut conv: F) -> ty::TypeParameterDef<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - let mut st = parse_state_from_data(data, crate_num, start, tcx, &mut conv); - parse_type_param_def(&mut st) -} - -fn parse_type_param_def<'a, 'tcx>(st: &mut PState<'a, 'tcx>) -> ty::TypeParameterDef<'tcx> { - let name = parse_name(st, ':'); - let def_id = parse_def(st, NominalType); - let space = parse_param_space(st); - assert_eq!(next(st), '|'); - let index = parse_u32(st); - assert_eq!(next(st), '|'); - let default_def_id = parse_def(st, NominalType); - let default = parse_opt(st, |st| parse_ty(st)); - let object_lifetime_default = parse_object_lifetime_default(st); - - ty::TypeParameterDef { - name: name, - def_id: def_id, - space: space, - index: index, - default_def_id: default_def_id, - default: default, - object_lifetime_default: object_lifetime_default, - } -} - -fn parse_object_lifetime_default<'a,'tcx>(st: &mut PState<'a,'tcx>) -> ty::ObjectLifetimeDefault { - match next(st) { - 'a' => ty::ObjectLifetimeDefault::Ambiguous, - 'b' => ty::ObjectLifetimeDefault::BaseDefault, - 's' => { - let region = parse_region(st); - ty::ObjectLifetimeDefault::Specific(region) - } - _ => panic!("parse_object_lifetime_default: bad input") - } -} - -fn parse_existential_bounds<'a,'tcx>(st: &mut PState<'a,'tcx>) -> ty::ExistentialBounds<'tcx> { - let builtin_bounds = parse_builtin_bounds(st); - let region_bound = parse_region(st); - let mut projection_bounds = Vec::new(); - - loop { - match next(st) { - 'P' => { - projection_bounds.push(ty::Binder(parse_projection_predicate(st))); - } - '.' => { break; } - c => { - panic!("parse_bounds: bad bounds ('{}')", c) - } - } +fn parse_unsafety(c: char) -> ast::Unsafety { + match c { + 'u' => ast::Unsafety::Unsafe, + 'n' => ast::Unsafety::Normal, + _ => panic!("parse_unsafety: bad unsafety {}", c) } - - return ty::ExistentialBounds { region_bound: region_bound, - builtin_bounds: builtin_bounds, - projection_bounds: projection_bounds }; } -fn parse_builtin_bounds(st: &mut PState) -> ty::BuiltinBounds { - let mut builtin_bounds = ty::BuiltinBounds::empty(); - loop { - match next(st) { - 'S' => { - builtin_bounds.insert(ty::BoundSend); - } - 'Z' => { - builtin_bounds.insert(ty::BoundSized); - } - 'P' => { - builtin_bounds.insert(ty::BoundCopy); - } - 'T' => { - builtin_bounds.insert(ty::BoundSync); - } - '.' => { - return builtin_bounds; - } - c => { - panic!("parse_bounds: bad builtin bounds ('{}')", c) - } - } - } -} From 70e2df5b1bedbab6fc1087fc9b3e66dd5e80b044 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 14 Aug 2015 05:14:54 -0400 Subject: [PATCH 4/7] tydecode: tighten privacy --- src/librustc/metadata/tydecode.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 2ddb0697c171b..270fc28499703 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -211,7 +211,7 @@ impl<'a,'tcx> PState<'a,'tcx> { return &self.data[start_pos..end_pos]; } - pub fn parse_name(&mut self, last: char) -> ast::Name { + fn parse_name(&mut self, last: char) -> ast::Name { fn is_last(b: char, c: char) -> bool { return c == b; } let bytes = self.scan(|a| is_last(last, a)); token::intern(str::from_utf8(bytes).unwrap()) @@ -655,7 +655,7 @@ impl<'a,'tcx> PState<'a,'tcx> { variadic: variadic}) } - pub fn parse_predicate(&mut self) -> ty::Predicate<'tcx> { + fn parse_predicate(&mut self) -> ty::Predicate<'tcx> { match self.next() { 't' => ty::Binder(self.parse_trait_ref()).to_predicate(), 'e' => ty::Binder(ty::EquatePredicate(self.parse_ty(), @@ -784,7 +784,7 @@ fn data_log_string(data: &[u8], pos: usize) -> String { } // Rust metadata parsing -pub fn parse_defid(buf: &[u8]) -> ast::DefId { +fn parse_defid(buf: &[u8]) -> ast::DefId { let mut colon_idx = 0; let len = buf.len(); while colon_idx < len && buf[colon_idx] != ':' as u8 { colon_idx += 1; } From 38e6b5780e59977608f3b989410bc3b038f1ddc9 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 14 Aug 2015 05:37:49 -0400 Subject: [PATCH 5/7] s/PState/TyDecoder/ --- src/librustc/metadata/tydecode.rs | 42 +++++++++++++++---------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 270fc28499703..a24bf76ca7658 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -65,7 +65,7 @@ pub fn parse_ty_closure_data<'tcx, F>(data: &[u8], -> ty::ClosureTy<'tcx> where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, { - let mut st = PState::new(data, crate_num, pos, tcx, &mut conv); + let mut st = TyDecoder::new(data, crate_num, pos, tcx, &mut conv); st.parse_closure_ty() } @@ -74,7 +74,7 @@ pub fn parse_ty_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: usize, F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, { debug!("parse_ty_data {}", data_log_string(data, pos)); - let mut st = PState::new(data, crate_num, pos, tcx, &mut conv); + let mut st = TyDecoder::new(data, crate_num, pos, tcx, &mut conv); st.parse_ty() } @@ -83,7 +83,7 @@ pub fn parse_region_data(data: &[u8], crate_num: ast::CrateNum, pos: usize, t F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, { debug!("parse_region_data {}", data_log_string(data, pos)); - let mut st = PState::new(data, crate_num, pos, tcx, &mut conv); + let mut st = TyDecoder::new(data, crate_num, pos, tcx, &mut conv); st.parse_region() } @@ -93,7 +93,7 @@ pub fn parse_bare_fn_ty_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, { debug!("parse_bare_fn_ty_data {}", data_log_string(data, pos)); - let mut st = PState::new(data, crate_num, pos, tcx, &mut conv); + let mut st = TyDecoder::new(data, crate_num, pos, tcx, &mut conv); st.parse_bare_fn_ty() } @@ -103,7 +103,7 @@ pub fn parse_trait_ref_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, { debug!("parse_trait_ref_data {}", data_log_string(data, pos)); - let mut st = PState::new(data, crate_num, pos, tcx, &mut conv); + let mut st = TyDecoder::new(data, crate_num, pos, tcx, &mut conv); st.parse_trait_ref() } @@ -112,7 +112,7 @@ pub fn parse_substs_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: us F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, { debug!("parse_substs_data{}", data_log_string(data, pos)); - let mut st = PState::new(data, crate_num, pos, tcx, &mut conv); + let mut st = TyDecoder::new(data, crate_num, pos, tcx, &mut conv); st.parse_substs() } @@ -121,7 +121,7 @@ pub fn parse_existential_bounds_data<'tcx, F>(data: &[u8], crate_num: ast::Crate -> ty::ExistentialBounds<'tcx> where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, { - let mut st = PState::new(data, crate_num, pos, tcx, &mut conv); + let mut st = TyDecoder::new(data, crate_num, pos, tcx, &mut conv); st.parse_existential_bounds() } @@ -130,7 +130,7 @@ pub fn parse_builtin_bounds_data(data: &[u8], crate_num: ast::CrateNum, -> ty::BuiltinBounds where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, { - let mut st = PState::new(data, crate_num, pos, tcx, &mut conv); + let mut st = TyDecoder::new(data, crate_num, pos, tcx, &mut conv); st.parse_builtin_bounds() } @@ -139,7 +139,7 @@ pub fn parse_type_param_def_data<'tcx, F>(data: &[u8], start: usize, mut conv: F) -> ty::TypeParameterDef<'tcx> where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, { - let mut st = PState::new(data, crate_num, start, tcx, &mut conv); + let mut st = TyDecoder::new(data, crate_num, start, tcx, &mut conv); st.parse_type_param_def() } @@ -151,13 +151,13 @@ pub fn parse_predicate_data<'tcx, F>(data: &[u8], -> ty::Predicate<'tcx> where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, { - let mut st = PState::new(data, crate_num, start, tcx, &mut conv); + let mut st = TyDecoder::new(data, crate_num, start, tcx, &mut conv); st.parse_predicate() } pub type DefIdConvert<'a> = &'a mut FnMut(DefIdSource, ast::DefId) -> ast::DefId; -pub struct PState<'a, 'tcx: 'a> { +pub struct TyDecoder<'a, 'tcx: 'a> { data: &'a [u8], krate: ast::CrateNum, pos: usize, @@ -165,14 +165,14 @@ pub struct PState<'a, 'tcx: 'a> { conv_def_id: DefIdConvert<'a>, } -impl<'a,'tcx> PState<'a,'tcx> { +impl<'a,'tcx> TyDecoder<'a,'tcx> { pub fn new(data: &'a [u8], crate_num: ast::CrateNum, pos: usize, tcx: &'a ty::ctxt<'tcx>, conv: DefIdConvert<'a>) - -> PState<'a, 'tcx> { - PState { + -> TyDecoder<'a, 'tcx> { + TyDecoder { data: data, krate: crate_num, pos: pos, @@ -231,7 +231,7 @@ impl<'a,'tcx> PState<'a,'tcx> { } fn parse_vec_per_param_space(&mut self, mut f: F) -> VecPerParamSpace where - F: FnMut(&mut PState<'a, 'tcx>) -> T, + F: FnMut(&mut TyDecoder<'a, 'tcx>) -> T, { let mut r = VecPerParamSpace::empty(); for &space in &subst::ParamSpace::all() { @@ -374,7 +374,7 @@ impl<'a,'tcx> PState<'a,'tcx> { } fn parse_opt(&mut self, f: F) -> Option - where F: FnOnce(&mut PState<'a, 'tcx>) -> T, + where F: FnOnce(&mut TyDecoder<'a, 'tcx>) -> T, { match self.next() { 'n' => None, @@ -503,11 +503,11 @@ impl<'a,'tcx> PState<'a,'tcx> { None => {} } - let mut substate = PState::new(self.data, - self.krate, - pos, - self.tcx, - self.conv_def_id); + let mut substate = TyDecoder::new(self.data, + self.krate, + pos, + self.tcx, + self.conv_def_id); let tt = substate.parse_ty(); tcx.rcache.borrow_mut().insert(key, tt); return tt; From b09cf1293a2123d316b2434a101a7c10599d7d43 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 14 Aug 2015 05:58:10 -0400 Subject: [PATCH 6/7] astencode: convert code to use TyDecoder directly --- src/librustc/metadata/tydecode.rs | 23 ++++-- src/librustc/middle/astencode.rs | 112 ++++++++++-------------------- 2 files changed, 54 insertions(+), 81 deletions(-) diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index a24bf76ca7658..52370f652a2fb 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -23,6 +23,7 @@ use middle::subst; use middle::subst::VecPerParamSpace; use middle::ty::{self, ToPredicate, Ty, HasTypeFlags}; +use rbml; use std::str; use syntax::abi; use syntax::ast; @@ -166,6 +167,14 @@ pub struct TyDecoder<'a, 'tcx: 'a> { } impl<'a,'tcx> TyDecoder<'a,'tcx> { + pub fn with_doc(tcx: &'a ty::ctxt<'tcx>, + crate_num: ast::CrateNum, + doc: rbml::Doc<'a>, + conv: DefIdConvert<'a>) + -> TyDecoder<'a,'tcx> { + TyDecoder::new(doc.data, crate_num, doc.start, tcx, conv) + } + pub fn new(data: &'a [u8], crate_num: ast::CrateNum, pos: usize, @@ -244,7 +253,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { r } - fn parse_substs(&mut self) -> subst::Substs<'tcx> { + pub fn parse_substs(&mut self) -> subst::Substs<'tcx> { let regions = self.parse_region_substs(); let types = self.parse_vec_per_param_space(|this| this.parse_ty()); subst::Substs { types: types, regions: regions } @@ -394,13 +403,13 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { result } - fn parse_trait_ref(&mut self) -> ty::TraitRef<'tcx> { + pub fn parse_trait_ref(&mut self) -> ty::TraitRef<'tcx> { let def = self.parse_def(NominalType); let substs = self.tcx.mk_substs(self.parse_substs()); ty::TraitRef {def_id: def, substs: substs} } - fn parse_ty(&mut self) -> Ty<'tcx> { + pub fn parse_ty(&mut self) -> Ty<'tcx> { let tcx = self.tcx; match self.next() { 'b' => return tcx.types.bool, @@ -609,7 +618,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { abi::lookup(&abi_str[..]).expect(abi_str) } - fn parse_closure_ty(&mut self) -> ty::ClosureTy<'tcx> { + pub fn parse_closure_ty(&mut self) -> ty::ClosureTy<'tcx> { let unsafety = parse_unsafety(self.next()); let sig = self.parse_sig(); let abi = self.parse_abi_set(); @@ -655,7 +664,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { variadic: variadic}) } - fn parse_predicate(&mut self) -> ty::Predicate<'tcx> { + pub fn parse_predicate(&mut self) -> ty::Predicate<'tcx> { match self.next() { 't' => ty::Binder(self.parse_trait_ref()).to_predicate(), 'e' => ty::Binder(ty::EquatePredicate(self.parse_ty(), @@ -685,7 +694,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { } } - fn parse_type_param_def(&mut self) -> ty::TypeParameterDef<'tcx> { + pub fn parse_type_param_def(&mut self) -> ty::TypeParameterDef<'tcx> { let name = self.parse_name(':'); let def_id = self.parse_def(NominalType); let space = self.parse_param_space(); @@ -719,7 +728,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { } } - fn parse_existential_bounds(&mut self) -> ty::ExistentialBounds<'tcx> { + pub fn parse_existential_bounds(&mut self) -> ty::ExistentialBounds<'tcx> { let builtin_bounds = self.parse_builtin_bounds(); let region_bound = self.parse_region(); let mut projection_bounds = Vec::new(); diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index a07b849b400aa..e544d8d474979 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -1075,6 +1075,10 @@ impl<'a> doc_decoder_helpers for rbml::Doc<'a> { } trait rbml_decoder_decoder_helpers<'tcx> { + fn read_ty_encoded<'a, 'b, F, R>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>, + f: F) -> R + where F: for<'x> FnOnce(&mut tydecode::TyDecoder<'x, 'tcx>) -> R; + fn read_ty<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> Ty<'tcx>; fn read_tys<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> Vec>; fn read_trait_ref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) @@ -1123,14 +1127,14 @@ trait rbml_decoder_decoder_helpers<'tcx> { impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> { fn read_ty_nodcx(&mut self, - tcx: &ty::ctxt<'tcx>, cdata: &cstore::crate_metadata) -> Ty<'tcx> { + tcx: &ty::ctxt<'tcx>, + cdata: &cstore::crate_metadata) + -> Ty<'tcx> { self.read_opaque(|_, doc| { - Ok(tydecode::parse_ty_data( - doc.data, - cdata.cnum, - doc.start, - tcx, - |_, id| decoder::translate_def_id(cdata, id))) + Ok( + tydecode::TyDecoder::with_doc(tcx, cdata.cnum, doc, + &mut |_, id| decoder::translate_def_id(cdata, id)) + .parse_ty()) }).unwrap() } @@ -1149,32 +1153,22 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> { -> subst::Substs<'tcx> { self.read_opaque(|_, doc| { - Ok(tydecode::parse_substs_data( - doc.data, - cdata.cnum, - doc.start, - tcx, - |_, id| decoder::translate_def_id(cdata, id))) + Ok( + tydecode::TyDecoder::with_doc(tcx, cdata.cnum, doc, + &mut |_, id| decoder::translate_def_id(cdata, id)) + .parse_substs()) }).unwrap() } - fn read_ty<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>) -> Ty<'tcx> { - // Note: regions types embed local node ids. In principle, we - // should translate these node ids into the new decode - // context. However, we do not bother, because region types - // are not used during trans. - + fn read_ty_encoded<'b, 'c, F, R>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>, op: F) -> R + where F: for<'x> FnOnce(&mut tydecode::TyDecoder<'x,'tcx>) -> R + { return self.read_opaque(|this, doc| { - debug!("read_ty({})", type_string(doc)); - - let ty = tydecode::parse_ty_data( - doc.data, - dcx.cdata.cnum, - doc.start, - dcx.tcx, - |s, a| this.convert_def_id(dcx, s, a)); - - Ok(ty) + debug!("read_ty_encoded({})", type_string(doc)); + Ok(op( + &mut tydecode::TyDecoder::with_doc( + dcx.tcx, dcx.cdata.cnum, doc, + &mut |s, a| this.convert_def_id(dcx, s, a)))) }).unwrap(); fn type_string(doc: rbml::Doc) -> String { @@ -1186,6 +1180,15 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> { } } + fn read_ty<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>) -> Ty<'tcx> { + // Note: regions types embed local node ids. In principle, we + // should translate these node ids into the new decode + // context. However, we do not bother, because region types + // are not used during trans. + + return self.read_ty_encoded(dcx, |decoder| decoder.parse_ty()); + } + fn read_tys<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>) -> Vec> { self.read_to_vec(|this| Ok(this.read_ty(dcx))).unwrap().into_iter().collect() @@ -1193,49 +1196,23 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> { fn read_trait_ref<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>) -> ty::TraitRef<'tcx> { - self.read_opaque(|this, doc| { - let ty = tydecode::parse_trait_ref_data( - doc.data, - dcx.cdata.cnum, - doc.start, - dcx.tcx, - |s, a| this.convert_def_id(dcx, s, a)); - Ok(ty) - }).unwrap() + self.read_ty_encoded(dcx, |decoder| decoder.parse_trait_ref()) } fn read_poly_trait_ref<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>) -> ty::PolyTraitRef<'tcx> { - ty::Binder(self.read_opaque(|this, doc| { - let ty = tydecode::parse_trait_ref_data( - doc.data, - dcx.cdata.cnum, - doc.start, - dcx.tcx, - |s, a| this.convert_def_id(dcx, s, a)); - Ok(ty) - }).unwrap()) + ty::Binder(self.read_ty_encoded(dcx, |decoder| decoder.parse_trait_ref())) } fn read_type_param_def<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>) -> ty::TypeParameterDef<'tcx> { - self.read_opaque(|this, doc| { - Ok(tydecode::parse_type_param_def_data( - doc.data, - doc.start, - dcx.cdata.cnum, - dcx.tcx, - |s, a| this.convert_def_id(dcx, s, a))) - }).unwrap() + self.read_ty_encoded(dcx, |decoder| decoder.parse_type_param_def()) } fn read_predicate<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>) -> ty::Predicate<'tcx> { - self.read_opaque(|this, doc| { - Ok(tydecode::parse_predicate_data(doc.data, doc.start, dcx.cdata.cnum, dcx.tcx, - |s, a| this.convert_def_id(dcx, s, a))) - }).unwrap() + self.read_ty_encoded(dcx, |decoder| decoder.parse_predicate()) } fn read_type_scheme<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>) @@ -1269,13 +1246,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> { fn read_existential_bounds<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>) -> ty::ExistentialBounds<'tcx> { - self.read_opaque(|this, doc| { - Ok(tydecode::parse_existential_bounds_data(doc.data, - dcx.cdata.cnum, - doc.start, - dcx.tcx, - |s, a| this.convert_def_id(dcx, s, a))) - }).unwrap() + self.read_ty_encoded(dcx, |decoder| decoder.parse_existential_bounds()) } fn read_substs<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>) @@ -1380,14 +1351,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> { fn read_closure_ty<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>) -> ty::ClosureTy<'tcx> { - self.read_opaque(|this, doc| { - Ok(tydecode::parse_ty_closure_data( - doc.data, - dcx.cdata.cnum, - doc.start, - dcx.tcx, - |s, a| this.convert_def_id(dcx, s, a))) - }).unwrap() + self.read_ty_encoded(dcx, |decoder| decoder.parse_closure_ty()) } /// Converts a def-id that appears in a type. The correct From 7a3a1be5e462775ff5556db79c35ea5979aac8f8 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sat, 15 Aug 2015 21:35:49 -0400 Subject: [PATCH 7/7] remove the last remnants of old interface --- src/librustc/metadata/decoder.rs | 42 ++++++----- src/librustc/metadata/tydecode.rs | 117 +----------------------------- src/librustc/middle/astencode.rs | 8 +- 3 files changed, 29 insertions(+), 138 deletions(-) diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 11a5cc8c9d737..e8393d754f2de 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -24,9 +24,7 @@ use metadata::csearch; use metadata::cstore; use metadata::encoder::def_to_u64; use metadata::inline::InlinedItem; -use metadata::tydecode::{parse_ty_data, parse_region_data, - parse_type_param_def_data, parse_bare_fn_ty_data, - parse_trait_ref_data, parse_predicate_data}; +use metadata::tydecode::TyDecoder; use middle::def; use middle::lang_items; use middle::subst; @@ -235,22 +233,25 @@ fn variant_disr_val(d: rbml::Doc) -> Option { fn doc_type<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd) -> Ty<'tcx> { let tp = reader::get_doc(doc, tag_items_data_item_type); - parse_ty_data(tp.data, cdata.cnum, tp.start, tcx, - |_, did| translate_def_id(cdata, did)) + TyDecoder::with_doc(tcx, cdata.cnum, tp, + &mut |_, did| translate_def_id(cdata, did)) + .parse_ty() } fn maybe_doc_type<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd) -> Option> { reader::maybe_get_doc(doc, tag_items_data_item_type).map(|tp| { - parse_ty_data(tp.data, cdata.cnum, tp.start, tcx, - |_, did| translate_def_id(cdata, did)) + TyDecoder::with_doc(tcx, cdata.cnum, tp, + &mut |_, did| translate_def_id(cdata, did)) + .parse_ty() }) } fn doc_method_fty<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd) -> ty::BareFnTy<'tcx> { let tp = reader::get_doc(doc, tag_item_method_fty); - parse_bare_fn_ty_data(tp.data, cdata.cnum, tp.start, tcx, - |_, did| translate_def_id(cdata, did)) + TyDecoder::with_doc(tcx, cdata.cnum, tp, + &mut |_, did| translate_def_id(cdata, did)) + .parse_bare_fn_ty() } pub fn item_type<'tcx>(_item_id: ast::DefId, item: rbml::Doc, @@ -260,8 +261,9 @@ pub fn item_type<'tcx>(_item_id: ast::DefId, item: rbml::Doc, fn doc_trait_ref<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd) -> ty::TraitRef<'tcx> { - parse_trait_ref_data(doc.data, cdata.cnum, doc.start, tcx, - |_, did| translate_def_id(cdata, did)) + TyDecoder::with_doc(tcx, cdata.cnum, doc, + &mut |_, did| translate_def_id(cdata, did)) + .parse_trait_ref() } fn item_trait_ref<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd) @@ -1465,9 +1467,10 @@ fn doc_generics<'tcx>(base_doc: rbml::Doc, let mut types = subst::VecPerParamSpace::empty(); for p in reader::tagged_docs(doc, tag_type_param_def) { - let bd = parse_type_param_def_data( - p.data, p.start, cdata.cnum, tcx, - |_, did| translate_def_id(cdata, did)); + let bd = + TyDecoder::with_doc(tcx, cdata.cnum, p, + &mut |_, did| translate_def_id(cdata, did)) + .parse_type_param_def(); types.push(bd.space, bd); } @@ -1487,8 +1490,9 @@ fn doc_generics<'tcx>(base_doc: rbml::Doc, let index = reader::doc_as_u64(doc) as u32; let bounds = reader::tagged_docs(rp_doc, tag_items_data_region).map(|p| { - parse_region_data(p.data, cdata.cnum, p.start, tcx, - |_, did| translate_def_id(cdata, did)) + TyDecoder::with_doc(tcx, cdata.cnum, p, + &mut |_, did| translate_def_id(cdata, did)) + .parse_region() }).collect(); regions.push(space, ty::RegionParameterDef { name: name, @@ -1515,8 +1519,10 @@ fn doc_predicates<'tcx>(base_doc: rbml::Doc, let space = subst::ParamSpace::from_uint(reader::doc_as_u8(space_doc) as usize); let data_doc = reader::get_doc(predicate_doc, tag_predicate_data); - let data = parse_predicate_data(data_doc.data, data_doc.start, cdata.cnum, tcx, - |_, did| translate_def_id(cdata, did)); + let data = + TyDecoder::with_doc(tcx, cdata.cnum, data_doc, + &mut |_, did| translate_def_id(cdata, did)) + .parse_predicate(); predicates.push(space, data); } diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 52370f652a2fb..9219442cf6282 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -58,104 +58,6 @@ pub enum DefIdSource { ClosureSource } -pub fn parse_ty_closure_data<'tcx, F>(data: &[u8], - crate_num: ast::CrateNum, - pos: usize, - tcx: &ty::ctxt<'tcx>, - mut conv: F) - -> ty::ClosureTy<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - let mut st = TyDecoder::new(data, crate_num, pos, tcx, &mut conv); - st.parse_closure_ty() -} - -pub fn parse_ty_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: usize, - tcx: &ty::ctxt<'tcx>, mut conv: F) -> Ty<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - debug!("parse_ty_data {}", data_log_string(data, pos)); - let mut st = TyDecoder::new(data, crate_num, pos, tcx, &mut conv); - st.parse_ty() -} - -pub fn parse_region_data(data: &[u8], crate_num: ast::CrateNum, pos: usize, tcx: &ty::ctxt, - mut conv: F) -> ty::Region where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - debug!("parse_region_data {}", data_log_string(data, pos)); - let mut st = TyDecoder::new(data, crate_num, pos, tcx, &mut conv); - st.parse_region() -} - -pub fn parse_bare_fn_ty_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: usize, - tcx: &ty::ctxt<'tcx>, mut conv: F) - -> ty::BareFnTy<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - debug!("parse_bare_fn_ty_data {}", data_log_string(data, pos)); - let mut st = TyDecoder::new(data, crate_num, pos, tcx, &mut conv); - st.parse_bare_fn_ty() -} - -pub fn parse_trait_ref_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: usize, - tcx: &ty::ctxt<'tcx>, mut conv: F) - -> ty::TraitRef<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - debug!("parse_trait_ref_data {}", data_log_string(data, pos)); - let mut st = TyDecoder::new(data, crate_num, pos, tcx, &mut conv); - st.parse_trait_ref() -} - -pub fn parse_substs_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: usize, - tcx: &ty::ctxt<'tcx>, mut conv: F) -> subst::Substs<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - debug!("parse_substs_data{}", data_log_string(data, pos)); - let mut st = TyDecoder::new(data, crate_num, pos, tcx, &mut conv); - st.parse_substs() -} - -pub fn parse_existential_bounds_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, - pos: usize, tcx: &ty::ctxt<'tcx>, mut conv: F) - -> ty::ExistentialBounds<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - let mut st = TyDecoder::new(data, crate_num, pos, tcx, &mut conv); - st.parse_existential_bounds() -} - -pub fn parse_builtin_bounds_data(data: &[u8], crate_num: ast::CrateNum, - pos: usize, tcx: &ty::ctxt, mut conv: F) - -> ty::BuiltinBounds where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - let mut st = TyDecoder::new(data, crate_num, pos, tcx, &mut conv); - st.parse_builtin_bounds() -} - -pub fn parse_type_param_def_data<'tcx, F>(data: &[u8], start: usize, - crate_num: ast::CrateNum, tcx: &ty::ctxt<'tcx>, - mut conv: F) -> ty::TypeParameterDef<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - let mut st = TyDecoder::new(data, crate_num, start, tcx, &mut conv); - st.parse_type_param_def() -} - -pub fn parse_predicate_data<'tcx, F>(data: &[u8], - start: usize, - crate_num: ast::CrateNum, - tcx: &ty::ctxt<'tcx>, - mut conv: F) - -> ty::Predicate<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - let mut st = TyDecoder::new(data, crate_num, start, tcx, &mut conv); - st.parse_predicate() -} - pub type DefIdConvert<'a> = &'a mut FnMut(DefIdSource, ast::DefId) -> ast::DefId; pub struct TyDecoder<'a, 'tcx: 'a> { @@ -292,7 +194,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { } } - fn parse_region(&mut self) -> ty::Region { + pub fn parse_region(&mut self) -> ty::Region { match self.next() { 'b' => { assert_eq!(self.next(), '['); @@ -629,7 +531,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { } } - fn parse_bare_fn_ty(&mut self) -> ty::BareFnTy<'tcx> { + pub fn parse_bare_fn_ty(&mut self) -> ty::BareFnTy<'tcx> { let unsafety = parse_unsafety(self.next()); let abi = self.parse_abi_set(); let sig = self.parse_sig(); @@ -777,21 +679,6 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { } } -fn data_log_string(data: &[u8], pos: usize) -> String { - let mut buf = String::new(); - buf.push_str("<<"); - for i in pos..data.len() { - let c = data[i]; - if c > 0x20 && c <= 0x7F { - buf.push(c as char); - } else { - buf.push('.'); - } - } - buf.push_str(">>"); - buf -} - // Rust metadata parsing fn parse_defid(buf: &[u8]) -> ast::DefId { let mut colon_idx = 0; diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index e544d8d474979..591fc043f914c 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -1252,11 +1252,9 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> { fn read_substs<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>) -> subst::Substs<'tcx> { self.read_opaque(|this, doc| { - Ok(tydecode::parse_substs_data(doc.data, - dcx.cdata.cnum, - doc.start, - dcx.tcx, - |s, a| this.convert_def_id(dcx, s, a))) + Ok(tydecode::TyDecoder::with_doc(dcx.tcx, dcx.cdata.cnum, doc, + &mut |s, a| this.convert_def_id(dcx, s, a)) + .parse_substs()) }).unwrap() }