1
Fork 0

Auto merge of #66578 - Centril:rollup-pgz1v7t, r=Centril

Rollup of 7 pull requests

Successful merges:

 - #66060 (Making ICEs and test them in incremental)
 - #66298 (rustdoc: fixes #64305: disable search field instead of hidding it)
 - #66457 (Just derive Hashstable in librustc)
 - #66496 (rustc_metadata: Privatize more things)
 - #66514 (Fix selected crate search filter)
 - #66535 (Avoid ICE when `break`ing to an unreachable label)
 - #66573 (Ignore run-make reproducible-build-2 on Mac)

Failed merges:

r? @ghost
This commit is contained in:
bors 2019-11-20 19:15:41 +00:00
commit f1b882b558
82 changed files with 590 additions and 674 deletions

View file

@ -3719,6 +3719,7 @@ dependencies = [
"rustc_errors", "rustc_errors",
"rustc_index", "rustc_index",
"rustc_lexer", "rustc_lexer",
"rustc_macros",
"rustc_target", "rustc_target",
"serialize", "serialize",
"smallvec 1.0.0", "smallvec 1.0.0",

View file

@ -578,7 +578,7 @@ impl<'tcx> DepNodeParams<'tcx> for HirId {
/// the need to be mapped or unmapped. (This ensures we can serialize /// the need to be mapped or unmapped. (This ensures we can serialize
/// them even in the absence of a tcx.) /// them even in the absence of a tcx.)
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash,
RustcEncodable, RustcDecodable)] RustcEncodable, RustcDecodable, HashStable)]
pub struct WorkProductId { pub struct WorkProductId {
hash: Fingerprint hash: Fingerprint
} }
@ -599,7 +599,3 @@ impl WorkProductId {
} }
} }
} }
impl_stable_hash_for!(struct crate::dep_graph::WorkProductId {
hash
});

View file

@ -313,11 +313,9 @@ pub enum DefPathData {
} }
#[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug, #[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug,
RustcEncodable, RustcDecodable)] RustcEncodable, RustcDecodable, HashStable)]
pub struct DefPathHash(pub Fingerprint); pub struct DefPathHash(pub Fingerprint);
impl_stable_hash_for!(tuple_struct DefPathHash { fingerprint });
impl Borrow<Fingerprint> for DefPathHash { impl Borrow<Fingerprint> for DefPathHash {
#[inline] #[inline]
fn borrow(&self) -> &Fingerprint { fn borrow(&self) -> &Fingerprint {

View file

@ -1215,7 +1215,7 @@ impl UnOp {
} }
/// A statement. /// A statement.
#[derive(RustcEncodable, RustcDecodable)] #[derive(RustcEncodable, RustcDecodable, HashStable)]
pub struct Stmt { pub struct Stmt {
pub hir_id: HirId, pub hir_id: HirId,
pub kind: StmtKind, pub kind: StmtKind,

View file

@ -140,13 +140,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::Ty {
impl_stable_hash_for_spanned!(hir::BinOpKind); 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_stable_hash_for_spanned!(ast::Name);
impl<'a> HashStable<StableHashingContext<'a>> for hir::Expr { impl<'a> HashStable<StableHashingContext<'a>> for hir::Expr {

View file

@ -1,7 +1,7 @@
use crate::ty::{self, Lift, TyCtxt, Region}; use crate::ty::{self, Lift, TyCtxt, Region};
use rustc_data_structures::transitive_relation::TransitiveRelation; use rustc_data_structures::transitive_relation::TransitiveRelation;
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Default)] #[derive(Clone, RustcEncodable, RustcDecodable, Debug, Default, HashStable)]
pub struct FreeRegionMap<'tcx> { pub struct FreeRegionMap<'tcx> {
// Stores the relation `a < b`, where `a` and `b` are regions. // 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> { impl<'a, 'tcx> Lift<'tcx> for FreeRegionMap<'a> {
type Lifted = FreeRegionMap<'tcx>; type Lifted = FreeRegionMap<'tcx>;
fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<FreeRegionMap<'tcx>> { fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<FreeRegionMap<'tcx>> {

View file

@ -543,18 +543,11 @@ impl LintId {
} }
/// Setting for how to handle a lint. /// 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 { pub enum Level {
Allow, Warn, Deny, Forbid, Allow, Warn, Deny, Forbid,
} }
impl_stable_hash_for!(enum self::Level {
Allow,
Warn,
Deny,
Forbid
});
impl Level { impl Level {
/// Converts a level to a lower-case string. /// Converts a level to a lower-case string.
pub fn as_str(self) -> &'static str { pub fn as_str(self) -> &'static str {
@ -590,7 +583,7 @@ impl Level {
} }
/// How a lint level was set. /// How a lint level was set.
#[derive(Clone, Copy, PartialEq, Eq)] #[derive(Clone, Copy, PartialEq, Eq, HashStable)]
pub enum LintSource { pub enum LintSource {
/// Lint is at the default level as declared /// Lint is at the default level as declared
/// in rustc or a plugin. /// in rustc or a plugin.
@ -603,12 +596,6 @@ pub enum LintSource {
CommandLine(Symbol), CommandLine(Symbol),
} }
impl_stable_hash_for!(enum self::LintSource {
Default,
Node(name, span, reason),
CommandLine(text)
});
pub type LevelSource = (Level, LintSource); pub type LevelSource = (Level, LintSource);
pub mod builtin; pub mod builtin;

View file

@ -11,17 +11,12 @@ use crate::ty::subst::SubstsRef;
/// kind of crate, including cdylibs which export very few things. /// kind of crate, including cdylibs which export very few things.
/// `Rust` will only be exported if the crate produced is a Rust /// `Rust` will only be exported if the crate produced is a Rust
/// dylib. /// dylib.
#[derive(Eq, PartialEq, Debug, Copy, Clone, RustcEncodable, RustcDecodable)] #[derive(Eq, PartialEq, Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable)]
pub enum SymbolExportLevel { pub enum SymbolExportLevel {
C, C,
Rust, Rust,
} }
impl_stable_hash_for!(enum self::SymbolExportLevel {
C,
Rust
});
impl SymbolExportLevel { impl SymbolExportLevel {
pub fn is_below_threshold(self, threshold: SymbolExportLevel) -> bool { pub fn is_below_threshold(self, threshold: SymbolExportLevel) -> bool {
threshold == SymbolExportLevel::Rust // export everything from Rust dylibs threshold == SymbolExportLevel::Rust // export everything from Rust dylibs

View file

@ -207,7 +207,7 @@ struct NamedRegionMap {
} }
/// See [`NamedRegionMap`]. /// See [`NamedRegionMap`].
#[derive(Default)] #[derive(Default, HashStable)]
pub struct ResolveLifetimes { pub struct ResolveLifetimes {
defs: FxHashMap<LocalDefId, FxHashMap<ItemLocalId, Region>>, defs: FxHashMap<LocalDefId, FxHashMap<ItemLocalId, Region>>,
late_bound: FxHashMap<LocalDefId, FxHashSet<ItemLocalId>>, late_bound: FxHashMap<LocalDefId, FxHashSet<ItemLocalId>>,
@ -215,12 +215,6 @@ pub struct ResolveLifetimes {
FxHashMap<LocalDefId, FxHashMap<ItemLocalId, Vec<ObjectLifetimeDefault>>>, FxHashMap<LocalDefId, FxHashMap<ItemLocalId, Vec<ObjectLifetimeDefault>>>,
} }
impl_stable_hash_for!(struct crate::middle::resolve_lifetime::ResolveLifetimes {
defs,
late_bound,
object_lifetime_defaults
});
struct LifetimeContext<'a, 'tcx> { struct LifetimeContext<'a, 'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
map: &'a mut NamedRegionMap, map: &'a mut NamedRegionMap,

View file

@ -52,7 +52,7 @@ enum AnnotationKind {
} }
/// An entry in the `depr_map`. /// An entry in the `depr_map`.
#[derive(Clone)] #[derive(Clone, HashStable)]
pub struct DeprecationEntry { pub struct DeprecationEntry {
/// The metadata of the attribute associated with this entry. /// The metadata of the attribute associated with this entry.
pub attr: Deprecation, pub attr: Deprecation,
@ -61,11 +61,6 @@ pub struct DeprecationEntry {
origin: Option<HirId>, origin: Option<HirId>,
} }
impl_stable_hash_for!(struct self::DeprecationEntry {
attr,
origin
});
impl DeprecationEntry { impl DeprecationEntry {
fn local(attr: Deprecation, id: HirId) -> DeprecationEntry { fn local(attr: Deprecation, id: HirId) -> DeprecationEntry {
DeprecationEntry { DeprecationEntry {
@ -90,6 +85,7 @@ impl DeprecationEntry {
} }
/// A stability index, giving the stability level for items and methods. /// A stability index, giving the stability level for items and methods.
#[derive(HashStable)]
pub struct Index<'tcx> { pub struct Index<'tcx> {
/// This is mostly a cache, except the stabilities of local items /// This is mostly a cache, except the stabilities of local items
/// are filled by the annotator. /// are filled by the annotator.
@ -103,13 +99,6 @@ pub struct Index<'tcx> {
active_features: FxHashSet<Symbol>, active_features: FxHashSet<Symbol>,
} }
impl_stable_hash_for!(struct self::Index<'tcx> {
stab_map,
depr_map,
staged_api,
active_features
});
// A private tree-walker for producing an Index. // A private tree-walker for producing an Index.
struct Annotator<'a, 'tcx> { struct Annotator<'a, 'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,

View file

@ -4,7 +4,6 @@ use super::{
Pointer, InterpResult, AllocId, ScalarMaybeUndef, write_target_uint, read_target_uint, Scalar, Pointer, InterpResult, AllocId, ScalarMaybeUndef, write_target_uint, read_target_uint, Scalar,
}; };
use crate::mir;
use crate::ty::layout::{Size, Align}; use crate::ty::layout::{Size, Align};
use rustc_data_structures::sorted_map::SortedMap; 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 /// 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. /// 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 { pub struct UndefMask {
blocks: Vec<Block>, blocks: Vec<Block>,
len: Size, len: Size,
} }
impl_stable_hash_for!(struct mir::interpret::UndefMask{blocks, len});
impl UndefMask { impl UndefMask {
pub const BLOCK_SIZE: u64 = 64; pub const BLOCK_SIZE: u64 = 64;

View file

@ -458,7 +458,7 @@ impl<Tag> From<Pointer<Tag>> for Scalar<Tag> {
} }
} }
#[derive(Clone, Copy, Eq, PartialEq, RustcEncodable, RustcDecodable)] #[derive(Clone, Copy, Eq, PartialEq, RustcEncodable, RustcDecodable, HashStable)]
pub enum ScalarMaybeUndef<Tag = (), Id = AllocId> { pub enum ScalarMaybeUndef<Tag = (), Id = AllocId> {
Scalar(Scalar<Tag, Id>), Scalar(Scalar<Tag, Id>),
Undef, Undef,
@ -583,11 +583,6 @@ impl<'tcx, Tag> ScalarMaybeUndef<Tag> {
} }
} }
impl_stable_hash_for!(enum crate::mir::interpret::ScalarMaybeUndef {
Scalar(v),
Undef
});
/// Gets the bytes of a constant slice value. /// Gets the bytes of a constant slice value.
pub fn get_slice_bytes<'tcx>(cx: &impl HasDataLayout, val: ConstValue<'tcx>) -> &'tcx [u8] { pub fn get_slice_bytes<'tcx>(cx: &impl HasDataLayout, val: ConstValue<'tcx>) -> &'tcx [u8] {
if let ConstValue::Slice { data, start, end } = val { if let ConstValue::Slice { data, start, end } = val {

View file

@ -70,7 +70,8 @@ impl<'tcx> HasLocalDecls<'tcx> for Body<'tcx> {
/// The various "big phases" that MIR goes through. /// The various "big phases" that MIR goes through.
/// ///
/// Warning: ordering of variants is significant. /// 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 { pub enum MirPhase {
Build = 0, Build = 0,
Const = 1, Const = 1,
@ -86,7 +87,7 @@ impl MirPhase {
} }
/// The lowered representation of a single function. /// The lowered representation of a single function.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, TypeFoldable)] #[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable, TypeFoldable)]
pub struct Body<'tcx> { pub struct Body<'tcx> {
/// A list of basic blocks. References to basic block use a newtyped index type `BasicBlock` /// A list of basic blocks. References to basic block use a newtyped index type `BasicBlock`
/// that indexes into this vector. /// that indexes into this vector.
@ -412,24 +413,6 @@ pub enum Safety {
ExplicitUnsafe(hir::HirId), 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<BasicBlock> for Body<'tcx> { impl<'tcx> Index<BasicBlock> for Body<'tcx> {
type Output = BasicBlockData<'tcx>; type Output = BasicBlockData<'tcx>;
@ -609,7 +592,7 @@ pub enum LocalKind {
ReturnPointer, ReturnPointer,
} }
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)] #[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
pub struct VarBindingForm<'tcx> { pub struct VarBindingForm<'tcx> {
/// Is variable bound via `x`, `mut x`, `ref x`, or `ref mut x`? /// Is variable bound via `x`, `mut x`, `ref x`, or `ref mut x`?
pub binding_mode: ty::BindingMode, pub binding_mode: ty::BindingMode,
@ -642,7 +625,7 @@ pub enum BindingForm<'tcx> {
} }
/// Represents what type of implicit self a function has, if any. /// 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 { pub enum ImplicitSelfKind {
/// Represents a `fn x(self);`. /// Represents a `fn x(self);`.
Imm, Imm,
@ -659,28 +642,6 @@ pub enum ImplicitSelfKind {
CloneTypeFoldableAndLiftImpls! { BindingForm<'tcx>, } 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 { mod binding_form_impl {
use crate::ich::StableHashingContext; use crate::ich::StableHashingContext;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; 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 /// involved in borrow_check errors, e.g., explanations of where the
/// temporaries come from, when their destructors are run, and/or how /// temporaries come from, when their destructors are run, and/or how
/// one might revise the code to satisfy the borrow checker's rules. /// 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 { pub struct BlockTailInfo {
/// If `true`, then the value resulting from evaluating this tail /// If `true`, then the value resulting from evaluating this tail
/// expression is ignored by the block's expression context. /// expression is ignored by the block's expression context.
@ -717,8 +678,6 @@ pub struct BlockTailInfo {
pub tail_result_is_ignored: bool, pub tail_result_is_ignored: bool,
} }
impl_stable_hash_for!(struct BlockTailInfo { tail_result_is_ignored });
/// A MIR local. /// A MIR local.
/// ///
/// This can be a binding declared by the user, a temporary inserted by the compiler, a function /// 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 /// 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 struct Static<'tcx> {
pub ty: Ty<'tcx>, pub ty: Ty<'tcx>,
pub kind: StaticKind<'tcx>, pub kind: StaticKind<'tcx>,
@ -1768,12 +1728,6 @@ pub enum StaticKind<'tcx> {
Static, Static,
} }
impl_stable_hash_for!(struct Static<'tcx> {
ty,
kind,
def_id
});
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[derive(RustcEncodable, RustcDecodable, HashStable)] #[derive(RustcEncodable, RustcDecodable, HashStable)]
pub enum ProjectionElem<V, T> { pub enum ProjectionElem<V, T> {

View file

@ -251,7 +251,7 @@ pub struct CodegenUnit<'tcx> {
size_estimate: Option<usize>, size_estimate: Option<usize>,
} }
#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable)] #[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable, HashStable)]
pub enum Linkage { pub enum Linkage {
External, External,
AvailableExternally, AvailableExternally,
@ -266,33 +266,13 @@ pub enum Linkage {
Common, Common,
} }
impl_stable_hash_for!(enum self::Linkage { #[derive(Copy, Clone, PartialEq, Debug, HashStable)]
External,
AvailableExternally,
LinkOnceAny,
LinkOnceODR,
WeakAny,
WeakODR,
Appending,
Internal,
Private,
ExternalWeak,
Common
});
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum Visibility { pub enum Visibility {
Default, Default,
Hidden, Hidden,
Protected, Protected,
} }
impl_stable_hash_for!(enum self::Visibility {
Default,
Hidden,
Protected
});
impl<'tcx> CodegenUnit<'tcx> { impl<'tcx> CodegenUnit<'tcx> {
pub fn new(name: Symbol) -> CodegenUnit<'tcx> { pub fn new(name: Symbol) -> CodegenUnit<'tcx> {
CodegenUnit { CodegenUnit {

View file

@ -29,6 +29,12 @@ use syntax_pos::symbol::Symbol;
// Queries marked with `fatal_cycle` do not need the latter implementation, // Queries marked with `fatal_cycle` do not need the latter implementation,
// as they will raise an fatal error on query cycles instead. // as they will raise an fatal error on query cycles instead.
rustc_queries! { rustc_queries! {
Other {
query trigger_delay_span_bug(key: DefId) -> () {
desc { "trigger a delay span bug" }
}
}
Other { Other {
/// Records the type of every item. /// Records the type of every item.
query type_of(key: DefId) -> Ty<'tcx> { query type_of(key: DefId) -> Ty<'tcx> {

View file

@ -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 struct DropckOutlivesResult<'tcx> {
pub kinds: Vec<GenericArg<'tcx>>, pub kinds: Vec<GenericArg<'tcx>>,
pub overflows: Vec<Ty<'tcx>>, pub overflows: Vec<Ty<'tcx>>,
@ -114,7 +114,7 @@ impl<'tcx> DropckOutlivesResult<'tcx> {
/// A set of constraints that need to be satisfied in order for /// A set of constraints that need to be satisfied in order for
/// a type to be valid for destruction. /// a type to be valid for destruction.
#[derive(Clone, Debug)] #[derive(Clone, Debug, HashStable)]
pub struct DtorckConstraint<'tcx> { pub struct DtorckConstraint<'tcx> {
/// Types that are required to be alive in order for this /// Types that are required to be alive in order for this
/// type to be valid for destruction. /// type to be valid for destruction.
@ -152,15 +152,6 @@ impl<'tcx> FromIterator<DtorckConstraint<'tcx>> for DtorckConstraint<'tcx> {
result 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 /// This returns true if the type `ty` is "trivial" for
/// dropck-outlives -- that is, if it doesn't require any types to /// dropck-outlives -- that is, if it doesn't require any types to

View file

@ -2,7 +2,7 @@ use rustc_data_structures::sync::Lrc;
use crate::infer::canonical::{Canonical, QueryResponse}; use crate::infer::canonical::{Canonical, QueryResponse};
use crate::ty::Ty; use crate::ty::Ty;
#[derive(Debug)] #[derive(Debug, HashStable)]
pub struct CandidateStep<'tcx> { pub struct CandidateStep<'tcx> {
pub self_ty: Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>, pub self_ty: Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
pub autoderefs: usize, pub autoderefs: usize,
@ -15,7 +15,7 @@ pub struct CandidateStep<'tcx> {
pub unsize: bool, pub unsize: bool,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug, HashStable)]
pub struct MethodAutoderefStepsResult<'tcx> { pub struct MethodAutoderefStepsResult<'tcx> {
/// The valid autoderef steps that could be find. /// The valid autoderef steps that could be find.
pub steps: Lrc<Vec<CandidateStep<'tcx>>>, pub steps: Lrc<Vec<CandidateStep<'tcx>>>,
@ -26,20 +26,8 @@ pub struct MethodAutoderefStepsResult<'tcx> {
pub reached_recursion_limit: bool, pub reached_recursion_limit: bool,
} }
#[derive(Debug)] #[derive(Debug, HashStable)]
pub struct MethodAutoderefBadTy<'tcx> { pub struct MethodAutoderefBadTy<'tcx> {
pub reached_raw_pointer: bool, pub reached_raw_pointer: bool,
pub ty: Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>, 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
});

View file

@ -40,7 +40,7 @@ pub type CanonicalTypeOpProvePredicateGoal<'tcx> =
pub type CanonicalTypeOpNormalizeGoal<'tcx, T> = pub type CanonicalTypeOpNormalizeGoal<'tcx, T> =
Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::normalize::Normalize<T>>>; Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::normalize::Normalize<T>>>;
#[derive(Clone, Debug)] #[derive(Clone, Debug, HashStable)]
pub struct NoSolution; pub struct NoSolution;
pub type Fallible<T> = Result<T, NoSolution>; pub type Fallible<T> = Result<T, NoSolution>;
@ -50,5 +50,3 @@ impl<'tcx> From<TypeError<'tcx>> for NoSolution {
NoSolution NoSolution
} }
} }
impl_stable_hash_for!(struct NoSolution { });

View file

@ -66,7 +66,7 @@ impl<'cx, 'tcx> At<'cx, 'tcx> {
} }
/// Result from the `normalize_projection_ty` query. /// Result from the `normalize_projection_ty` query.
#[derive(Clone, Debug, TypeFoldable, Lift)] #[derive(Clone, Debug, HashStable, TypeFoldable, Lift)]
pub struct NormalizationResult<'tcx> { pub struct NormalizationResult<'tcx> {
/// Result of normalization. /// Result of normalization.
pub normalized_ty: Ty<'tcx>, 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) constant.eval(self.infcx.tcx, self.param_env)
} }
} }
impl_stable_hash_for!(struct NormalizationResult<'tcx> {
normalized_ty
});

View file

@ -4,7 +4,7 @@ use crate::hir::def_id::DefId;
use crate::ty::{ParamEnvAnd, Ty, TyCtxt}; use crate::ty::{ParamEnvAnd, Ty, TyCtxt};
use crate::ty::subst::UserSubsts; 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 struct AscribeUserType<'tcx> {
pub mir_ty: Ty<'tcx>, pub mir_ty: Ty<'tcx>,
pub def_id: DefId, pub def_id: DefId,
@ -38,9 +38,3 @@ impl<'tcx> super::QueryTypeOp<'tcx> for AscribeUserType<'tcx> {
tcx.type_op_ascribe_user_type(canonicalized) tcx.type_op_ascribe_user_type(canonicalized)
} }
} }
impl_stable_hash_for! {
struct AscribeUserType<'tcx> {
mir_ty, def_id, user_substs
}
}

View file

@ -2,7 +2,7 @@ use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse};
use crate::traits::query::Fallible; use crate::traits::query::Fallible;
use crate::ty::{ParamEnvAnd, Ty, TyCtxt}; 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 struct Eq<'tcx> {
pub a: Ty<'tcx>, pub a: Ty<'tcx>,
pub b: Ty<'tcx>, pub b: Ty<'tcx>,
@ -35,7 +35,3 @@ impl<'tcx> super::QueryTypeOp<'tcx> for Eq<'tcx> {
tcx.type_op_eq(canonicalized) tcx.type_op_eq(canonicalized)
} }
} }
impl_stable_hash_for! {
struct Eq<'tcx> { a, b }
}

View file

@ -3,7 +3,7 @@ use crate::traits::query::outlives_bounds::OutlivesBound;
use crate::traits::query::Fallible; use crate::traits::query::Fallible;
use crate::ty::{ParamEnvAnd, Ty, TyCtxt}; use crate::ty::{ParamEnvAnd, Ty, TyCtxt};
#[derive(Clone, Debug, TypeFoldable, Lift)] #[derive(Clone, Debug, HashStable, TypeFoldable, Lift)]
pub struct ImpliedOutlivesBounds<'tcx> { pub struct ImpliedOutlivesBounds<'tcx> {
pub ty: Ty<'tcx>, pub ty: Ty<'tcx>,
} }
@ -39,7 +39,3 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ImpliedOutlivesBounds<'tcx> {
tcx.implied_outlives_bounds(canonicalized) tcx.implied_outlives_bounds(canonicalized)
} }
} }
impl_stable_hash_for! {
struct ImpliedOutlivesBounds<'tcx> { ty }
}

