about summary refs log tree commit diff
path: root/src/librustc_metadata/decoder.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/librustc_metadata/decoder.rs')
-rw-r--r--src/librustc_metadata/decoder.rs54
1 files changed, 36 insertions, 18 deletions
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index d3c04874a08..0118cacad18 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -20,7 +20,6 @@ use common::*;
 use def_key;
 use encoder::def_to_u64;
 use index;
-use tydecode::TyDecoder;
 
 use rustc::hir::def_id::CRATE_DEF_INDEX;
 use rustc::hir::svh::Svh;
@@ -45,13 +44,14 @@ use rustc_const_math::ConstInt;
 use rustc::mir::repr::Mir;
 
 use std::io;
+use std::mem;
 use std::rc::Rc;
 use std::str;
 use std::u32;
 
 use rbml::reader;
 use rbml;
-use rustc_serialize::{Decodable, SpecializedDecoder, opaque};
+use rustc_serialize::{Decodable, Decoder, SpecializedDecoder, opaque};
 use rustc_serialize as serialize;
 use syntax::attr;
 use syntax::parse::token;
@@ -233,35 +233,53 @@ 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> {
-        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())
+        let tcx = self.tcx();
+
+        // Handle shorthands first, if we have an usize > 0x80.
+        if self.opaque.data[self.opaque.position()] & 0x80 != 0 {
+            let pos = self.read_usize()?;
+            assert!(pos >= TYPE_SHORTHAND_OFFSET);
+            let key = ty::CReaderCacheKey {
+                cnum: self.cdata().cnum,
+                pos: pos - TYPE_SHORTHAND_OFFSET
+            };
+            if let Some(ty) = tcx.rcache.borrow().get(&key).cloned() {
+                return Ok(ty);
+            }
+
+            let new = opaque::Decoder::new(self.opaque.data, key.pos);
+            let old = mem::replace(&mut self.opaque, new);
+            let ty = Ty::decode(self)?;
+            self.opaque = old;
+            tcx.rcache.borrow_mut().insert(key, ty);
+            return Ok(ty);
+        }
+
+        Ok(tcx.mk_ty(ty::TypeVariants::decode(self)?))
     }
 }
 
 impl<'a, 'tcx> SpecializedDecoder<&'tcx Substs<'tcx>> for DecodeContext<'a, 'tcx> {
     fn specialized_decode(&mut self) -> Result<&'tcx Substs<'tcx>, Self::Error> {
-        let substs = Substs::decode(self)?;
-        Ok(self.tcx().mk_substs(substs))
+        Ok(self.tcx().mk_substs(Decodable::decode(self)?))
     }
 }
 
 impl<'a, 'tcx> SpecializedDecoder<&'tcx ty::Region> for DecodeContext<'a, 'tcx> {
     fn specialized_decode(&mut self) -> Result<&'tcx ty::Region, Self::Error> {
-        let r = ty::Region::decode(self)?;
-        Ok(self.tcx().mk_region(r))
+        Ok(self.tcx().mk_region(Decodable::decode(self)?))
     }
 }
 
-impl<'a, 'tcx> SpecializedDecoder<ty::ClosureSubsts<'tcx>> for DecodeContext<'a, 'tcx> {
-    fn specialized_decode(&mut self) -> Result<ty::ClosureSubsts<'tcx>, Self::Error> {
-        Ok(ty::ClosureSubsts {
-            func_substs: Decodable::decode(self)?,
-            upvar_tys: self.tcx().mk_type_list(Decodable::decode(self)?)
-        })
+impl<'a, 'tcx> SpecializedDecoder<&'tcx ty::Slice<Ty<'tcx>>> for DecodeContext<'a, 'tcx> {
+    fn specialized_decode(&mut self) -> Result<&'tcx ty::Slice<Ty<'tcx>>, Self::Error> {
+        Ok(self.tcx().mk_type_list(Decodable::decode(self)?))
+    }
+}
+
+impl<'a, 'tcx> SpecializedDecoder<&'tcx ty::BareFnTy<'tcx>> for DecodeContext<'a, 'tcx> {
+    fn specialized_decode(&mut self) -> Result<&'tcx ty::BareFnTy<'tcx>, Self::Error> {
+        Ok(self.tcx().mk_bare_fn(Decodable::decode(self)?))
     }
 }