rustc_metadata: side-step ty{en,de}code for everything but Ty.

This commit is contained in:
Eduard Burtescu 2016-09-02 00:49:29 +03:00
parent 0863012fb9
commit bcbb4107a1
7 changed files with 99 additions and 380 deletions

View file

@ -668,7 +668,7 @@ pub enum IntVarValue {
/// from `T:'a` annotations appearing in the type definition. If
/// this is `None`, then the default is inherited from the
/// surrounding context. See RFC #599 for details.
#[derive(Copy, Clone)]
#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
pub enum ObjectLifetimeDefault<'tcx> {
/// Require an explicit annotation. Occurs when multiple
/// `T:'a` constraints are found.
@ -681,7 +681,7 @@ pub enum ObjectLifetimeDefault<'tcx> {
Specific(&'tcx Region),
}
#[derive(Clone)]
#[derive(Clone, RustcEncodable, RustcDecodable)]
pub struct TypeParameterDef<'tcx> {
pub name: Name,
pub def_id: DefId,
@ -691,7 +691,7 @@ pub struct TypeParameterDef<'tcx> {
pub object_lifetime_default: ObjectLifetimeDefault<'tcx>,
}
#[derive(Clone)]
#[derive(Clone, RustcEncodable, RustcDecodable)]
pub struct RegionParameterDef<'tcx> {
pub name: Name,
pub def_id: DefId,
@ -719,7 +719,7 @@ impl<'tcx> RegionParameterDef<'tcx> {
/// Information about the formal type/lifetime parameters associated
/// with an item or method. Analogous to hir::Generics.
#[derive(Clone, Debug)]
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct Generics<'tcx> {
pub parent: Option<DefId>,
pub parent_regions: u32,
@ -786,7 +786,7 @@ impl<'a, 'gcx, 'tcx> GenericPredicates<'tcx> {
}
}
#[derive(Clone, PartialEq, Eq, Hash)]
#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub enum Predicate<'tcx> {
/// Corresponds to `where Foo : Bar<A,B,C>`. `Foo` here would be
/// the `Self` type of the trait reference and `A`, `B`, and `C`
@ -910,7 +910,7 @@ impl<'a, 'gcx, 'tcx> Predicate<'tcx> {
}
}
#[derive(Clone, PartialEq, Eq, Hash)]
#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub struct TraitPredicate<'tcx> {
pub trait_ref: TraitRef<'tcx>
}
@ -967,11 +967,11 @@ impl<'tcx> PolyTraitPredicate<'tcx> {
}
}
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
#[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
pub struct EquatePredicate<'tcx>(pub Ty<'tcx>, pub Ty<'tcx>); // `0 == 1`
pub type PolyEquatePredicate<'tcx> = ty::Binder<EquatePredicate<'tcx>>;
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
#[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
pub struct OutlivesPredicate<A,B>(pub A, pub B); // `A : B`
pub type PolyOutlivesPredicate<A,B> = ty::Binder<OutlivesPredicate<A,B>>;
pub type PolyRegionOutlivesPredicate<'tcx> = PolyOutlivesPredicate<&'tcx ty::Region,
@ -990,7 +990,7 @@ pub type PolyTypeOutlivesPredicate<'tcx> = PolyOutlivesPredicate<Ty<'tcx>, &'tcx
/// equality between arbitrary types. Processing an instance of Form
/// #2 eventually yields one of these `ProjectionPredicate`
/// instances to normalize the LHS.
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub struct ProjectionPredicate<'tcx> {
pub projection_ty: ProjectionTy<'tcx>,
pub ty: Ty<'tcx>,

View file