View file

@ -4,7 +4,7 @@ use crate::traits::query::Fallible;
use crate::ty::fold::TypeFoldable; use crate::ty::fold::TypeFoldable;
use crate::ty::{self, Lift, ParamEnvAnd, Ty, TyCtxt}; 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<T> { pub struct Normalize<T> {
pub value: T, pub value: T,
} }
@ -82,9 +82,3 @@ impl Normalizable<'tcx> for ty::FnSig<'tcx> {
tcx.type_op_normalize_fn_sig(canonicalized) tcx.type_op_normalize_fn_sig(canonicalized)
} }
} }
impl_stable_hash_for! {
impl<T> for struct Normalize<T> {
value
}
}

View file

@ -3,7 +3,7 @@ use crate::traits::query::dropck_outlives::{DropckOutlivesResult, trivial_dropck
use crate::traits::query::Fallible; use crate::traits::query::Fallible;
use crate::ty::{ParamEnvAnd, Ty, TyCtxt}; use crate::ty::{ParamEnvAnd, Ty, TyCtxt};
#[derive(Copy, Clone, Debug, TypeFoldable, Lift)] #[derive(Copy, Clone, Debug, HashStable, TypeFoldable, Lift)]
pub struct DropckOutlives<'tcx> { pub struct DropckOutlives<'tcx> {
dropped_ty: Ty<'tcx>, dropped_ty: Ty<'tcx>,
} }
@ -53,7 +53,3 @@ impl super::QueryTypeOp<'tcx> for DropckOutlives<'tcx> {
tcx.dropck_outlives(canonicalized) tcx.dropck_outlives(canonicalized)
} }
} }
impl_stable_hash_for! {
struct DropckOutlives<'tcx> { dropped_ty }
}

View file

