about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/dep_graph/dep_node.rs8
-rw-r--r--src/librustc/ich/impls_mir.rs6
-rw-r--r--src/librustc/middle/borrowck.rs1
-rw-r--r--src/librustc/mir/mod.rs34
-rw-r--r--src/librustc/ty/context.rs6
-rw-r--r--src/librustc/ty/maps/on_disk_cache.rs45
-rw-r--r--src/librustc/ty/mod.rs2
-rw-r--r--src/librustc_data_structures/indexed_set.rs21
-rw-r--r--src/librustc_metadata/decoder.rs9
-rw-r--r--src/librustc_metadata/encoder.rs9
-rw-r--r--src/librustc_mir/build/mod.rs2
-rw-r--r--src/librustc_mir/shim.rs8
-rw-r--r--src/librustc_mir/transform/check_unsafety.rs19
-rw-r--r--src/libserialize/collection_impls.rs24
14 files changed, 147 insertions, 47 deletions
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index 00c602d033f..1fc3b04adb8 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -562,7 +562,7 @@ define_dep_nodes!( <'tcx>
     [] IsPanicRuntime(CrateNum),
     [] IsCompilerBuiltins(CrateNum),
     [] HasGlobalAllocator(CrateNum),
-    [] ExternCrate(DefId),
+    [input] ExternCrate(DefId),
     [eval_always] LintLevels,
     [] Specializes { impl1: DefId, impl2: DefId },
     [input] InScopeTraits(DefIndex),
@@ -602,8 +602,8 @@ define_dep_nodes!( <'tcx>
     [] MissingLangItems(CrateNum),
     [] ExternConstBody(DefId),
     [] VisibleParentMap,
-    [] MissingExternCrateItem(CrateNum),
-    [] UsedCrateSource(CrateNum),
+    [input] MissingExternCrateItem(CrateNum),
+    [input] UsedCrateSource(CrateNum),
     [input] PostorderCnums,
     [input] HasCloneClosures(CrateNum),
     [input] HasCopyClosures(CrateNum),
@@ -619,7 +619,7 @@ define_dep_nodes!( <'tcx>
     [input] Freevars(DefId),
     [input] MaybeUnusedTraitImport(DefId),
     [input] MaybeUnusedExternCrates,
-    [] StabilityIndex,
+    [eval_always] StabilityIndex,
     [input] AllCrateNums,
     [] ExportedSymbols(CrateNum),
     [eval_always] CollectAndPartitionTranslationItems,
diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs
index e40d07d936b..424259de4fd 100644
--- a/src/librustc/ich/impls_mir.rs
+++ b/src/librustc/ich/impls_mir.rs
@@ -98,7 +98,7 @@ for mir::Terminator<'gcx> {
     }
 }
 
-impl<'gcx, T> HashStable<StableHashingContext<'gcx>> for mir::ClearOnDecode<T>
+impl<'gcx, T> HashStable<StableHashingContext<'gcx>> for mir::ClearCrossCrate<T>
     where T: HashStable<StableHashingContext<'gcx>>
 {
     #[inline]
@@ -107,8 +107,8 @@ impl<'gcx, T> HashStable<StableHashingContext<'gcx>> for mir::ClearOnDecode<T>
                                           hasher: &mut StableHasher<W>) {
         mem::discriminant(self).hash_stable(hcx, hasher);
         match *self {
-            mir::ClearOnDecode::Clear => {}
-            mir::ClearOnDecode::Set(ref value) => {
+            mir::ClearCrossCrate::Clear => {}
+            mir::ClearCrossCrate::Set(ref value) => {
                 value.hash_stable(hcx, hasher);
             }
         }
diff --git a/src/librustc/middle/borrowck.rs b/src/librustc/middle/borrowck.rs
index c8690422b18..380f79361e2 100644
--- a/src/librustc/middle/borrowck.rs
+++ b/src/librustc/middle/borrowck.rs
@@ -15,6 +15,7 @@ use util::nodemap::FxHashSet;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
                                            StableHasherResult};
 
+#[derive(Debug, RustcEncodable, RustcDecodable)]
 pub struct BorrowCheckResult {
     pub used_mut_nodes: FxHashSet<HirId>,
 }
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index d5df90a5ea0..4946ef93c7d 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -36,6 +36,7 @@ use std::ops::{Index, IndexMut};
 use std::rc::Rc;
 use std::vec::IntoIter;
 use syntax::ast::{self, Name};
+use syntax::symbol::InternedString;
 use syntax_pos::Span;
 
 mod cache;
@@ -75,7 +76,7 @@ pub struct Mir<'tcx> {
 
     /// Crate-local information for each visibility scope, that can't (and
     /// needn't) be tracked across crates.
-    pub visibility_scope_info: ClearOnDecode<IndexVec<VisibilityScope, VisibilityScopeInfo>>,
+    pub visibility_scope_info: ClearCrossCrate<IndexVec<VisibilityScope, VisibilityScopeInfo>>,
 
     /// Rvalues promoted from this function, such as borrows of constants.
     /// Each of them is the Mir of a constant with the fn's type parameters
@@ -129,8 +130,8 @@ pub const START_BLOCK: BasicBlock = BasicBlock(0);
 impl<'tcx> Mir<'tcx> {
     pub fn new(basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
                visibility_scopes: IndexVec<VisibilityScope, VisibilityScopeData>,
-               visibility_scope_info: ClearOnDecode<IndexVec<VisibilityScope,
-                                                             VisibilityScopeInfo>>,
+               visibility_scope_info: ClearCrossCrate<IndexVec<VisibilityScope,
+                                                               VisibilityScopeInfo>>,
                promoted: IndexVec<Promoted, Mir<'tcx>>,
                yield_ty: Option<Ty<'tcx>>,
                local_decls: IndexVec<Local, LocalDecl<'tcx>>,
@@ -283,7 +284,7 @@ impl<'tcx> Mir<'tcx> {
     }
 }
 
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
 pub struct VisibilityScopeInfo {
     /// A NodeId with lint levels equivalent to this scope's lint levels.
     pub lint_root: ast::NodeId,
@@ -291,7 +292,7 @@ pub struct VisibilityScopeInfo {
     pub safety: Safety,
 }
 
-#[derive(Copy, Clone, Debug)]
+#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
 pub enum Safety {
     Safe,
     /// Unsafe because of a PushUnsafeBlock
@@ -335,22 +336,13 @@ impl<'tcx> IndexMut<BasicBlock> for Mir<'tcx> {
 }
 
 #[derive(Clone, Debug)]
-pub enum ClearOnDecode<T> {
+pub enum ClearCrossCrate<T> {
     Clear,
     Set(T)
 }
 
-impl<T> serialize::Encodable for ClearOnDecode<T> {
-    fn encode<S: serialize::Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        serialize::Encodable::encode(&(), s)
-    }
-}
-
-impl<T> serialize::Decodable for ClearOnDecode<T> {
-    fn decode<D: serialize::Decoder>(d: &mut D) -> Result<Self, D::Error> {
-        serialize::Decodable::decode(d).map(|()| ClearOnDecode::Clear)
-    }
-}
+impl<T: serialize::Encodable> serialize::UseSpecializedEncodable for ClearCrossCrate<T> {}
+impl<T: serialize::Decodable> serialize::UseSpecializedDecodable for ClearCrossCrate<T> {}
 
 /// Grouped information about the source code origin of a MIR entity.
 /// Intended to be inspected by diagnostics and debuginfo.
@@ -1733,21 +1725,21 @@ impl Location {
     }
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
 pub enum UnsafetyViolationKind {
     General,
     ExternStatic(ast::NodeId),
     BorrowPacked(ast::NodeId),
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
 pub struct UnsafetyViolation {
     pub source_info: SourceInfo,
-    pub description: &'static str,
+    pub description: InternedString,
     pub kind: UnsafetyViolationKind,
 }
 
-#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
 pub struct UnsafetyCheckResult {
     /// Violations that are propagated *upwards* from this function
     pub violations: Rc<[UnsafetyViolation]>,
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index b0dce1f6684..56754bbc13e 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -1124,11 +1124,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     }
 
     pub fn stability(self) -> Rc<stability::Index<'tcx>> {
-        // FIXME(#42293) we should actually track this, but fails too many tests
-        // today.
-        self.dep_graph.with_ignore(|| {
-            self.stability_index(LOCAL_CRATE)
-        })
+        self.stability_index(LOCAL_CRATE)
     }
 
     pub fn crates(self) -> Rc<Vec<CrateNum>> {
diff --git a/src/librustc/ty/maps/on_disk_cache.rs b/src/librustc/ty/maps/on_disk_cache.rs
index 6f55df76df4..01f2374033d 100644
--- a/src/librustc/ty/maps/on_disk_cache.rs
+++ b/src/librustc/ty/maps/on_disk_cache.rs
@@ -15,6 +15,7 @@ use hir::def_id::{CrateNum, DefIndex, DefId, LocalDefId,
                   RESERVED_FOR_INCR_COMP_CACHE, LOCAL_CRATE};
 use hir::map::definitions::DefPathHash;
 use middle::cstore::CrateStore;
+use mir;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque,
@@ -36,6 +37,9 @@ use ty::context::TyCtxt;
 const PREV_DIAGNOSTICS_TAG: u64 = 0x1234_5678_A1A1_A1A1;
 const QUERY_RESULT_INDEX_TAG: u64 = 0x1234_5678_C3C3_C3C3;
 
+const TAG_CLEAR_CROSS_CRATE_CLEAR: u8 = 0;
+const TAG_CLEAR_CROSS_CRATE_SET: u8 = 1;
+
 /// `OnDiskCache` provides an interface to incr. comp. data cached from the
 /// previous compilation session. This data will eventually include the results
 /// of a few selected queries (like `typeck_tables_of` and `mir_optimized`) and
@@ -518,12 +522,32 @@ impl<'a, 'tcx, 'x> SpecializedDecoder<hir::HirId> for CacheDecoder<'a, 'tcx, 'x>
 // NodeIds are not stable across compilation sessions, so we store them in their
 // HirId representation. This allows use to map them to the current NodeId.
 impl<'a, 'tcx, 'x> SpecializedDecoder<NodeId> for CacheDecoder<'a, 'tcx, 'x> {
+    #[inline]
     fn specialized_decode(&mut self) -> Result<NodeId, Self::Error> {
         let hir_id = hir::HirId::decode(self)?;
         Ok(self.tcx().hir.hir_to_node_id(hir_id))
     }
 }
 
+impl<'a, 'tcx, 'x, T: Decodable> SpecializedDecoder<mir::ClearCrossCrate<T>>
+for CacheDecoder<'a, 'tcx, 'x> {
+    #[inline]
+    fn specialized_decode(&mut self) -> Result<mir::ClearCrossCrate<T>, Self::Error> {
+        let discr = u8::decode(self)?;
+
+        match discr {
+            TAG_CLEAR_CROSS_CRATE_CLEAR => Ok(mir::ClearCrossCrate::Clear),
+            TAG_CLEAR_CROSS_CRATE_SET => {
+                let val = T::decode(self)?;
+                Ok(mir::ClearCrossCrate::Set(val))
+            }
+            _ => {
+                unreachable!()
+            }
+        }
+    }
+}
+
 //- ENCODING -------------------------------------------------------------------
 
 struct CacheEncoder<'enc, 'a, 'tcx, E>
@@ -658,6 +682,27 @@ impl<'enc, 'a, 'tcx, E> SpecializedEncoder<NodeId> for CacheEncoder<'enc, 'a, 't
     }
 }
 
+impl<'enc, 'a, 'tcx, E, T> SpecializedEncoder<mir::ClearCrossCrate<T>>
+for CacheEncoder<'enc, 'a, 'tcx, E>
+    where E: 'enc + ty_codec::TyEncoder,
+          T: Encodable,
+{
+    #[inline]
+    fn specialized_encode(&mut self,
+                          val: &mir::ClearCrossCrate<T>)
+                          -> Result<(), Self::Error> {
+        match *val {
+            mir::ClearCrossCrate::Clear => {
+                TAG_CLEAR_CROSS_CRATE_CLEAR.encode(self)
+            }
+            mir::ClearCrossCrate::Set(ref val) => {
+                TAG_CLEAR_CROSS_CRATE_SET.encode(self)?;
+                val.encode(self)
+            }
+        }
+    }
+}
+
 macro_rules! encoder_methods {
     ($($name:ident($ty:ty);)*) => {
         $(fn $name(&mut self, value: $ty) -> Result<(), Self::Error> {
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 583dcb46f00..591d1525c82 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -2702,7 +2702,7 @@ impl<'tcx> DtorckConstraint<'tcx> {
     }
 }
 
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable)]
 pub struct SymbolName {
     // FIXME: we don't rely on interning or equality here - better have
     // this be a `&'tcx str`.
diff --git a/src/librustc_data_structures/indexed_set.rs b/src/librustc_data_structures/indexed_set.rs
index c5ffb003399..cb80f602a1c 100644
--- a/src/librustc_data_structures/indexed_set.rs
+++ b/src/librustc_data_structures/indexed_set.rs
@@ -17,6 +17,7 @@ use std::slice;
 use bitslice::{BitSlice, Word};
 use bitslice::{bitwise, Union, Subtract, Intersect};
 use indexed_vec::Idx;
+use rustc_serialize;
 
 /// Represents a set (or packed family of sets), of some element type
 /// E, where each E is identified by some unique index type `T`.
@@ -35,6 +36,26 @@ impl<T: Idx> Clone for IdxSetBuf<T> {
     }
 }
 
+impl<T: Idx> rustc_serialize::Encodable for IdxSetBuf<T> {
+    fn encode<E: rustc_serialize::Encoder>(&self,
+                                     encoder: &mut E)
+                                     -> Result<(), E::Error> {
+        self.bits.encode(encoder)
+    }
+}
+
+impl<T: Idx> rustc_serialize::Decodable for IdxSetBuf<T> {
+    fn decode<D: rustc_serialize::Decoder>(d: &mut D) -> Result<IdxSetBuf<T>, D::Error> {
+        let words: Vec<Word> = rustc_serialize::Decodable::decode(d)?;
+
+        Ok(IdxSetBuf {
+            _pd: PhantomData,
+            bits: words,
+        })
+    }
+}
+
+
 // pnkfelix wants to have this be `IdxSet<T>([Word]) and then pass
 // around `&mut IdxSet<T>` or `&IdxSet<T>`.
 //
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 633806d5ef5..eb2bcfc93c5 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -21,6 +21,7 @@ use rustc::hir::def::{self, Def, CtorKind};
 use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc::ich::Fingerprint;
 use rustc::middle::lang_items;
+use rustc::mir;
 use rustc::session::Session;
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::codec::TyDecoder;
@@ -327,6 +328,14 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
     }
 }
 
+impl<'a, 'tcx, T: Decodable> SpecializedDecoder<mir::ClearCrossCrate<T>>
+for DecodeContext<'a, 'tcx> {
+    #[inline]
+    fn specialized_decode(&mut self) -> Result<mir::ClearCrossCrate<T>, Self::Error> {
+        Ok(mir::ClearCrossCrate::Clear)
+    }
+}
+
 implement_ty_decoder!( DecodeContext<'a, 'tcx> );
 
 impl<'a, 'tcx> MetadataBlob {
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index d82d50164cb..de6bb9ea738 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -157,6 +157,15 @@ impl<'a, 'tcx> SpecializedEncoder<ty::GenericPredicates<'tcx>> for EncodeContext
     }
 }
 
+impl<'a, 'tcx, T: Encodable> SpecializedEncoder<mir::ClearCrossCrate<T>>
+for EncodeContext<'a, 'tcx> {
+    fn specialized_encode(&mut self,
+                          _: &mir::ClearCrossCrate<T>)
+                          -> Result<(), Self::Error> {
+        Ok(())
+    }
+}
+
 impl<'a, 'tcx> TyEncoder for EncodeContext<'a, 'tcx> {
     fn position(&self) -> usize {
         self.opaque.position()
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index 080cf4b47cf..2086e92a984 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -543,7 +543,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
 
         Mir::new(self.cfg.basic_blocks,
                  self.visibility_scopes,
-                 ClearOnDecode::Set(self.visibility_scope_info),
+                 ClearCrossCrate::Set(self.visibility_scope_info),
                  IndexVec::new(),
                  yield_ty,
                  self.local_decls,
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index 119cd35910f..15b06bd3892 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -198,7 +198,7 @@ fn build_drop_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         IndexVec::from_elem_n(
             VisibilityScopeData { span: span, parent_scope: None }, 1
         ),
-        ClearOnDecode::Clear,
+        ClearCrossCrate::Clear,
         IndexVec::new(),
         None,
         local_decls_for_sig(&sig, span),
@@ -345,7 +345,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
             IndexVec::from_elem_n(
                 VisibilityScopeData { span: self.span, parent_scope: None }, 1
             ),
-            ClearOnDecode::Clear,
+            ClearCrossCrate::Clear,
             IndexVec::new(),
             None,
             self.local_decls,
@@ -807,7 +807,7 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         IndexVec::from_elem_n(
             VisibilityScopeData { span: span, parent_scope: None }, 1
         ),
-        ClearOnDecode::Clear,
+        ClearCrossCrate::Clear,
         IndexVec::new(),
         None,
         local_decls,
@@ -885,7 +885,7 @@ pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>,
         IndexVec::from_elem_n(
             VisibilityScopeData { span: span, parent_scope: None }, 1
         ),
-        ClearOnDecode::Clear,
+        ClearCrossCrate::Clear,
         IndexVec::new(),
         None,
         local_decls,
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index c8a23280079..fefb1590bd3 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -20,6 +20,7 @@ use rustc::mir::*;
 use rustc::mir::visit::{LvalueContext, Visitor};
 
 use syntax::ast;
+use syntax::symbol::Symbol;
 
 use std::rc::Rc;
 use util;
@@ -145,7 +146,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
                     self.visibility_scope_info[source_info.scope].lint_root;
                 self.register_violations(&[UnsafetyViolation {
                     source_info,
-                    description: "borrow of packed field",
+                    description: Symbol::intern("borrow of packed field").as_str(),
                     kind: UnsafetyViolationKind::BorrowPacked(lint_root)
                 }], &[]);
             }
@@ -209,7 +210,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
                         self.visibility_scope_info[source_info.scope].lint_root;
                     self.register_violations(&[UnsafetyViolation {
                         source_info,
-                        description: "use of extern static",
+                        description: Symbol::intern("use of extern static").as_str(),
                         kind: UnsafetyViolationKind::ExternStatic(lint_root)
                     }], &[]);
                 }
@@ -225,7 +226,9 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
     {
         let source_info = self.source_info;
         self.register_violations(&[UnsafetyViolation {
-            source_info, description, kind: UnsafetyViolationKind::General
+            source_info,
+            description: Symbol::intern(description).as_str(),
+            kind: UnsafetyViolationKind::General,
         }], &[]);
     }
 
@@ -320,8 +323,8 @@ fn unsafety_check_result<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
     let mir = &tcx.mir_built(def_id).borrow();
 
     let visibility_scope_info = match mir.visibility_scope_info {
-        ClearOnDecode::Set(ref data) => data,
-        ClearOnDecode::Clear => {
+        ClearCrossCrate::Set(ref data) => data,
+        ClearCrossCrate::Clear => {
             debug!("unsafety_violations: {:?} - remote, skipping", def_id);
             return UnsafetyCheckResult {
                 violations: Rc::new([]),
@@ -433,7 +436,7 @@ pub fn check_unsafety<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
                 struct_span_err!(
                     tcx.sess, source_info.span, E0133,
                     "{} requires unsafe function or block", description)
-                    .span_label(source_info.span, description)
+                    .span_label(source_info.span, &description[..])
                     .emit();
             }
             UnsafetyViolationKind::ExternStatic(lint_node_id) => {
@@ -441,7 +444,7 @@ pub fn check_unsafety<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
                               lint_node_id,
                               source_info.span,
                               &format!("{} requires unsafe function or \
-                                        block (error E0133)", description));
+                                        block (error E0133)", &description[..]));
             }
             UnsafetyViolationKind::BorrowPacked(lint_node_id) => {
                 if let Some(impl_def_id) = builtin_derive_def_id(tcx, def_id) {
@@ -451,7 +454,7 @@ pub fn check_unsafety<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
                                   lint_node_id,
                                   source_info.span,
                                   &format!("{} requires unsafe function or \
-                                            block (error E0133)", description));
+                                            block (error E0133)", &description[..]));
                 }
             }
         }
diff --git a/src/libserialize/collection_impls.rs b/src/libserialize/collection_impls.rs
index 1a995276931..d8ae9729224 100644
--- a/src/libserialize/collection_impls.rs
+++ b/src/libserialize/collection_impls.rs
@@ -14,6 +14,7 @@ use std::hash::{Hash, BuildHasher};
 
 use {Decodable, Encodable, Decoder, Encoder};
 use std::collections::{LinkedList, VecDeque, BTreeMap, BTreeSet, HashMap, HashSet};
+use std::rc::Rc;
 
 impl<
     T: Encodable
@@ -194,3 +195,26 @@ impl<T, S> Decodable for HashSet<T, S>
         })
     }
 }
+
+impl<T: Encodable> Encodable for Rc<[T]> {
+    fn encode<E: Encoder>(&self, s: &mut E) -> Result<(), E::Error> {
+        s.emit_seq(self.len(), |s| {
+            for (index, e) in self.iter().enumerate() {
+                s.emit_seq_elt(index, |s| e.encode(s))?;
+            }
+            Ok(())
+        })
+    }
+}
+
+impl<T: Decodable> Decodable for Rc<[T]> {
+    fn decode<D: Decoder>(d: &mut D) -> Result<Rc<[T]>, D::Error> {
+        d.read_seq(|d, len| {
+            let mut vec = Vec::with_capacity(len);
+            for index in 0..len {
+                vec.push(d.read_seq_elt(index, |d| Decodable::decode(d))?);
+            }
+            Ok(vec.into())
+        })
+    }
+}