@ -290,7 +290,7 @@ pub struct TraitObject<'tcx> {
/// Note that a `TraitRef` introduces a level of region binding, to
/// account for higher-ranked trait bounds like `T : for<'a> Foo<&'a
/// U>` or higher-ranked object types.
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub struct TraitRef<'tcx> {
pub def_id: DefId,
pub substs: &'tcx Substs<'tcx>,
@ -366,7 +366,7 @@ impl<'tcx> PolyExistentialTraitRef<'tcx> {
/// erase, or otherwise "discharge" these bound regions, we change the
/// type from `Binder<T>` to just `T` (see
/// e.g. `liberate_late_bound_regions`).
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
pub struct Binder<T>(pub T);
impl<T> Binder<T> {
@ -414,7 +414,7 @@ impl fmt::Debug for TypeFlags {
/// Represents the projection of an associated type. In explicit UFCS
/// form this would be written `<T as Trait<..>>::N`.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
pub struct ProjectionTy<'tcx> {
/// The trait reference `T as Trait<..>`.
pub trait_ref: ty::TraitRef<'tcx>,
@ -430,7 +430,7 @@ pub struct BareFnTy<'tcx> {
pub sig: PolyFnSig<'tcx>,
}
#[derive(Clone, PartialEq, Eq, Hash)]
#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub struct ClosureTy<'tcx> {
pub unsafety: hir::Unsafety,
pub abi: abi::Abi,
@ -443,7 +443,7 @@ pub struct ClosureTy<'tcx> {
/// - `inputs` is the list of arguments and their modes.
/// - `output` is the return type.
/// - `variadic` indicates whether this is a variadic function. (only true for foreign fns)
#[derive(Clone, PartialEq, Eq, Hash)]
#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub struct FnSig<'tcx> {
pub inputs: Vec<Ty<'tcx>>,
pub output: Ty<'tcx>,

View file

@ -14,7 +14,7 @@ use hir::def_id::DefId;
use ty::{self, Ty, TyCtxt};
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
use serialize;
use serialize::{self, Encodable, Encoder, Decodable, Decoder};
use syntax_pos::{Span, DUMMY_SP};
use core::nonzero::NonZero;
@ -128,8 +128,40 @@ impl<'tcx> TypeFoldable<'tcx> for Kind<'tcx> {
}
}
impl<'tcx> Encodable for Kind<'tcx> {
fn encode<E: Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
e.emit_enum("Kind", |e| {
if let Some(ty) = self.as_type() {
e.emit_enum_variant("Ty", TYPE_TAG, 1, |e| {
e.emit_enum_variant_arg(0, |e| ty.encode(e))
})
} else if let Some(r) = self.as_region() {
e.emit_enum_variant("Region", REGION_TAG, 1, |e| {
e.emit_enum_variant_arg(0, |e| r.encode(e))
})
} else {
bug!()
}
})
}
}
impl<'tcx> Decodable for Kind<'tcx> {
fn decode<D: Decoder>(d: &mut D) -> Result<Kind<'tcx>, D::Error> {
d.read_enum("Kind", |d| {
d.read_enum_variant(&["Ty", "Region"], |d, tag| {
match tag {
TYPE_TAG => Ty::decode(d).map(Kind::from),
REGION_TAG => <&ty::Region>::decode(d).map(Kind::from),
_ => Err(d.error("invalid Kind tag"))
}
})
})
}
}
/// A substitution mapping type/region parameters to new values.
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
#[derive(Clone, PartialEq, Eq, Debug, Hash, RustcEncodable, RustcDecodable)]
pub struct Substs<'tcx> {
params: Vec<Kind<'tcx>>
}
@ -297,7 +329,6 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx Substs<'tcx> {
}
}
impl<'tcx> serialize::UseSpecializedEncodable for &'tcx Substs<'tcx> {}
impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Substs<'tcx> {}
///////////////////////////////////////////////////////////////////////////

View file