@ -2,7 +2,7 @@ use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse};
use crate::traits::query::Fallible; use crate::traits::query::Fallible;
use crate::ty::{ParamEnvAnd, Predicate, TyCtxt}; 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 struct ProvePredicate<'tcx> {
pub predicate: Predicate<'tcx>, pub predicate: Predicate<'tcx>,
} }
@ -44,7 +44,3 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> {
tcx.type_op_prove_predicate(canonicalized) tcx.type_op_prove_predicate(canonicalized)
} }
} }
impl_stable_hash_for! {
struct ProvePredicate<'tcx> { predicate }
}

View file

@ -2,7 +2,7 @@ use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse};
use crate::traits::query::Fallible; use crate::traits::query::Fallible;
use crate::ty::{ParamEnvAnd, Ty, TyCtxt}; 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 struct Subtype<'tcx> {
pub sub: Ty<'tcx>, pub sub: Ty<'tcx>,
pub sup: Ty<'tcx>, pub sup: Ty<'tcx>,
@ -35,7 +35,3 @@ impl<'tcx> super::QueryTypeOp<'tcx> for Subtype<'tcx> {
tcx.type_op_subtype(canonicalized) tcx.type_op_subtype(canonicalized)
} }
} }
impl_stable_hash_for! {
struct Subtype<'tcx> { sub, sup }
}

View file

@ -367,7 +367,6 @@ enum BuiltinImplConditions<'tcx> {
Ambiguous, Ambiguous,
} }
#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
/// The result of trait evaluation. The order is important /// The result of trait evaluation. The order is important
/// here as the evaluation of a list is the maximum of the /// here as the evaluation of a list is the maximum of the
/// evaluations. /// evaluations.
@ -380,6 +379,7 @@ enum BuiltinImplConditions<'tcx> {
/// all the "potential success" candidates can potentially succeed, /// all the "potential success" candidates can potentially succeed,
/// so they are noops when unioned with a definite error, and within /// so they are noops when unioned with a definite error, and within
/// the categories it's easy to see that the unions are correct. /// the categories it's easy to see that the unions are correct.
#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq, HashStable)]
pub enum EvaluationResult { pub enum EvaluationResult {
/// Evaluation successful /// Evaluation successful
EvaluatedToOk, 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. /// Indicates that trait evaluation caused overflow.
#[derive(Copy, Clone, Debug, PartialEq, Eq, HashStable)]
pub struct OverflowError; pub struct OverflowError;
impl_stable_hash_for!(struct OverflowError {});
impl<'tcx> From<OverflowError> for SelectionError<'tcx> { impl<'tcx> From<OverflowError> for SelectionError<'tcx> {
fn from(OverflowError: OverflowError) -> SelectionError<'tcx> { fn from(OverflowError: OverflowError) -> SelectionError<'tcx> {
SelectionError::Overflow SelectionError::Overflow

View file

@ -24,7 +24,7 @@ use crate::util::nodemap::{DefIdMap, FxHashMap};
/// parents of a given specializing impl, which is needed for extracting /// parents of a given specializing impl, which is needed for extracting
/// default items amongst other things. In the simple "chain" rule, every impl /// default items amongst other things. In the simple "chain" rule, every impl
/// has at most one parent. /// has at most one parent.
#[derive(RustcEncodable, RustcDecodable)] #[derive(RustcEncodable, RustcDecodable, HashStable)]
pub struct Graph { pub struct Graph {
// All impls have a parent; the "root" impls have as their parent the `def_id` // All impls have a parent; the "root" impls have as their parent the `def_id`
// of the trait. // of the trait.
@ -535,8 +535,3 @@ impl<'a> HashStable<StableHashingContext<'a>> for Children {
ich::hash_stable_trait_impls(hcx, hasher, blanket_impls, nonblanket_impls); ich::hash_stable_trait_impls(hcx, hasher, blanket_impls, nonblanket_impls);
} }
} }
impl_stable_hash_for!(struct self::Graph {
parent,
children
});

View file

@ -2,7 +2,7 @@ use crate::hir::BindingAnnotation::*;
use crate::hir::BindingAnnotation; use crate::hir::BindingAnnotation;
use crate::hir::Mutability; use crate::hir::Mutability;
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)] #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)]
pub enum BindingMode { pub enum BindingMode {
BindByReference(Mutability), BindByReference(Mutability),
BindByValue(Mutability), BindByValue(Mutability),
@ -20,8 +20,3 @@ impl BindingMode {
} }
} }
} }
impl_stable_hash_for!(enum self::BindingMode {
BindByReference(mutability),
BindByValue(mutability)
});

View file

