diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 00c602d033f8f..1fc3b04adb86d 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 e40d07d936bbc..424259de4fd1d 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> for mir::ClearOnDecode +impl<'gcx, T> HashStable> for mir::ClearCrossCrate where T: HashStable> { #[inline] @@ -107,8 +107,8 @@ impl<'gcx, T> HashStable> for mir::ClearOnDecode hasher: &mut StableHasher) { 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 c8690422b1893..380f79361e27f 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, } diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index d5df90a5ea02c..4946ef93c7dde 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>, + pub visibility_scope_info: ClearCrossCrate>, /// 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>, visibility_scopes: IndexVec, - visibility_scope_info: ClearOnDecode>, + visibility_scope_info: ClearCrossCrate>, promoted: IndexVec>, yield_ty: Option>, local_decls: IndexVec>, @@ -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 for Mir<'tcx> { } #[derive(Clone, Debug)] -pub enum ClearOnDecode { +pub enum ClearCrossCrate { Clear, Set(T) } -impl serialize::Encodable for ClearOnDecode { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - serialize::Encodable::encode(&(), s) - } -} - -impl serialize::Decodable for ClearOnDecode { - fn decode(d: &mut D) -> Result { - serialize::Decodable::decode(d).map(|()| ClearOnDecode::Clear) - } -} +impl serialize::UseSpecializedEncodable for ClearCrossCrate {} +impl serialize::UseSpecializedDecodable for ClearCrossCrate {} /// 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 b0dce1f668491..56754bbc13ed4 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> { - // 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> { diff --git a/src/librustc/ty/maps/on_disk_cache.rs b/src/librustc/ty/maps/on_disk_cache.rs index 6f55df76df4a1..01f2374033da8 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 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 for CacheDecoder<'a, 'tcx, 'x> { + #[inline] fn specialized_decode(&mut self) -> Result { let hir_id = hir::HirId::decode(self)?; Ok(self.tcx().hir.hir_to_node_id(hir_id)) } } +impl<'a, 'tcx, 'x, T: Decodable> SpecializedDecoder> +for CacheDecoder<'a, 'tcx, 'x> { + #[inline] + fn specialized_decode(&mut self) -> Result, 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 for CacheEncoder<'enc, 'a, 't } } +impl<'enc, 'a, 'tcx, E, T> SpecializedEncoder> +for CacheEncoder<'enc, 'a, 'tcx, E> + where E: 'enc + ty_codec::TyEncoder, + T: Encodable, +{ + #[inline] + fn specialized_encode(&mut self, + val: &mir::ClearCrossCrate) + -> 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 583dcb46f000c..591d1525c827a 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 c5ffb00339995..cb80f602a1c7f 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 Clone for IdxSetBuf { } } +impl rustc_serialize::Encodable for IdxSetBuf { + fn encode(&self, + encoder: &mut E) + -> Result<(), E::Error> { + self.bits.encode(encoder) + } +} + +impl rustc_serialize::Decodable for IdxSetBuf { + fn decode(d: &mut D) -> Result, D::Error> { + let words: Vec = rustc_serialize::Decodable::decode(d)?; + + Ok(IdxSetBuf { + _pd: PhantomData, + bits: words, + }) + } +} + + // pnkfelix wants to have this be `IdxSet([Word]) and then pass // around `&mut IdxSet` or `&IdxSet`. // diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 633806d5ef568..eb2bcfc93c5fb 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 for DecodeContext<'a, 'tcx> { } } +impl<'a, 'tcx, T: Decodable> SpecializedDecoder> +for DecodeContext<'a, 'tcx> { + #[inline] + fn specialized_decode(&mut self) -> Result, 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 d82d50164cbb5..de6bb9ea738be 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -157,6 +157,15 @@ impl<'a, 'tcx> SpecializedEncoder> for EncodeContext } } +impl<'a, 'tcx, T: Encodable> SpecializedEncoder> +for EncodeContext<'a, 'tcx> { + fn specialized_encode(&mut self, + _: &mir::ClearCrossCrate) + -> 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 080cf4b47cf87..2086e92a98464 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 119cd35910fd5..15b06bd38924a 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 c8a23280079c1..fefb1590bd3f9 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 1a995276931d8..d8ae9729224d7 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 Decodable for HashSet }) } } + +impl Encodable for Rc<[T]> { + fn encode(&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 Decodable for Rc<[T]> { + fn decode(d: &mut D) -> Result, 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()) + }) + } +}