@ -94,16 +94,6 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
pub fn cdata(&self) -> &'a cstore::CrateMetadata {
self.cdata.expect("missing CrateMetadata in DecodeContext")
}
fn read_ty_encoded<F, R>(&mut self, op: F) -> R
where F: for<'x> FnOnce(&mut TyDecoder<'x,'tcx>) -> R
{
let pos = self.opaque.position();
let doc = rbml::Doc::at(self.opaque.data, pos);
self.opaque.advance(doc.end - pos);
op(&mut TyDecoder::with_doc(self.tcx(), self.cdata().cnum, doc,
&mut |d| translate_def_id(self.cdata(), d)))
}
}
macro_rules! decoder_methods {
@ -243,13 +233,19 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
impl<'a, 'tcx> SpecializedDecoder<Ty<'tcx>> for DecodeContext<'a, 'tcx> {
fn specialized_decode(&mut self) -> Result<Ty<'tcx>, Self::Error> {
Ok(self.read_ty_encoded(|d| d.parse_ty()))
let pos = self.opaque.position();
let doc = rbml::Doc::at(self.opaque.data, pos);
self.opaque.advance(doc.end - pos);
Ok(TyDecoder::with_doc(self.tcx(), self.cdata().cnum, doc,
&mut |d| translate_def_id(self.cdata(), d))
.parse_ty())
}
}
impl<'a, 'tcx> SpecializedDecoder<&'tcx Substs<'tcx>> for DecodeContext<'a, 'tcx> {
fn specialized_decode(&mut self) -> Result<&'tcx Substs<'tcx>, Self::Error> {
Ok(self.read_ty_encoded(|d| d.parse_substs()))
let substs = Substs::decode(self)?;
Ok(self.tcx().mk_substs(substs))
}
}
@ -469,26 +465,25 @@ fn variant_disr_val(d: rbml::Doc) -> u64 {
}
fn doc_type<'a, 'tcx>(doc: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>, cdata: Cmd) -> Ty<'tcx> {
let tp = reader::get_doc(doc, tag_items_data_item_type);
TyDecoder::with_doc(tcx, cdata.cnum, tp,
&mut |did| translate_def_id(cdata, did))
.parse_ty()
maybe_doc_type(doc, tcx, cdata).expect("missing tag_items_data_item_type")
}
fn maybe_doc_type<'a, 'tcx>(doc: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>, cdata: Cmd)
-> Option<Ty<'tcx>> {
reader::maybe_get_doc(doc, tag_items_data_item_type).map(|tp| {
TyDecoder::with_doc(tcx, cdata.cnum, tp,
&mut |did| translate_def_id(cdata, did))
.parse_ty()
let mut dcx = tp.decoder();
dcx.tcx = Some(tcx);
dcx.cdata = Some(cdata);
Decodable::decode(&mut dcx).unwrap()
})
}
fn doc_trait_ref<'a, 'tcx>(doc: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>, cdata: Cmd)
-> ty::TraitRef<'tcx> {
TyDecoder::with_doc(tcx, cdata.cnum, doc,
&mut |did| translate_def_id(cdata, did))
.parse_trait_ref()
let mut dcx = doc.decoder();
dcx.tcx = Some(tcx);
dcx.cdata = Some(cdata);
Decodable::decode(&mut dcx).unwrap()
}
fn item_trait_ref<'a, 'tcx>(doc: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>, cdata: Cmd)
@ -1628,10 +1623,10 @@ fn doc_generics<'a, 'tcx>(base_doc: rbml::Doc,
cdata: Cmd)
-> &'tcx ty::Generics<'tcx>
{
let doc = reader::get_doc(base_doc, tag_item_generics);
TyDecoder::with_doc(tcx, cdata.cnum, doc,
&mut |did| translate_def_id(cdata, did))
.parse_generics()
let mut dcx = reader::get_doc(base_doc, tag_item_generics).decoder();
dcx.tcx = Some(tcx);
dcx.cdata = Some(cdata);
tcx.alloc_generics(Decodable::decode(&mut dcx).unwrap())
}
fn doc_predicate<'a, 'tcx>(cdata: Cmd,
@ -1641,10 +1636,14 @@ fn doc_predicate<'a, 'tcx>(cdata: Cmd,
{
let predicate_pos = cdata.xref_index.lookup(
cdata.data(), reader::doc_as_u32(doc)).unwrap() as usize;
TyDecoder::new(
cdata.data(), cdata.cnum, predicate_pos, tcx,
&mut |did| translate_def_id(cdata, did)
).parse_predicate()
let mut dcx = rbml::Doc {
data: cdata.data(),
start: predicate_pos,
end: cdata.data().len(),
}.decoder();
dcx.tcx = Some(tcx);
dcx.cdata = Some(cdata);
Decodable::decode(&mut dcx).unwrap()
}
fn doc_predicates<'a, 'tcx>(base_doc: rbml::Doc,
@ -1694,8 +1693,10 @@ pub fn closure_ty<'a, 'tcx>(cdata: Cmd, closure_id: DefIndex, tcx: TyCtxt<'a, 't
-> ty::ClosureTy<'tcx> {
let closure_doc = cdata.lookup_item(closure_id);
let closure_ty_doc = reader::get_doc(closure_doc, tag_items_closure_ty);
TyDecoder::with_doc(tcx, cdata.cnum, closure_ty_doc, &mut |did| translate_def_id(cdata, did))
.parse_closure_ty()
let mut dcx = closure_ty_doc.decoder();
dcx.tcx = Some(tcx);
dcx.cdata = Some(cdata);
Decodable::decode(&mut dcx).unwrap()
}
pub fn def_key(cdata: Cmd, id: DefIndex) -> hir_map::DefKey {

View file

@ -28,7 +28,6 @@ use middle::dependency_format::Linkage;
use rustc::dep_graph::DepNode;
use rustc::traits::specialization_graph;
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::subst::Substs;
use rustc::hir::svh::Svh;
use rustc::mir::mir_map::MirMap;
@ -126,17 +125,6 @@ impl<'a, 'tcx> SpecializedEncoder<Ty<'tcx>> for EncodeContext<'a, 'tcx> {
}
}
impl<'a, 'tcx> SpecializedEncoder<&'tcx Substs<'tcx>> for EncodeContext<'a, 'tcx> {
fn specialized_encode(&mut self, substs: &&'tcx Substs<'tcx>) -> Result<(), Self::Error> {
let cx = self.ty_str_ctxt();
self.start_tag(tag_opaque)?;
tyencode::enc_substs(&mut self.rbml_w.opaque.cursor, &cx, substs);
self.mark_stable_position();
self.end_tag()
}
}
fn encode_name(ecx: &mut EncodeContext, name: Name) {
ecx.wr_tagged_str(tag_paths_data_name, &name.as_str());
}
@ -163,10 +151,8 @@ fn encode_def_id_and_key(ecx: &mut EncodeContext, def_id: DefId) {
fn encode_trait_ref<'a, 'tcx>(ecx: &mut EncodeContext<'a, 'tcx>,
trait_ref: ty::TraitRef<'tcx>,
tag: usize) {
let cx = ecx.ty_str_ctxt();
ecx.start_tag(tag);
tyencode::enc_trait_ref(&mut ecx.opaque.cursor, &cx, trait_ref);
ecx.mark_stable_position();
trait_ref.encode(ecx).unwrap();
ecx.end_tag();
}
@ -211,19 +197,10 @@ fn encode_variant_id(ecx: &mut EncodeContext, vid: DefId) {
ecx.wr_tagged_u64(tag_mod_child, id);
}
fn write_closure_type<'a, 'tcx>(ecx: &mut EncodeContext<'a, 'tcx>,
closure_type: &ty::ClosureTy<'tcx>) {
let cx = ecx.ty_str_ctxt();
tyencode::enc_closure_ty(&mut ecx.opaque.cursor, &cx, closure_type);
ecx.mark_stable_position();
}
impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> {
fn encode_type(&mut self, typ: Ty<'tcx>) {
let cx = self.ty_str_ctxt();
self.start_tag(tag_items_data_item_type);
tyencode::enc_ty(&mut self.opaque.cursor, &cx, typ);
self.mark_stable_position();
typ.encode(self.ecx).unwrap();
self.end_tag();
}
@ -519,10 +496,8 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> {
generics: &ty::Generics<'tcx>,
predicates: &ty::GenericPredicates<'tcx>)
{
let cx = self.ty_str_ctxt();
self.start_tag(tag_item_generics);
tyencode::enc_generics(&mut self.opaque.cursor, &cx, generics);
self.mark_stable_position();
generics.encode(self.ecx).unwrap();
self.end_tag();
self.encode_predicates(predicates, tag_item_predicates);
}
@ -859,7 +834,6 @@ fn encode_xrefs<'a, 'tcx>(ecx: &mut EncodeContext<'a, 'tcx>,
xrefs: FnvHashMap<XRef<'tcx>, u32>)
{
let mut xref_positions = vec![0; xrefs.len()];
let cx = ecx.ty_str_ctxt();
// Encode XRefs sorted by their ID
let mut sorted_xrefs: Vec<_> = xrefs.into_iter().collect();
@ -869,9 +843,7 @@ fn encode_xrefs<'a, 'tcx>(ecx: &mut EncodeContext<'a, 'tcx>,
for (xref, id) in sorted_xrefs.into_iter() {
xref_positions[id as usize] = ecx.mark_stable_position() as u32;
match xref {
XRef::Predicate(p) => {
tyencode::enc_predicate(&mut ecx.opaque.cursor, &cx, &p)
}
XRef::Predicate(p) => p.encode(ecx).unwrap()
}
}
ecx.mark_stable_position();
@ -1396,8 +1368,7 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> {
encode_name(self, syntax::parse::token::intern("<closure>"));
self.start_tag(tag_items_closure_ty);
write_closure_type(self,
&tcx.tables.borrow().closure_tys[&def_id]);
tcx.tables.borrow().closure_tys[&def_id].encode(self.ecx).unwrap();
self.end_tag();
self.start_tag(tag_items_closure_kind);

View file

@ -21,7 +21,7 @@ use rustc::hir;
use rustc::hir::def_id::{CrateNum, DefId, DefIndex};
use middle::region;
use rustc::ty::subst::{Kind, Substs};
use rustc::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable};
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
use rbml;
use rustc_serialize::leb128;
@ -109,12 +109,6 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
value as usize
}
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<usize> {
assert_eq!(self.next(), '/');
@ -128,7 +122,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
}
}
pub fn parse_substs(&mut self) -> &'tcx Substs<'tcx> {
fn parse_substs(&mut self) -> &'tcx Substs<'tcx> {
let mut params = vec![];
assert_eq!(self.next(), '[');
while self.peek() != ']' {
@ -144,34 +138,6 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
Substs::new(self.tcx, params)
}
pub fn parse_generics(&mut self) -> &'tcx ty::Generics<'tcx> {
let parent = self.parse_opt(|this| this.parse_def());
let parent_regions = self.parse_u32();
assert_eq!(self.next(), '|');
let parent_types = self.parse_u32();
let mut regions = vec![];
let mut types = vec![];
assert_eq!(self.next(), '[');
while self.peek() != '|' {
regions.push(self.parse_region_param_def());
}
assert_eq!(self.next(), '|');
while self.peek() != ']' {
types.push(self.parse_type_param_def());
}
assert_eq!(self.next(), ']');
self.tcx.alloc_generics(ty::Generics {
parent: parent,
parent_regions: parent_regions,
parent_types: parent_types,
regions: regions,
types: types,
has_self: self.next() == 'S'
})
}
fn parse_bound_region(&mut self) -> ty::BoundRegion {
match self.next() {
'a' => {
@ -207,7 +173,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
}
}
pub fn parse_region(&mut self) -> &'tcx ty::Region {
fn parse_region(&mut self) -> &'tcx ty::Region {
self.tcx.mk_region(match self.next() {
'b' => {
assert_eq!(self.next(), '[');
@ -300,16 +266,6 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
})
}
fn parse_opt<T, F>(&mut self, f: F) -> Option<T>
where F: FnOnce(&mut TyDecoder<'a, 'tcx>) -> T,
{
match self.next() {
'n' => None,
's' => Some(f(self)),
_ => bug!("parse_opt: bad input")
}
}
fn parse_str(&mut self, term: char) -> String {
let mut result = String::new();
while self.peek() != term {
@ -321,14 +277,14 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
result
}
pub fn parse_trait_ref(&mut self) -> ty::TraitRef<'tcx> {
fn parse_trait_ref(&mut self) -> ty::TraitRef<'tcx> {
ty::TraitRef {
def_id: self.parse_def(),
substs: self.parse_substs()
}
}
pub fn parse_existential_trait_ref(&mut self) -> ty::ExistentialTraitRef<'tcx> {
fn parse_existential_trait_ref(&mut self) -> ty::ExistentialTraitRef<'tcx> {
ty::ExistentialTraitRef {
def_id: self.parse_def(),
substs: self.parse_substs()
@ -538,18 +494,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
abi::lookup(&abi_str[..]).expect(abi_str)
}
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,
}
}
pub fn parse_bare_fn_ty(&mut self) -> &'tcx ty::BareFnTy<'tcx> {
fn parse_bare_fn_ty(&mut self) -> &'tcx ty::BareFnTy<'tcx> {
let unsafety = parse_unsafety(self.next());
let abi = self.parse_abi_set();
let sig = self.parse_sig();
@ -578,48 +523,6 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
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();
assert_eq!(self.next(), '|');
ty::Predicate::ObjectSafe(def_id)
}
'c' => {
let def_id = self.parse_def();
assert_eq!(self.next(), '|');
let kind = match self.next() {
'f' => ty::ClosureKind::Fn,
'm' => ty::ClosureKind::FnMut,
'o' => ty::ClosureKind::FnOnce,
c => bug!("Encountered invalid character in metadata: {}", c)
};
assert_eq!(self.next(), '|');
ty::Predicate::ClosureKind(def_id, kind)
}
c => bug!("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::intern(&self.parse_str('|')),
},
ty: self.parse_ty(),
}
}
fn parse_existential_projection(&mut self) -> ty::ExistentialProjection<'tcx> {
ty::ExistentialProjection {
trait_ref: self.parse_existential_trait_ref(),
@ -628,61 +531,6 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
}
}
fn parse_type_param_def(&mut self) -> ty::TypeParameterDef<'tcx> {
let name = self.parse_name(':');
let def_id = self.parse_def();
let index = self.parse_u32();
assert_eq!(self.next(), '|');
let default_def_id = self.parse_def();
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,
index: index,
default_def_id: default_def_id,
default: default,
object_lifetime_default: object_lifetime_default,
}
}
fn parse_region_param_def(&mut self) -> ty::RegionParameterDef<'tcx> {
let name = self.parse_name(':');
let def_id = self.parse_def();
let index = self.parse_u32();
assert_eq!(self.next(), '|');
let mut bounds = vec![];
loop {
match self.next() {
'R' => bounds.push(self.parse_region()),
'.' => { break; }
c => {
bug!("parse_region_param_def: bad bounds ('{}')", c)
}
}
}
ty::RegionParameterDef {
name: name,
def_id: def_id,
index: index,
bounds: bounds,
}
}
fn parse_object_lifetime_default(&mut self) -> ty::ObjectLifetimeDefault<'tcx> {
match self.next() {
'a' => ty::ObjectLifetimeDefault::Ambiguous,
'b' => ty::ObjectLifetimeDefault::BaseDefault,
's' => {
let region = self.parse_region();
ty::ObjectLifetimeDefault::Specific(region)
}
_ => bug!("parse_object_lifetime_default: bad input")
}
}
fn parse_builtin_bounds(&mut self) -> ty::BuiltinBounds {
let mut builtin_bounds = ty::BuiltinBounds::empty();
loop {

View file

@ -220,22 +220,8 @@ fn enc_mt<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
enc_ty(w, cx, mt.ty);
}
fn enc_opt<T, F>(w: &mut Cursor<Vec<u8>>, t: Option<T>, enc_f: F) where
F: FnOnce(&mut Cursor<Vec<u8>>, T),
{
match t {
None => {
write!(w, "n");
}
Some(v) => {
write!(w, "s");
enc_f(w, v);
}
}
}
pub fn enc_substs<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
substs: &Substs<'tcx>) {
fn enc_substs<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
substs: &Substs<'tcx>) {
write!(w, "[");
for &k in substs.params() {
if let Some(ty) = k.as_type() {
@ -251,32 +237,7 @@ pub fn enc_substs<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
write!(w, "]");
}
pub fn enc_generics<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
generics: &ty::Generics<'tcx>) {
enc_opt(w, generics.parent, |w, def_id| {
write!(w, "{}|", (cx.ds)(cx.tcx, def_id));
});
write!(w, "{}|{}[",
generics.parent_regions,
generics.parent_types);
for r in &generics.regions {
enc_region_param_def(w, cx, r)
}
write!(w, "|");
for t in &generics.types {
enc_type_param_def(w, cx, t);
}
write!(w, "]");
if generics.has_self {
write!(w, "S");
} else {
write!(w, "N");
}
}
pub fn enc_region(w: &mut Cursor<Vec<u8>>, cx: &ctxt, r: &ty::Region) {
fn enc_region(w: &mut Cursor<Vec<u8>>, cx: &ctxt, r: &ty::Region) {
match *r {
ty::ReLateBound(id, br) => {
write!(w, "b[{}|", id.depth);
@ -355,8 +316,8 @@ fn enc_bound_region(w: &mut Cursor<Vec<u8>>, cx: &ctxt, br: ty::BoundRegion) {
}
}
pub fn enc_trait_ref<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
s: ty::TraitRef<'tcx>) {
fn enc_trait_ref<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
s: ty::TraitRef<'tcx>) {
write!(w, "{}|", (cx.ds)(cx.tcx, s.def_id));
enc_substs(w, cx, s.substs);
}
@ -380,20 +341,13 @@ fn enc_abi(w: &mut Cursor<Vec<u8>>, abi: Abi) {
write!(w, "]");
}
pub fn enc_bare_fn_ty<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
ft: &ty::BareFnTy<'tcx>) {
fn enc_bare_fn_ty<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
ft: &ty::BareFnTy<'tcx>) {
enc_unsafety(w, ft.unsafety);
enc_abi(w, ft.abi);
enc_fn_sig(w, cx, &ft.sig);
}
pub fn enc_closure_ty<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
ft: &ty::ClosureTy<'tcx>) {
enc_unsafety(w, ft.unsafety);
enc_fn_sig(w, cx, &ft.sig);
enc_abi(w, ft.abi);
}
fn enc_fn_sig<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
fsig: &ty::PolyFnSig<'tcx>) {
write!(w, "[");
@ -422,92 +376,6 @@ fn enc_builtin_bounds(w: &mut Cursor<Vec<u8>>, _cx: &ctxt, bs: &ty::BuiltinBound
write!(w, ".");
}
fn enc_type_param_def<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
v: &ty::TypeParameterDef<'tcx>) {
write!(w, "{}:{}|{}|{}|",
v.name, (cx.ds)(cx.tcx, v.def_id),
v.index, (cx.ds)(cx.tcx, v.default_def_id));
enc_opt(w, v.default, |w, t| enc_ty(w, cx, t));
enc_object_lifetime_default(w, cx, v.object_lifetime_default);
}
fn enc_region_param_def(w: &mut Cursor<Vec<u8>>, cx: &ctxt,
v: &ty::RegionParameterDef) {
write!(w, "{}:{}|{}|",
v.name, (cx.ds)(cx.tcx, v.def_id), v.index);
for &r in &v.bounds {
write!(w, "R");
enc_region(w, cx, r);
}
write!(w, ".");
}
fn enc_object_lifetime_default<'a, 'tcx>(w: &mut Cursor<Vec<u8>>,
cx: &ctxt<'a, 'tcx>,
default: ty::ObjectLifetimeDefault)
{
match default {
ty::ObjectLifetimeDefault::Ambiguous => {
write!(w, "a");
}
ty::ObjectLifetimeDefault::BaseDefault => {
write!(w, "b");
}
ty::ObjectLifetimeDefault::Specific(r) => {
write!(w, "s");
enc_region(w, cx, r);
}
}
}
pub fn enc_predicate<'a, 'tcx>(w: &mut Cursor<Vec<u8>>,
cx: &ctxt<'a, 'tcx>,
p: &ty::Predicate<'tcx>)
{
match *p {
ty::Predicate::Trait(ref trait_ref) => {
write!(w, "t");
enc_trait_ref(w, cx, trait_ref.0.trait_ref);
}
ty::Predicate::Equate(ty::Binder(ty::EquatePredicate(a, b))) => {
write!(w, "e");
enc_ty(w, cx, a);
enc_ty(w, cx, b);
}
ty::Predicate::RegionOutlives(ty::Binder(ty::OutlivesPredicate(a, b))) => {
write!(w, "r");
enc_region(w, cx, a);
enc_region(w, cx, b);
}
ty::Predicate::TypeOutlives(ty::Binder(ty::OutlivesPredicate(a, b))) => {
write!(w, "o");
enc_ty(w, cx, a);
enc_region(w, cx, b);
}
ty::Predicate::Projection(ty::Binder(ref data)) => {
write!(w, "p");
enc_trait_ref(w, cx, data.projection_ty.trait_ref);
write!(w, "{}|", data.projection_ty.item_name);
enc_ty(w, cx, data.ty);
}
ty::Predicate::WellFormed(data) => {
write!(w, "w");
enc_ty(w, cx, data);
}
ty::Predicate::ObjectSafe(trait_def_id) => {
write!(w, "O{}|", (cx.ds)(cx.tcx, trait_def_id));
}
ty::Predicate::ClosureKind(closure_def_id, kind) => {
let kind_char = match kind {
ty::ClosureKind::Fn => 'f',
ty::ClosureKind::FnMut => 'm',
ty::ClosureKind::FnOnce => 'o',
};
write!(w, "c{}|{}|", (cx.ds)(cx.tcx, closure_def_id), kind_char);
}
}
}
fn enc_existential_projection<'a, 'tcx>(w: &mut Cursor<Vec<u8>>,
cx: &ctxt<'a, 'tcx>,
data: &ty::ExistentialProjection<'tcx>) {