@ -1590,12 +1590,11 @@ rustc_index::newtype_index! {
/// type -- an idealized representative of "types in general" that we /// type -- an idealized representative of "types in general" that we
/// use for checking generic functions. /// use for checking generic functions.
pub struct UniverseIndex { pub struct UniverseIndex {
derive [HashStable]
DEBUG_FORMAT = "U{}", DEBUG_FORMAT = "U{}",
} }
} }
impl_stable_hash_for!(struct UniverseIndex { private });
impl UniverseIndex { impl UniverseIndex {
pub const ROOT: UniverseIndex = UniverseIndex::from_u32_const(0); 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. /// Definition of a variant -- a struct's fields or a enum variant.
#[derive(Debug)] #[derive(Debug, HashStable)]
pub struct VariantDef { pub struct VariantDef {
/// `DefId` that identifies the variant itself. /// `DefId` that identifies the variant itself.
/// If this variant belongs to a struct or union, then this is a copy of its `DefId`. /// 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`. /// If this variant is a struct variant, then this is `None`.
pub ctor_def_id: Option<DefId>, pub ctor_def_id: Option<DefId>,
/// Variant or struct name. /// Variant or struct name.
#[stable_hasher(project(name))]
pub ident: Ident, pub ident: Ident,
/// Discriminant of this variant. /// Discriminant of this variant.
pub discr: VariantDiscr, 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)] #[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
pub enum VariantDiscr { pub enum VariantDiscr {
/// Explicit value for this variant, i.e., `X = 123`. /// Explicit value for this variant, i.e., `X = 123`.
@ -2061,7 +2050,7 @@ impl Into<DataTypeKind> for AdtKind {
} }
bitflags! { bitflags! {
#[derive(RustcEncodable, RustcDecodable, Default)] #[derive(RustcEncodable, RustcDecodable, Default, HashStable)]
pub struct ReprFlags: u8 { pub struct ReprFlags: u8 {
const IS_C = 1 << 0; const IS_C = 1 << 0;
const IS_SIMD = 1 << 1; 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, /// 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 struct ReprOptions {
pub int: Option<attr::IntType>, pub int: Option<attr::IntType>,
pub align: Option<Align>, pub align: Option<Align>,
@ -2089,13 +2075,6 @@ pub struct ReprOptions {
pub flags: ReprFlags, pub flags: ReprFlags,
} }
impl_stable_hash_for!(struct ReprOptions {
align,
pack,
int,
flags
});
impl ReprOptions { impl ReprOptions {
pub fn new(tcx: TyCtxt<'_>, did: DefId) -> ReprOptions { pub fn new(tcx: TyCtxt<'_>, did: DefId) -> ReprOptions {
let mut flags = ReprFlags::empty(); let mut flags = ReprFlags::empty();
@ -3439,17 +3418,13 @@ pub struct CrateInherentImpls {
pub inherent_impls: DefIdMap<Vec<DefId>>, pub inherent_impls: DefIdMap<Vec<DefId>>,
} }
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable)] #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
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`.
pub name: Symbol pub name: Symbol
} }
impl_stable_hash_for!(struct self::SymbolName {
name
});
impl SymbolName { impl SymbolName {
pub fn new(name: &str) -> SymbolName { pub fn new(name: &str) -> SymbolName {
SymbolName { SymbolName {

View file

@ -1204,6 +1204,7 @@ rustc_index::newtype_index! {
/// is the outer fn. /// is the outer fn.
/// ///
/// [dbi]: http://en.wikipedia.org/wiki/De_Bruijn_index /// [dbi]: http://en.wikipedia.org/wiki/De_Bruijn_index
#[derive(HashStable)]
pub struct DebruijnIndex { pub struct DebruijnIndex {
DEBUG_FORMAT = "DebruijnIndex({})", DEBUG_FORMAT = "DebruijnIndex({})",
const INNERMOST = 0, const INNERMOST = 0,
@ -1379,21 +1380,20 @@ rustc_index::newtype_index! {
pub struct BoundVar { .. } 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 struct BoundTy {
pub var: BoundVar, pub var: BoundVar,
pub kind: BoundTyKind, 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 { pub enum BoundTyKind {
Anon, Anon,
Param(Symbol), Param(Symbol),
} }
impl_stable_hash_for!(struct BoundTy { var, kind });
impl_stable_hash_for!(enum self::BoundTyKind { Anon, Param(a) });
impl From<BoundVar> for BoundTy { impl From<BoundVar> for BoundTy {
fn from(var: BoundVar) -> Self { fn from(var: BoundVar) -> Self {
BoundTy { BoundTy {
@ -1518,8 +1518,6 @@ impl DebruijnIndex {
} }
} }
impl_stable_hash_for!(struct DebruijnIndex { private });
/// Region utilities /// Region utilities
impl RegionKind { impl RegionKind {
/// Is this region named by the user? /// Is this region named by the user?

View file

@ -19,7 +19,7 @@ extern crate rustc;
use rustc::ty::TyCtxt; use rustc::ty::TyCtxt;
use rustc::ty::query::Providers; use rustc::ty::query::Providers;
use rustc::hir::def_id::LOCAL_CRATE; use rustc::hir::def_id::{LOCAL_CRATE, DefId};
use syntax::symbol::sym; use syntax::symbol::sym;
pub mod link; pub mod link;
@ -27,18 +27,50 @@ pub mod codegen_backend;
pub mod symbol_names; pub mod symbol_names;
pub mod symbol_names_test; 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 /// check for the #[rustc_error] annotation, which forces an
/// error in codegen. This is used to write compile-fail tests /// error in codegen. This is used to write compile-fail tests
/// that actually test that compilation succeeds without /// that actually test that compilation succeeds without
/// reporting an error. /// reporting an error.
pub fn check_for_rustc_errors_attr(tcx: TyCtxt<'_>) { pub fn check_for_rustc_errors_attr(tcx: TyCtxt<'_>) {
if let Some((def_id, _)) = tcx.entry_fn(LOCAL_CRATE) { if let Some((def_id, _)) = tcx.entry_fn(LOCAL_CRATE) {
if tcx.has_attr(def_id, sym::rustc_error) { let attrs = &*tcx.get_attrs(def_id);
tcx.sess.span_fatal(tcx.def_span(def_id), "compilation successful"); 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<'_>) { pub fn provide(providers: &mut Providers<'_>) {
crate::symbol_names::provide(providers); crate::symbol_names::provide(providers);
*providers = Providers {
trigger_delay_span_bug,
..*providers
};
} }

View file

@ -1,21 +1,17 @@
//! Validates all used crates and extern libraries and loads their metadata //! Validates all used crates and extern libraries and loads their metadata
use crate::cstore::{self, CStore, MetadataBlob}; use crate::cstore::CStore;
use crate::locator::{self, CratePaths}; use crate::locator::{CrateLocator, CratePaths};
use crate::rmeta::{CrateRoot, CrateDep}; use crate::rmeta::{CrateMetadata, CrateNumMap, CrateRoot, CrateDep, MetadataBlob};
use rustc_data_structures::sync::{Lock, Once, AtomicCell};
use rustc::hir::def_id::CrateNum; use rustc::hir::def_id::CrateNum;
use rustc_data_structures::svh::Svh; use rustc_data_structures::svh::Svh;
use rustc::dep_graph::DepNodeIndex;
use rustc::middle::cstore::DepKind; use rustc::middle::cstore::DepKind;
use rustc::mir::interpret::AllocDecodingState;
use rustc::session::{Session, CrateDisambiguator}; use rustc::session::{Session, CrateDisambiguator};
use rustc::session::config::{Sanitizer, self}; use rustc::session::config::{Sanitizer, self};
use rustc_target::spec::{PanicStrategy, TargetTriple}; use rustc_target::spec::{PanicStrategy, TargetTriple};
use rustc::session::search_paths::PathKind; use rustc::session::search_paths::PathKind;
use rustc::middle::cstore::{CrateSource, ExternCrate, ExternCrateSource, MetadataLoaderDyn}; use rustc::middle::cstore::{CrateSource, ExternCrate, ExternCrateSource, MetadataLoaderDyn};
use rustc::util::common::record_time;
use rustc::util::nodemap::FxHashSet; use rustc::util::nodemap::FxHashSet;
use rustc::hir::map::Definitions; use rustc::hir::map::Definitions;
use rustc::hir::def_id::LOCAL_CRATE; use rustc::hir::def_id::LOCAL_CRATE;
@ -50,9 +46,9 @@ pub struct CrateLoader<'a> {
fn dump_crates(cstore: &CStore) { fn dump_crates(cstore: &CStore) {
info!("resolved crates:"); info!("resolved crates:");
cstore.iter_crate_data(|_, data| { cstore.iter_crate_data(|cnum, data| {
info!(" name: {}", data.root.name); info!(" name: {}", data.root.name);
info!(" cnum: {}", data.cnum); info!(" cnum: {}", cnum);
info!(" hash: {}", data.root.hash); info!(" hash: {}", data.root.hash);
info!(" reqd: {:?}", *data.dep_kind.lock()); info!(" reqd: {:?}", *data.dep_kind.lock());
let CrateSource { dylib, rlib, rmeta } = data.source.clone(); let CrateSource { dylib, rlib, rmeta } = data.source.clone();
@ -68,13 +64,13 @@ enum LoadResult {
} }
enum LoadError<'a> { enum LoadError<'a> {
LocatorError(locator::Context<'a>), LocatorError(CrateLocator<'a>),
} }
impl<'a> LoadError<'a> { impl<'a> LoadError<'a> {
fn report(self) -> ! { fn report(self) -> ! {
match 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()) let prev_kind = source.dylib.as_ref().or(source.rlib.as_ref())
.or(source.rmeta.as_ref()) .or(source.rmeta.as_ref())
.expect("No sources for crate").1; .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); ret = Some(cnum);
} }
}); });
@ -211,15 +207,13 @@ impl<'a> CrateLoader<'a> {
let root = if let Some(root) = root { let root = if let Some(root) = root {
root root
} else { } else {
crate_paths = CratePaths { name: crate_root.name, source: source.clone() }; crate_paths = CratePaths::new(crate_root.name, source.clone());
&crate_paths &crate_paths
}; };
let cnum_map = self.resolve_crate_deps(root, &crate_root, &metadata, cnum, span, dep_kind); let cnum_map = self.resolve_crate_deps(root, &crate_root, &metadata, cnum, span, dep_kind);
let dependencies: Vec<CrateNum> = cnum_map.iter().cloned().collect(); let raw_proc_macros = if crate_root.is_proc_macro_crate() {
let raw_proc_macros = crate_root.proc_macro_data.map(|_| {
let temp_root; let temp_root;
let (dlsym_source, dlsym_root) = match &host_lib { let (dlsym_source, dlsym_root) = match &host_lib {
Some(host_lib) => Some(host_lib) =>
@ -227,55 +221,38 @@ impl<'a> CrateLoader<'a> {
None => (&source, &crate_root), None => (&source, &crate_root),
}; };
let dlsym_dylib = dlsym_source.dylib.as_ref().expect("no dylib for a proc-macro crate"); 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) Some(self.dlsym_proc_macros(&dlsym_dylib.0, dlsym_root.disambiguator, span))
}); } else {
None
};
let interpret_alloc_index: Vec<u32> = crate_root.interpret_alloc_index self.cstore.set_crate_data(cnum, CrateMetadata::new(
.decode(&metadata) self.sess,
.collect(); metadata,
let trait_impls = crate_root crate_root,
.impls raw_proc_macros,
.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))
});
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,
cnum, cnum,
dependencies: Lock::new(dependencies), cnum_map,
source_map_import_info: Once::new(), dep_kind,
alloc_decoding_state: AllocDecodingState::new(interpret_alloc_index),
dep_kind: Lock::new(dep_kind),
source, source,
private_dep, private_dep,
raw_proc_macros, host_hash,
dep_node_index: AtomicCell::new(DepNodeIndex::INVALID), ));
});
cnum cnum
} }
fn load_proc_macro<'b>( fn load_proc_macro<'b>(
&self, &self,
locate_ctxt: &mut locator::Context<'b>, locator: &mut CrateLocator<'b>,
path_kind: PathKind, path_kind: PathKind,
) -> Option<(LoadResult, Option<Library>)> ) -> Option<(LoadResult, Option<Library>)>
where where
'a: 'b, '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 // message we emit
let mut proc_macro_locator = locate_ctxt.clone(); let mut proc_macro_locator = locator.clone();
// Try to load a proc macro // Try to load a proc macro
proc_macro_locator.is_proc_macro = Some(true); 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::Previous(cnum) => return Some((LoadResult::Previous(cnum), None)),
LoadResult::Loaded(library) => Some(LoadResult::Loaded(library)) LoadResult::Loaded(library) => Some(LoadResult::Loaded(library))
}; };
locate_ctxt.hash = locate_ctxt.host_hash; locator.hash = locator.host_hash;
// Use the locate_ctxt when looking for the host proc macro crate, as that is required // Use the locator when looking for the host proc macro crate, as that is required
// so we want it to affect the error message // so we want it to affect the error message
(locate_ctxt, result) (locator, result)
} else { } else {
(&mut proc_macro_locator, None) (&mut proc_macro_locator, None)
}; };
@ -350,37 +327,30 @@ impl<'a> CrateLoader<'a> {
(LoadResult::Previous(cnum), None) (LoadResult::Previous(cnum), None)
} else { } else {
info!("falling back to a load"); info!("falling back to a load");
let mut locate_ctxt = locator::Context { let mut locator = CrateLocator::new(
sess: self.sess, self.sess,
span, self.metadata_loader,
crate_name: name, name,
hash, hash,
host_hash, host_hash,
extra_filename, extra_filename,
filesearch: self.sess.target_filesearch(path_kind), false, // is_host
target: &self.sess.target.target, path_kind,
triple: self.sess.opts.target_triple.clone(), span,
root, root,
rejected_via_hash: vec![], Some(false), // is_proc_macro
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,
};
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; dep_kind = DepKind::UnexportedMacrosOnly;
self.load_proc_macro(&mut locate_ctxt, path_kind) self.load_proc_macro(&mut locator, path_kind)
}).ok_or_else(move || LoadError::LocatorError(locate_ctxt))? }).ok_or_else(move || LoadError::LocatorError(locator))?
}; };
match result { match result {
(LoadResult::Previous(cnum), None) => { (LoadResult::Previous(cnum), None) => {
let data = self.cstore.get_crate_data(cnum); 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; dep_kind = DepKind::UnexportedMacrosOnly;
} }
data.dep_kind.with_lock(|data_dep_kind| { 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<LoadResult> { fn load(&self, locator: &mut CrateLocator<'_>) -> Option<LoadResult> {
let library = locate_ctxt.maybe_load_library_crate()?; let library = locator.maybe_load_library_crate()?;
// In the case that we're loading a crate, but not matching // 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 // 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 // don't want to match a host crate against an equivalent target one
// already loaded. // already loaded.
let root = library.metadata.get_root(); 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); let mut result = LoadResult::Loaded(library);
self.cstore.iter_crate_data(|cnum, data| { self.cstore.iter_crate_data(|cnum, data| {
if data.root.name == root.name && root.hash == data.root.hash { 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); info!("load success, going to previous cnum: {}", cnum);
result = LoadResult::Previous(cnum); result = LoadResult::Previous(cnum);
} }
@ -471,16 +441,16 @@ impl<'a> CrateLoader<'a> {
krate: CrateNum, krate: CrateNum,
span: Span, span: Span,
dep_kind: DepKind) dep_kind: DepKind)
-> cstore::CrateNumMap { -> CrateNumMap {
debug!("resolving deps of external crate"); debug!("resolving deps of external crate");
if crate_root.proc_macro_data.is_some() { if crate_root.is_proc_macro_crate() {
return cstore::CrateNumMap::new(); return CrateNumMap::new();
} }
// The map from crate numbers in the crate we're resolving to local crate numbers. // 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" // We map 0 and all other holes in the map to our parent crate. The "additional"
// self-dependencies should be harmless. // 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, info!("resolving dep crate {} hash: `{}` extra filename: `{}`", dep.name, dep.hash,
dep.extra_filename); dep.extra_filename);
if dep.kind == DepKind::UnexportedMacrosOnly { if dep.kind == DepKind::UnexportedMacrosOnly {
@ -824,7 +794,7 @@ impl<'a> CrateLoader<'a> {
fn inject_dependency_if(&self, fn inject_dependency_if(&self,
krate: CrateNum, krate: CrateNum,
what: &str, 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 // don't perform this validation if the session has errors, as one of
// those errors may indicate a circular dependency which could cause // those errors may indicate a circular dependency which could cause
// this to stack overflow. // this to stack overflow.

View file

@ -1,109 +1,23 @@
// The crate store - a central repo for information collected about external // The crate store - a central repo for information collected about external
// crates and libraries // crates and libraries
use crate::rmeta; use crate::rmeta::CrateMetadata;
use rustc::dep_graph::DepNodeIndex;
use rustc::hir::def_id::{CrateNum, DefIndex}; use rustc_data_structures::sync::Lrc;
use rustc::hir::map::definitions::DefPathTable;
use rustc::middle::cstore::{CrateSource, DepKind, ExternCrate};
use rustc::mir::interpret::AllocDecodingState;
use rustc_index::vec::IndexVec; use rustc_index::vec::IndexVec;
use rustc::util::nodemap::FxHashMap; use rustc::hir::def_id::CrateNum;
use rustc_data_structures::sync::{Lrc, Lock, MetadataRef, Once, AtomicCell};
use rustc_data_structures::svh::Svh;
use syntax::ast; use syntax::ast;
use syntax::edition::Edition; use syntax::edition::Edition;
use syntax_expand::base::SyntaxExtension;
use syntax::expand::allocator::AllocatorKind; use syntax::expand::allocator::AllocatorKind;
use syntax_pos; use syntax_expand::base::SyntaxExtension;
use proc_macro::bridge::client::ProcMacro;
pub use crate::rmeta::{provide, provide_extern}; 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<CrateNum, CrateNum>;
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<syntax_pos::SourceFile>,
}
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<Vec<ImportedSourceFile>>,
/// 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<DepNodeIndex>,
// --- 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<Vec<CrateNum>>,
/// How to link (or not link) this crate to the currently compiled crate.
crate dep_kind: Lock<DepKind>,
/// 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<Svh>,
// --- 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<Option<ExternCrate>>,
}
#[derive(Clone)] #[derive(Clone)]
pub struct CStore { pub struct CStore {
metas: IndexVec<CrateNum, Option<Lrc<CrateMetadata>>>, metas: IndexVec<CrateNum, Option<Lrc<CrateMetadata>>>,
pub(crate) injected_panic_runtime: Option<CrateNum>, crate injected_panic_runtime: Option<CrateNum>,
pub(crate) allocator_kind: Option<AllocatorKind>, crate allocator_kind: Option<AllocatorKind>,
} }
pub enum LoadedMacro { pub enum LoadedMacro {

View file

@ -212,9 +212,8 @@
//! no means all of the necessary details. Take a look at the rest of //! no means all of the necessary details. Take a look at the rest of
//! metadata::locator or metadata::creader for all the juicy details! //! metadata::locator or metadata::creader for all the juicy details!
use crate::cstore::MetadataBlob;
use crate::creader::Library; 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::fx::FxHashSet;
use rustc_data_structures::svh::Svh; use rustc_data_structures::svh::Svh;
@ -249,37 +248,47 @@ use log::{debug, info, warn};
use rustc_error_codes::*; use rustc_error_codes::*;
#[derive(Clone)] #[derive(Clone)]
crate struct CrateMismatch { struct CrateMismatch {
path: PathBuf, path: PathBuf,
got: String, got: String,
} }
#[derive(Clone)] #[derive(Clone)]
crate struct Context<'a> { crate struct CrateLocator<'a> {
pub sess: &'a Session, // Immutable per-session configuration.
pub span: Span, sess: &'a Session,
pub crate_name: Symbol, metadata_loader: &'a dyn MetadataLoader,
// Immutable per-search configuration.
crate_name: Symbol,
exact_paths: Vec<PathBuf>,
pub hash: Option<&'a Svh>, pub hash: Option<&'a Svh>,
pub host_hash: Option<&'a Svh>, pub host_hash: Option<&'a Svh>,
pub extra_filename: Option<&'a str>, extra_filename: Option<&'a str>,
// points to either self.sess.target.target or self.sess.host, must match triple
pub target: &'a Target, pub target: &'a Target,
pub triple: TargetTriple, pub triple: TargetTriple,
pub filesearch: FileSearch<'a>, pub filesearch: FileSearch<'a>,
pub root: Option<&'a CratePaths>, span: Span,
pub rejected_via_hash: Vec<CrateMismatch>, root: Option<&'a CratePaths>,
pub rejected_via_triple: Vec<CrateMismatch>,
pub rejected_via_kind: Vec<CrateMismatch>,
pub rejected_via_version: Vec<CrateMismatch>,
pub rejected_via_filename: Vec<CrateMismatch>,
pub should_match_name: bool,
pub is_proc_macro: Option<bool>, pub is_proc_macro: Option<bool>,
pub metadata_loader: &'a dyn MetadataLoader,
// Mutable in-progress state or output.
rejected_via_hash: Vec<CrateMismatch>,
rejected_via_triple: Vec<CrateMismatch>,
rejected_via_kind: Vec<CrateMismatch>,
rejected_via_version: Vec<CrateMismatch>,
rejected_via_filename: Vec<CrateMismatch>,
} }
crate struct CratePaths { crate struct CratePaths {
pub name: Symbol, name: Symbol,
pub source: CrateSource, source: CrateSource,
}
impl CratePaths {
crate fn new(name: Symbol, source: CrateSource) -> CratePaths {
CratePaths { name, source }
}
} }
#[derive(Copy, Clone, PartialEq)] #[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<bool>,
) -> 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) { crate fn reset(&mut self) {
self.rejected_via_hash.clear(); self.rejected_via_hash.clear();
self.rejected_via_triple.clear(); self.rejected_via_triple.clear();
@ -309,6 +369,9 @@ impl<'a> Context<'a> {
} }
crate fn maybe_load_library_crate(&mut self) -> Option<Library> { crate fn maybe_load_library_crate(&mut self) -> Option<Library> {
if !self.exact_paths.is_empty() {
return self.find_commandline_library();
}
let mut seen_paths = FxHashSet::default(); let mut seen_paths = FxHashSet::default();
match self.extra_filename { match self.extra_filename {
Some(s) => self.find_library_crate(s, &mut seen_paths) Some(s) => self.find_library_crate(s, &mut seen_paths)
@ -434,21 +497,6 @@ impl<'a> Context<'a> {
extra_prefix: &str, extra_prefix: &str,
seen_paths: &mut FxHashSet<PathBuf>) seen_paths: &mut FxHashSet<PathBuf>)
-> Option<Library> { -> Option<Library> {
// 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 dypair = self.dylibname();
let staticpair = self.staticlibname(); let staticpair = self.staticlibname();
@ -716,15 +764,16 @@ impl<'a> Context<'a> {
} }
let root = metadata.get_root(); let root = metadata.get_root();
if let Some(is_proc_macro) = self.is_proc_macro { if let Some(expected_is_proc_macro) = self.is_proc_macro {
if root.proc_macro_data.is_some() != 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 {}", 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; return None;
} }
} }
if self.should_match_name { if self.exact_paths.is_empty() {
if self.crate_name != root.name { if self.crate_name != root.name {
info!("Rejecting via crate name"); info!("Rejecting via crate name");
return None; return None;
@ -771,9 +820,7 @@ impl<'a> Context<'a> {
(t.options.staticlib_prefix.clone(), t.options.staticlib_suffix.clone()) (t.options.staticlib_prefix.clone(), t.options.staticlib_suffix.clone())
} }
fn find_commandline_library<'b, LOCS>(&mut self, locs: LOCS) -> Option<Library> fn find_commandline_library(&mut self) -> Option<Library> {
where LOCS: Iterator<Item = &'b String>
{
// First, filter out all libraries that look suspicious. We only accept // First, filter out all libraries that look suspicious. We only accept
// files which actually exist that have the correct naming scheme for // files which actually exist that have the correct naming scheme for
// rlibs/dylibs. // rlibs/dylibs.
@ -783,10 +830,12 @@ impl<'a> Context<'a> {
let mut rmetas = FxHashMap::default(); let mut rmetas = FxHashMap::default();
let mut dylibs = 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() { if !loc.exists() {
sess.err(&format!("extern location for {} does not exist: {}", sess.err(&format!("extern location for {} does not exist: {}",
self.crate_name, crate_name,
loc.display())); loc.display()));
return false; return false;
} }
@ -794,7 +843,7 @@ impl<'a> Context<'a> {
Some(file) => file, Some(file) => file,
None => { None => {
sess.err(&format!("extern location for {} is not a file: {}", sess.err(&format!("extern location for {} is not a file: {}",
self.crate_name, crate_name,
loc.display())); loc.display()));
return false; return false;
} }
@ -809,8 +858,8 @@ impl<'a> Context<'a> {
} }
} }
self.rejected_via_filename.push(CrateMismatch { rejected_via_filename.push(CrateMismatch {
path: loc.clone(), path: (*loc).clone(),
got: String::new(), got: String::new(),
}); });
@ -907,7 +956,7 @@ fn get_metadata_section_imp(target: &Target,
rustc_erase_owner!(OwningRef::new(StableDerefMmap(mmap)).map_owner_box()) 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() { if blob.is_compatible() {
Ok(blob) Ok(blob)
} else { } else {
@ -927,28 +976,21 @@ pub fn find_plugin_registrar(
let host_triple = TargetTriple::from_triple(config::host_triple()); let host_triple = TargetTriple::from_triple(config::host_triple());
let is_cross = target_triple != host_triple; let is_cross = target_triple != host_triple;
let mut target_only = false; let mut target_only = false;
let mut locate_ctxt = Context { let mut locator = CrateLocator::new(
sess, 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, 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 { if !is_cross {
return None return None
} }
@ -956,15 +998,15 @@ pub fn find_plugin_registrar(
// try to load a plugin registrar function, // try to load a plugin registrar function,
target_only = true; target_only = true;
locate_ctxt.target = &sess.target.target; locator.target = &sess.target.target;
locate_ctxt.triple = target_triple; locator.triple = target_triple;
locate_ctxt.filesearch = sess.target_filesearch(PathKind::Crate); locator.filesearch = sess.target_filesearch(PathKind::Crate);
locate_ctxt.maybe_load_library_crate() locator.maybe_load_library_crate()
}); });
let library = match library { let library = match library {
Some(l) => l, Some(l) => l,
None => locate_ctxt.report_errs(), None => locator.report_errs(),
}; };
if target_only { if target_only {

View file

@ -1,27 +1,30 @@
// Decoding metadata from a single crate's metadata // Decoding metadata from a single crate's metadata
use crate::cstore::{self, CrateMetadata, MetadataBlob};
use crate::rmeta::*; use crate::rmeta::*;
use crate::rmeta::table::{FixedSizeEncoding, PerDefTable}; use crate::rmeta::table::{FixedSizeEncoding, PerDefTable};
use rustc_index::vec::IndexVec; 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::{DefKey, DefPath, DefPathData, DefPathHash};
use rustc::hir::map::definitions::DefPathTable;
use rustc::hir; use rustc::hir;
use rustc::middle::cstore::{CrateSource, ExternCrate};
use rustc::middle::cstore::{LinkagePreference, NativeLibrary, ForeignModule}; use rustc::middle::cstore::{LinkagePreference, NativeLibrary, ForeignModule};
use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel}; use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
use rustc::hir::def::{self, Res, DefKind, CtorOf, CtorKind}; 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::hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::FxHashMap; 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::middle::lang_items;
use rustc::mir::{self, interpret}; use rustc::mir::{self, interpret};
use rustc::mir::interpret::AllocDecodingSession; use rustc::mir::interpret::{AllocDecodingSession, AllocDecodingState};
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;
use rustc::mir::{Body, Promoted}; use rustc::mir::{Body, Promoted};
use rustc::util::common::record_time;
use rustc::util::captures::Captures; use rustc::util::captures::Captures;
use std::io; use std::io;
@ -44,7 +47,86 @@ pub use cstore_impl::{provide, provide_extern};
mod cstore_impl; 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<CrateNum, CrateNum>;
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<Vec<ImportedSourceFile>>,
/// 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<DepNodeIndex>,
// --- 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<Vec<CrateNum>>,
/// How to link (or not link) this crate to the currently compiled crate.
crate dep_kind: Lock<DepKind>,
/// 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<Svh>,
// --- 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<Option<ExternCrate>>,
}
/// 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<syntax_pos::SourceFile>,
}
pub(super) struct DecodeContext<'a, 'tcx> {
opaque: opaque::Decoder<'a>, opaque: opaque::Decoder<'a>,
cdata: Option<&'a CrateMetadata>, cdata: Option<&'a CrateMetadata>,
sess: Option<&'tcx Session>, sess: Option<&'tcx Session>,
@ -60,7 +142,7 @@ crate struct DecodeContext<'a, 'tcx> {
} }
/// Abstract over the various ways one can create metadata decoders. /// 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 raw_bytes(self) -> &'a [u8];
fn cdata(self) -> Option<&'a CrateMetadata> { None } fn cdata(self) -> Option<&'a CrateMetadata> { None }
fn sess(self) -> Option<&'tcx Session> { 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<T> { impl<'a, 'tcx, T: Encodable + Decodable> Lazy<T> {
crate fn decode<M: Metadata<'a, 'tcx>>(self, metadata: M) -> T { fn decode<M: Metadata<'a, 'tcx>>(self, metadata: M) -> T {
let mut dcx = metadata.decoder(self.position.get()); let mut dcx = metadata.decoder(self.position.get());
dcx.lazy_state = LazyState::NodeStart(self.position); dcx.lazy_state = LazyState::NodeStart(self.position);
T::decode(&mut dcx).unwrap() T::decode(&mut dcx).unwrap()
@ -144,7 +226,7 @@ impl<'a, 'tcx, T: Encodable + Decodable> Lazy<T> {
} }
impl<'a: 'x, 'tcx: 'x, 'x, T: Encodable + Decodable> Lazy<[T]> { impl<'a: 'x, 'tcx: 'x, 'x, T: Encodable + Decodable> Lazy<[T]> {
crate fn decode<M: Metadata<'a, 'tcx>>( fn decode<M: Metadata<'a, 'tcx>>(
self, self,
metadata: M, metadata: M,
) -> impl ExactSizeIterator<Item = T> + Captures<'a> + Captures<'tcx> + 'x { ) -> impl ExactSizeIterator<Item = T> + Captures<'a> + Captures<'tcx> + 'x {
@ -393,7 +475,11 @@ for DecodeContext<'a, 'tcx> {
implement_ty_decoder!( 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 { crate fn is_compatible(&self) -> bool {
self.raw_bytes().starts_with(METADATA_HEADER) 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<Item = CrateDep> + Captures<'a> {
self.crate_deps.decode(metadata)
}
}
impl<'a, 'tcx> CrateMetadata { impl<'a, 'tcx> CrateMetadata {
fn is_proc_macro_crate(&self) -> bool { crate fn new(
self.root.proc_macro_decls_static.is_some() 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<Svh>,
) -> 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 { fn is_proc_macro(&self, id: DefIndex) -> bool {
self.is_proc_macro_crate() && self.root.proc_macro_data.and_then(|data| data.decode(self).find(|x| *x == id)).is_some()
self.root.proc_macro_data.unwrap().decode(self).find(|x| *x == id).is_some()
} }
fn maybe_kind(&self, item_id: DefIndex) -> Option<EntryKind<'tcx>> { fn maybe_kind(&self, item_id: DefIndex) -> Option<EntryKind<'tcx>> {
@ -757,7 +891,7 @@ impl<'a, 'tcx> CrateMetadata {
/// Iterates over the language items in the given crate. /// Iterates over the language items in the given crate.
fn get_lang_items(&self, tcx: TyCtxt<'tcx>) -> &'tcx [(DefId, usize)] { 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. // Proc macro crates do not export any lang-items to the target.
&[] &[]
} else { } else {
@ -773,7 +907,7 @@ impl<'a, 'tcx> CrateMetadata {
&self, &self,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
) -> &'tcx FxHashMap<Symbol, DefId> { ) -> &'tcx FxHashMap<Symbol, DefId> {
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. // Proc macro crates do not export any diagnostic-items to the target.
Default::default() Default::default()
} else { } else {
@ -1081,7 +1215,7 @@ impl<'a, 'tcx> CrateMetadata {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
filter: Option<DefId>, filter: Option<DefId>,
) -> &'tcx [DefId] { ) -> &'tcx [DefId] {
if self.is_proc_macro_crate() { if self.root.is_proc_macro_crate() {
// proc-macro crates export no trait impls. // proc-macro crates export no trait impls.
return &[] return &[]
} }
@ -1125,7 +1259,7 @@ impl<'a, 'tcx> CrateMetadata {
fn get_native_libraries(&self, sess: &Session) -> Vec<NativeLibrary> { fn get_native_libraries(&self, sess: &Session) -> Vec<NativeLibrary> {
if self.is_proc_macro_crate() { if self.root.is_proc_macro_crate() {
// Proc macro crates do not have any *target* native libraries. // Proc macro crates do not have any *target* native libraries.
vec![] vec![]
} else { } else {
@ -1134,7 +1268,7 @@ impl<'a, 'tcx> CrateMetadata {
} }
fn get_foreign_modules(&self, tcx: TyCtxt<'tcx>) -> &'tcx [ForeignModule] { 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. // Proc macro crates do not have any *target* foreign modules.
&[] &[]
} else { } else {
@ -1157,7 +1291,7 @@ impl<'a, 'tcx> CrateMetadata {
} }
fn get_missing_lang_items(&self, tcx: TyCtxt<'tcx>) -> &'tcx [lang_items::LangItem] { 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. // Proc macro crates do not depend on any target weak lang-items.
&[] &[]
} else { } else {
@ -1181,7 +1315,7 @@ impl<'a, 'tcx> CrateMetadata {
&self, &self,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
) -> Vec<(ExportedSymbol<'tcx>, SymbolExportLevel)> { ) -> 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 // If this crate is a custom derive crate, then we're not even going to
// link those in so we skip those crates. // link those in so we skip those crates.
vec![] vec![]
@ -1296,7 +1430,7 @@ impl<'a, 'tcx> CrateMetadata {
fn imported_source_files( fn imported_source_files(
&'a self, &'a self,
local_source_map: &source_map::SourceMap, local_source_map: &source_map::SourceMap,
) -> &[cstore::ImportedSourceFile] { ) -> &[ImportedSourceFile] {
self.source_map_import_info.init_locking(|| { self.source_map_import_info.init_locking(|| {
let external_source_map = self.root.source_map.decode(self); 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.name, start_pos, end_pos,
local_version.start_pos, local_version.end_pos); local_version.start_pos, local_version.end_pos);
cstore::ImportedSourceFile { ImportedSourceFile {
original_start_pos: start_pos, original_start_pos: start_pos,
original_end_pos: end_pos, original_end_pos: end_pos,
translated_source_file: local_version, translated_source_file: local_version,
@ -1374,7 +1508,7 @@ impl<'a, 'tcx> CrateMetadata {
// would always write the same value. // would always write the same value.
let def_path_hash = self.def_path_hash(CRATE_DEF_INDEX); 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); dep_node_index = tcx.dep_graph.dep_node_index_of(&dep_node);
assert!(dep_node_index != DepNodeIndex::INVALID); assert!(dep_node_index != DepNodeIndex::INVALID);

View file

@ -52,7 +52,7 @@ macro_rules! provide {
assert!(!$def_id.is_local()); assert!(!$def_id.is_local());
let $cdata = $tcx.crate_data_as_any($def_id.krate); let $cdata = $tcx.crate_data_as_any($def_id.krate);
let $cdata = $cdata.downcast_ref::<cstore::CrateMetadata>() let $cdata = $cdata.downcast_ref::<rmeta::CrateMetadata>()
.expect("CrateStore created data is not a CrateMetadata"); .expect("CrateStore created data is not a CrateMetadata");
if $tcx.dep_graph.is_fully_enabled() { 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 _prof_timer = sess.prof.generic_activity("metadata_load_macro");
let data = self.get_crate_data(id.krate); 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)); return LoadedMacro::ProcMacro(data.load_proc_macro(id.index, sess));
} }

View file

@ -14,6 +14,7 @@ use rustc::ty::{self, Ty, ReprOptions};
use rustc_target::spec::{PanicStrategy, TargetTriple}; use rustc_target::spec::{PanicStrategy, TargetTriple};
use rustc_index::vec::IndexVec; use rustc_index::vec::IndexVec;
use rustc_data_structures::svh::Svh; use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::MetadataRef;
use rustc_serialize::Encodable; use rustc_serialize::Encodable;
use syntax::{ast, attr}; use syntax::{ast, attr};
use syntax::edition::Edition; use syntax::edition::Edition;
@ -24,6 +25,7 @@ use std::marker::PhantomData;
use std::num::NonZeroUsize; use std::num::NonZeroUsize;
pub use decoder::{provide, provide_extern}; pub use decoder::{provide, provide_extern};
crate use decoder::{CrateMetadata, CrateNumMap, MetadataBlob};
mod decoder; mod decoder;
mod encoder; mod encoder;
@ -49,7 +51,7 @@ crate const METADATA_HEADER: &[u8; 8] =
/// Additional metadata for a `Lazy<T>` where `T` may not be `Sized`, /// Additional metadata for a `Lazy<T>` where `T` may not be `Sized`,
/// e.g. for `Lazy<[T]>`, this is the length (count of `T` values). /// e.g. for `Lazy<[T]>`, this is the length (count of `T` values).
crate trait LazyMeta { trait LazyMeta {
type Meta: Copy + 'static; type Meta: Copy + 'static;
/// Returns the minimum encoded size. /// Returns the minimum encoded size.
@ -103,7 +105,7 @@ impl<T: Encodable> LazyMeta for [T] {
#[must_use] #[must_use]
// FIXME(#59875) the `Meta` parameter only exists to dodge // FIXME(#59875) the `Meta` parameter only exists to dodge
// invariance wrt `T` (coming from the `meta: T::Meta` field). // invariance wrt `T` (coming from the `meta: T::Meta` field).
crate struct Lazy<T, Meta = <T as LazyMeta>::Meta> struct Lazy<T, Meta = <T as LazyMeta>::Meta>
where T: ?Sized + LazyMeta<Meta = Meta>, where T: ?Sized + LazyMeta<Meta = Meta>,
Meta: 'static + Copy, Meta: 'static + Copy,
{ {
@ -186,7 +188,7 @@ crate struct CrateRoot<'tcx> {
proc_macro_decls_static: Option<DefIndex>, proc_macro_decls_static: Option<DefIndex>,
proc_macro_stability: Option<attr::Stability>, proc_macro_stability: Option<attr::Stability>,
pub crate_deps: Lazy<[CrateDep]>, crate_deps: Lazy<[CrateDep]>,
dylib_dependency_formats: Lazy<[Option<LinkagePreference>]>, dylib_dependency_formats: Lazy<[Option<LinkagePreference>]>,
lib_features: Lazy<[(Symbol, Option<Symbol>)]>, lib_features: Lazy<[(Symbol, Option<Symbol>)]>,
lang_items: Lazy<[(DefIndex, usize)]>, lang_items: Lazy<[(DefIndex, usize)]>,
@ -195,16 +197,15 @@ crate struct CrateRoot<'tcx> {
native_libraries: Lazy<[NativeLibrary]>, native_libraries: Lazy<[NativeLibrary]>,
foreign_modules: Lazy<[ForeignModule]>, foreign_modules: Lazy<[ForeignModule]>,
source_map: Lazy<[syntax_pos::SourceFile]>, source_map: Lazy<[syntax_pos::SourceFile]>,
pub def_path_table: Lazy<hir::map::definitions::DefPathTable>, def_path_table: Lazy<hir::map::definitions::DefPathTable>,
pub impls: Lazy<[TraitImpls]>, impls: Lazy<[TraitImpls]>,
exported_symbols: Lazy!([(ExportedSymbol<'tcx>, SymbolExportLevel)]), exported_symbols: Lazy!([(ExportedSymbol<'tcx>, SymbolExportLevel)]),
pub interpret_alloc_index: Lazy<[u32]>, interpret_alloc_index: Lazy<[u32]>,
per_def: LazyPerDefTables<'tcx>, per_def: LazyPerDefTables<'tcx>,
/// The DefIndex's of any proc macros delcared by /// The DefIndex's of any proc macros delcared by this crate.
/// this crate proc_macro_data: Option<Lazy<[DefIndex]>>,
pub proc_macro_data: Option<Lazy<[DefIndex]>>,
compiler_builtins: bool, compiler_builtins: bool,
pub needs_allocator: bool, pub needs_allocator: bool,
@ -227,8 +228,8 @@ crate struct CrateDep {
#[derive(RustcEncodable, RustcDecodable)] #[derive(RustcEncodable, RustcDecodable)]
crate struct TraitImpls { crate struct TraitImpls {
pub trait_id: (u32, DefIndex), trait_id: (u32, DefIndex),
pub impls: Lazy<[DefIndex]>, impls: Lazy<[DefIndex]>,
} }
#[derive(RustcEncodable, RustcDecodable)] #[derive(RustcEncodable, RustcDecodable)]

View file

@ -22,6 +22,7 @@ rustc_data_structures = { path = "../librustc_data_structures" }
rustc_index = { path = "../librustc_index" } rustc_index = { path = "../librustc_index" }
rustc_errors = { path = "../librustc_errors" } rustc_errors = { path = "../librustc_errors" }
rustc_lexer = { path = "../librustc_lexer" } rustc_lexer = { path = "../librustc_lexer" }
rustc_macros = { path = "../librustc_macros" }
rustc_serialize = { path = "../libserialize", package = "serialize" } rustc_serialize = { path = "../libserialize", package = "serialize" }
syntax = { path = "../libsyntax" } syntax = { path = "../libsyntax" }
syntax_pos = { path = "../libsyntax_pos" } syntax_pos = { path = "../libsyntax_pos" }

View file

@ -18,6 +18,7 @@ use rustc::mir::interpret::{
InterpResult, truncate, sign_extend, InterpResult, truncate, sign_extend,
}; };
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_macros::HashStable;
use super::{ use super::{
Immediate, Operand, MemPlace, MPlaceTy, Place, PlaceTy, ScalarMaybeUndef, Immediate, Operand, MemPlace, MPlaceTy, Place, PlaceTy, ScalarMaybeUndef,
@ -93,7 +94,7 @@ pub struct Frame<'mir, 'tcx, Tag=(), Extra=()> {
pub stmt: usize, 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 { pub enum StackPopCleanup {
/// Jump to the next block in the caller, or cause UB if None (that's a function /// 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 /// 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 /// 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 struct LocalState<'tcx, Tag=(), Id=AllocId> {
pub value: LocalValue<Tag, Id>, pub value: LocalValue<Tag, Id>,
/// Don't modify if `Some`, this is only used to prevent computing the layout twice /// Don't modify if `Some`, this is only used to prevent computing the layout twice
#[stable_hasher(ignore)]
pub layout: Cell<Option<TyLayout<'tcx>>>, pub layout: Cell<Option<TyLayout<'tcx>>>,
} }
/// Current value of a local variable /// 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<Tag=(), Id=AllocId> { pub enum LocalValue<Tag=(), Id=AllocId> {
/// This local is not currently alive, and cannot be used at all. /// This local is not currently alive, and cannot be used at all.
Dead, Dead,

View file

@ -18,6 +18,7 @@ use super::{
MemPlace, MPlaceTy, PlaceTy, Place, MemPlace, MPlaceTy, PlaceTy, Place,
}; };
pub use rustc::mir::interpret::ScalarMaybeUndef; pub use rustc::mir::interpret::ScalarMaybeUndef;
use rustc_macros::HashStable;
/// An `Immediate` represents a single immediate self-contained Rust value. /// 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. /// operations and fat pointers. This idea was taken from rustc's codegen.
/// In particular, thanks to `ScalarPair`, arithmetic operations and casts can be entirely /// In particular, thanks to `ScalarPair`, arithmetic operations and casts can be entirely
/// defined on `Immediate`, and do not have to work with a `Place`. /// 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<Tag=(), Id=AllocId> { pub enum Immediate<Tag=(), Id=AllocId> {
Scalar(ScalarMaybeUndef<Tag, Id>), Scalar(ScalarMaybeUndef<Tag, Id>),
ScalarPair(ScalarMaybeUndef<Tag, Id>, ScalarMaybeUndef<Tag, Id>), ScalarPair(ScalarMaybeUndef<Tag, Id>, ScalarMaybeUndef<Tag, Id>),
@ -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, /// 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 /// 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. /// 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<Tag=(), Id=AllocId> { pub enum Operand<Tag=(), Id=AllocId> {
Immediate(Immediate<Tag, Id>), Immediate(Immediate<Tag, Id>),
Indirect(MemPlace<Tag, Id>), Indirect(MemPlace<Tag, Id>),

View file

@ -12,6 +12,7 @@ use rustc::ty::layout::{
self, Size, Align, LayoutOf, TyLayout, HasDataLayout, VariantIdx, PrimitiveExt self, Size, Align, LayoutOf, TyLayout, HasDataLayout, VariantIdx, PrimitiveExt
}; };
use rustc::ty::TypeFoldable; use rustc::ty::TypeFoldable;
use rustc_macros::HashStable;
use super::{ use super::{
GlobalId, AllocId, Allocation, Scalar, InterpResult, Pointer, PointerArithmetic, GlobalId, AllocId, Allocation, Scalar, InterpResult, Pointer, PointerArithmetic,
@ -19,7 +20,7 @@ use super::{
RawConst, Immediate, ImmTy, ScalarMaybeUndef, Operand, OpTy, MemoryKind, LocalValue, 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<Tag=(), Id=AllocId> { pub struct MemPlace<Tag=(), Id=AllocId> {
/// A place may have an integral pointer for ZSTs, and since it might /// A place may have an integral pointer for ZSTs, and since it might
/// be turned back into a reference before ever being dereferenced. /// be turned back into a reference before ever being dereferenced.
@ -32,7 +33,7 @@ pub struct MemPlace<Tag=(), Id=AllocId> {
pub meta: Option<Scalar<Tag, Id>>, pub meta: Option<Scalar<Tag, Id>>,
} }
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable)]
pub enum Place<Tag=(), Id=AllocId> { pub enum Place<Tag=(), Id=AllocId> {
/// A place referring to a value allocated in the `Memory` system. /// A place referring to a value allocated in the `Memory` system.
Ptr(MemPlace<Tag, Id>), Ptr(MemPlace<Tag, Id>),

View file

@ -19,6 +19,7 @@ use rustc::ty::layout::{Align, Size};
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_index::vec::IndexVec; use rustc_index::vec::IndexVec;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_macros::HashStable;
use syntax::ast::Mutability; use syntax::ast::Mutability;
use syntax::source_map::Span; use syntax::source_map::Span;
@ -197,21 +198,12 @@ impl_snapshot_for!(enum ScalarMaybeUndef {
Undef, Undef,
}); });
impl_stable_hash_for!(struct crate::interpret::MemPlace {
ptr,
align,
meta,
});
impl_snapshot_for!(struct MemPlace { impl_snapshot_for!(struct MemPlace {
ptr, ptr,
meta, meta,
align -> *align, // just copy alignment verbatim 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 impl<'a, Ctx> Snapshot<'a, Ctx> for Place
where Ctx: SnapshotContext<'a>, 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 { impl_snapshot_for!(enum Immediate {
Scalar(s), Scalar(s),
ScalarPair(s, t), ScalarPair(s, t),
}); });
impl_stable_hash_for!(enum crate::interpret::Operand {
Immediate(x),
Indirect(x),
});
impl_snapshot_for!(enum Operand { impl_snapshot_for!(enum Operand {
Immediate(v), Immediate(v),
Indirect(m), Indirect(m),
}); });
impl_stable_hash_for!(enum crate::interpret::LocalValue {
Dead,
Uninitialized,
Live(x),
});
impl_snapshot_for!(enum LocalValue { impl_snapshot_for!(enum LocalValue {
Dead, Dead,
Uninitialized, 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)] #[derive(Eq, PartialEq)]
struct FrameSnapshot<'a, 'tcx> { struct FrameSnapshot<'a, 'tcx> {
instance: ty::Instance<'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> impl<'b, 'mir, 'tcx> SnapshotContext<'b>
for Memory<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>> 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. /// The virtual machine state during const-evaluation at a given point in time.
/// We assume the `CompileTimeInterpreter` has no interesting extra state that /// We assume the `CompileTimeInterpreter` has no interesting extra state that
/// is worth considering here. /// is worth considering here.
#[derive(HashStable)]
struct InterpSnapshot<'mir, 'tcx> { 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>>, memory: Memory<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>,
stack: Vec<Frame<'mir, 'tcx>>, stack: Vec<Frame<'mir, 'tcx>>,
} }
@ -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> Eq for InterpSnapshot<'mir, 'tcx> {}
impl<'mir, 'tcx> PartialEq for InterpSnapshot<'mir, 'tcx> { impl<'mir, 'tcx> PartialEq for InterpSnapshot<'mir, 'tcx> {

View file

@ -987,8 +987,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
opt_expr.map_or(succ, |expr| self.propagate_through_expr(expr, succ)) opt_expr.map_or(succ, |expr| self.propagate_through_expr(expr, succ))
} }
fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode) fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode) -> LiveNode {
-> LiveNode {
debug!("propagate_through_expr: {}", self.ir.tcx.hir().hir_to_pretty_string(expr.hir_id)); debug!("propagate_through_expr: {}", self.ir.tcx.hir().hir_to_pretty_string(expr.hir_id));
match expr.kind { match expr.kind {
@ -1074,7 +1073,15 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
match target { match target {
Some(b) => self.propagate_through_opt_expr(opt_expr.as_ref().map(|e| &**e), b), 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()
}
} }
} }

View file

@ -87,10 +87,11 @@ pub fn render<T: Print, S: Print>(
</div>\ </div>\
<script src=\"{static_root_path}theme{suffix}.js\"></script>\ <script src=\"{static_root_path}theme{suffix}.js\"></script>\
<nav class=\"sub\">\ <nav class=\"sub\">\
<form class=\"search-form js-only\">\ <form class=\"search-form\">\
<div class=\"search-container\">\ <div class=\"search-container\">\
<div>{filter_crates}\ <div>{filter_crates}\
<input class=\"search-input\" name=\"search\" \ <input class=\"search-input\" name=\"search\" \
disabled \
autocomplete=\"off\" \ autocomplete=\"off\" \
spellcheck=\"false\" \ spellcheck=\"false\" \
placeholder=\"Click or press S to search, ? for more options…\" \ placeholder=\"Click or press S to search, ? for more options…\" \

View file

@ -882,7 +882,9 @@ themePicker.onblur = handleThemeButtonsBlur;
v.push_str(&minify_replacer( v.push_str(&minify_replacer(
&format!("{}\n{}", variables.join(""), all_indexes.join("\n")), &format!("{}\n{}", variables.join(""), all_indexes.join("\n")),
options.enable_minification)); options.enable_minification));
v.push_str("initSearch(searchIndex);addSearchOptions(searchIndex);"); // "addSearchOptions" has to be called first so the crate filtering can be set before the
// search might start (if it's set into the URL for example).
v.push_str("addSearchOptions(searchIndex);initSearch(searchIndex);");
cx.shared.fs.write(&dst, &v)?; cx.shared.fs.write(&dst, &v)?;
} }
if options.enable_index_page { if options.enable_index_page {

View file

@ -142,10 +142,6 @@ function getSearchElement() {
var TY_PRIMITIVE = itemTypes.indexOf("primitive"); var TY_PRIMITIVE = itemTypes.indexOf("primitive");
var TY_KEYWORD = itemTypes.indexOf("keyword"); var TY_KEYWORD = itemTypes.indexOf("keyword");
onEachLazy(document.getElementsByClassName("js-only"), function(e) {
removeClass(e, "js-only");
});
function getQueryStringParams() { function getQueryStringParams() {
var params = {}; var params = {};
window.location.search.substring(1).split("&"). window.location.search.substring(1).split("&").
@ -525,21 +521,6 @@ function getSearchElement() {
var OUTPUT_DATA = 1; var OUTPUT_DATA = 1;
var params = getQueryStringParams(); var params = getQueryStringParams();
// Set the crate filter from saved storage, if the current page has the saved crate filter.
//
// If not, ignore the crate filter -- we want to support filtering for crates on sites like
// doc.rust-lang.org where the crates may differ from page to page while on the same domain.
var savedCrate = getCurrentValue("rustdoc-saved-filter-crate");
if (savedCrate !== null) {
onEachLazy(document.getElementById("crate-search").getElementsByTagName("option"),
function(e) {
if (e.value === savedCrate) {
document.getElementById("crate-search").value = e.value;
return true;
}
});
}
// Populate search bar with query string search term when provided, // Populate search bar with query string search term when provided,
// but only if the input bar is empty. This avoid the obnoxious issue // but only if the input bar is empty. This avoid the obnoxious issue
// where you start trying to do a search, and the index loads, and // where you start trying to do a search, and the index loads, and
@ -2633,12 +2614,26 @@ function getSearchElement() {
} }
return 0; return 0;
}); });
var savedCrate = getCurrentValue("rustdoc-saved-filter-crate");
for (var i = 0; i < crates_text.length; ++i) { for (var i = 0; i < crates_text.length; ++i) {
var option = document.createElement("option"); var option = document.createElement("option");
option.value = crates_text[i]; option.value = crates_text[i];
option.innerText = crates_text[i]; option.innerText = crates_text[i];
elem.appendChild(option); elem.appendChild(option);
// Set the crate filter from saved storage, if the current page has the saved crate
// filter.
//
// If not, ignore the crate filter -- we want to support filtering for crates on sites
// like doc.rust-lang.org where the crates may differ from page to page while on the
// same domain.
if (crates_text[i] === savedCrate) {
elem.value = savedCrate;
}
} }
if (search_input) {
search_input.removeAttribute('disabled');
};
} }
window.addSearchOptions = addSearchOptions; window.addSearchOptions = addSearchOptions;

View file

@ -203,7 +203,7 @@ nav.sub {
/* Everything else */ /* Everything else */
.js-only, .hidden { .hidden {
display: none !important; display: none !important;
} }

View file

@ -177,6 +177,10 @@ a.test-arrow {
border-color: #008dfd; border-color: #008dfd;
} }
.search-focus:disabled {
background-color: #c5c4c4;
}
#crate-search + .search-input:focus { #crate-search + .search-input:focus {
box-shadow: 0 0 8px 4px #078dd8; box-shadow: 0 0 8px 4px #078dd8;
} }

View file

@ -177,6 +177,10 @@ a.test-arrow {
border-color: #66afe9; border-color: #66afe9;
} }
.search-focus:disabled {
background-color: #e6e6e6;
}
#crate-search + .search-input:focus { #crate-search + .search-input:focus {
box-shadow: 0 0 8px #078dd8; box-shadow: 0 0 8px #078dd8;
} }

View file

@ -543,7 +543,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
rustc_attr!(TEST, rustc_variance, Normal, template!(Word)), rustc_attr!(TEST, rustc_variance, Normal, template!(Word)),
rustc_attr!(TEST, rustc_layout, Normal, template!(List: "field1, field2, ...")), rustc_attr!(TEST, rustc_layout, Normal, template!(List: "field1, field2, ...")),
rustc_attr!(TEST, rustc_regions, Normal, template!(Word)), rustc_attr!(TEST, rustc_regions, Normal, template!(Word)),
rustc_attr!(TEST, rustc_error, Whitelisted, template!(Word)), rustc_attr!(
TEST, rustc_error, Whitelisted,
template!(Word, List: "delay_span_bug_from_inside_query")
),
rustc_attr!(TEST, rustc_dump_user_substs, Whitelisted, template!(Word)), rustc_attr!(TEST, rustc_dump_user_substs, Whitelisted, template!(Word)),
rustc_attr!(TEST, rustc_if_this_changed, Whitelisted, template!(Word, List: "DepNode")), rustc_attr!(TEST, rustc_if_this_changed, Whitelisted, template!(Word, List: "DepNode")),
rustc_attr!(TEST, rustc_then_this_would_need, Whitelisted, template!(List: "DepNode")), rustc_attr!(TEST, rustc_then_this_would_need, Whitelisted, template!(List: "DepNode")),

View file

@ -236,6 +236,7 @@ symbols! {
default_lib_allocator, default_lib_allocator,
default_type_parameter_fallback, default_type_parameter_fallback,
default_type_params, default_type_params,
delay_span_bug_from_inside_query,
deny, deny,
deprecated, deprecated,
deref, deref,

View file

@ -0,0 +1,8 @@
// revisions: cfail1 cfail2
// should-ice
// error-pattern: delayed span bug triggered by #[rustc_error(delay_span_bug_from_inside_query)]
#![feature(rustc_attrs)]
#[rustc_error(delay_span_bug_from_inside_query)]
fn main() {}

View file

@ -2,6 +2,7 @@
# ignore-musl # ignore-musl
# ignore-windows # ignore-windows
# ignore-macos (rust-lang/rust#66568)
# Objects are reproducible but their path is not. # Objects are reproducible but their path is not.
all: \ all: \

View file

@ -45,4 +45,4 @@ fn clause2<T>() where T: for<'a> Fn() -> <() as Foo<'a>>::Item {
} }
#[rustc_error] #[rustc_error]
fn main() { } //[ok]~ ERROR compilation successful fn main() { } //[ok]~ ERROR fatal error triggered by #[rustc_error]

View file

@ -1,4 +1,4 @@
error: compilation successful error: fatal error triggered by #[rustc_error]
--> $DIR/bound-lifetime-in-binding-only.rs:71:1 --> $DIR/bound-lifetime-in-binding-only.rs:71:1
| |
LL | fn main() { } LL | fn main() { }

View file

@ -68,4 +68,4 @@ fn ok3<T>() where for<'a> Parameterized<'a>: Foo<Item=&'a i32> {
} }
#[rustc_error] #[rustc_error]
fn main() { } //[ok]~ ERROR compilation successful fn main() { } //[ok]~ ERROR fatal error triggered by #[rustc_error]

View file

@ -1,4 +1,4 @@
error: compilation successful error: fatal error triggered by #[rustc_error]
--> $DIR/bound-lifetime-in-return-only.rs:49:1 --> $DIR/bound-lifetime-in-return-only.rs:49:1
| |
LL | fn main() { } LL | fn main() { }

View file

@ -46,4 +46,4 @@ fn ok2(_: &dyn for<'a,'b> Fn<(&'b Parameterized<'a>,), Output=&'a i32>) {
} }
#[rustc_error] #[rustc_error]
fn main() { } //[ok]~ ERROR compilation successful fn main() { } //[ok]~ ERROR fatal error triggered by #[rustc_error]

View file

@ -1,4 +1,4 @@
error: compilation successful error: fatal error triggered by #[rustc_error]
--> $DIR/project-fn-ret-contravariant.rs:50:1 --> $DIR/project-fn-ret-contravariant.rs:50:1
| |
LL | fn main() { } LL | fn main() { }

View file

@ -1,4 +1,4 @@
error: compilation successful error: fatal error triggered by #[rustc_error]
--> $DIR/project-fn-ret-contravariant.rs:50:1 --> $DIR/project-fn-ret-contravariant.rs:50:1
| |
LL | fn main() { } LL | fn main() { }

View file

@ -48,5 +48,5 @@ fn transmute<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
#[rustc_error] #[rustc_error]
fn main() { } fn main() { }
//[ok]~^ ERROR compilation successful //[ok]~^ ERROR fatal error triggered by #[rustc_error]
//[oneuse]~^^ ERROR compilation successful //[oneuse]~^^ ERROR fatal error triggered by #[rustc_error]

View file

@ -1,4 +1,4 @@
error: compilation successful error: fatal error triggered by #[rustc_error]
--> $DIR/project-fn-ret-invariant.rs:59:1 --> $DIR/project-fn-ret-invariant.rs:59:1
| |
LL | fn main() { } LL | fn main() { }

View file

@ -57,4 +57,4 @@ fn transmute<'a,'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
#[rustc_error] #[rustc_error]
fn main() { } fn main() { }
//[ok]~^ ERROR compilation successful //[ok]~^ ERROR fatal error triggered by #[rustc_error]

View file

@ -1,4 +1,4 @@
error: compilation successful error: fatal error triggered by #[rustc_error]
--> $DIR/higher-ranked-projection.rs:24:1 --> $DIR/higher-ranked-projection.rs:24:1
| |
LL | / fn main() { LL | / fn main() {

View file

@ -21,7 +21,7 @@ fn foo<U, T>(_t: T)
{} {}
#[rustc_error] #[rustc_error]
fn main() { //[good]~ ERROR compilation successful fn main() { //[good]~ ERROR fatal error triggered by #[rustc_error]
foo(()); foo(());
//[bad]~^ ERROR type mismatch //[bad]~^ ERROR type mismatch
} }

View file

@ -1,4 +1,4 @@
error: compilation successful error: fatal error triggered by #[rustc_error]
--> $DIR/hr-subtype.rs:100:1 --> $DIR/hr-subtype.rs:100:1
| |
LL | / fn main() { LL | / fn main() {

View file

@ -1,4 +1,4 @@
error: compilation successful error: fatal error triggered by #[rustc_error]
--> $DIR/hr-subtype.rs:100:1 --> $DIR/hr-subtype.rs:100:1
| |
LL | / fn main() { LL | / fn main() {

View file

@ -1,4 +1,4 @@
error: compilation successful error: fatal error triggered by #[rustc_error]
--> $DIR/hr-subtype.rs:100:1 --> $DIR/hr-subtype.rs:100:1
| |
LL | / fn main() { LL | / fn main() {

View file

@ -1,4 +1,4 @@
error: compilation successful error: fatal error triggered by #[rustc_error]
--> $DIR/hr-subtype.rs:100:1 --> $DIR/hr-subtype.rs:100:1
| |
LL | / fn main() { LL | / fn main() {

View file

@ -1,4 +1,4 @@
error: compilation successful error: fatal error triggered by #[rustc_error]
--> $DIR/hr-subtype.rs:100:1 --> $DIR/hr-subtype.rs:100:1
| |
LL | / fn main() { LL | / fn main() {

View file

@ -98,9 +98,9 @@ check! { bound_a_b_ret_a_vs_bound_a_ret_a: (for<'a,'b> fn(&'a u32, &'b u32) -> &
#[rustc_error] #[rustc_error]
fn main() { fn main() {
//[bound_a_vs_bound_a]~^ ERROR compilation successful //[bound_a_vs_bound_a]~^ ERROR fatal error triggered by #[rustc_error]
//[bound_a_vs_bound_b]~^^ ERROR compilation successful //[bound_a_vs_bound_b]~^^ ERROR fatal error triggered by #[rustc_error]
//[bound_inv_a_vs_bound_inv_b]~^^^ ERROR compilation successful //[bound_inv_a_vs_bound_inv_b]~^^^ ERROR fatal error triggered by #[rustc_error]
//[bound_co_a_vs_bound_co_b]~^^^^ ERROR compilation successful //[bound_co_a_vs_bound_co_b]~^^^^ ERROR fatal error triggered by #[rustc_error]
//[free_x_vs_free_x]~^^^^^ ERROR compilation successful //[free_x_vs_free_x]~^^^^^ ERROR fatal error triggered by #[rustc_error]
} }

View file

@ -0,0 +1,10 @@
#![feature(label_break_value)]
fn main() {
// This used to ICE during liveness check because `target_id` passed to
// `propagate_through_expr` would be the closure and not the `loop`, which wouldn't be found in
// `self.break_ln`. (#62480)
'a: {
|| break 'a //~ ERROR `break` to unknown label
}
}

View file

@ -0,0 +1,8 @@
error: `break` to unknown label
--> $DIR/issue-62480.rs:8:12
|
LL | || break 'a
| ^^^^^^^^
error: aborting due to previous error

View file

@ -7,4 +7,4 @@ extern crate test_macros;
//~^ WARN unused extern crate //~^ WARN unused extern crate
#[rustc_error] #[rustc_error]
fn main() {} //~ ERROR compilation successful fn main() {} //~ ERROR fatal error triggered by #[rustc_error]

View file

@ -10,7 +10,7 @@ note: lint level defined here
LL | #![warn(unused_extern_crates)] LL | #![warn(unused_extern_crates)]
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
error: compilation successful error: fatal error triggered by #[rustc_error]
--> $DIR/no-macro-use-attr.rs:10:1 --> $DIR/no-macro-use-attr.rs:10:1
| |
LL | fn main() {} LL | fn main() {}

View file

@ -18,7 +18,7 @@ struct Foo {
const FOO: Foo = Foo { x: 0 }; const FOO: Foo = Foo { x: 0 };
#[rustc_error] #[rustc_error]
fn main() { //[with_gate]~ ERROR compilation successful fn main() { //[with_gate]~ ERROR fatal error triggered by #[rustc_error]
let y = Foo { x: 1 }; let y = Foo { x: 1 };
match y { match y {
FOO => { } FOO => { }

View file

@ -1,4 +1,4 @@
error: compilation successful error: fatal error triggered by #[rustc_error]
--> $DIR/feature-gate.rs:21:1 --> $DIR/feature-gate.rs:21:1
| |
LL | / fn main() { LL | / fn main() {

View file

@ -2,5 +2,5 @@
#[rustc_error] #[rustc_error]
fn main() { fn main() {
//~^ ERROR compilation successful //~^ ERROR fatal error triggered by #[rustc_error]
} }

View file

@ -1,4 +1,4 @@
error: compilation successful error: fatal error triggered by #[rustc_error]
--> $DIR/rustc-error.rs:4:1 --> $DIR/rustc-error.rs:4:1
| |
LL | / fn main() { LL | / fn main() {

View file

@ -375,6 +375,8 @@ pub struct TestProps {
// If true, `rustfix` will only apply `MachineApplicable` suggestions. // If true, `rustfix` will only apply `MachineApplicable` suggestions.
pub rustfix_only_machine_applicable: bool, pub rustfix_only_machine_applicable: bool,
pub assembly_output: Option<String>, pub assembly_output: Option<String>,
// If true, the test is expected to ICE
pub should_ice: bool,
} }
impl TestProps { impl TestProps {
@ -413,6 +415,7 @@ impl TestProps {
run_rustfix: false, run_rustfix: false,
rustfix_only_machine_applicable: false, rustfix_only_machine_applicable: false,
assembly_output: None, assembly_output: None,
should_ice: false,
} }
} }
@ -463,6 +466,10 @@ impl TestProps {
self.pp_exact = config.parse_pp_exact(ln, testfile); self.pp_exact = config.parse_pp_exact(ln, testfile);
} }
if !self.should_ice {
self.should_ice = config.parse_should_ice(ln);
}
if !self.build_aux_docs { if !self.build_aux_docs {
self.build_aux_docs = config.parse_build_aux_docs(ln); self.build_aux_docs = config.parse_build_aux_docs(ln);
} }
@ -577,6 +584,9 @@ impl TestProps {
_ => 1, _ => 1,
}; };
} }
if self.should_ice {
self.failure_status = 101;
}
for key in &["RUST_TEST_NOCAPTURE", "RUST_TEST_THREADS"] { for key in &["RUST_TEST_NOCAPTURE", "RUST_TEST_THREADS"] {
if let Ok(val) = env::var(key) { if let Ok(val) = env::var(key) {
@ -687,6 +697,9 @@ fn iter_header(testfile: &Path, cfg: Option<&str>, it: &mut dyn FnMut(&str)) {
} }
impl Config { impl Config {
fn parse_should_ice(&self, line: &str) -> bool {
self.parse_name_directive(line, "should-ice")
}
fn parse_error_pattern(&self, line: &str) -> Option<String> { fn parse_error_pattern(&self, line: &str) -> Option<String> {
self.parse_name_value_directive(line, "error-pattern") self.parse_name_value_directive(line, "error-pattern")
} }

View file

@ -298,6 +298,12 @@ impl<'test> TestCx<'test> {
/// Code executed for each revision in turn (or, if there are no /// Code executed for each revision in turn (or, if there are no
/// revisions, exactly once, with revision == None). /// revisions, exactly once, with revision == None).
fn run_revision(&self) { fn run_revision(&self) {
if self.props.should_ice {
if self.config.mode != CompileFail &&
self.config.mode != Incremental {
self.fatal("cannot use should-ice in a test that is not cfail");
}
}
match self.config.mode { match self.config.mode {
CompileFail => self.run_cfail_test(), CompileFail => self.run_cfail_test(),
RunFail => self.run_rfail_test(), RunFail => self.run_rfail_test(),
@ -383,7 +389,7 @@ impl<'test> TestCx<'test> {
fn run_cfail_test(&self) { fn run_cfail_test(&self) {
let proc_res = self.compile_test(); let proc_res = self.compile_test();
self.check_if_test_should_compile(&proc_res); self.check_if_test_should_compile(&proc_res);
self.check_no_compiler_crash(&proc_res); self.check_no_compiler_crash(&proc_res, self.props.should_ice);
let output_to_check = self.get_output(&proc_res); let output_to_check = self.get_output(&proc_res);
let expected_errors = errors::load_errors(&self.testpaths.file, self.revision); let expected_errors = errors::load_errors(&self.testpaths.file, self.revision);
@ -395,6 +401,12 @@ impl<'test> TestCx<'test> {
} else { } else {
self.check_error_patterns(&output_to_check, &proc_res); self.check_error_patterns(&output_to_check, &proc_res);
} }
if self.props.should_ice {
match proc_res.status.code() {
Some(101) => (),
_ => self.fatal("expected ICE"),
}
}
self.check_forbid_output(&output_to_check, &proc_res); self.check_forbid_output(&output_to_check, &proc_res);
} }
@ -1402,9 +1414,11 @@ impl<'test> TestCx<'test> {
} }
} }
fn check_no_compiler_crash(&self, proc_res: &ProcRes) { fn check_no_compiler_crash(&self, proc_res: &ProcRes, should_ice: bool) {
match proc_res.status.code() { match proc_res.status.code() {
Some(101) => self.fatal_proc_rec("compiler encountered internal error", proc_res), Some(101) if !should_ice => {
self.fatal_proc_rec("compiler encountered internal error", proc_res)
}
None => self.fatal_proc_rec("compiler terminated by signal", proc_res), None => self.fatal_proc_rec("compiler terminated by signal", proc_res),
_ => (), _ => (),
} }
@ -2518,7 +2532,7 @@ impl<'test> TestCx<'test> {
self.fatal_proc_rec("compilation failed!", &proc_res); self.fatal_proc_rec("compilation failed!", &proc_res);
} }
self.check_no_compiler_crash(&proc_res); self.check_no_compiler_crash(&proc_res, self.props.should_ice);
const PREFIX: &'static str = "MONO_ITEM "; const PREFIX: &'static str = "MONO_ITEM ";
const CGU_MARKER: &'static str = "@@"; const CGU_MARKER: &'static str = "@@";
@ -2774,8 +2788,14 @@ impl<'test> TestCx<'test> {
} }
if revision.starts_with("rpass") { if revision.starts_with("rpass") {
if revision_cx.props.should_ice {
revision_cx.fatal("can only use should-ice in cfail tests");
}
revision_cx.run_rpass_test(); revision_cx.run_rpass_test();
} else if revision.starts_with("rfail") { } else if revision.starts_with("rfail") {
if revision_cx.props.should_ice {
revision_cx.fatal("can only use should-ice in cfail tests");
}
revision_cx.run_rfail_test(); revision_cx.run_rfail_test();
} else if revision.starts_with("cfail") { } else if revision.starts_with("cfail") {
revision_cx.run_cfail_test(); revision_cx.run_cfail_test();