diff --git a/Cargo.lock b/Cargo.lock index 84e0d44d938d8..d5d66f8998710 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3719,6 +3719,7 @@ dependencies = [ "rustc_errors", "rustc_index", "rustc_lexer", + "rustc_macros", "rustc_target", "serialize", "smallvec 1.0.0", diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index cea790375fc3d..17ab0c187a2fc 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -578,7 +578,7 @@ impl<'tcx> DepNodeParams<'tcx> for HirId { /// the need to be mapped or unmapped. (This ensures we can serialize /// them even in the absence of a tcx.) #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, - RustcEncodable, RustcDecodable)] + RustcEncodable, RustcDecodable, HashStable)] pub struct WorkProductId { hash: Fingerprint } @@ -599,7 +599,3 @@ impl WorkProductId { } } } - -impl_stable_hash_for!(struct crate::dep_graph::WorkProductId { - hash -}); diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index 1e444e8a5b84e..2b3bc37c87ccb 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -313,11 +313,9 @@ pub enum DefPathData { } #[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug, - RustcEncodable, RustcDecodable)] + RustcEncodable, RustcDecodable, HashStable)] pub struct DefPathHash(pub Fingerprint); -impl_stable_hash_for!(tuple_struct DefPathHash { fingerprint }); - impl Borrow for DefPathHash { #[inline] fn borrow(&self) -> &Fingerprint { diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index bbd3b40e1be90..465673082e50a 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1215,7 +1215,7 @@ impl UnOp { } /// A statement. -#[derive(RustcEncodable, RustcDecodable)] +#[derive(RustcEncodable, RustcDecodable, HashStable)] pub struct Stmt { pub hir_id: HirId, pub kind: StmtKind, diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index c0255e5b8a481..816e93698bce9 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -140,13 +140,6 @@ impl<'a> HashStable> for hir::Ty { impl_stable_hash_for_spanned!(hir::BinOpKind); -impl_stable_hash_for!(struct hir::Stmt { - hir_id, - kind, - span, -}); - - impl_stable_hash_for_spanned!(ast::Name); impl<'a> HashStable> for hir::Expr { diff --git a/src/librustc/infer/outlives/free_region_map.rs b/src/librustc/infer/outlives/free_region_map.rs index c085df6a6e7ab..fd8ccce683352 100644 --- a/src/librustc/infer/outlives/free_region_map.rs +++ b/src/librustc/infer/outlives/free_region_map.rs @@ -1,7 +1,7 @@ use crate::ty::{self, Lift, TyCtxt, Region}; use rustc_data_structures::transitive_relation::TransitiveRelation; -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Default)] +#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Default, HashStable)] pub struct FreeRegionMap<'tcx> { // Stores the relation `a < b`, where `a` and `b` are regions. // @@ -89,10 +89,6 @@ fn is_free_or_static(r: Region<'_>) -> bool { } } -impl_stable_hash_for!(struct FreeRegionMap<'tcx> { - relation -}); - impl<'a, 'tcx> Lift<'tcx> for FreeRegionMap<'a> { type Lifted = FreeRegionMap<'tcx>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option> { diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 11d0d0d90fa86..d84102ff3c5d8 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -543,18 +543,11 @@ impl LintId { } /// Setting for how to handle a lint. -#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)] +#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash, HashStable)] pub enum Level { Allow, Warn, Deny, Forbid, } -impl_stable_hash_for!(enum self::Level { - Allow, - Warn, - Deny, - Forbid -}); - impl Level { /// Converts a level to a lower-case string. pub fn as_str(self) -> &'static str { @@ -590,7 +583,7 @@ impl Level { } /// How a lint level was set. -#[derive(Clone, Copy, PartialEq, Eq)] +#[derive(Clone, Copy, PartialEq, Eq, HashStable)] pub enum LintSource { /// Lint is at the default level as declared /// in rustc or a plugin. @@ -603,12 +596,6 @@ pub enum LintSource { CommandLine(Symbol), } -impl_stable_hash_for!(enum self::LintSource { - Default, - Node(name, span, reason), - CommandLine(text) -}); - pub type LevelSource = (Level, LintSource); pub mod builtin; diff --git a/src/librustc/middle/exported_symbols.rs b/src/librustc/middle/exported_symbols.rs index 4d14299751c3d..7182f03182402 100644 --- a/src/librustc/middle/exported_symbols.rs +++ b/src/librustc/middle/exported_symbols.rs @@ -11,17 +11,12 @@ use crate::ty::subst::SubstsRef; /// kind of crate, including cdylibs which export very few things. /// `Rust` will only be exported if the crate produced is a Rust /// dylib. -#[derive(Eq, PartialEq, Debug, Copy, Clone, RustcEncodable, RustcDecodable)] +#[derive(Eq, PartialEq, Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable)] pub enum SymbolExportLevel { C, Rust, } -impl_stable_hash_for!(enum self::SymbolExportLevel { - C, - Rust -}); - impl SymbolExportLevel { pub fn is_below_threshold(self, threshold: SymbolExportLevel) -> bool { threshold == SymbolExportLevel::Rust // export everything from Rust dylibs diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index a70fe2be96cc1..c13c44c413d77 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -207,7 +207,7 @@ struct NamedRegionMap { } /// See [`NamedRegionMap`]. -#[derive(Default)] +#[derive(Default, HashStable)] pub struct ResolveLifetimes { defs: FxHashMap>, late_bound: FxHashMap>, @@ -215,12 +215,6 @@ pub struct ResolveLifetimes { FxHashMap>>, } -impl_stable_hash_for!(struct crate::middle::resolve_lifetime::ResolveLifetimes { - defs, - late_bound, - object_lifetime_defaults -}); - struct LifetimeContext<'a, 'tcx> { tcx: TyCtxt<'tcx>, map: &'a mut NamedRegionMap, diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 8f8b4ed98bd3b..411a47423c5aa 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -52,7 +52,7 @@ enum AnnotationKind { } /// An entry in the `depr_map`. -#[derive(Clone)] +#[derive(Clone, HashStable)] pub struct DeprecationEntry { /// The metadata of the attribute associated with this entry. pub attr: Deprecation, @@ -61,11 +61,6 @@ pub struct DeprecationEntry { origin: Option, } -impl_stable_hash_for!(struct self::DeprecationEntry { - attr, - origin -}); - impl DeprecationEntry { fn local(attr: Deprecation, id: HirId) -> DeprecationEntry { DeprecationEntry { @@ -90,6 +85,7 @@ impl DeprecationEntry { } /// A stability index, giving the stability level for items and methods. +#[derive(HashStable)] pub struct Index<'tcx> { /// This is mostly a cache, except the stabilities of local items /// are filled by the annotator. @@ -103,13 +99,6 @@ pub struct Index<'tcx> { active_features: FxHashSet, } -impl_stable_hash_for!(struct self::Index<'tcx> { - stab_map, - depr_map, - staged_api, - active_features -}); - // A private tree-walker for producing an Index. struct Annotator<'a, 'tcx> { tcx: TyCtxt<'tcx>, diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs index aa8ac4902a894..f849361e08be9 100644 --- a/src/librustc/mir/interpret/allocation.rs +++ b/src/librustc/mir/interpret/allocation.rs @@ -4,7 +4,6 @@ use super::{ Pointer, InterpResult, AllocId, ScalarMaybeUndef, write_target_uint, read_target_uint, Scalar, }; -use crate::mir; use crate::ty::layout::{Size, Align}; use rustc_data_structures::sorted_map::SortedMap; @@ -787,14 +786,13 @@ type Block = u64; /// A bitmask where each bit refers to the byte with the same index. If the bit is `true`, the byte /// is defined. If it is `false` the byte is undefined. -#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)] +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash, + RustcEncodable, RustcDecodable, HashStable)] pub struct UndefMask { blocks: Vec, len: Size, } -impl_stable_hash_for!(struct mir::interpret::UndefMask{blocks, len}); - impl UndefMask { pub const BLOCK_SIZE: u64 = 64; diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index a0367154b75b3..52c72de7579e1 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -458,7 +458,7 @@ impl From> for Scalar { } } -#[derive(Clone, Copy, Eq, PartialEq, RustcEncodable, RustcDecodable)] +#[derive(Clone, Copy, Eq, PartialEq, RustcEncodable, RustcDecodable, HashStable)] pub enum ScalarMaybeUndef { Scalar(Scalar), Undef, @@ -583,11 +583,6 @@ impl<'tcx, Tag> ScalarMaybeUndef { } } -impl_stable_hash_for!(enum crate::mir::interpret::ScalarMaybeUndef { - Scalar(v), - Undef -}); - /// Gets the bytes of a constant slice value. pub fn get_slice_bytes<'tcx>(cx: &impl HasDataLayout, val: ConstValue<'tcx>) -> &'tcx [u8] { if let ConstValue::Slice { data, start, end } = val { diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 5997e4367bf29..79468b68055d4 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -70,7 +70,8 @@ impl<'tcx> HasLocalDecls<'tcx> for Body<'tcx> { /// The various "big phases" that MIR goes through. /// /// Warning: ordering of variants is significant. -#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Copy, Clone, RustcEncodable, RustcDecodable, HashStable, + Debug, PartialEq, Eq, PartialOrd, Ord)] pub enum MirPhase { Build = 0, Const = 1, @@ -86,7 +87,7 @@ impl MirPhase { } /// The lowered representation of a single function. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, TypeFoldable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable, TypeFoldable)] pub struct Body<'tcx> { /// A list of basic blocks. References to basic block use a newtyped index type `BasicBlock` /// that indexes into this vector. @@ -412,24 +413,6 @@ pub enum Safety { ExplicitUnsafe(hir::HirId), } -impl_stable_hash_for!(struct Body<'tcx> { - phase, - basic_blocks, - source_scopes, - source_scope_local_data, - yield_ty, - generator_drop, - generator_layout, - local_decls, - user_type_annotations, - arg_count, - __upvar_debuginfo_codegen_only_do_not_use, - spread_arg, - control_flow_destroyed, - span, - cache -}); - impl<'tcx> Index for Body<'tcx> { type Output = BasicBlockData<'tcx>; @@ -609,7 +592,7 @@ pub enum LocalKind { ReturnPointer, } -#[derive(Clone, Debug, RustcEncodable, RustcDecodable)] +#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)] pub struct VarBindingForm<'tcx> { /// Is variable bound via `x`, `mut x`, `ref x`, or `ref mut x`? pub binding_mode: ty::BindingMode, @@ -642,7 +625,7 @@ pub enum BindingForm<'tcx> { } /// Represents what type of implicit self a function has, if any. -#[derive(Clone, Copy, PartialEq, Debug, RustcEncodable, RustcDecodable)] +#[derive(Clone, Copy, PartialEq, Debug, RustcEncodable, RustcDecodable, HashStable)] pub enum ImplicitSelfKind { /// Represents a `fn x(self);`. Imm, @@ -659,28 +642,6 @@ pub enum ImplicitSelfKind { CloneTypeFoldableAndLiftImpls! { BindingForm<'tcx>, } -impl_stable_hash_for!(struct self::VarBindingForm<'tcx> { - binding_mode, - opt_ty_info, - opt_match_place, - pat_span -}); - -impl_stable_hash_for!(enum self::ImplicitSelfKind { - Imm, - Mut, - ImmRef, - MutRef, - None -}); - -impl_stable_hash_for!(enum self::MirPhase { - Build, - Const, - Validated, - Optimized, -}); - mod binding_form_impl { use crate::ich::StableHashingContext; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; @@ -707,7 +668,7 @@ mod binding_form_impl { /// involved in borrow_check errors, e.g., explanations of where the /// temporaries come from, when their destructors are run, and/or how /// one might revise the code to satisfy the borrow checker's rules. -#[derive(Clone, Debug, RustcEncodable, RustcDecodable)] +#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)] pub struct BlockTailInfo { /// If `true`, then the value resulting from evaluating this tail /// expression is ignored by the block's expression context. @@ -717,8 +678,6 @@ pub struct BlockTailInfo { pub tail_result_is_ignored: bool, } -impl_stable_hash_for!(struct BlockTailInfo { tail_result_is_ignored }); - /// A MIR local. /// /// This can be a binding declared by the user, a temporary inserted by the compiler, a function @@ -1746,7 +1705,8 @@ pub enum PlaceBase<'tcx> { } /// We store the normalized type to avoid requiring normalization when reading MIR -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, + RustcEncodable, RustcDecodable, HashStable)] pub struct Static<'tcx> { pub ty: Ty<'tcx>, pub kind: StaticKind<'tcx>, @@ -1768,12 +1728,6 @@ pub enum StaticKind<'tcx> { Static, } -impl_stable_hash_for!(struct Static<'tcx> { - ty, - kind, - def_id -}); - #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(RustcEncodable, RustcDecodable, HashStable)] pub enum ProjectionElem { diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs index a54635c3d51a3..34daf185b2952 100644 --- a/src/librustc/mir/mono.rs +++ b/src/librustc/mir/mono.rs @@ -251,7 +251,7 @@ pub struct CodegenUnit<'tcx> { size_estimate: Option, } -#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable)] +#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable, HashStable)] pub enum Linkage { External, AvailableExternally, @@ -266,33 +266,13 @@ pub enum Linkage { Common, } -impl_stable_hash_for!(enum self::Linkage { - External, - AvailableExternally, - LinkOnceAny, - LinkOnceODR, - WeakAny, - WeakODR, - Appending, - Internal, - Private, - ExternalWeak, - Common -}); - -#[derive(Copy, Clone, PartialEq, Debug)] +#[derive(Copy, Clone, PartialEq, Debug, HashStable)] pub enum Visibility { Default, Hidden, Protected, } -impl_stable_hash_for!(enum self::Visibility { - Default, - Hidden, - Protected -}); - impl<'tcx> CodegenUnit<'tcx> { pub fn new(name: Symbol) -> CodegenUnit<'tcx> { CodegenUnit { diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index e07726bfa2aa1..cd93fed8e1e0e 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -29,6 +29,12 @@ use syntax_pos::symbol::Symbol; // Queries marked with `fatal_cycle` do not need the latter implementation, // as they will raise an fatal error on query cycles instead. rustc_queries! { + Other { + query trigger_delay_span_bug(key: DefId) -> () { + desc { "trigger a delay span bug" } + } + } + Other { /// Records the type of every item. query type_of(key: DefId) -> Ty<'tcx> { diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs index 93f56804a9f4f..785b4122d0873 100644 --- a/src/librustc/traits/query/dropck_outlives.rs +++ b/src/librustc/traits/query/dropck_outlives.rs @@ -79,7 +79,7 @@ impl<'cx, 'tcx> At<'cx, 'tcx> { } } -#[derive(Clone, Debug, Default, TypeFoldable, Lift)] +#[derive(Clone, Debug, Default, HashStable, TypeFoldable, Lift)] pub struct DropckOutlivesResult<'tcx> { pub kinds: Vec>, pub overflows: Vec>, @@ -114,7 +114,7 @@ impl<'tcx> DropckOutlivesResult<'tcx> { /// A set of constraints that need to be satisfied in order for /// a type to be valid for destruction. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, HashStable)] pub struct DtorckConstraint<'tcx> { /// Types that are required to be alive in order for this /// type to be valid for destruction. @@ -152,15 +152,6 @@ impl<'tcx> FromIterator> for DtorckConstraint<'tcx> { result } } -impl_stable_hash_for!(struct DropckOutlivesResult<'tcx> { - kinds, overflows -}); - -impl_stable_hash_for!(struct DtorckConstraint<'tcx> { - outlives, - dtorck_types, - overflows -}); /// This returns true if the type `ty` is "trivial" for /// dropck-outlives -- that is, if it doesn't require any types to diff --git a/src/librustc/traits/query/method_autoderef.rs b/src/librustc/traits/query/method_autoderef.rs index 039dea1ffcd16..be846287e290c 100644 --- a/src/librustc/traits/query/method_autoderef.rs +++ b/src/librustc/traits/query/method_autoderef.rs @@ -2,7 +2,7 @@ use rustc_data_structures::sync::Lrc; use crate::infer::canonical::{Canonical, QueryResponse}; use crate::ty::Ty; -#[derive(Debug)] +#[derive(Debug, HashStable)] pub struct CandidateStep<'tcx> { pub self_ty: Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>, pub autoderefs: usize, @@ -15,7 +15,7 @@ pub struct CandidateStep<'tcx> { pub unsize: bool, } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, HashStable)] pub struct MethodAutoderefStepsResult<'tcx> { /// The valid autoderef steps that could be find. pub steps: Lrc>>, @@ -26,20 +26,8 @@ pub struct MethodAutoderefStepsResult<'tcx> { pub reached_recursion_limit: bool, } -#[derive(Debug)] +#[derive(Debug, HashStable)] pub struct MethodAutoderefBadTy<'tcx> { pub reached_raw_pointer: bool, pub ty: Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>, } - -impl_stable_hash_for!(struct MethodAutoderefBadTy<'tcx> { - reached_raw_pointer, ty -}); - -impl_stable_hash_for!(struct MethodAutoderefStepsResult<'tcx> { - reached_recursion_limit, steps, opt_bad_ty -}); - -impl_stable_hash_for!(struct CandidateStep<'tcx> { - self_ty, autoderefs, from_unsafe_deref, unsize -}); diff --git a/src/librustc/traits/query/mod.rs b/src/librustc/traits/query/mod.rs index f6ea77dc5cc68..66683cab95960 100644 --- a/src/librustc/traits/query/mod.rs +++ b/src/librustc/traits/query/mod.rs @@ -40,7 +40,7 @@ pub type CanonicalTypeOpProvePredicateGoal<'tcx> = pub type CanonicalTypeOpNormalizeGoal<'tcx, T> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::normalize::Normalize>>; -#[derive(Clone, Debug)] +#[derive(Clone, Debug, HashStable)] pub struct NoSolution; pub type Fallible = Result; @@ -50,5 +50,3 @@ impl<'tcx> From> for NoSolution { NoSolution } } - -impl_stable_hash_for!(struct NoSolution { }); diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs index 30528dcebdae9..09c7f45c22b0a 100644 --- a/src/librustc/traits/query/normalize.rs +++ b/src/librustc/traits/query/normalize.rs @@ -66,7 +66,7 @@ impl<'cx, 'tcx> At<'cx, 'tcx> { } /// Result from the `normalize_projection_ty` query. -#[derive(Clone, Debug, TypeFoldable, Lift)] +#[derive(Clone, Debug, HashStable, TypeFoldable, Lift)] pub struct NormalizationResult<'tcx> { /// Result of normalization. pub normalized_ty: Ty<'tcx>, @@ -193,7 +193,3 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { constant.eval(self.infcx.tcx, self.param_env) } } - -impl_stable_hash_for!(struct NormalizationResult<'tcx> { - normalized_ty -}); diff --git a/src/librustc/traits/query/type_op/ascribe_user_type.rs b/src/librustc/traits/query/type_op/ascribe_user_type.rs index 8b0ee5feed7bc..ee8b73f86a61a 100644 --- a/src/librustc/traits/query/type_op/ascribe_user_type.rs +++ b/src/librustc/traits/query/type_op/ascribe_user_type.rs @@ -4,7 +4,7 @@ use crate::hir::def_id::DefId; use crate::ty::{ParamEnvAnd, Ty, TyCtxt}; use crate::ty::subst::UserSubsts; -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, TypeFoldable, Lift)] +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, Lift)] pub struct AscribeUserType<'tcx> { pub mir_ty: Ty<'tcx>, pub def_id: DefId, @@ -38,9 +38,3 @@ impl<'tcx> super::QueryTypeOp<'tcx> for AscribeUserType<'tcx> { tcx.type_op_ascribe_user_type(canonicalized) } } - -impl_stable_hash_for! { - struct AscribeUserType<'tcx> { - mir_ty, def_id, user_substs - } -} diff --git a/src/librustc/traits/query/type_op/eq.rs b/src/librustc/traits/query/type_op/eq.rs index 5086994fbb6ed..8ea800cced213 100644 --- a/src/librustc/traits/query/type_op/eq.rs +++ b/src/librustc/traits/query/type_op/eq.rs @@ -2,7 +2,7 @@ use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse}; use crate::traits::query::Fallible; use crate::ty::{ParamEnvAnd, Ty, TyCtxt}; -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, TypeFoldable, Lift)] +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, Lift)] pub struct Eq<'tcx> { pub a: Ty<'tcx>, pub b: Ty<'tcx>, @@ -35,7 +35,3 @@ impl<'tcx> super::QueryTypeOp<'tcx> for Eq<'tcx> { tcx.type_op_eq(canonicalized) } } - -impl_stable_hash_for! { - struct Eq<'tcx> { a, b } -} diff --git a/src/librustc/traits/query/type_op/implied_outlives_bounds.rs b/src/librustc/traits/query/type_op/implied_outlives_bounds.rs index f97b34f9e9a5a..6f45d76a8e9d7 100644 --- a/src/librustc/traits/query/type_op/implied_outlives_bounds.rs +++ b/src/librustc/traits/query/type_op/implied_outlives_bounds.rs @@ -3,7 +3,7 @@ use crate::traits::query::outlives_bounds::OutlivesBound; use crate::traits::query::Fallible; use crate::ty::{ParamEnvAnd, Ty, TyCtxt}; -#[derive(Clone, Debug, TypeFoldable, Lift)] +#[derive(Clone, Debug, HashStable, TypeFoldable, Lift)] pub struct ImpliedOutlivesBounds<'tcx> { pub ty: Ty<'tcx>, } @@ -39,7 +39,3 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ImpliedOutlivesBounds<'tcx> { tcx.implied_outlives_bounds(canonicalized) } } - -impl_stable_hash_for! { - struct ImpliedOutlivesBounds<'tcx> { ty } -} diff --git a/src/librustc/traits/query/type_op/normalize.rs b/src/librustc/traits/query/type_op/normalize.rs index 798fc5224ccc6..f905d5a019ec8 100644 --- a/src/librustc/traits/query/type_op/normalize.rs +++ b/src/librustc/traits/query/type_op/normalize.rs @@ -4,7 +4,7 @@ use crate::traits::query::Fallible; use crate::ty::fold::TypeFoldable; use crate::ty::{self, Lift, ParamEnvAnd, Ty, TyCtxt}; -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, TypeFoldable, Lift)] +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, Lift)] pub struct Normalize { pub value: T, } @@ -82,9 +82,3 @@ impl Normalizable<'tcx> for ty::FnSig<'tcx> { tcx.type_op_normalize_fn_sig(canonicalized) } } - -impl_stable_hash_for! { - impl for struct Normalize { - value - } -} diff --git a/src/librustc/traits/query/type_op/outlives.rs b/src/librustc/traits/query/type_op/outlives.rs index d2a7fdc8946df..83d51b6d3ebf7 100644 --- a/src/librustc/traits/query/type_op/outlives.rs +++ b/src/librustc/traits/query/type_op/outlives.rs @@ -3,7 +3,7 @@ use crate::traits::query::dropck_outlives::{DropckOutlivesResult, trivial_dropck use crate::traits::query::Fallible; use crate::ty::{ParamEnvAnd, Ty, TyCtxt}; -#[derive(Copy, Clone, Debug, TypeFoldable, Lift)] +#[derive(Copy, Clone, Debug, HashStable, TypeFoldable, Lift)] pub struct DropckOutlives<'tcx> { dropped_ty: Ty<'tcx>, } @@ -53,7 +53,3 @@ impl super::QueryTypeOp<'tcx> for DropckOutlives<'tcx> { tcx.dropck_outlives(canonicalized) } } - -impl_stable_hash_for! { - struct DropckOutlives<'tcx> { dropped_ty } -} diff --git a/src/librustc/traits/query/type_op/prove_predicate.rs b/src/librustc/traits/query/type_op/prove_predicate.rs index cbf485fcfe02f..c0a0cbe9a3876 100644 --- a/src/librustc/traits/query/type_op/prove_predicate.rs +++ b/src/librustc/traits/query/type_op/prove_predicate.rs @@ -2,7 +2,7 @@ use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse}; use crate::traits::query::Fallible; use crate::ty::{ParamEnvAnd, Predicate, TyCtxt}; -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, TypeFoldable, Lift)] +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, Lift)] pub struct ProvePredicate<'tcx> { pub predicate: Predicate<'tcx>, } @@ -44,7 +44,3 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> { tcx.type_op_prove_predicate(canonicalized) } } - -impl_stable_hash_for! { - struct ProvePredicate<'tcx> { predicate } -} diff --git a/src/librustc/traits/query/type_op/subtype.rs b/src/librustc/traits/query/type_op/subtype.rs index bd53e234a6a49..76292f9dea085 100644 --- a/src/librustc/traits/query/type_op/subtype.rs +++ b/src/librustc/traits/query/type_op/subtype.rs @@ -2,7 +2,7 @@ use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse}; use crate::traits::query::Fallible; use crate::ty::{ParamEnvAnd, Ty, TyCtxt}; -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, TypeFoldable, Lift)] +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, Lift)] pub struct Subtype<'tcx> { pub sub: Ty<'tcx>, pub sup: Ty<'tcx>, @@ -35,7 +35,3 @@ impl<'tcx> super::QueryTypeOp<'tcx> for Subtype<'tcx> { tcx.type_op_subtype(canonicalized) } } - -impl_stable_hash_for! { - struct Subtype<'tcx> { sub, sup } -} diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 608883d609f47..ffc94cf2b125e 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -367,7 +367,6 @@ enum BuiltinImplConditions<'tcx> { Ambiguous, } -#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)] /// The result of trait evaluation. The order is important /// here as the evaluation of a list is the maximum of the /// evaluations. @@ -380,6 +379,7 @@ enum BuiltinImplConditions<'tcx> { /// all the "potential success" candidates can potentially succeed, /// so they are noops when unioned with a definite error, and within /// the categories it's easy to see that the unions are correct. +#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq, HashStable)] pub enum EvaluationResult { /// Evaluation successful EvaluatedToOk, @@ -478,21 +478,10 @@ impl EvaluationResult { } } -impl_stable_hash_for!(enum self::EvaluationResult { - EvaluatedToOk, - EvaluatedToOkModuloRegions, - EvaluatedToAmbig, - EvaluatedToUnknown, - EvaluatedToRecur, - EvaluatedToErr -}); - -#[derive(Copy, Clone, Debug, PartialEq, Eq)] /// Indicates that trait evaluation caused overflow. +#[derive(Copy, Clone, Debug, PartialEq, Eq, HashStable)] pub struct OverflowError; -impl_stable_hash_for!(struct OverflowError {}); - impl<'tcx> From for SelectionError<'tcx> { fn from(OverflowError: OverflowError) -> SelectionError<'tcx> { SelectionError::Overflow diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs index c64d6748ea97d..d945c756f6662 100644 --- a/src/librustc/traits/specialize/specialization_graph.rs +++ b/src/librustc/traits/specialize/specialization_graph.rs @@ -24,7 +24,7 @@ use crate::util::nodemap::{DefIdMap, FxHashMap}; /// parents of a given specializing impl, which is needed for extracting /// default items amongst other things. In the simple "chain" rule, every impl /// has at most one parent. -#[derive(RustcEncodable, RustcDecodable)] +#[derive(RustcEncodable, RustcDecodable, HashStable)] pub struct Graph { // All impls have a parent; the "root" impls have as their parent the `def_id` // of the trait. @@ -535,8 +535,3 @@ impl<'a> HashStable> for Children { ich::hash_stable_trait_impls(hcx, hasher, blanket_impls, nonblanket_impls); } } - -impl_stable_hash_for!(struct self::Graph { - parent, - children -}); diff --git a/src/librustc/ty/binding.rs b/src/librustc/ty/binding.rs index 905d7abb7828c..491e09dff0950 100644 --- a/src/librustc/ty/binding.rs +++ b/src/librustc/ty/binding.rs @@ -2,7 +2,7 @@ use crate::hir::BindingAnnotation::*; use crate::hir::BindingAnnotation; use crate::hir::Mutability; -#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)] +#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)] pub enum BindingMode { BindByReference(Mutability), BindByValue(Mutability), @@ -20,8 +20,3 @@ impl BindingMode { } } } - -impl_stable_hash_for!(enum self::BindingMode { - BindByReference(mutability), - BindByValue(mutability) -}); diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 031d6f09b4485..a54bf5079cac4 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1590,12 +1590,11 @@ rustc_index::newtype_index! { /// type -- an idealized representative of "types in general" that we /// use for checking generic functions. pub struct UniverseIndex { + derive [HashStable] DEBUG_FORMAT = "U{}", } } -impl_stable_hash_for!(struct UniverseIndex { private }); - impl UniverseIndex { pub const ROOT: UniverseIndex = UniverseIndex::from_u32_const(0); @@ -1839,7 +1838,7 @@ bitflags! { } /// Definition of a variant -- a struct's fields or a enum variant. -#[derive(Debug)] +#[derive(Debug, HashStable)] pub struct VariantDef { /// `DefId` that identifies the variant itself. /// If this variant belongs to a struct or union, then this is a copy of its `DefId`. @@ -1848,6 +1847,7 @@ pub struct VariantDef { /// If this variant is a struct variant, then this is `None`. pub ctor_def_id: Option, /// Variant or struct name. + #[stable_hasher(project(name))] pub ident: Ident, /// Discriminant of this variant. pub discr: VariantDiscr, @@ -1927,17 +1927,6 @@ impl<'tcx> VariantDef { } } -impl_stable_hash_for!(struct VariantDef { - def_id, - ctor_def_id, - ident -> (ident.name), - discr, - fields, - ctor_kind, - flags, - recovered -}); - #[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)] pub enum VariantDiscr { /// Explicit value for this variant, i.e., `X = 123`. @@ -2061,7 +2050,7 @@ impl Into for AdtKind { } bitflags! { - #[derive(RustcEncodable, RustcDecodable, Default)] + #[derive(RustcEncodable, RustcDecodable, Default, HashStable)] pub struct ReprFlags: u8 { const IS_C = 1 << 0; const IS_SIMD = 1 << 1; @@ -2076,12 +2065,9 @@ bitflags! { } } -impl_stable_hash_for!(struct ReprFlags { - bits -}); - /// Represents the repr options provided by the user, -#[derive(Copy, Clone, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Default)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, + Default, HashStable)] pub struct ReprOptions { pub int: Option, pub align: Option, @@ -2089,13 +2075,6 @@ pub struct ReprOptions { pub flags: ReprFlags, } -impl_stable_hash_for!(struct ReprOptions { - align, - pack, - int, - flags -}); - impl ReprOptions { pub fn new(tcx: TyCtxt<'_>, did: DefId) -> ReprOptions { let mut flags = ReprFlags::empty(); @@ -3439,17 +3418,13 @@ pub struct CrateInherentImpls { pub inherent_impls: DefIdMap>, } -#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable)] +#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)] pub struct SymbolName { // FIXME: we don't rely on interning or equality here - better have // this be a `&'tcx str`. pub name: Symbol } -impl_stable_hash_for!(struct self::SymbolName { - name -}); - impl SymbolName { pub fn new(name: &str) -> SymbolName { SymbolName { diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index fa22709d66fc4..07258717cd9d4 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1204,6 +1204,7 @@ rustc_index::newtype_index! { /// is the outer fn. /// /// [dbi]: http://en.wikipedia.org/wiki/De_Bruijn_index + #[derive(HashStable)] pub struct DebruijnIndex { DEBUG_FORMAT = "DebruijnIndex({})", const INNERMOST = 0, @@ -1379,21 +1380,20 @@ rustc_index::newtype_index! { pub struct BoundVar { .. } } -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, + RustcEncodable, RustcDecodable, HashStable)] pub struct BoundTy { pub var: BoundVar, pub kind: BoundTyKind, } -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, + RustcEncodable, RustcDecodable, HashStable)] pub enum BoundTyKind { Anon, Param(Symbol), } -impl_stable_hash_for!(struct BoundTy { var, kind }); -impl_stable_hash_for!(enum self::BoundTyKind { Anon, Param(a) }); - impl From for BoundTy { fn from(var: BoundVar) -> Self { BoundTy { @@ -1518,8 +1518,6 @@ impl DebruijnIndex { } } -impl_stable_hash_for!(struct DebruijnIndex { private }); - /// Region utilities impl RegionKind { /// Is this region named by the user? diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs index 66920342ff6ba..fb2099e71a31a 100644 --- a/src/librustc_codegen_utils/lib.rs +++ b/src/librustc_codegen_utils/lib.rs @@ -19,7 +19,7 @@ extern crate rustc; use rustc::ty::TyCtxt; use rustc::ty::query::Providers; -use rustc::hir::def_id::LOCAL_CRATE; +use rustc::hir::def_id::{LOCAL_CRATE, DefId}; use syntax::symbol::sym; pub mod link; @@ -27,18 +27,50 @@ pub mod codegen_backend; pub mod symbol_names; pub mod symbol_names_test; + +pub fn trigger_delay_span_bug(tcx: TyCtxt<'_>, key: DefId) { + tcx.sess.delay_span_bug( + tcx.def_span(key), + "delayed span bug triggered by #[rustc_error(delay_span_bug_from_inside_query)]" + ); +} + /// check for the #[rustc_error] annotation, which forces an /// error in codegen. This is used to write compile-fail tests /// that actually test that compilation succeeds without /// reporting an error. pub fn check_for_rustc_errors_attr(tcx: TyCtxt<'_>) { if let Some((def_id, _)) = tcx.entry_fn(LOCAL_CRATE) { - if tcx.has_attr(def_id, sym::rustc_error) { - tcx.sess.span_fatal(tcx.def_span(def_id), "compilation successful"); + let attrs = &*tcx.get_attrs(def_id); + for attr in attrs { + if attr.check_name(sym::rustc_error) { + match attr.meta_item_list() { + // check if there is a #[rustc_error(delayed)] + Some(list) => { + if list.iter().any(|list_item| { + list_item.ident().map(|i| i.name) == + Some(sym::delay_span_bug_from_inside_query) + }) { + tcx.ensure().trigger_delay_span_bug(def_id); + } + } + // bare #[rustc_error] + None => { + tcx.sess.span_fatal( + tcx.def_span(def_id), + "fatal error triggered by #[rustc_error]" + ); + } + } + } } } } pub fn provide(providers: &mut Providers<'_>) { crate::symbol_names::provide(providers); + *providers = Providers { + trigger_delay_span_bug, + ..*providers + }; } diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 6dfb24097753d..a721e381b4e99 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -1,21 +1,17 @@ //! Validates all used crates and extern libraries and loads their metadata -use crate::cstore::{self, CStore, MetadataBlob}; -use crate::locator::{self, CratePaths}; -use crate::rmeta::{CrateRoot, CrateDep}; -use rustc_data_structures::sync::{Lock, Once, AtomicCell}; +use crate::cstore::CStore; +use crate::locator::{CrateLocator, CratePaths}; +use crate::rmeta::{CrateMetadata, CrateNumMap, CrateRoot, CrateDep, MetadataBlob}; use rustc::hir::def_id::CrateNum; use rustc_data_structures::svh::Svh; -use rustc::dep_graph::DepNodeIndex; use rustc::middle::cstore::DepKind; -use rustc::mir::interpret::AllocDecodingState; use rustc::session::{Session, CrateDisambiguator}; use rustc::session::config::{Sanitizer, self}; use rustc_target::spec::{PanicStrategy, TargetTriple}; use rustc::session::search_paths::PathKind; use rustc::middle::cstore::{CrateSource, ExternCrate, ExternCrateSource, MetadataLoaderDyn}; -use rustc::util::common::record_time; use rustc::util::nodemap::FxHashSet; use rustc::hir::map::Definitions; use rustc::hir::def_id::LOCAL_CRATE; @@ -50,9 +46,9 @@ pub struct CrateLoader<'a> { fn dump_crates(cstore: &CStore) { info!("resolved crates:"); - cstore.iter_crate_data(|_, data| { + cstore.iter_crate_data(|cnum, data| { info!(" name: {}", data.root.name); - info!(" cnum: {}", data.cnum); + info!(" cnum: {}", cnum); info!(" hash: {}", data.root.hash); info!(" reqd: {:?}", *data.dep_kind.lock()); let CrateSource { dylib, rlib, rmeta } = data.source.clone(); @@ -68,13 +64,13 @@ enum LoadResult { } enum LoadError<'a> { - LocatorError(locator::Context<'a>), + LocatorError(CrateLocator<'a>), } impl<'a> LoadError<'a> { fn report(self) -> ! { match self { - LoadError::LocatorError(locate_ctxt) => locate_ctxt.report_errs(), + LoadError::LocatorError(locator) => locator.report_errs(), } } } @@ -145,7 +141,7 @@ impl<'a> CrateLoader<'a> { let prev_kind = source.dylib.as_ref().or(source.rlib.as_ref()) .or(source.rmeta.as_ref()) .expect("No sources for crate").1; - if ret.is_none() && (prev_kind == kind || prev_kind == PathKind::All) { + if kind.matches(prev_kind) { ret = Some(cnum); } }); @@ -211,15 +207,13 @@ impl<'a> CrateLoader<'a> { let root = if let Some(root) = root { root } else { - crate_paths = CratePaths { name: crate_root.name, source: source.clone() }; + crate_paths = CratePaths::new(crate_root.name, source.clone()); &crate_paths }; let cnum_map = self.resolve_crate_deps(root, &crate_root, &metadata, cnum, span, dep_kind); - let dependencies: Vec = cnum_map.iter().cloned().collect(); - - let raw_proc_macros = crate_root.proc_macro_data.map(|_| { + let raw_proc_macros = if crate_root.is_proc_macro_crate() { let temp_root; let (dlsym_source, dlsym_root) = match &host_lib { Some(host_lib) => @@ -227,55 +221,38 @@ impl<'a> CrateLoader<'a> { None => (&source, &crate_root), }; let dlsym_dylib = dlsym_source.dylib.as_ref().expect("no dylib for a proc-macro crate"); - self.dlsym_proc_macros(&dlsym_dylib.0, dlsym_root.disambiguator, span) - }); - - let interpret_alloc_index: Vec = crate_root.interpret_alloc_index - .decode(&metadata) - .collect(); - let trait_impls = crate_root - .impls - .decode((&metadata, self.sess)) - .map(|trait_impls| (trait_impls.trait_id, trait_impls.impls)) - .collect(); - - let def_path_table = record_time(&self.sess.perf_stats.decode_def_path_tables_time, || { - crate_root.def_path_table.decode((&metadata, self.sess)) - }); + Some(self.dlsym_proc_macros(&dlsym_dylib.0, dlsym_root.disambiguator, span)) + } else { + None + }; - self.cstore.set_crate_data(cnum, cstore::CrateMetadata { - extern_crate: Lock::new(None), - def_path_table, - trait_impls, - root: crate_root, - host_hash, - blob: metadata, - cnum_map, + self.cstore.set_crate_data(cnum, CrateMetadata::new( + self.sess, + metadata, + crate_root, + raw_proc_macros, cnum, - dependencies: Lock::new(dependencies), - source_map_import_info: Once::new(), - alloc_decoding_state: AllocDecodingState::new(interpret_alloc_index), - dep_kind: Lock::new(dep_kind), + cnum_map, + dep_kind, source, private_dep, - raw_proc_macros, - dep_node_index: AtomicCell::new(DepNodeIndex::INVALID), - }); + host_hash, + )); cnum } fn load_proc_macro<'b>( &self, - locate_ctxt: &mut locator::Context<'b>, + locator: &mut CrateLocator<'b>, path_kind: PathKind, ) -> Option<(LoadResult, Option)> where 'a: 'b, { - // Use a new locator Context so trying to load a proc macro doesn't affect the error + // Use a new crate locator so trying to load a proc macro doesn't affect the error // message we emit - let mut proc_macro_locator = locate_ctxt.clone(); + let mut proc_macro_locator = locator.clone(); // Try to load a proc macro proc_macro_locator.is_proc_macro = Some(true); @@ -287,10 +264,10 @@ impl<'a> CrateLoader<'a> { LoadResult::Previous(cnum) => return Some((LoadResult::Previous(cnum), None)), LoadResult::Loaded(library) => Some(LoadResult::Loaded(library)) }; - locate_ctxt.hash = locate_ctxt.host_hash; - // Use the locate_ctxt when looking for the host proc macro crate, as that is required + locator.hash = locator.host_hash; + // Use the locator when looking for the host proc macro crate, as that is required // so we want it to affect the error message - (locate_ctxt, result) + (locator, result) } else { (&mut proc_macro_locator, None) }; @@ -350,37 +327,30 @@ impl<'a> CrateLoader<'a> { (LoadResult::Previous(cnum), None) } else { info!("falling back to a load"); - let mut locate_ctxt = locator::Context { - sess: self.sess, - span, - crate_name: name, + let mut locator = CrateLocator::new( + self.sess, + self.metadata_loader, + name, hash, host_hash, extra_filename, - filesearch: self.sess.target_filesearch(path_kind), - target: &self.sess.target.target, - triple: self.sess.opts.target_triple.clone(), + false, // is_host + path_kind, + span, root, - rejected_via_hash: vec![], - rejected_via_triple: vec![], - rejected_via_kind: vec![], - rejected_via_version: vec![], - rejected_via_filename: vec![], - should_match_name: true, - is_proc_macro: Some(false), - metadata_loader: self.metadata_loader, - }; + Some(false), // is_proc_macro + ); - self.load(&mut locate_ctxt).map(|r| (r, None)).or_else(|| { + self.load(&mut locator).map(|r| (r, None)).or_else(|| { dep_kind = DepKind::UnexportedMacrosOnly; - self.load_proc_macro(&mut locate_ctxt, path_kind) - }).ok_or_else(move || LoadError::LocatorError(locate_ctxt))? + self.load_proc_macro(&mut locator, path_kind) + }).ok_or_else(move || LoadError::LocatorError(locator))? }; match result { (LoadResult::Previous(cnum), None) => { let data = self.cstore.get_crate_data(cnum); - if data.root.proc_macro_data.is_some() { + if data.root.is_proc_macro_crate() { dep_kind = DepKind::UnexportedMacrosOnly; } data.dep_kind.with_lock(|data_dep_kind| { @@ -395,8 +365,8 @@ impl<'a> CrateLoader<'a> { } } - fn load(&self, locate_ctxt: &mut locator::Context<'_>) -> Option { - let library = locate_ctxt.maybe_load_library_crate()?; + fn load(&self, locator: &mut CrateLocator<'_>) -> Option { + let library = locator.maybe_load_library_crate()?; // In the case that we're loading a crate, but not matching // against a hash, we could load a crate which has the same hash @@ -407,11 +377,11 @@ impl<'a> CrateLoader<'a> { // don't want to match a host crate against an equivalent target one // already loaded. let root = library.metadata.get_root(); - if locate_ctxt.triple == self.sess.opts.target_triple { + if locator.triple == self.sess.opts.target_triple { let mut result = LoadResult::Loaded(library); self.cstore.iter_crate_data(|cnum, data| { if data.root.name == root.name && root.hash == data.root.hash { - assert!(locate_ctxt.hash.is_none()); + assert!(locator.hash.is_none()); info!("load success, going to previous cnum: {}", cnum); result = LoadResult::Previous(cnum); } @@ -471,16 +441,16 @@ impl<'a> CrateLoader<'a> { krate: CrateNum, span: Span, dep_kind: DepKind) - -> cstore::CrateNumMap { + -> CrateNumMap { debug!("resolving deps of external crate"); - if crate_root.proc_macro_data.is_some() { - return cstore::CrateNumMap::new(); + if crate_root.is_proc_macro_crate() { + return CrateNumMap::new(); } // The map from crate numbers in the crate we're resolving to local crate numbers. // We map 0 and all other holes in the map to our parent crate. The "additional" // self-dependencies should be harmless. - std::iter::once(krate).chain(crate_root.crate_deps.decode(metadata).map(|dep| { + std::iter::once(krate).chain(crate_root.decode_crate_deps(metadata).map(|dep| { info!("resolving dep crate {} hash: `{}` extra filename: `{}`", dep.name, dep.hash, dep.extra_filename); if dep.kind == DepKind::UnexportedMacrosOnly { @@ -824,7 +794,7 @@ impl<'a> CrateLoader<'a> { fn inject_dependency_if(&self, krate: CrateNum, what: &str, - needs_dep: &dyn Fn(&cstore::CrateMetadata) -> bool) { + needs_dep: &dyn Fn(&CrateMetadata) -> bool) { // don't perform this validation if the session has errors, as one of // those errors may indicate a circular dependency which could cause // this to stack overflow. diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 54857ce1b8281..48cf0b982f290 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -1,109 +1,23 @@ // The crate store - a central repo for information collected about external // crates and libraries -use crate::rmeta; -use rustc::dep_graph::DepNodeIndex; -use rustc::hir::def_id::{CrateNum, DefIndex}; -use rustc::hir::map::definitions::DefPathTable; -use rustc::middle::cstore::{CrateSource, DepKind, ExternCrate}; -use rustc::mir::interpret::AllocDecodingState; +use crate::rmeta::CrateMetadata; + +use rustc_data_structures::sync::Lrc; use rustc_index::vec::IndexVec; -use rustc::util::nodemap::FxHashMap; -use rustc_data_structures::sync::{Lrc, Lock, MetadataRef, Once, AtomicCell}; -use rustc_data_structures::svh::Svh; +use rustc::hir::def_id::CrateNum; use syntax::ast; use syntax::edition::Edition; -use syntax_expand::base::SyntaxExtension; use syntax::expand::allocator::AllocatorKind; -use syntax_pos; -use proc_macro::bridge::client::ProcMacro; +use syntax_expand::base::SyntaxExtension; pub use crate::rmeta::{provide, provide_extern}; -// A map from external crate numbers (as decoded from some crate file) to -// local crate numbers (as generated during this session). Each external -// crate may refer to types in other external crates, and each has their -// own crate numbers. -crate type CrateNumMap = IndexVec; - -crate struct MetadataBlob(pub MetadataRef); - -/// Holds information about a syntax_pos::SourceFile imported from another crate. -/// See `imported_source_files()` for more information. -crate struct ImportedSourceFile { - /// This SourceFile's byte-offset within the source_map of its original crate - pub original_start_pos: syntax_pos::BytePos, - /// The end of this SourceFile within the source_map of its original crate - pub original_end_pos: syntax_pos::BytePos, - /// The imported SourceFile's representation within the local source_map - pub translated_source_file: Lrc, -} - -crate struct CrateMetadata { - /// The primary crate data - binary metadata blob. - crate blob: MetadataBlob, - - // --- Some data pre-decoded from the metadata blob, usually for performance --- - - /// Properties of the whole crate. - /// NOTE(eddyb) we pass `'static` to a `'tcx` parameter because this - /// lifetime is only used behind `Lazy`, and therefore acts like an - /// universal (`for<'tcx>`), that is paired up with whichever `TyCtxt` - /// is being used to decode those values. - crate root: rmeta::CrateRoot<'static>, - /// For each definition in this crate, we encode a key. When the - /// crate is loaded, we read all the keys and put them in this - /// hashmap, which gives the reverse mapping. This allows us to - /// quickly retrace a `DefPath`, which is needed for incremental - /// compilation support. - crate def_path_table: DefPathTable, - /// Trait impl data. - /// FIXME: Used only from queries and can use query cache, - /// so pre-decoding can probably be avoided. - crate trait_impls: FxHashMap<(u32, DefIndex), rmeta::Lazy<[DefIndex]>>, - /// Proc macro descriptions for this crate, if it's a proc macro crate. - crate raw_proc_macros: Option<&'static [ProcMacro]>, - /// Source maps for code from the crate. - crate source_map_import_info: Once>, - /// Used for decoding interpret::AllocIds in a cached & thread-safe manner. - crate alloc_decoding_state: AllocDecodingState, - /// The `DepNodeIndex` of the `DepNode` representing this upstream crate. - /// It is initialized on the first access in `get_crate_dep_node_index()`. - /// Do not access the value directly, as it might not have been initialized yet. - /// The field must always be initialized to `DepNodeIndex::INVALID`. - crate dep_node_index: AtomicCell, - - // --- Other significant crate properties --- - - /// ID of this crate, from the current compilation session's point of view. - crate cnum: CrateNum, - /// Maps crate IDs as they are were seen from this crate's compilation sessions into - /// IDs as they are seen from the current compilation session. - crate cnum_map: CrateNumMap, - /// Same ID set as `cnum_map` plus maybe some injected crates like panic runtime. - crate dependencies: Lock>, - /// How to link (or not link) this crate to the currently compiled crate. - crate dep_kind: Lock, - /// Filesystem location of this crate. - crate source: CrateSource, - /// Whether or not this crate should be consider a private dependency - /// for purposes of the 'exported_private_dependencies' lint - crate private_dep: bool, - /// The hash for the host proc macro. Used to support `-Z dual-proc-macro`. - crate host_hash: Option, - - // --- Data used only for improving diagnostics --- - - /// Information about the `extern crate` item or path that caused this crate to be loaded. - /// If this is `None`, then the crate was injected (e.g., by the allocator). - crate extern_crate: Lock>, -} - #[derive(Clone)] pub struct CStore { metas: IndexVec>>, - pub(crate) injected_panic_runtime: Option, - pub(crate) allocator_kind: Option, + crate injected_panic_runtime: Option, + crate allocator_kind: Option, } pub enum LoadedMacro { diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index 582602138e54e..64230fd9e608d 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -212,9 +212,8 @@ //! no means all of the necessary details. Take a look at the rest of //! metadata::locator or metadata::creader for all the juicy details! -use crate::cstore::MetadataBlob; use crate::creader::Library; -use crate::rmeta::{METADATA_HEADER, rustc_version}; +use crate::rmeta::{METADATA_HEADER, rustc_version, MetadataBlob}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::svh::Svh; @@ -249,37 +248,47 @@ use log::{debug, info, warn}; use rustc_error_codes::*; #[derive(Clone)] -crate struct CrateMismatch { +struct CrateMismatch { path: PathBuf, got: String, } #[derive(Clone)] -crate struct Context<'a> { - pub sess: &'a Session, - pub span: Span, - pub crate_name: Symbol, +crate struct CrateLocator<'a> { + // Immutable per-session configuration. + sess: &'a Session, + metadata_loader: &'a dyn MetadataLoader, + + // Immutable per-search configuration. + crate_name: Symbol, + exact_paths: Vec, pub hash: Option<&'a Svh>, pub host_hash: Option<&'a Svh>, - pub extra_filename: Option<&'a str>, - // points to either self.sess.target.target or self.sess.host, must match triple + extra_filename: Option<&'a str>, pub target: &'a Target, pub triple: TargetTriple, pub filesearch: FileSearch<'a>, - pub root: Option<&'a CratePaths>, - pub rejected_via_hash: Vec, - pub rejected_via_triple: Vec, - pub rejected_via_kind: Vec, - pub rejected_via_version: Vec, - pub rejected_via_filename: Vec, - pub should_match_name: bool, + span: Span, + root: Option<&'a CratePaths>, pub is_proc_macro: Option, - pub metadata_loader: &'a dyn MetadataLoader, + + // Mutable in-progress state or output. + rejected_via_hash: Vec, + rejected_via_triple: Vec, + rejected_via_kind: Vec, + rejected_via_version: Vec, + rejected_via_filename: Vec, } crate struct CratePaths { - pub name: Symbol, - pub source: CrateSource, + name: Symbol, + source: CrateSource, +} + +impl CratePaths { + crate fn new(name: Symbol, source: CrateSource) -> CratePaths { + CratePaths { name, source } + } } #[derive(Copy, Clone, PartialEq)] @@ -299,7 +308,58 @@ impl fmt::Display for CrateFlavor { } } -impl<'a> Context<'a> { +impl<'a> CrateLocator<'a> { + crate fn new( + sess: &'a Session, + metadata_loader: &'a dyn MetadataLoader, + crate_name: Symbol, + hash: Option<&'a Svh>, + host_hash: Option<&'a Svh>, + extra_filename: Option<&'a str>, + is_host: bool, + path_kind: PathKind, + span: Span, + root: Option<&'a CratePaths>, + is_proc_macro: Option, + ) -> CrateLocator<'a> { + CrateLocator { + sess, + metadata_loader, + crate_name, + exact_paths: if hash.is_none() { + sess.opts.externs.get(&crate_name.as_str()).into_iter() + .flat_map(|entry| entry.locations.iter()) + .filter_map(|location| location.clone().map(PathBuf::from)).collect() + } else { + // SVH being specified means this is a transitive dependency, + // so `--extern` options do not apply. + Vec::new() + }, + hash, + host_hash, + extra_filename, + target: if is_host { &sess.host } else { &sess.target.target }, + triple: if is_host { + TargetTriple::from_triple(config::host_triple()) + } else { + sess.opts.target_triple.clone() + }, + filesearch: if is_host { + sess.host_filesearch(path_kind) + } else { + sess.target_filesearch(path_kind) + }, + span, + root, + is_proc_macro, + rejected_via_hash: Vec::new(), + rejected_via_triple: Vec::new(), + rejected_via_kind: Vec::new(), + rejected_via_version: Vec::new(), + rejected_via_filename: Vec::new(), + } + } + crate fn reset(&mut self) { self.rejected_via_hash.clear(); self.rejected_via_triple.clear(); @@ -309,6 +369,9 @@ impl<'a> Context<'a> { } crate fn maybe_load_library_crate(&mut self) -> Option { + if !self.exact_paths.is_empty() { + return self.find_commandline_library(); + } let mut seen_paths = FxHashSet::default(); match self.extra_filename { Some(s) => self.find_library_crate(s, &mut seen_paths) @@ -434,21 +497,6 @@ impl<'a> Context<'a> { extra_prefix: &str, seen_paths: &mut FxHashSet) -> Option { - // If an SVH is specified, then this is a transitive dependency that - // must be loaded via -L plus some filtering. - if self.hash.is_none() { - self.should_match_name = false; - if let Some(entry) = self.sess.opts.externs.get(&self.crate_name.as_str()) { - // Only use `--extern crate_name=path` here, not `--extern crate_name`. - if entry.locations.iter().any(|l| l.is_some()) { - return self.find_commandline_library( - entry.locations.iter().filter_map(|l| l.as_ref()), - ); - } - } - self.should_match_name = true; - } - let dypair = self.dylibname(); let staticpair = self.staticlibname(); @@ -716,15 +764,16 @@ impl<'a> Context<'a> { } let root = metadata.get_root(); - if let Some(is_proc_macro) = self.is_proc_macro { - if root.proc_macro_data.is_some() != is_proc_macro { + if let Some(expected_is_proc_macro) = self.is_proc_macro { + let is_proc_macro = root.is_proc_macro_crate(); + if is_proc_macro != expected_is_proc_macro { info!("Rejecting via proc macro: expected {} got {}", - is_proc_macro, root.proc_macro_data.is_some()); + expected_is_proc_macro, is_proc_macro); return None; } } - if self.should_match_name { + if self.exact_paths.is_empty() { if self.crate_name != root.name { info!("Rejecting via crate name"); return None; @@ -771,9 +820,7 @@ impl<'a> Context<'a> { (t.options.staticlib_prefix.clone(), t.options.staticlib_suffix.clone()) } - fn find_commandline_library<'b, LOCS>(&mut self, locs: LOCS) -> Option - where LOCS: Iterator - { + fn find_commandline_library(&mut self) -> Option { // First, filter out all libraries that look suspicious. We only accept // files which actually exist that have the correct naming scheme for // rlibs/dylibs. @@ -783,10 +830,12 @@ impl<'a> Context<'a> { let mut rmetas = FxHashMap::default(); let mut dylibs = FxHashMap::default(); { - let locs = locs.map(|l| PathBuf::from(l)).filter(|loc| { + let crate_name = self.crate_name; + let rejected_via_filename = &mut self.rejected_via_filename; + let locs = self.exact_paths.iter().filter(|loc| { if !loc.exists() { sess.err(&format!("extern location for {} does not exist: {}", - self.crate_name, + crate_name, loc.display())); return false; } @@ -794,7 +843,7 @@ impl<'a> Context<'a> { Some(file) => file, None => { sess.err(&format!("extern location for {} is not a file: {}", - self.crate_name, + crate_name, loc.display())); return false; } @@ -809,8 +858,8 @@ impl<'a> Context<'a> { } } - self.rejected_via_filename.push(CrateMismatch { - path: loc.clone(), + rejected_via_filename.push(CrateMismatch { + path: (*loc).clone(), got: String::new(), }); @@ -907,7 +956,7 @@ fn get_metadata_section_imp(target: &Target, rustc_erase_owner!(OwningRef::new(StableDerefMmap(mmap)).map_owner_box()) } }; - let blob = MetadataBlob(raw_bytes); + let blob = MetadataBlob::new(raw_bytes); if blob.is_compatible() { Ok(blob) } else { @@ -927,28 +976,21 @@ pub fn find_plugin_registrar( let host_triple = TargetTriple::from_triple(config::host_triple()); let is_cross = target_triple != host_triple; let mut target_only = false; - let mut locate_ctxt = Context { + let mut locator = CrateLocator::new( sess, - span, - crate_name: name, - hash: None, - host_hash: None, - extra_filename: None, - filesearch: sess.host_filesearch(PathKind::Crate), - target: &sess.host, - triple: host_triple, - root: None, - rejected_via_hash: vec![], - rejected_via_triple: vec![], - rejected_via_kind: vec![], - rejected_via_version: vec![], - rejected_via_filename: vec![], - should_match_name: true, - is_proc_macro: None, metadata_loader, - }; + name, + None, // hash + None, // host_hash + None, // extra_filename + true, // is_host + PathKind::Crate, + span, + None, // root + None, // is_proc_macro + ); - let library = locate_ctxt.maybe_load_library_crate().or_else(|| { + let library = locator.maybe_load_library_crate().or_else(|| { if !is_cross { return None } @@ -956,15 +998,15 @@ pub fn find_plugin_registrar( // try to load a plugin registrar function, target_only = true; - locate_ctxt.target = &sess.target.target; - locate_ctxt.triple = target_triple; - locate_ctxt.filesearch = sess.target_filesearch(PathKind::Crate); + locator.target = &sess.target.target; + locator.triple = target_triple; + locator.filesearch = sess.target_filesearch(PathKind::Crate); - locate_ctxt.maybe_load_library_crate() + locator.maybe_load_library_crate() }); let library = match library { Some(l) => l, - None => locate_ctxt.report_errs(), + None => locator.report_errs(), }; if target_only { diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs index fc0a0010240ad..7b0cf451ff918 100644 --- a/src/librustc_metadata/rmeta/decoder.rs +++ b/src/librustc_metadata/rmeta/decoder.rs @@ -1,27 +1,30 @@ // Decoding metadata from a single crate's metadata -use crate::cstore::{self, CrateMetadata, MetadataBlob}; use crate::rmeta::*; use crate::rmeta::table::{FixedSizeEncoding, PerDefTable}; use rustc_index::vec::IndexVec; -use rustc_data_structures::sync::Lrc; +use rustc_data_structures::sync::{Lrc, Lock, Once, AtomicCell}; use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash}; +use rustc::hir::map::definitions::DefPathTable; use rustc::hir; +use rustc::middle::cstore::{CrateSource, ExternCrate}; use rustc::middle::cstore::{LinkagePreference, NativeLibrary, ForeignModule}; use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel}; use rustc::hir::def::{self, Res, DefKind, CtorOf, CtorKind}; use rustc::hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; -use rustc::dep_graph::{DepNodeIndex, DepKind}; +use rustc_data_structures::svh::Svh; +use rustc::dep_graph::{self, DepNodeIndex}; use rustc::middle::lang_items; use rustc::mir::{self, interpret}; -use rustc::mir::interpret::AllocDecodingSession; +use rustc::mir::interpret::{AllocDecodingSession, AllocDecodingState}; use rustc::session::Session; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::codec::TyDecoder; use rustc::mir::{Body, Promoted}; +use rustc::util::common::record_time; use rustc::util::captures::Captures; use std::io; @@ -44,7 +47,86 @@ pub use cstore_impl::{provide, provide_extern}; mod cstore_impl; -crate struct DecodeContext<'a, 'tcx> { +crate struct MetadataBlob(MetadataRef); + +// A map from external crate numbers (as decoded from some crate file) to +// local crate numbers (as generated during this session). Each external +// crate may refer to types in other external crates, and each has their +// own crate numbers. +crate type CrateNumMap = IndexVec; + +crate struct CrateMetadata { + /// The primary crate data - binary metadata blob. + blob: MetadataBlob, + + // --- Some data pre-decoded from the metadata blob, usually for performance --- + + /// Properties of the whole crate. + /// NOTE(eddyb) we pass `'static` to a `'tcx` parameter because this + /// lifetime is only used behind `Lazy`, and therefore acts like an + /// universal (`for<'tcx>`), that is paired up with whichever `TyCtxt` + /// is being used to decode those values. + crate root: CrateRoot<'static>, + /// For each definition in this crate, we encode a key. When the + /// crate is loaded, we read all the keys and put them in this + /// hashmap, which gives the reverse mapping. This allows us to + /// quickly retrace a `DefPath`, which is needed for incremental + /// compilation support. + def_path_table: DefPathTable, + /// Trait impl data. + /// FIXME: Used only from queries and can use query cache, + /// so pre-decoding can probably be avoided. + trait_impls: FxHashMap<(u32, DefIndex), Lazy<[DefIndex]>>, + /// Proc macro descriptions for this crate, if it's a proc macro crate. + raw_proc_macros: Option<&'static [ProcMacro]>, + /// Source maps for code from the crate. + source_map_import_info: Once>, + /// Used for decoding interpret::AllocIds in a cached & thread-safe manner. + alloc_decoding_state: AllocDecodingState, + /// The `DepNodeIndex` of the `DepNode` representing this upstream crate. + /// It is initialized on the first access in `get_crate_dep_node_index()`. + /// Do not access the value directly, as it might not have been initialized yet. + /// The field must always be initialized to `DepNodeIndex::INVALID`. + dep_node_index: AtomicCell, + + // --- Other significant crate properties --- + + /// ID of this crate, from the current compilation session's point of view. + cnum: CrateNum, + /// Maps crate IDs as they are were seen from this crate's compilation sessions into + /// IDs as they are seen from the current compilation session. + cnum_map: CrateNumMap, + /// Same ID set as `cnum_map` plus maybe some injected crates like panic runtime. + crate dependencies: Lock>, + /// How to link (or not link) this crate to the currently compiled crate. + crate dep_kind: Lock, + /// Filesystem location of this crate. + crate source: CrateSource, + /// Whether or not this crate should be consider a private dependency + /// for purposes of the 'exported_private_dependencies' lint + private_dep: bool, + /// The hash for the host proc macro. Used to support `-Z dual-proc-macro`. + host_hash: Option, + + // --- Data used only for improving diagnostics --- + + /// Information about the `extern crate` item or path that caused this crate to be loaded. + /// If this is `None`, then the crate was injected (e.g., by the allocator). + crate extern_crate: Lock>, +} + +/// Holds information about a syntax_pos::SourceFile imported from another crate. +/// See `imported_source_files()` for more information. +struct ImportedSourceFile { + /// This SourceFile's byte-offset within the source_map of its original crate + original_start_pos: syntax_pos::BytePos, + /// The end of this SourceFile within the source_map of its original crate + original_end_pos: syntax_pos::BytePos, + /// The imported SourceFile's representation within the local source_map + translated_source_file: Lrc, +} + +pub(super) struct DecodeContext<'a, 'tcx> { opaque: opaque::Decoder<'a>, cdata: Option<&'a CrateMetadata>, sess: Option<&'tcx Session>, @@ -60,7 +142,7 @@ crate struct DecodeContext<'a, 'tcx> { } /// Abstract over the various ways one can create metadata decoders. -crate trait Metadata<'a, 'tcx>: Copy { +pub(super) trait Metadata<'a, 'tcx>: Copy { fn raw_bytes(self) -> &'a [u8]; fn cdata(self) -> Option<&'a CrateMetadata> { None } fn sess(self) -> Option<&'tcx Session> { None } @@ -136,7 +218,7 @@ impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a CrateMetadata, TyCtxt<'tcx>) { } impl<'a, 'tcx, T: Encodable + Decodable> Lazy { - crate fn decode>(self, metadata: M) -> T { + fn decode>(self, metadata: M) -> T { let mut dcx = metadata.decoder(self.position.get()); dcx.lazy_state = LazyState::NodeStart(self.position); T::decode(&mut dcx).unwrap() @@ -144,7 +226,7 @@ impl<'a, 'tcx, T: Encodable + Decodable> Lazy { } impl<'a: 'x, 'tcx: 'x, 'x, T: Encodable + Decodable> Lazy<[T]> { - crate fn decode>( + fn decode>( self, metadata: M, ) -> impl ExactSizeIterator + Captures<'a> + Captures<'tcx> + 'x { @@ -393,7 +475,11 @@ for DecodeContext<'a, 'tcx> { implement_ty_decoder!( DecodeContext<'a, 'tcx> ); -impl<'tcx> MetadataBlob { +impl MetadataBlob { + crate fn new(metadata_ref: MetadataRef) -> MetadataBlob { + MetadataBlob(metadata_ref) + } + crate fn is_compatible(&self) -> bool { self.raw_bytes().starts_with(METADATA_HEADER) } @@ -467,14 +553,62 @@ impl<'tcx> EntryKind<'tcx> { } } +impl CrateRoot<'_> { + crate fn is_proc_macro_crate(&self) -> bool { + self.proc_macro_data.is_some() + } + + crate fn decode_crate_deps( + &self, + metadata: &'a MetadataBlob, + ) -> impl ExactSizeIterator + Captures<'a> { + self.crate_deps.decode(metadata) + } +} + impl<'a, 'tcx> CrateMetadata { - fn is_proc_macro_crate(&self) -> bool { - self.root.proc_macro_decls_static.is_some() + crate fn new( + sess: &Session, + blob: MetadataBlob, + root: CrateRoot<'static>, + raw_proc_macros: Option<&'static [ProcMacro]>, + cnum: CrateNum, + cnum_map: CrateNumMap, + dep_kind: DepKind, + source: CrateSource, + private_dep: bool, + host_hash: Option, + ) -> CrateMetadata { + let def_path_table = record_time(&sess.perf_stats.decode_def_path_tables_time, || { + root.def_path_table.decode((&blob, sess)) + }); + let trait_impls = root.impls.decode((&blob, sess)) + .map(|trait_impls| (trait_impls.trait_id, trait_impls.impls)).collect(); + let alloc_decoding_state = + AllocDecodingState::new(root.interpret_alloc_index.decode(&blob).collect()); + let dependencies = Lock::new(cnum_map.iter().cloned().collect()); + CrateMetadata { + blob, + root, + def_path_table, + trait_impls, + raw_proc_macros, + source_map_import_info: Once::new(), + alloc_decoding_state, + dep_node_index: AtomicCell::new(DepNodeIndex::INVALID), + cnum, + cnum_map, + dependencies, + dep_kind: Lock::new(dep_kind), + source, + private_dep, + host_hash, + extern_crate: Lock::new(None), + } } fn is_proc_macro(&self, id: DefIndex) -> bool { - self.is_proc_macro_crate() && - self.root.proc_macro_data.unwrap().decode(self).find(|x| *x == id).is_some() + self.root.proc_macro_data.and_then(|data| data.decode(self).find(|x| *x == id)).is_some() } fn maybe_kind(&self, item_id: DefIndex) -> Option> { @@ -757,7 +891,7 @@ impl<'a, 'tcx> CrateMetadata { /// Iterates over the language items in the given crate. fn get_lang_items(&self, tcx: TyCtxt<'tcx>) -> &'tcx [(DefId, usize)] { - if self.is_proc_macro_crate() { + if self.root.is_proc_macro_crate() { // Proc macro crates do not export any lang-items to the target. &[] } else { @@ -773,7 +907,7 @@ impl<'a, 'tcx> CrateMetadata { &self, tcx: TyCtxt<'tcx>, ) -> &'tcx FxHashMap { - tcx.arena.alloc(if self.is_proc_macro_crate() { + tcx.arena.alloc(if self.root.is_proc_macro_crate() { // Proc macro crates do not export any diagnostic-items to the target. Default::default() } else { @@ -1081,7 +1215,7 @@ impl<'a, 'tcx> CrateMetadata { tcx: TyCtxt<'tcx>, filter: Option, ) -> &'tcx [DefId] { - if self.is_proc_macro_crate() { + if self.root.is_proc_macro_crate() { // proc-macro crates export no trait impls. return &[] } @@ -1125,7 +1259,7 @@ impl<'a, 'tcx> CrateMetadata { fn get_native_libraries(&self, sess: &Session) -> Vec { - if self.is_proc_macro_crate() { + if self.root.is_proc_macro_crate() { // Proc macro crates do not have any *target* native libraries. vec![] } else { @@ -1134,7 +1268,7 @@ impl<'a, 'tcx> CrateMetadata { } fn get_foreign_modules(&self, tcx: TyCtxt<'tcx>) -> &'tcx [ForeignModule] { - if self.is_proc_macro_crate() { + if self.root.is_proc_macro_crate() { // Proc macro crates do not have any *target* foreign modules. &[] } else { @@ -1157,7 +1291,7 @@ impl<'a, 'tcx> CrateMetadata { } fn get_missing_lang_items(&self, tcx: TyCtxt<'tcx>) -> &'tcx [lang_items::LangItem] { - if self.is_proc_macro_crate() { + if self.root.is_proc_macro_crate() { // Proc macro crates do not depend on any target weak lang-items. &[] } else { @@ -1181,7 +1315,7 @@ impl<'a, 'tcx> CrateMetadata { &self, tcx: TyCtxt<'tcx>, ) -> Vec<(ExportedSymbol<'tcx>, SymbolExportLevel)> { - if self.is_proc_macro_crate() { + if self.root.is_proc_macro_crate() { // If this crate is a custom derive crate, then we're not even going to // link those in so we skip those crates. vec![] @@ -1296,7 +1430,7 @@ impl<'a, 'tcx> CrateMetadata { fn imported_source_files( &'a self, local_source_map: &source_map::SourceMap, - ) -> &[cstore::ImportedSourceFile] { + ) -> &[ImportedSourceFile] { self.source_map_import_info.init_locking(|| { let external_source_map = self.root.source_map.decode(self); @@ -1351,7 +1485,7 @@ impl<'a, 'tcx> CrateMetadata { local_version.name, start_pos, end_pos, local_version.start_pos, local_version.end_pos); - cstore::ImportedSourceFile { + ImportedSourceFile { original_start_pos: start_pos, original_end_pos: end_pos, translated_source_file: local_version, @@ -1374,7 +1508,7 @@ impl<'a, 'tcx> CrateMetadata { // would always write the same value. let def_path_hash = self.def_path_hash(CRATE_DEF_INDEX); - let dep_node = def_path_hash.to_dep_node(DepKind::CrateMetadata); + let dep_node = def_path_hash.to_dep_node(dep_graph::DepKind::CrateMetadata); dep_node_index = tcx.dep_graph.dep_node_index_of(&dep_node); assert!(dep_node_index != DepNodeIndex::INVALID); diff --git a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs index a6cb3864ca7d4..abb0ceb4ff427 100644 --- a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs +++ b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs @@ -52,7 +52,7 @@ macro_rules! provide { assert!(!$def_id.is_local()); let $cdata = $tcx.crate_data_as_any($def_id.krate); - let $cdata = $cdata.downcast_ref::() + let $cdata = $cdata.downcast_ref::() .expect("CrateStore created data is not a CrateMetadata"); if $tcx.dep_graph.is_fully_enabled() { @@ -410,7 +410,7 @@ impl cstore::CStore { let _prof_timer = sess.prof.generic_activity("metadata_load_macro"); let data = self.get_crate_data(id.krate); - if data.is_proc_macro_crate() { + if data.root.is_proc_macro_crate() { return LoadedMacro::ProcMacro(data.load_proc_macro(id.index, sess)); } diff --git a/src/librustc_metadata/rmeta/mod.rs b/src/librustc_metadata/rmeta/mod.rs index 850ee5afbc808..23c0204ee256b 100644 --- a/src/librustc_metadata/rmeta/mod.rs +++ b/src/librustc_metadata/rmeta/mod.rs @@ -14,6 +14,7 @@ use rustc::ty::{self, Ty, ReprOptions}; use rustc_target::spec::{PanicStrategy, TargetTriple}; use rustc_index::vec::IndexVec; use rustc_data_structures::svh::Svh; +use rustc_data_structures::sync::MetadataRef; use rustc_serialize::Encodable; use syntax::{ast, attr}; use syntax::edition::Edition; @@ -24,6 +25,7 @@ use std::marker::PhantomData; use std::num::NonZeroUsize; pub use decoder::{provide, provide_extern}; +crate use decoder::{CrateMetadata, CrateNumMap, MetadataBlob}; mod decoder; mod encoder; @@ -49,7 +51,7 @@ crate const METADATA_HEADER: &[u8; 8] = /// Additional metadata for a `Lazy` where `T` may not be `Sized`, /// e.g. for `Lazy<[T]>`, this is the length (count of `T` values). -crate trait LazyMeta { +trait LazyMeta { type Meta: Copy + 'static; /// Returns the minimum encoded size. @@ -103,7 +105,7 @@ impl LazyMeta for [T] { #[must_use] // FIXME(#59875) the `Meta` parameter only exists to dodge // invariance wrt `T` (coming from the `meta: T::Meta` field). -crate struct Lazy::Meta> +struct Lazy::Meta> where T: ?Sized + LazyMeta, Meta: 'static + Copy, { @@ -186,7 +188,7 @@ crate struct CrateRoot<'tcx> { proc_macro_decls_static: Option, proc_macro_stability: Option, - pub crate_deps: Lazy<[CrateDep]>, + crate_deps: Lazy<[CrateDep]>, dylib_dependency_formats: Lazy<[Option]>, lib_features: Lazy<[(Symbol, Option)]>, lang_items: Lazy<[(DefIndex, usize)]>, @@ -195,16 +197,15 @@ crate struct CrateRoot<'tcx> { native_libraries: Lazy<[NativeLibrary]>, foreign_modules: Lazy<[ForeignModule]>, source_map: Lazy<[syntax_pos::SourceFile]>, - pub def_path_table: Lazy, - pub impls: Lazy<[TraitImpls]>, + def_path_table: Lazy, + impls: Lazy<[TraitImpls]>, exported_symbols: Lazy!([(ExportedSymbol<'tcx>, SymbolExportLevel)]), - pub interpret_alloc_index: Lazy<[u32]>, + interpret_alloc_index: Lazy<[u32]>, per_def: LazyPerDefTables<'tcx>, - /// The DefIndex's of any proc macros delcared by - /// this crate - pub proc_macro_data: Option>, + /// The DefIndex's of any proc macros delcared by this crate. + proc_macro_data: Option>, compiler_builtins: bool, pub needs_allocator: bool, @@ -227,8 +228,8 @@ crate struct CrateDep { #[derive(RustcEncodable, RustcDecodable)] crate struct TraitImpls { - pub trait_id: (u32, DefIndex), - pub impls: Lazy<[DefIndex]>, + trait_id: (u32, DefIndex), + impls: Lazy<[DefIndex]>, } #[derive(RustcEncodable, RustcDecodable)] diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml index daa2617bd9e5e..9bc6d32b7cb38 100644 --- a/src/librustc_mir/Cargo.toml +++ b/src/librustc_mir/Cargo.toml @@ -22,6 +22,7 @@ rustc_data_structures = { path = "../librustc_data_structures" } rustc_index = { path = "../librustc_index" } rustc_errors = { path = "../librustc_errors" } rustc_lexer = { path = "../librustc_lexer" } +rustc_macros = { path = "../librustc_macros" } rustc_serialize = { path = "../libserialize", package = "serialize" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 92358ad247e18..08640476f7ab7 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -18,6 +18,7 @@ use rustc::mir::interpret::{ InterpResult, truncate, sign_extend, }; use rustc_data_structures::fx::FxHashMap; +use rustc_macros::HashStable; use super::{ Immediate, Operand, MemPlace, MPlaceTy, Place, PlaceTy, ScalarMaybeUndef, @@ -93,7 +94,7 @@ pub struct Frame<'mir, 'tcx, Tag=(), Extra=()> { pub stmt: usize, } -#[derive(Clone, Eq, PartialEq, Debug)] // Miri debug-prints these +#[derive(Clone, Eq, PartialEq, Debug, HashStable)] // Miri debug-prints these pub enum StackPopCleanup { /// Jump to the next block in the caller, or cause UB if None (that's a function /// that may never return). Also store layout of return place so @@ -109,15 +110,16 @@ pub enum StackPopCleanup { } /// State of a local variable including a memoized layout -#[derive(Clone, PartialEq, Eq)] +#[derive(Clone, PartialEq, Eq, HashStable)] pub struct LocalState<'tcx, Tag=(), Id=AllocId> { pub value: LocalValue, /// Don't modify if `Some`, this is only used to prevent computing the layout twice + #[stable_hasher(ignore)] pub layout: Cell>>, } /// Current value of a local variable -#[derive(Clone, PartialEq, Eq, Debug)] // Miri debug-prints these +#[derive(Clone, PartialEq, Eq, Debug, HashStable)] // Miri debug-prints these pub enum LocalValue { /// This local is not currently alive, and cannot be used at all. Dead, diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 4d2ccdc20da65..cfa70164cdce4 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -18,6 +18,7 @@ use super::{ MemPlace, MPlaceTy, PlaceTy, Place, }; pub use rustc::mir::interpret::ScalarMaybeUndef; +use rustc_macros::HashStable; /// An `Immediate` represents a single immediate self-contained Rust value. /// @@ -26,7 +27,7 @@ pub use rustc::mir::interpret::ScalarMaybeUndef; /// operations and fat pointers. This idea was taken from rustc's codegen. /// In particular, thanks to `ScalarPair`, arithmetic operations and casts can be entirely /// defined on `Immediate`, and do not have to work with a `Place`. -#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, HashStable)] pub enum Immediate { Scalar(ScalarMaybeUndef), ScalarPair(ScalarMaybeUndef, ScalarMaybeUndef), @@ -103,7 +104,7 @@ impl<'tcx, Tag> ::std::ops::Deref for ImmTy<'tcx, Tag> { /// An `Operand` is the result of computing a `mir::Operand`. It can be immediate, /// or still in memory. The latter is an optimization, to delay reading that chunk of /// memory and to avoid having to store arbitrary-sized data here. -#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, HashStable)] pub enum Operand { Immediate(Immediate), Indirect(MemPlace), diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 0bd47edc04660..088fbe1695efd 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -12,6 +12,7 @@ use rustc::ty::layout::{ self, Size, Align, LayoutOf, TyLayout, HasDataLayout, VariantIdx, PrimitiveExt }; use rustc::ty::TypeFoldable; +use rustc_macros::HashStable; use super::{ GlobalId, AllocId, Allocation, Scalar, InterpResult, Pointer, PointerArithmetic, @@ -19,7 +20,7 @@ use super::{ RawConst, Immediate, ImmTy, ScalarMaybeUndef, Operand, OpTy, MemoryKind, LocalValue, }; -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable)] pub struct MemPlace { /// A place may have an integral pointer for ZSTs, and since it might /// be turned back into a reference before ever being dereferenced. @@ -32,7 +33,7 @@ pub struct MemPlace { pub meta: Option>, } -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable)] pub enum Place { /// A place referring to a value allocated in the `Memory` system. Ptr(MemPlace), diff --git a/src/librustc_mir/interpret/snapshot.rs b/src/librustc_mir/interpret/snapshot.rs index 7f3ea0283cda3..b460badd1fdac 100644 --- a/src/librustc_mir/interpret/snapshot.rs +++ b/src/librustc_mir/interpret/snapshot.rs @@ -19,6 +19,7 @@ use rustc::ty::layout::{Align, Size}; use rustc_data_structures::fx::FxHashSet; use rustc_index::vec::IndexVec; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_macros::HashStable; use syntax::ast::Mutability; use syntax::source_map::Span; @@ -197,21 +198,12 @@ impl_snapshot_for!(enum ScalarMaybeUndef { Undef, }); -impl_stable_hash_for!(struct crate::interpret::MemPlace { - ptr, - align, - meta, -}); impl_snapshot_for!(struct MemPlace { ptr, meta, align -> *align, // just copy alignment verbatim }); -impl_stable_hash_for!(enum crate::interpret::Place { - Ptr(mem_place), - Local { frame, local }, -}); impl<'a, Ctx> Snapshot<'a, Ctx> for Place where Ctx: SnapshotContext<'a>, { @@ -229,29 +221,16 @@ impl<'a, Ctx> Snapshot<'a, Ctx> for Place } } -impl_stable_hash_for!(enum crate::interpret::Immediate { - Scalar(x), - ScalarPair(x, y), -}); impl_snapshot_for!(enum Immediate { Scalar(s), ScalarPair(s, t), }); -impl_stable_hash_for!(enum crate::interpret::Operand { - Immediate(x), - Indirect(x), -}); impl_snapshot_for!(enum Operand { Immediate(v), Indirect(m), }); -impl_stable_hash_for!(enum crate::interpret::LocalValue { - Dead, - Uninitialized, - Live(x), -}); impl_snapshot_for!(enum LocalValue { Dead, Uninitialized, @@ -314,11 +293,6 @@ impl<'a, Ctx> Snapshot<'a, Ctx> for &'a Allocation } } -impl_stable_hash_for!(enum crate::interpret::eval_context::StackPopCleanup { - Goto { ret, unwind }, - None { cleanup }, -}); - #[derive(Eq, PartialEq)] struct FrameSnapshot<'a, 'tcx> { instance: ty::Instance<'tcx>, @@ -383,11 +357,6 @@ impl<'a, 'tcx, Ctx> Snapshot<'a, Ctx> for &'a LocalState<'tcx> } } -impl_stable_hash_for!(struct LocalState<'tcx> { - value, - layout -> _, -}); - impl<'b, 'mir, 'tcx> SnapshotContext<'b> for Memory<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>> { @@ -399,7 +368,10 @@ impl<'b, 'mir, 'tcx> SnapshotContext<'b> /// The virtual machine state during const-evaluation at a given point in time. /// We assume the `CompileTimeInterpreter` has no interesting extra state that /// is worth considering here. +#[derive(HashStable)] struct InterpSnapshot<'mir, 'tcx> { + // Not hashing memory: Avoid hashing memory all the time during execution + #[stable_hasher(ignore)] memory: Memory<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>, stack: Vec>, } @@ -434,12 +406,6 @@ impl<'mir, 'tcx> Hash for InterpSnapshot<'mir, 'tcx> { } } -impl_stable_hash_for!(impl<> for struct InterpSnapshot<'mir, 'tcx> { - // Not hashing memory: Avoid hashing memory all the time during execution - memory -> _, - stack, -}); - impl<'mir, 'tcx> Eq for InterpSnapshot<'mir, 'tcx> {} impl<'mir, 'tcx> PartialEq for InterpSnapshot<'mir, 'tcx> { diff --git a/src/librustc_passes/liveness.rs b/src/librustc_passes/liveness.rs index fb06808619f66..6847e45458a0b 100644 --- a/src/librustc_passes/liveness.rs +++ b/src/librustc_passes/liveness.rs @@ -987,8 +987,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { opt_expr.map_or(succ, |expr| self.propagate_through_expr(expr, succ)) } - fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode) - -> LiveNode { + fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode) -> LiveNode { debug!("propagate_through_expr: {}", self.ir.tcx.hir().hir_to_pretty_string(expr.hir_id)); match expr.kind { @@ -1074,7 +1073,15 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { match target { Some(b) => self.propagate_through_opt_expr(opt_expr.as_ref().map(|e| &**e), b), - None => span_bug!(expr.span, "break to unknown label") + None => { + // FIXME: This should have been checked earlier. Once this is fixed, + // replace with `delay_span_bug`. (#62480) + self.ir.tcx.sess.struct_span_err( + expr.span, + "`break` to unknown label", + ).emit(); + errors::FatalError.raise() + } } } diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index 8249e69e9a74f..a6f37053687c9 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -87,10 +87,11 @@ pub fn render( \ \