diff --git a/src/librustc/ast_map/mod.rs b/src/librustc/ast_map/mod.rs index a193ffcc731..b38c15d0f6a 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 2ade251018f..d33b163c972 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 fdd45251711..0554d35a920 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -23,9 +23,8 @@ use metadata::csearch::MethodInfo; use metadata::csearch; use metadata::cstore; use metadata::encoder::def_to_u64; -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::inline::InlinedItem; +use metadata::tydecode::TyDecoder; use middle::def; use middle::lang_items; use middle::subst; @@ -234,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, @@ -259,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) @@ -776,7 +779,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) @@ -1468,9 +1471,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); } @@ -1490,8 +1494,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, @@ -1518,8 +1523,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/encoder.rs b/src/librustc/metadata/encoder.rs index cc723d94f74..91638f0de7e 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::dependency_format::Linkage; use middle::stability; @@ -48,14 +47,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; @@ -832,7 +823,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(); @@ -870,7 +861,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); @@ -1052,7 +1043,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(); @@ -1069,7 +1060,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); @@ -1134,7 +1125,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. @@ -1182,7 +1173,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); @@ -1457,7 +1448,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 @@ -1471,7 +1462,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'); } @@ -1510,7 +1502,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 00000000000..ba09e173fd8 --- /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 0bf1e6d198f..44901eb0547 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/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index a8b22846b78..9219442cf62 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; @@ -57,677 +58,629 @@ 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> { +pub struct TyDecoder<'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 { - 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(st: &mut PState, mut is_last: F, op: G) -> R where - F: FnMut(char) -> bool, - G: FnOnce(&[u8]) -> R, -{ - 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); +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) } - let end_pos = st.pos; - st.pos += 1; - return op(&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) ) -} + pub fn new(data: &'a [u8], + crate_num: ast::CrateNum, + pos: usize, + tcx: &'a ty::ctxt<'tcx>, + conv: DefIdConvert<'a>) + -> TyDecoder<'a, 'tcx> { + TyDecoder { + data: data, + krate: crate_num, + pos: pos, + tcx: tcx, + conv_def_id: conv, + } + } -fn parse_name_(st: &mut PState, is_last: F) -> ast::Name where - F: FnMut(char) -> bool, -{ - scan(st, is_last, |bytes| { + 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 end_pos = self.pos; + self.pos += 1; + return &self.data[start_pos..end_pos]; + } + + 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()) - }) -} - -pub fn parse_state_from_data<'a, 'tcx>(data: &'a [u8], crate_num: ast::CrateNum, - pos: usize, tcx: &'a ty::ctxt<'tcx>) - -> PState<'a, 'tcx> { - PState { - data: data, - krate: crate_num, - pos: pos, - tcx: 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); + fn parse_size(&mut self) -> Option { + assert_eq!(self.next(), '/'); + + if self.peek() == '|' { + assert_eq!(self.next(), '|'); + None } else { - buf.push('.'); + let n = self.parse_uint(); + assert_eq!(self.next(), '|'); + Some(n) } } - buf.push_str(">>"); - buf -} -pub fn parse_ty_closure_data<'tcx, F>(data: &[u8], - crate_num: ast::CrateNum, - pos: usize, - tcx: &ty::ctxt<'tcx>, - 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) -} - -pub fn parse_ty_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: usize, - tcx: &ty::ctxt<'tcx>, 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) -} - -pub fn parse_region_data(data: &[u8], crate_num: ast::CrateNum, pos: usize, tcx: &ty::ctxt, - 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) -} - -pub fn parse_bare_fn_ty_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: usize, - tcx: &ty::ctxt<'tcx>, 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) -} - -pub fn parse_trait_ref_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: usize, - tcx: &ty::ctxt<'tcx>, 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) -} - -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 - 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) -} - -pub fn parse_existential_bounds_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, - pos: usize, tcx: &ty::ctxt<'tcx>, 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) -} - -pub fn parse_builtin_bounds_data(data: &[u8], crate_num: ast::CrateNum, - pos: usize, tcx: &ty::ctxt, 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) -} - -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) - } -} - -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, -{ - let mut r = VecPerParamSpace::empty(); - for &space in &subst::ParamSpace::all() { - assert_eq!(next(st), '['); - while peek(st) != ']' { - r.push(space, f(st)); + fn parse_vec_per_param_space(&mut self, mut f: F) -> VecPerParamSpace where + F: FnMut(&mut TyDecoder<'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(), ']'); } - assert_eq!(next(st), ']'); + r } - 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, 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, -{ - match next(st) { - 'e' => subst::ErasedRegions, - 'n' => { - subst::NonerasedRegions( - parse_vec_per_param_space( - st, |st| parse_region_(st, conv))) - } - _ => panic!("parse_bound_region: bad input") + 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 } } -} -fn parse_bound_region_(st: &mut PState, conv: &mut F) -> ty::BoundRegion where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - match next(st) { - 'a' => { - let id = parse_u32(st); - assert_eq!(next(st), '|'); - ty::BrAnon(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") } - '[' => { - let def = parse_def_(st, RegionParameter, conv); - let ident = token::str_to_ident(&parse_str(st, ']')); - ty::BrNamed(def, ident.name) - } - 'f' => { - let id = parse_u32(st); - assert_eq!(next(st), '|'); - ty::BrFresh(id) - } - 'e' => ty::BrEnv, - _ => panic!("parse_bound_region: bad input") } -} -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, -{ - 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); - 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, conv); - 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_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") + } } -} -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 + pub 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") + } + } + + 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") + } + } + + 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(&mut self, f: F) -> Option + where F: FnOnce(&mut TyDecoder<'a, 'tcx>) -> T, + { + match self.next() { + 'n' => None, + 's' => Some(f(self)), + _ => panic!("parse_opt: bad input") + } + } + + 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()]) } } - 'M' => { - let node_id = parse_uint(st) as ast::NodeId; - region::CodeExtent::Misc(node_id) - } - 'D' => { - let node_id = parse_uint(st) as ast::NodeId; - region::CodeExtent::DestructionScope(node_id) - } - '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) - } - _ => panic!("parse_scope: bad input") + self.next(); + result } -} -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_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") + 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_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)]) - } - } - next(st); - result -} + pub 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. -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) -} + 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 => {} + } -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)); - 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, -{ - 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, conv); - let substs = parse_substs_(st, conv); - 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); - 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, conv)), - '*' => return tcx.mk_ptr(parse_mt_(st, conv)), - '&' => { - let r = parse_region_(st, conv); - let mt = parse_mt_(st, conv); - return tcx.mk_ref(tcx.mk_region(r), mt); - } - 'V' => { - let t = parse_ty_(st, conv); - 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, conv)); } - 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))); - } - 'G' => { - return tcx.mk_fn(None, tcx.mk_bare_fn(parse_bare_fn_ty_(st, conv))); - } - '#' => { - 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() { + 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; } - } - 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, - .. *st - }; - let tt = parse_ty_(&mut ps, conv); - tcx.rcache.borrow_mut().insert(key, tt); - return tt; - } - '\"' => { - let _ = parse_def_(st, TypeWithId, conv); - let inner = parse_ty_(st, conv); - inner - } - 'a' => { - assert_eq!(next(st), '['); - let did = parse_def_(st, NominalType, conv); - let substs = parse_substs_(st, conv); - 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 mut tys = vec![]; - while peek(st) != '.' { - tys.push(parse_ty_(st, conv)); - } - 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, conv); - 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_mutability(st: &mut PState) -> ast::Mutability { - match peek(st) { - 'm' => { next(st); ast::MutMutable } - _ => { ast::MutImmutable } + fn parse_mutability(&mut self) -> ast::Mutability { + match self.peek() { + 'm' => { self.next(); ast::MutMutable } + _ => { ast::MutImmutable } + } } -} -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, -{ - let m = parse_mutability(st); - ty::TypeAndMut { ty: parse_ty_(st, conv), mutbl: m } -} + fn parse_mt(&mut self) -> ty::TypeAndMut<'tcx> { + let m = self.parse_mutability(); + ty::TypeAndMut { ty: self.parse_ty(), 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(&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(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_u32(st: &mut PState) -> u32 { - let n = parse_uint(st); - let m = n as u32; - assert_eq!(m as usize, n); - m -} - -fn parse_param_space(st: &mut PState) -> subst::ParamSpace { - subst::ParamSpace::from_uint(parse_uint(st)) -} - -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' { + 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); - } else { n += 10 + (cur as usize) - ('a' as usize); } - }; -} - -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_abi_set(st: &mut PState) -> abi::Abi { - assert_eq!(next(st), '['); - scan(st, |c| c == ']', |bytes| { + 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_param_space(&mut self) -> subst::ParamSpace { + subst::ParamSpace::from_uint(self.parse_uint()) + } + + 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_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_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, -{ - let unsafety = parse_unsafety(next(st)); - let sig = parse_sig_(st, conv); - let abi = parse_abi_set(st); - ty::ClosureTy { - unsafety: unsafety, - sig: sig, - abi: abi, } -} -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, -{ - let unsafety = parse_unsafety(next(st)); - let abi = parse_abi_set(st); - let sig = parse_sig_(st, conv); - ty::BareFnTy { - unsafety: unsafety, - abi: abi, - sig: sig - } -} - -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, -{ - assert_eq!(next(st), '['); - let mut inputs = Vec::new(); - while peek(st) != ']' { - inputs.push(parse_ty_(st, conv)); - } - 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 + 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(); + ty::ClosureTy { + unsafety: unsafety, + sig: sig, + abi: abi, } - _ => ty::FnConverging(parse_ty_(st, conv)) - }; - ty::Binder(ty::FnSig {inputs: inputs, - output: output, - variadic: variadic}) + } + + 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(); + ty::BareFnTy { + unsafety: unsafety, + abi: abi, + sig: sig + } + } + + 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}) + } + + 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_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(), + } + } + + 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(); + 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") + } + } + + 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(); + + loop { + match self.next() { + 'P' => { + projection_bounds.push(ty::Binder(self.parse_projection_predicate())); + } + '.' => { break; } + c => { + panic!("parse_bounds: bad bounds ('{}')", c) + } + } + } + + return ty::ExistentialBounds { region_bound: region_bound, + builtin_bounds: builtin_bounds, + projection_bounds: projection_bounds }; + } + + 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) + } + } + } + } } // Rust metadata parsing -pub fn parse_def_id(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; } @@ -742,202 +695,25 @@ pub fn parse_def_id(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_def_id: 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_def_id: 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>, - 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) -} - -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, -{ - 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)), - 'O' => { - let def_id = parse_def_(st, NominalType, conv); - assert_eq!(next(st), '|'); - 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_<'a,'tcx, F>( - st: &mut PState<'a, 'tcx>, - conv: &mut F, -) -> ty::ProjectionPredicate<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - ty::ProjectionPredicate { - projection_ty: ty::ProjectionTy { - trait_ref: parse_trait_ref_(st, conv), - item_name: token::str_to_ident(&parse_str(st, '|')).name, - }, - ty: parse_ty_(st, conv), - } -} - -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 - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - parse_type_param_def_(st, &mut conv) -} - -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, -{ - let name = parse_name(st, ':'); - let def_id = parse_def_(st, NominalType, conv); - 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); - - 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, F>(st: &mut PState<'a,'tcx>, - conv: &mut F) - -> ty::ObjectLifetimeDefault - where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - match next(st) { - 'a' => ty::ObjectLifetimeDefault::Ambiguous, - 'b' => ty::ObjectLifetimeDefault::BaseDefault, - 's' => { - let region = parse_region_(st, conv); - 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); - let mut projection_bounds = Vec::new(); - - loop { - match next(st) { - 'P' => { - projection_bounds.push( - ty::Binder(parse_projection_predicate_(st, conv))); - } - '.' => { break; } - c => { - panic!("parse_bounds: bad bounds ('{}')", c) - } - } - } - - return ty::ExistentialBounds { region_bound: region_bound, - builtin_bounds: builtin_bounds, - 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, -{ - 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) - } - } - } -} diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index c064b31173f..591fc043f91 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 }); @@ -1074,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>) @@ -1122,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() } @@ -1148,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 { @@ -1185,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() @@ -1192,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>) @@ -1268,23 +1246,15 @@ 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>) -> 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() } @@ -1379,14 +1349,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 @@ -1644,15 +1607,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 fd1c8d4892a..a1327df224a 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 2a033d36a47..dafc1e900f3 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 01bfc51a5c0..c6450d06eb6 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 08c6dcc7f87..0bcd97cfe87 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 83d3c9c4ec5..7aff92ecb70 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 ad144d6033b..259564337a2 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 {