Auto merge of #46299 - michaelwoerister:incr-comp-krimskrams, r=nikomatsakis
incr.comp.: Some preparatory work for caching more query results. This PR * adds and updates some encoding/decoding routines for various query result types so they can be cached later, and * adds missing `[input]` annotations for a few `DepNode` variants. The situation around having to explicitly mark dep-nodes/queries as inputs is not really satisfactory. I hope we can find a way of making this more fool-proof in the future. r? @nikomatsakis
This commit is contained in:
commit
4fa202d23b
14 changed files with 147 additions and 47 deletions
|
@ -562,7 +562,7 @@ define_dep_nodes!( <'tcx>
|
||||||
[] IsPanicRuntime(CrateNum),
|
[] IsPanicRuntime(CrateNum),
|
||||||
[] IsCompilerBuiltins(CrateNum),
|
[] IsCompilerBuiltins(CrateNum),
|
||||||
[] HasGlobalAllocator(CrateNum),
|
[] HasGlobalAllocator(CrateNum),
|
||||||
[] ExternCrate(DefId),
|
[input] ExternCrate(DefId),
|
||||||
[eval_always] LintLevels,
|
[eval_always] LintLevels,
|
||||||
[] Specializes { impl1: DefId, impl2: DefId },
|
[] Specializes { impl1: DefId, impl2: DefId },
|
||||||
[input] InScopeTraits(DefIndex),
|
[input] InScopeTraits(DefIndex),
|
||||||
|
@ -602,8 +602,8 @@ define_dep_nodes!( <'tcx>
|
||||||
[] MissingLangItems(CrateNum),
|
[] MissingLangItems(CrateNum),
|
||||||
[] ExternConstBody(DefId),
|
[] ExternConstBody(DefId),
|
||||||
[] VisibleParentMap,
|
[] VisibleParentMap,
|
||||||
[] MissingExternCrateItem(CrateNum),
|
[input] MissingExternCrateItem(CrateNum),
|
||||||
[] UsedCrateSource(CrateNum),
|
[input] UsedCrateSource(CrateNum),
|
||||||
[input] PostorderCnums,
|
[input] PostorderCnums,
|
||||||
[input] HasCloneClosures(CrateNum),
|
[input] HasCloneClosures(CrateNum),
|
||||||
[input] HasCopyClosures(CrateNum),
|
[input] HasCopyClosures(CrateNum),
|
||||||
|
@ -619,7 +619,7 @@ define_dep_nodes!( <'tcx>
|
||||||
[input] Freevars(DefId),
|
[input] Freevars(DefId),
|
||||||
[input] MaybeUnusedTraitImport(DefId),
|
[input] MaybeUnusedTraitImport(DefId),
|
||||||
[input] MaybeUnusedExternCrates,
|
[input] MaybeUnusedExternCrates,
|
||||||
[] StabilityIndex,
|
[eval_always] StabilityIndex,
|
||||||
[input] AllCrateNums,
|
[input] AllCrateNums,
|
||||||
[] ExportedSymbols(CrateNum),
|
[] ExportedSymbols(CrateNum),
|
||||||
[eval_always] CollectAndPartitionTranslationItems,
|
[eval_always] CollectAndPartitionTranslationItems,
|
||||||
|
|
|
@ -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>>
|
where T: HashStable<StableHashingContext<'gcx>>
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -107,8 +107,8 @@ impl<'gcx, T> HashStable<StableHashingContext<'gcx>> for mir::ClearOnDecode<T>
|
||||||
hasher: &mut StableHasher<W>) {
|
hasher: &mut StableHasher<W>) {
|
||||||
mem::discriminant(self).hash_stable(hcx, hasher);
|
mem::discriminant(self).hash_stable(hcx, hasher);
|
||||||
match *self {
|
match *self {
|
||||||
mir::ClearOnDecode::Clear => {}
|
mir::ClearCrossCrate::Clear => {}
|
||||||
mir::ClearOnDecode::Set(ref value) => {
|
mir::ClearCrossCrate::Set(ref value) => {
|
||||||
value.hash_stable(hcx, hasher);
|
value.hash_stable(hcx, hasher);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ use util::nodemap::FxHashSet;
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
|
||||||
StableHasherResult};
|
StableHasherResult};
|
||||||
|
|
||||||
|
#[derive(Debug, RustcEncodable, RustcDecodable)]
|
||||||
pub struct BorrowCheckResult {
|
pub struct BorrowCheckResult {
|
||||||
pub used_mut_nodes: FxHashSet<HirId>,
|
pub used_mut_nodes: FxHashSet<HirId>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ use std::ops::{Index, IndexMut};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::vec::IntoIter;
|
use std::vec::IntoIter;
|
||||||
use syntax::ast::{self, Name};
|
use syntax::ast::{self, Name};
|
||||||
|
use syntax::symbol::InternedString;
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
|
|
||||||
mod cache;
|
mod cache;
|
||||||
|
@ -75,7 +76,7 @@ pub struct Mir<'tcx> {
|
||||||
|
|
||||||
/// Crate-local information for each visibility scope, that can't (and
|
/// Crate-local information for each visibility scope, that can't (and
|
||||||
/// needn't) be tracked across crates.
|
/// 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.
|
/// 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
|
/// Each of them is the Mir of a constant with the fn's type parameters
|
||||||
|
@ -129,7 +130,7 @@ pub const START_BLOCK: BasicBlock = BasicBlock(0);
|
||||||
impl<'tcx> Mir<'tcx> {
|
impl<'tcx> Mir<'tcx> {
|
||||||
pub fn new(basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
|
pub fn new(basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
|
||||||
visibility_scopes: IndexVec<VisibilityScope, VisibilityScopeData>,
|
visibility_scopes: IndexVec<VisibilityScope, VisibilityScopeData>,
|
||||||
visibility_scope_info: ClearOnDecode<IndexVec<VisibilityScope,
|
visibility_scope_info: ClearCrossCrate<IndexVec<VisibilityScope,
|
||||||
VisibilityScopeInfo>>,
|
VisibilityScopeInfo>>,
|
||||||
promoted: IndexVec<Promoted, Mir<'tcx>>,
|
promoted: IndexVec<Promoted, Mir<'tcx>>,
|
||||||
yield_ty: Option<Ty<'tcx>>,
|
yield_ty: Option<Ty<'tcx>>,
|
||||||
|
@ -283,7 +284,7 @@ impl<'tcx> Mir<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
|
||||||
pub struct VisibilityScopeInfo {
|
pub struct VisibilityScopeInfo {
|
||||||
/// A NodeId with lint levels equivalent to this scope's lint levels.
|
/// A NodeId with lint levels equivalent to this scope's lint levels.
|
||||||
pub lint_root: ast::NodeId,
|
pub lint_root: ast::NodeId,
|
||||||
|
@ -291,7 +292,7 @@ pub struct VisibilityScopeInfo {
|
||||||
pub safety: Safety,
|
pub safety: Safety,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
|
||||||
pub enum Safety {
|
pub enum Safety {
|
||||||
Safe,
|
Safe,
|
||||||
/// Unsafe because of a PushUnsafeBlock
|
/// Unsafe because of a PushUnsafeBlock
|
||||||
|
@ -335,22 +336,13 @@ impl<'tcx> IndexMut<BasicBlock> for Mir<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum ClearOnDecode<T> {
|
pub enum ClearCrossCrate<T> {
|
||||||
Clear,
|
Clear,
|
||||||
Set(T)
|
Set(T)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> serialize::Encodable for ClearOnDecode<T> {
|
impl<T: serialize::Encodable> serialize::UseSpecializedEncodable for ClearCrossCrate<T> {}
|
||||||
fn encode<S: serialize::Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
|
impl<T: serialize::Decodable> serialize::UseSpecializedDecodable for ClearCrossCrate<T> {}
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Grouped information about the source code origin of a MIR entity.
|
/// Grouped information about the source code origin of a MIR entity.
|
||||||
/// Intended to be inspected by diagnostics and debuginfo.
|
/// 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 {
|
pub enum UnsafetyViolationKind {
|
||||||
General,
|
General,
|
||||||
ExternStatic(ast::NodeId),
|
ExternStatic(ast::NodeId),
|
||||||
BorrowPacked(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 struct UnsafetyViolation {
|
||||||
pub source_info: SourceInfo,
|
pub source_info: SourceInfo,
|
||||||
pub description: &'static str,
|
pub description: InternedString,
|
||||||
pub kind: UnsafetyViolationKind,
|
pub kind: UnsafetyViolationKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
|
||||||
pub struct UnsafetyCheckResult {
|
pub struct UnsafetyCheckResult {
|
||||||
/// Violations that are propagated *upwards* from this function
|
/// Violations that are propagated *upwards* from this function
|
||||||
pub violations: Rc<[UnsafetyViolation]>,
|
pub violations: Rc<[UnsafetyViolation]>,
|
||||||
|
|
|
@ -1124,11 +1124,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn stability(self) -> Rc<stability::Index<'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>> {
|
pub fn crates(self) -> Rc<Vec<CrateNum>> {
|
||||||
|
|
|
@ -15,6 +15,7 @@ use hir::def_id::{CrateNum, DefIndex, DefId, LocalDefId,
|
||||||
RESERVED_FOR_INCR_COMP_CACHE, LOCAL_CRATE};
|
RESERVED_FOR_INCR_COMP_CACHE, LOCAL_CRATE};
|
||||||
use hir::map::definitions::DefPathHash;
|
use hir::map::definitions::DefPathHash;
|
||||||
use middle::cstore::CrateStore;
|
use middle::cstore::CrateStore;
|
||||||
|
use mir;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
|
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
|
||||||
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque,
|
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 PREV_DIAGNOSTICS_TAG: u64 = 0x1234_5678_A1A1_A1A1;
|
||||||
const QUERY_RESULT_INDEX_TAG: u64 = 0x1234_5678_C3C3_C3C3;
|
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
|
/// `OnDiskCache` provides an interface to incr. comp. data cached from the
|
||||||
/// previous compilation session. This data will eventually include the results
|
/// previous compilation session. This data will eventually include the results
|
||||||
/// of a few selected queries (like `typeck_tables_of` and `mir_optimized`) and
|
/// 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
|
// 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.
|
// HirId representation. This allows use to map them to the current NodeId.
|
||||||
impl<'a, 'tcx, 'x> SpecializedDecoder<NodeId> for CacheDecoder<'a, 'tcx, 'x> {
|
impl<'a, 'tcx, 'x> SpecializedDecoder<NodeId> for CacheDecoder<'a, 'tcx, 'x> {
|
||||||
|
#[inline]
|
||||||
fn specialized_decode(&mut self) -> Result<NodeId, Self::Error> {
|
fn specialized_decode(&mut self) -> Result<NodeId, Self::Error> {
|
||||||
let hir_id = hir::HirId::decode(self)?;
|
let hir_id = hir::HirId::decode(self)?;
|
||||||
Ok(self.tcx().hir.hir_to_node_id(hir_id))
|
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 -------------------------------------------------------------------
|
//- ENCODING -------------------------------------------------------------------
|
||||||
|
|
||||||
struct CacheEncoder<'enc, 'a, 'tcx, E>
|
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 {
|
macro_rules! encoder_methods {
|
||||||
($($name:ident($ty:ty);)*) => {
|
($($name:ident($ty:ty);)*) => {
|
||||||
$(fn $name(&mut self, value: $ty) -> Result<(), Self::Error> {
|
$(fn $name(&mut self, value: $ty) -> Result<(), Self::Error> {
|
||||||
|
|
|
@ -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 {
|
pub struct SymbolName {
|
||||||
// FIXME: we don't rely on interning or equality here - better have
|
// FIXME: we don't rely on interning or equality here - better have
|
||||||
// this be a `&'tcx str`.
|
// this be a `&'tcx str`.
|
||||||
|
|
|
@ -17,6 +17,7 @@ use std::slice;
|
||||||
use bitslice::{BitSlice, Word};
|
use bitslice::{BitSlice, Word};
|
||||||
use bitslice::{bitwise, Union, Subtract, Intersect};
|
use bitslice::{bitwise, Union, Subtract, Intersect};
|
||||||
use indexed_vec::Idx;
|
use indexed_vec::Idx;
|
||||||
|
use rustc_serialize;
|
||||||
|
|
||||||
/// Represents a set (or packed family of sets), of some element type
|
/// Represents a set (or packed family of sets), of some element type
|
||||||
/// E, where each E is identified by some unique index type `T`.
|
/// 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
|
// pnkfelix wants to have this be `IdxSet<T>([Word]) and then pass
|
||||||
// around `&mut IdxSet<T>` or `&IdxSet<T>`.
|
// around `&mut IdxSet<T>` or `&IdxSet<T>`.
|
||||||
//
|
//
|
||||||
|
|
|
@ -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::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
|
||||||
use rustc::ich::Fingerprint;
|
use rustc::ich::Fingerprint;
|
||||||
use rustc::middle::lang_items;
|
use rustc::middle::lang_items;
|
||||||
|
use rustc::mir;
|
||||||
use rustc::session::Session;
|
use rustc::session::Session;
|
||||||
use rustc::ty::{self, Ty, TyCtxt};
|
use rustc::ty::{self, Ty, TyCtxt};
|
||||||
use rustc::ty::codec::TyDecoder;
|
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> );
|
implement_ty_decoder!( DecodeContext<'a, 'tcx> );
|
||||||
|
|
||||||
impl<'a, 'tcx> MetadataBlob {
|
impl<'a, 'tcx> MetadataBlob {
|
||||||
|
|
|
@ -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> {
|
impl<'a, 'tcx> TyEncoder for EncodeContext<'a, 'tcx> {
|
||||||
fn position(&self) -> usize {
|
fn position(&self) -> usize {
|
||||||
self.opaque.position()
|
self.opaque.position()
|
||||||
|
|
|
@ -543,7 +543,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||||
|
|
||||||
Mir::new(self.cfg.basic_blocks,
|
Mir::new(self.cfg.basic_blocks,
|
||||||
self.visibility_scopes,
|
self.visibility_scopes,
|
||||||
ClearOnDecode::Set(self.visibility_scope_info),
|
ClearCrossCrate::Set(self.visibility_scope_info),
|
||||||
IndexVec::new(),
|
IndexVec::new(),
|
||||||
yield_ty,
|
yield_ty,
|
||||||
self.local_decls,
|
self.local_decls,
|
||||||
|
|
|
@ -198,7 +198,7 @@ fn build_drop_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
IndexVec::from_elem_n(
|
IndexVec::from_elem_n(
|
||||||
VisibilityScopeData { span: span, parent_scope: None }, 1
|
VisibilityScopeData { span: span, parent_scope: None }, 1
|
||||||
),
|
),
|
||||||
ClearOnDecode::Clear,
|
ClearCrossCrate::Clear,
|
||||||
IndexVec::new(),
|
IndexVec::new(),
|
||||||
None,
|
None,
|
||||||
local_decls_for_sig(&sig, span),
|
local_decls_for_sig(&sig, span),
|
||||||
|
@ -345,7 +345,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
|
||||||
IndexVec::from_elem_n(
|
IndexVec::from_elem_n(
|
||||||
VisibilityScopeData { span: self.span, parent_scope: None }, 1
|
VisibilityScopeData { span: self.span, parent_scope: None }, 1
|
||||||
),
|
),
|
||||||
ClearOnDecode::Clear,
|
ClearCrossCrate::Clear,
|
||||||
IndexVec::new(),
|
IndexVec::new(),
|
||||||
None,
|
None,
|
||||||
self.local_decls,
|
self.local_decls,
|
||||||
|
@ -807,7 +807,7 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
IndexVec::from_elem_n(
|
IndexVec::from_elem_n(
|
||||||
VisibilityScopeData { span: span, parent_scope: None }, 1
|
VisibilityScopeData { span: span, parent_scope: None }, 1
|
||||||
),
|
),
|
||||||
ClearOnDecode::Clear,
|
ClearCrossCrate::Clear,
|
||||||
IndexVec::new(),
|
IndexVec::new(),
|
||||||
None,
|
None,
|
||||||
local_decls,
|
local_decls,
|
||||||
|
@ -885,7 +885,7 @@ pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>,
|
||||||
IndexVec::from_elem_n(
|
IndexVec::from_elem_n(
|
||||||
VisibilityScopeData { span: span, parent_scope: None }, 1
|
VisibilityScopeData { span: span, parent_scope: None }, 1
|
||||||
),
|
),
|
||||||
ClearOnDecode::Clear,
|
ClearCrossCrate::Clear,
|
||||||
IndexVec::new(),
|
IndexVec::new(),
|
||||||
None,
|
None,
|
||||||
local_decls,
|
local_decls,
|
||||||
|
|
|
@ -20,6 +20,7 @@ use rustc::mir::*;
|
||||||
use rustc::mir::visit::{LvalueContext, Visitor};
|
use rustc::mir::visit::{LvalueContext, Visitor};
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
|
use syntax::symbol::Symbol;
|
||||||
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use util;
|
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.visibility_scope_info[source_info.scope].lint_root;
|
||||||
self.register_violations(&[UnsafetyViolation {
|
self.register_violations(&[UnsafetyViolation {
|
||||||
source_info,
|
source_info,
|
||||||
description: "borrow of packed field",
|
description: Symbol::intern("borrow of packed field").as_str(),
|
||||||
kind: UnsafetyViolationKind::BorrowPacked(lint_root)
|
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.visibility_scope_info[source_info.scope].lint_root;
|
||||||
self.register_violations(&[UnsafetyViolation {
|
self.register_violations(&[UnsafetyViolation {
|
||||||
source_info,
|
source_info,
|
||||||
description: "use of extern static",
|
description: Symbol::intern("use of extern static").as_str(),
|
||||||
kind: UnsafetyViolationKind::ExternStatic(lint_root)
|
kind: UnsafetyViolationKind::ExternStatic(lint_root)
|
||||||
}], &[]);
|
}], &[]);
|
||||||
}
|
}
|
||||||
|
@ -225,7 +226,9 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
|
||||||
{
|
{
|
||||||
let source_info = self.source_info;
|
let source_info = self.source_info;
|
||||||
self.register_violations(&[UnsafetyViolation {
|
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 mir = &tcx.mir_built(def_id).borrow();
|
||||||
|
|
||||||
let visibility_scope_info = match mir.visibility_scope_info {
|
let visibility_scope_info = match mir.visibility_scope_info {
|
||||||
ClearOnDecode::Set(ref data) => data,
|
ClearCrossCrate::Set(ref data) => data,
|
||||||
ClearOnDecode::Clear => {
|
ClearCrossCrate::Clear => {
|
||||||
debug!("unsafety_violations: {:?} - remote, skipping", def_id);
|
debug!("unsafety_violations: {:?} - remote, skipping", def_id);
|
||||||
return UnsafetyCheckResult {
|
return UnsafetyCheckResult {
|
||||||
violations: Rc::new([]),
|
violations: Rc::new([]),
|
||||||
|
@ -433,7 +436,7 @@ pub fn check_unsafety<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
|
||||||
struct_span_err!(
|
struct_span_err!(
|
||||||
tcx.sess, source_info.span, E0133,
|
tcx.sess, source_info.span, E0133,
|
||||||
"{} requires unsafe function or block", description)
|
"{} requires unsafe function or block", description)
|
||||||
.span_label(source_info.span, description)
|
.span_label(source_info.span, &description[..])
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
UnsafetyViolationKind::ExternStatic(lint_node_id) => {
|
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,
|
lint_node_id,
|
||||||
source_info.span,
|
source_info.span,
|
||||||
&format!("{} requires unsafe function or \
|
&format!("{} requires unsafe function or \
|
||||||
block (error E0133)", description));
|
block (error E0133)", &description[..]));
|
||||||
}
|
}
|
||||||
UnsafetyViolationKind::BorrowPacked(lint_node_id) => {
|
UnsafetyViolationKind::BorrowPacked(lint_node_id) => {
|
||||||
if let Some(impl_def_id) = builtin_derive_def_id(tcx, def_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,
|
lint_node_id,
|
||||||
source_info.span,
|
source_info.span,
|
||||||
&format!("{} requires unsafe function or \
|
&format!("{} requires unsafe function or \
|
||||||
block (error E0133)", description));
|
block (error E0133)", &description[..]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ use std::hash::{Hash, BuildHasher};
|
||||||
|
|
||||||
use {Decodable, Encodable, Decoder, Encoder};
|
use {Decodable, Encodable, Decoder, Encoder};
|
||||||
use std::collections::{LinkedList, VecDeque, BTreeMap, BTreeSet, HashMap, HashSet};
|
use std::collections::{LinkedList, VecDeque, BTreeMap, BTreeSet, HashMap, HashSet};
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
impl<
|
impl<
|
||||||
T: Encodable
|
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())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue