//! Type context book-keeping.
use crate::arena::Arena;
-use crate::dep_graph::DepGraph;
-use crate::hir::exports::ExportMap;
+use crate::dep_graph::{DepGraph, DepNode};
use crate::hir::place::Place as HirPlace;
use crate::ich::{NodeIdHashingMode, StableHashingContext};
use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos};
use crate::lint::{struct_lint_level, LintDiagnosticBuilder, LintLevelSource};
use crate::middle;
-use crate::middle::cstore::{CrateStoreDyn, EncodedMetadata};
-use crate::middle::resolve_lifetime::{self, ObjectLifetimeDefault};
+use crate::middle::cstore::EncodedMetadata;
+use crate::middle::resolve_lifetime::{self, LifetimeScopeForPath, ObjectLifetimeDefault};
use crate::middle::stability;
use crate::mir::interpret::{self, Allocation, ConstValue, Scalar};
use crate::mir::{Body, Field, Local, Place, PlaceElem, ProjectionKind, Promoted};
+use crate::thir::Thir;
use crate::traits;
use crate::ty::query::{self, TyCtxtAt};
use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSubsts};
use crate::ty::TyKind::*;
use crate::ty::{
- self, AdtDef, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig, Const, ConstVid,
- DefIdTree, ExistentialPredicate, FloatTy, FloatVar, FloatVid, GenericParamDefKind, InferConst,
- InferTy, IntTy, IntVar, IntVid, List, ParamConst, ParamTy, PolyFnSig, Predicate,
- PredicateInner, PredicateKind, ProjectionTy, Region, RegionKind, ReprOptions,
- TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy, Visibility,
+ self, AdtDef, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig,
+ ClosureSizeProfileData, Const, ConstVid, DefIdTree, ExistentialPredicate, FloatTy, FloatVar,
+ FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List, ParamConst,
+ ParamTy, PolyFnSig, Predicate, PredicateInner, PredicateKind, ProjectionTy, Region, RegionKind,
+ ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy,
};
use rustc_ast as ast;
-use rustc_ast::expand::allocator::AllocatorKind;
use rustc_attr as attr;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::profiling::SelfProfilerRef;
use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
-use rustc_data_structures::stable_hasher::{
- hash_stable_hashmap, HashStable, StableHasher, StableVec,
-};
+use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::steal::Steal;
use rustc_data_structures::sync::{self, Lock, Lrc, WorkerLocal};
use rustc_errors::ErrorReported;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LOCAL_CRATE};
-use rustc_hir::definitions::Definitions;
use rustc_hir::intravisit::Visitor;
use rustc_hir::lang_items::LangItem;
use rustc_hir::{
- Constness, HirId, ItemKind, ItemLocalId, ItemLocalMap, ItemLocalSet, Node, TraitCandidate,
+ Constness, ExprKind, HirId, ImplItemKind, ItemKind, ItemLocalId, ItemLocalMap, ItemLocalSet,
+ Node, TraitCandidate, TraitItemKind,
};
use rustc_index::vec::{Idx, IndexVec};
use rustc_macros::HashStable;
+use rustc_middle::mir::FakeReadCause;
use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
use rustc_session::config::{BorrowckMode, CrateType, OutputFilenames};
use rustc_session::lint::{Level, Lint};
+use rustc_session::Limit;
use rustc_session::Session;
-use rustc_span::source_map::MultiSpan;
-use rustc_span::symbol::{kw, sym, Symbol};
+use rustc_span::def_id::{DefPathHash, StableCrateId};
+use rustc_span::source_map::{MultiSpan, SourceMap};
+use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{Span, DUMMY_SP};
use rustc_target::abi::{Layout, TargetDataLayout, VariantIdx};
use rustc_target::spec::abi;
use std::ops::{Bound, Deref};
use std::sync::Arc;
+pub trait OnDiskCache<'tcx>: rustc_data_structures::sync::Sync {
+ /// Creates a new `OnDiskCache` instance from the serialized data in `data`.
+ fn new(sess: &'tcx Session, data: Vec<u8>, start_pos: usize) -> Self
+ where
+ Self: Sized;
+
+ fn new_empty(source_map: &'tcx SourceMap) -> Self
+ where
+ Self: Sized;
+
+ /// Converts a `DefPathHash` to its corresponding `DefId` in the current compilation
+ /// session, if it still exists. This is used during incremental compilation to
+ /// turn a deserialized `DefPathHash` into its current `DefId`.
+ fn def_path_hash_to_def_id(
+ &self,
+ tcx: TyCtxt<'tcx>,
+ def_path_hash: DefPathHash,
+ ) -> Option<DefId>;
+
+ /// If the given `dep_node`'s hash still exists in the current compilation,
+ /// and its current `DefId` is foreign, calls `store_foreign_def_id` with it.
+ ///
+ /// Normally, `store_foreign_def_id_hash` can be called directly by
+ /// the dependency graph when we construct a `DepNode`. However,
+ /// when we re-use a deserialized `DepNode` from the previous compilation
+ /// session, we only have the `DefPathHash` available. This method is used
+ /// to that any `DepNode` that we re-use has a `DefPathHash` -> `RawId` written
+ /// out for usage in the next compilation session.
+ fn register_reused_dep_node(&self, tcx: TyCtxt<'tcx>, dep_node: &DepNode);
+ fn store_foreign_def_id_hash(&self, def_id: DefId, hash: DefPathHash);
+
+ fn serialize(&self, tcx: TyCtxt<'tcx>, encoder: &mut FileEncoder) -> FileEncodeResult;
+}
+
/// A type that is not publicly constructable. This prevents people from making [`TyKind::Error`]s
/// except through the error-reporting functions on a [`tcx`][TyCtxt].
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
substs: InternedSet<'tcx, InternalSubsts<'tcx>>,
canonical_var_infos: InternedSet<'tcx, List<CanonicalVarInfo<'tcx>>>,
region: InternedSet<'tcx, RegionKind>,
- poly_existential_predicates: InternedSet<'tcx, List<ty::Binder<ExistentialPredicate<'tcx>>>>,
+ poly_existential_predicates:
+ InternedSet<'tcx, List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>>>,
predicate: InternedSet<'tcx, PredicateInner<'tcx>>,
predicates: InternedSet<'tcx, List<Predicate<'tcx>>>,
projs: InternedSet<'tcx, List<ProjectionKind>>,
place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
const_: InternedSet<'tcx, Const<'tcx>>,
+ /// Const allocations.
+ allocation: InternedSet<'tcx, Allocation>,
+ bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
}
impl<'tcx> CtxtInterners<'tcx> {
projs: Default::default(),
place_elems: Default::default(),
const_: Default::default(),
+ allocation: Default::default(),
+ bound_variable_kinds: Default::default(),
}
}
}
#[inline(never)]
- fn intern_predicate(&self, kind: Binder<PredicateKind<'tcx>>) -> &'tcx PredicateInner<'tcx> {
+ fn intern_predicate(
+ &self,
+ kind: Binder<'tcx, PredicateKind<'tcx>>,
+ ) -> &'tcx PredicateInner<'tcx> {
self.predicate
.intern(kind, |kind| {
let flags = super::flags::FlagComputation::for_predicate(kind);
/// would be in a different frame of reference and using its `local_id`
/// would result in lookup errors, or worse, in silently wrong data being
/// stored/returned.
+#[inline]
fn validate_hir_id_for_typeck_results(hir_owner: LocalDefId, hir_id: hir::HirId) {
if hir_id.owner != hir_owner {
- ty::tls::with(|tcx| {
- bug!(
- "node {} with HirId::owner {:?} cannot be placed in TypeckResults with hir_owner {:?}",
- tcx.hir().node_to_string(hir_id),
- hir_id.owner,
- hir_owner
- )
- });
+ invalid_hir_id_for_typeck_results(hir_owner, hir_id);
}
}
+#[cold]
+#[inline(never)]
+fn invalid_hir_id_for_typeck_results(hir_owner: LocalDefId, hir_id: hir::HirId) {
+ ty::tls::with(|tcx| {
+ bug!(
+ "node {} with HirId::owner {:?} cannot be placed in TypeckResults with hir_owner {:?}",
+ tcx.hir().node_to_string(hir_id),
+ hir_id.owner,
+ hir_owner
+ )
+ });
+}
+
impl<'a, V> LocalTableInContext<'a, V> {
pub fn contains_key(&self, id: hir::HirId) -> bool {
validate_hir_id_for_typeck_results(self.hir_owner, id);
}
}
-/// All information necessary to validate and reveal an `impl Trait`.
-#[derive(TyEncodable, TyDecodable, Debug, HashStable)]
-pub struct ResolvedOpaqueTy<'tcx> {
- /// The revealed type as seen by this function.
- pub concrete_type: Ty<'tcx>,
- /// Generic parameters on the opaque type as passed by this function.
- /// For `type Foo<A, B> = impl Bar<A, B>; fn foo<T, U>() -> Foo<T, U> { .. }`
- /// this is `[T, U]`, not `[A, B]`.
- pub substs: SubstsRef<'tcx>,
-}
-
/// Whenever a value may be live across a generator yield, the type of that value winds up in the
/// `GeneratorInteriorTypeCause` struct. This struct adds additional information about such
/// captured types that can be useful for diagnostics. In particular, it stores the span that
/// <https://github.com/rust-lang/rfcs/blob/master/text/2005-match-ergonomics.md#definitions>
pat_adjustments: ItemLocalMap<Vec<Ty<'tcx>>>,
- /// Borrows
- pub upvar_capture_map: ty::UpvarCaptureMap<'tcx>,
-
/// Records the reasons that we picked the kind of each closure;
/// not all closures are present in the map.
closure_kind_origins: ItemLocalMap<(Span, HirPlace<'tcx>)>,
/// (including late-bound regions) are replaced with free
/// equivalents. This table is not used in codegen (since regions
/// are erased there) and hence is not serialized to metadata.
+ ///
+ /// This table also contains the "revealed" values for any `impl Trait`
+ /// that appear in the signature and whose values are being inferred
+ /// by this function.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// fn foo(x: &u32) -> impl Debug { *x }
+ /// ```
+ ///
+ /// The function signature here would be:
+ ///
+ /// ```
+ /// for<'a> fn(&'a u32) -> Foo
+ /// ```
+ ///
+ /// where `Foo` is an opaque type created for this function.
+ ///
+ ///
+ /// The *liberated* form of this would be
+ ///
+ /// ```
+ /// fn(&'a u32) -> u32
+ /// ```
+ ///
+ /// Note that `'a` is not bound (it would be an `ReFree`) and
+ /// that the `Foo` opaque type is replaced by its hidden type.
liberated_fn_sigs: ItemLocalMap<ty::FnSig<'tcx>>,
/// For each FRU expression, record the normalized types of the fields
/// All the opaque types that are restricted to concrete types
/// by this function.
- pub concrete_opaque_types: FxHashMap<DefId, ResolvedOpaqueTy<'tcx>>,
-
- /// Given the closure ID this map provides the list of UpvarIDs used by it.
- /// The upvarID contains the HIR node ID and it also contains the full path
- /// leading to the member of the struct or tuple that is used instead of the
- /// entire variable.
- pub closure_captures: ty::UpvarListMap,
+ pub concrete_opaque_types: FxHashSet<DefId>,
/// Tracks the minimum captures required for a closure;
/// see `MinCaptureInformationMap` for more details.
pub closure_min_captures: ty::MinCaptureInformationMap<'tcx>,
+ /// Tracks the fake reads required for a closure and the reason for the fake read.
+ /// When performing pattern matching for closures, there are times we don't end up
+ /// reading places that are mentioned in a closure (because of _ patterns). However,
+ /// to ensure the places are initialized, we introduce fake reads.
+ /// Consider these two examples:
+ /// ``` (discriminant matching with only wildcard arm)
+ /// let x: u8;
+ /// let c = || match x { _ => () };
+ /// ```
+ /// In this example, we don't need to actually read/borrow `x` in `c`, and so we don't
+ /// want to capture it. However, we do still want an error here, because `x` should have
+ /// to be initialized at the point where c is created. Therefore, we add a "fake read"
+ /// instead.
+ /// ``` (destructured assignments)
+ /// let c = || {
+ /// let (t1, t2) = t;
+ /// }
+ /// ```
+ /// In the second example, we capture the disjoint fields of `t` (`t.0` & `t.1`), but
+ /// we never capture `t`. This becomes an issue when we build MIR as we require
+ /// information on `t` in order to create place `t.0` and `t.1`. We can solve this
+ /// issue by fake reading `t`.
+ pub closure_fake_reads: FxHashMap<DefId, Vec<(HirPlace<'tcx>, FakeReadCause, hir::HirId)>>,
+
/// Stores the type, expression, span and optional scope span of all types
/// that are live across the yield of this generator (if a generator).
- pub generator_interior_types: ty::Binder<Vec<GeneratorInteriorTypeCause<'tcx>>>,
+ pub generator_interior_types: ty::Binder<'tcx, Vec<GeneratorInteriorTypeCause<'tcx>>>,
/// We sometimes treat byte string literals (which are of type `&[u8; N]`)
/// as `&[u8]`, depending on the pattern in which they are used.
/// This hashset records all instances where we behave
/// like this to allow `const_to_pat` to reliably handle this situation.
pub treat_byte_string_as_slice: ItemLocalSet,
+
+ /// Contains the data for evaluating the effect of feature `capture_disjoint_fields`
+ /// on closure size.
+ pub closure_size_eval: FxHashMap<DefId, ClosureSizeProfileData<'tcx>>,
}
impl<'tcx> TypeckResults<'tcx> {
adjustments: Default::default(),
pat_binding_modes: Default::default(),
pat_adjustments: Default::default(),
- upvar_capture_map: Default::default(),
closure_kind_origins: Default::default(),
liberated_fn_sigs: Default::default(),
fru_field_types: Default::default(),
used_trait_imports: Lrc::new(Default::default()),
tainted_by_errors: None,
concrete_opaque_types: Default::default(),
- closure_captures: Default::default(),
closure_min_captures: Default::default(),
+ closure_fake_reads: Default::default(),
generator_interior_types: ty::Binder::dummy(Default::default()),
treat_byte_string_as_slice: Default::default(),
+ closure_size_eval: Default::default(),
}
}
.flatten()
}
- pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> ty::UpvarCapture<'tcx> {
- self.upvar_capture_map[&upvar_id]
- }
-
pub fn closure_kind_origins(&self) -> LocalTableInContext<'_, (Span, HirPlace<'tcx>)> {
LocalTableInContext { hir_owner: self.hir_owner, data: &self.closure_kind_origins }
}
ref adjustments,
ref pat_binding_modes,
ref pat_adjustments,
- ref upvar_capture_map,
ref closure_kind_origins,
ref liberated_fn_sigs,
ref fru_field_types,
-
ref coercion_casts,
-
ref used_trait_imports,
tainted_by_errors,
ref concrete_opaque_types,
- ref closure_captures,
ref closure_min_captures,
+ ref closure_fake_reads,
ref generator_interior_types,
ref treat_byte_string_as_slice,
+ ref closure_size_eval,
} = *self;
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
+ hcx.local_def_path_hash(hir_owner);
+
type_dependent_defs.hash_stable(hcx, hasher);
field_indices.hash_stable(hcx, hasher);
user_provided_types.hash_stable(hcx, hasher);
adjustments.hash_stable(hcx, hasher);
pat_binding_modes.hash_stable(hcx, hasher);
pat_adjustments.hash_stable(hcx, hasher);
- hash_stable_hashmap(hcx, hasher, upvar_capture_map, |up_var_id, hcx| {
- let ty::UpvarId { var_path, closure_expr_id } = *up_var_id;
-
- assert_eq!(var_path.hir_id.owner, hir_owner);
-
- (
- hcx.local_def_path_hash(var_path.hir_id.owner),
- var_path.hir_id.local_id,
- hcx.local_def_path_hash(closure_expr_id),
- )
- });
closure_kind_origins.hash_stable(hcx, hasher);
liberated_fn_sigs.hash_stable(hcx, hasher);
used_trait_imports.hash_stable(hcx, hasher);
tainted_by_errors.hash_stable(hcx, hasher);
concrete_opaque_types.hash_stable(hcx, hasher);
- closure_captures.hash_stable(hcx, hasher);
closure_min_captures.hash_stable(hcx, hasher);
+ closure_fake_reads.hash_stable(hcx, hasher);
generator_interior_types.hash_stable(hcx, hasher);
treat_byte_string_as_slice.hash_stable(hcx, hasher);
+ closure_size_eval.hash_stable(hcx, hasher);
})
}
}
return false;
}
- user_substs.substs.iter().zip(BoundVar::new(0)..).all(|(kind, cvar)| {
+ iter::zip(user_substs.substs, BoundVar::new(0)..).all(|(kind, cvar)| {
match kind.unpack() {
GenericArgKind::Type(ty) => match ty.kind() {
ty::Bound(debruijn, b) => {
ty::ReLateBound(debruijn, br) => {
// We only allow a `ty::INNERMOST` index in substitutions.
assert_eq!(*debruijn, ty::INNERMOST);
- cvar == br.assert_bound_var()
+ cvar == br.var
}
_ => false,
},
interners: CtxtInterners<'tcx>,
- pub(crate) cstore: Box<CrateStoreDyn>,
-
pub sess: &'tcx Session,
/// This only ever stores a `LintStore` but we don't want a dependency on that type here.
/// Common consts, pre-interned for your convenience.
pub consts: CommonConsts<'tcx>,
- /// Visibilities produced by resolver.
- pub visibilities: FxHashMap<LocalDefId, Visibility>,
-
- /// Resolutions of `extern crate` items produced by resolver.
- extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
-
- /// Map indicating what traits are in scope for places where this
- /// is relevant; generated by resolve.
- trait_map: FxHashMap<LocalDefId, FxHashMap<ItemLocalId, StableVec<TraitCandidate>>>,
-
- /// Export map produced by name resolution.
- export_map: ExportMap<LocalDefId>,
+ /// Output of the resolver.
+ pub(crate) untracked_resolutions: ty::ResolverOutputs,
pub(crate) untracked_crate: &'tcx hir::Crate<'tcx>,
- pub(crate) definitions: &'tcx Definitions,
- pub queries: query::Queries<'tcx>,
+ /// This provides access to the incremental compilation on-disk cache for query results.
+ /// Do not access this directly. It is only meant to be used by
+ /// `DepGraph::try_mark_green()` and the query infrastructure.
+ /// This is `None` if we are not incremental compilation mode
+ pub on_disk_cache: Option<&'tcx dyn OnDiskCache<'tcx>>,
- maybe_unused_trait_imports: FxHashSet<LocalDefId>,
- maybe_unused_extern_crates: Vec<(LocalDefId, Span)>,
- /// A map of glob use to a set of names it actually imports. Currently only
- /// used in save-analysis.
- pub(crate) glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
- /// Extern prelude entries. The value is `true` if the entry was introduced
- /// via `extern crate` item and not `--extern` option or compiler built-in.
- pub extern_prelude: FxHashMap<Symbol, bool>,
+ pub queries: &'tcx dyn query::QueryEngine<'tcx>,
+ pub query_caches: query::QueryCaches<'tcx>,
// Internal caches for metadata decoding. No need to track deps on this.
pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
/// The definite name of the current crate after taking into account
/// attributes, commandline parameters, etc.
- pub crate_name: Symbol,
+ crate_name: Symbol,
/// Data layout specification for the current target.
pub data_layout: TargetDataLayout,
/// `#[rustc_const_stable]` and `#[rustc_const_unstable]` attributes
const_stability_interner: ShardedHashMap<&'tcx attr::ConstStability, ()>,
- /// Stores the value of constants (and deduplicates the actual memory)
- allocation_interner: ShardedHashMap<&'tcx Allocation, ()>,
-
/// Stores memory for globals (statics/consts).
pub(crate) alloc_map: Lock<interpret::AllocMap<'tcx>>,
}
}
+ pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
+ self.arena.alloc(Steal::new(thir))
+ }
+
pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
self.arena.alloc(Steal::new(mir))
}
}
pub fn intern_const_alloc(self, alloc: Allocation) -> &'tcx Allocation {
- self.allocation_interner.intern(alloc, |alloc| self.arena.alloc(alloc))
+ self.interners
+ .allocation
+ .intern(alloc, |alloc| Interned(self.interners.arena.alloc(alloc)))
+ .0
}
/// Allocates a read-only byte or string literal for `mir::interpret`.
pub fn allocate_bytes(self, bytes: &[u8]) -> interpret::AllocId {
// Create an allocation that just contains these bytes.
- let alloc = interpret::Allocation::from_byte_aligned_bytes(bytes);
+ let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes);
let alloc = self.intern_const_alloc(alloc);
self.create_memory_alloc(alloc)
}
pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound<u128>, Bound<u128>) {
let attrs = self.get_attrs(def_id);
let get = |name| {
- let attr = match attrs.iter().find(|a| self.sess.check_name(a, name)) {
+ let attr = match attrs.iter().find(|a| a.has_name(name)) {
Some(attr) => attr,
None => return Bound::Unbounded,
};
debug!("layout_scalar_valid_range: attr={:?}", attr);
- for meta in attr.meta_item_list().expect("rustc_layout_scalar_valid_range takes args") {
- match meta.literal().expect("attribute takes lit").kind {
- ast::LitKind::Int(a, _) => return Bound::Included(a),
- _ => span_bug!(attr.span, "rustc_layout_scalar_valid_range expects int arg"),
- }
+ if let Some(
+ &[ast::NestedMetaItem::Literal(ast::Lit { kind: ast::LitKind::Int(a, _), .. })],
+ ) = attr.meta_item_list().as_deref()
+ {
+ Bound::Included(a)
+ } else {
+ self.sess
+ .delay_span_bug(attr.span, "invalid rustc_layout_scalar_valid_range attribute");
+ Bound::Unbounded
}
- span_bug!(attr.span, "no arguments to `rustc_layout_scalar_valid_range` attribute");
};
(
get(sym::rustc_layout_scalar_valid_range_start),
pub fn create_global_ctxt(
s: &'tcx Session,
lint_store: Lrc<dyn Any + sync::Send + sync::Sync>,
- local_providers: ty::query::Providers,
- extern_providers: ty::query::Providers,
arena: &'tcx WorkerLocal<Arena<'tcx>>,
resolutions: ty::ResolverOutputs,
krate: &'tcx hir::Crate<'tcx>,
- definitions: &'tcx Definitions,
dep_graph: DepGraph,
- on_disk_query_result_cache: Option<query::OnDiskCache<'tcx>>,
+ on_disk_cache: Option<&'tcx dyn OnDiskCache<'tcx>>,
+ queries: &'tcx dyn query::QueryEngine<'tcx>,
crate_name: &str,
- output_filenames: &OutputFilenames,
+ output_filenames: OutputFilenames,
) -> GlobalCtxt<'tcx> {
let data_layout = TargetDataLayout::parse(&s.target).unwrap_or_else(|err| {
s.fatal(&err);
let common_types = CommonTypes::new(&interners);
let common_lifetimes = CommonLifetimes::new(&interners);
let common_consts = CommonConsts::new(&interners, &common_types);
- let cstore = resolutions.cstore;
- let crates = cstore.crates_untracked();
- let max_cnum = crates.iter().map(|c| c.as_usize()).max().unwrap_or(0);
- let mut providers = IndexVec::from_elem_n(extern_providers, max_cnum + 1);
- providers[LOCAL_CRATE] = local_providers;
-
- let mut trait_map: FxHashMap<_, FxHashMap<_, _>> = FxHashMap::default();
- for (hir_id, v) in krate.trait_map.iter() {
- let map = trait_map.entry(hir_id.owner).or_default();
- map.insert(hir_id.local_id, StableVec::new(v.to_vec()));
- }
GlobalCtxt {
sess: s,
lint_store,
- cstore,
arena,
interners,
dep_graph,
+ untracked_resolutions: resolutions,
prof: s.prof.clone(),
types: common_types,
lifetimes: common_lifetimes,
consts: common_consts,
- visibilities: resolutions.visibilities,
- extern_crate_map: resolutions.extern_crate_map,
- trait_map,
- export_map: resolutions.export_map,
- maybe_unused_trait_imports: resolutions.maybe_unused_trait_imports,
- maybe_unused_extern_crates: resolutions.maybe_unused_extern_crates,
- glob_map: resolutions.glob_map,
- extern_prelude: resolutions.extern_prelude,
untracked_crate: krate,
- definitions,
- queries: query::Queries::new(providers, extern_providers, on_disk_query_result_cache),
+ on_disk_cache,
+ queries,
+ query_caches: query::QueryCaches::default(),
ty_rcache: Default::default(),
pred_rcache: Default::default(),
selection_cache: Default::default(),
layout_interner: Default::default(),
stability_interner: Default::default(),
const_stability_interner: Default::default(),
- allocation_interner: Default::default(),
alloc_map: Lock::new(interpret::AllocMap::new()),
- output_filenames: Arc::new(output_filenames.clone()),
+ output_filenames: Arc::new(output_filenames),
}
}
}
pub fn lib_features(self) -> &'tcx middle::lib_features::LibFeatures {
- self.get_lib_features(LOCAL_CRATE)
+ self.get_lib_features(())
}
/// Obtain all lang items of this crate and all dependencies (recursively)
pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems {
- self.get_lang_items(LOCAL_CRATE)
+ self.get_lang_items(())
}
/// Obtain the given diagnostic item's `DefId`. Use `is_diagnostic_item` if you just want to
/// compare against another `DefId`, since `is_diagnostic_item` is cheaper.
pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
- self.all_diagnostic_items(LOCAL_CRATE).get(&name).copied()
+ self.all_diagnostic_items(()).get(&name).copied()
}
/// Check whether the diagnostic item with the given `name` has the given `DefId`.
}
pub fn stability(self) -> &'tcx stability::Index<'tcx> {
- self.stability_index(LOCAL_CRATE)
- }
-
- pub fn crates(self) -> &'tcx [CrateNum] {
- self.all_crate_nums(LOCAL_CRATE)
- }
-
- pub fn allocator_kind(self) -> Option<AllocatorKind> {
- self.cstore.allocator_kind()
+ self.stability_index(())
}
pub fn features(self) -> &'tcx rustc_feature::Features {
- self.features_query(LOCAL_CRATE)
+ self.features_query(())
}
pub fn def_key(self, id: DefId) -> rustc_hir::definitions::DefKey {
- if let Some(id) = id.as_local() { self.hir().def_key(id) } else { self.cstore.def_key(id) }
+ // Accessing the DefKey is ok, since it is part of DefPathHash.
+ if let Some(id) = id.as_local() {
+ self.untracked_resolutions.definitions.def_key(id)
+ } else {
+ self.untracked_resolutions.cstore.def_key(id)
+ }
}
/// Converts a `DefId` into its fully expanded `DefPath` (every
/// Note that if `id` is not local to this crate, the result will
/// be a non-local `DefPath`.
pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
+ // Accessing the DefPath is ok, since it is part of DefPathHash.
if let Some(id) = id.as_local() {
- self.hir().def_path(id)
+ self.untracked_resolutions.definitions.def_path(id)
} else {
- self.cstore.def_path(id)
+ self.untracked_resolutions.cstore.def_path(id)
}
}
- /// Returns whether or not the crate with CrateNum 'cnum'
- /// is marked as a private dependency
- pub fn is_private_dep(self, cnum: CrateNum) -> bool {
- if cnum == LOCAL_CRATE { false } else { self.cstore.crate_is_private_dep_untracked(cnum) }
- }
-
#[inline]
pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
+ // Accessing the DefPathHash is ok, it is incr. comp. stable.
if let Some(def_id) = def_id.as_local() {
- self.definitions.def_path_hash(def_id)
+ self.untracked_resolutions.definitions.def_path_hash(def_id)
} else {
- self.cstore.def_path_hash(def_id)
+ self.untracked_resolutions.cstore.def_path_hash(def_id)
+ }
+ }
+
+ #[inline]
+ pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
+ if crate_num == LOCAL_CRATE {
+ self.sess.local_stable_crate_id()
+ } else {
+ self.untracked_resolutions.cstore.stable_crate_id(crate_num)
}
}
pub fn def_path_debug_str(self, def_id: DefId) -> String {
// We are explicitly not going through queries here in order to get
- // crate name and disambiguator since this code is called from debug!()
+ // crate name and stable crate id since this code is called from debug!()
// statements within the query system and we'd run into endless
// recursion otherwise.
- let (crate_name, crate_disambiguator) = if def_id.is_local() {
- (self.crate_name, self.sess.local_crate_disambiguator())
+ let (crate_name, stable_crate_id) = if def_id.is_local() {
+ (self.crate_name, self.sess.local_stable_crate_id())
} else {
- (
- self.cstore.crate_name_untracked(def_id.krate),
- self.cstore.crate_disambiguator_untracked(def_id.krate),
- )
+ let cstore = &self.untracked_resolutions.cstore;
+ (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
};
format!(
"{}[{}]{}",
crate_name,
- // Don't print the whole crate disambiguator. That's just
+ // Don't print the whole stable crate id. That's just
// annoying in debug output.
- &(crate_disambiguator.to_fingerprint().to_hex())[..4],
+ &(format!("{:08x}", stable_crate_id.to_u64()))[..4],
self.def_path(def_id).to_string_no_crate_verbose()
)
}
- pub fn metadata_encoding_version(self) -> Vec<u8> {
- self.cstore.metadata_encoding_version().to_vec()
- }
-
pub fn encode_metadata(self) -> EncodedMetadata {
let _prof_timer = self.prof.verbose_generic_activity("generate_crate_metadata");
- self.cstore.encode_metadata(self)
+ self.untracked_resolutions.cstore.encode_metadata(self)
+ }
+
+ /// Note that this is *untracked* and should only be used within the query
+ /// system if the result is otherwise tracked through queries
+ pub fn cstore_untracked(self) -> &'tcx ty::CrateStoreDyn {
+ &*self.untracked_resolutions.cstore
}
- // Note that this is *untracked* and should only be used within the query
- // system if the result is otherwise tracked through queries
- pub fn cstore_as_any(self) -> &'tcx dyn Any {
- self.cstore.as_any()
+ /// Note that this is *untracked* and should only be used within the query
+ /// system if the result is otherwise tracked through queries
+ pub fn definitions_untracked(self) -> &'tcx hir::definitions::Definitions {
+ &self.untracked_resolutions.definitions
}
#[inline(always)]
pub fn create_stable_hashing_context(self) -> StableHashingContext<'tcx> {
let krate = self.gcx.untracked_crate;
+ let resolutions = &self.gcx.untracked_resolutions;
- StableHashingContext::new(self.sess, krate, self.definitions, &*self.cstore)
+ StableHashingContext::new(self.sess, krate, &resolutions.definitions, &*resolutions.cstore)
}
#[inline(always)]
pub fn create_no_span_stable_hashing_context(self) -> StableHashingContext<'tcx> {
let krate = self.gcx.untracked_crate;
+ let resolutions = &self.gcx.untracked_resolutions;
- StableHashingContext::ignore_spans(self.sess, krate, self.definitions, &*self.cstore)
+ StableHashingContext::ignore_spans(
+ self.sess,
+ krate,
+ &resolutions.definitions,
+ &*resolutions.cstore,
+ )
}
pub fn serialize_query_result_cache(self, encoder: &mut FileEncoder) -> FileEncodeResult {
- self.queries.on_disk_cache.as_ref().map_or(Ok(()), |c| c.serialize(self, encoder))
+ self.on_disk_cache.as_ref().map_or(Ok(()), |c| c.serialize(self, encoder))
}
/// If `true`, we should use the MIR-based borrowck, but also
#[inline]
pub fn lazy_normalization(self) -> bool {
let features = self.features();
- // Note: We do not enable lazy normalization for `min_const_generics`.
- features.const_generics || features.lazy_normalization_consts
+ // Note: We only use lazy normalization for generic const expressions.
+ features.generic_const_exprs
}
#[inline]
}
pub fn return_type_impl_trait(self, scope_def_id: LocalDefId) -> Option<(Ty<'tcx>, Span)> {
- // HACK: `type_of_def_id()` will fail on these (#55796), so return `None`.
+ // `type_of()` will fail on these (#55796, #86483), so only allow `fn`s or closures.
let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id);
match self.hir().get(hir_id) {
- Node::Item(item) => {
- match item.kind {
- ItemKind::Fn(..) => { /* `type_of_def_id()` will work */ }
- _ => {
- return None;
- }
- }
- }
- _ => { /* `type_of_def_id()` will work or panic */ }
+ Node::Item(&hir::Item { kind: ItemKind::Fn(..), .. }) => {}
+ Node::TraitItem(&hir::TraitItem { kind: TraitItemKind::Fn(..), .. }) => {}
+ Node::ImplItem(&hir::ImplItem { kind: ImplItemKind::Fn(..), .. }) => {}
+ Node::Expr(&hir::Expr { kind: ExprKind::Closure(..), .. }) => {}
+ _ => return None,
}
let ret_ty = self.type_of(scope_def_id);
def_kind => (def_kind.article(), def_kind.descr(def_id)),
}
}
+
+ pub fn type_length_limit(self) -> Limit {
+ self.limits(()).type_length_limit
+ }
+
+ pub fn recursion_limit(self) -> Limit {
+ self.limits(()).recursion_limit
+ }
+
+ pub fn move_size_limit(self) -> Limit {
+ self.limits(()).move_size_limit
+ }
+
+ pub fn const_eval_limit(self) -> Limit {
+ self.limits(()).const_eval_limit
+ }
}
/// A trait implemented for all `X<'a>` types that can be safely and
nop_lift! {type_; Ty<'a> => Ty<'tcx>}
nop_lift! {region; Region<'a> => Region<'tcx>}
nop_lift! {const_; &'a Const<'a> => &'tcx Const<'tcx>}
+nop_lift! {allocation; &'a Allocation => &'tcx Allocation}
nop_lift! {predicate; &'a PredicateInner<'a> => &'tcx PredicateInner<'tcx>}
nop_list_lift! {type_list; Ty<'a> => Ty<'tcx>}
-nop_list_lift! {poly_existential_predicates; ty::Binder<ExistentialPredicate<'a>> => ty::Binder<ExistentialPredicate<'tcx>>}
+nop_list_lift! {poly_existential_predicates; ty::Binder<'a, ExistentialPredicate<'a>> => ty::Binder<'tcx, ExistentialPredicate<'tcx>>}
nop_list_lift! {predicates; Predicate<'a> => Predicate<'tcx>}
nop_list_lift! {canonical_var_infos; CanonicalVarInfo<'a> => CanonicalVarInfo<'tcx>}
nop_list_lift! {projs; ProjectionKind => ProjectionKind}
+nop_list_lift! {bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariableKind}
// This is the impl for `&'a InternalSubsts<'a>`.
nop_list_lift! {substs; GenericArg<'a> => GenericArg<'tcx>}
-CloneLiftImpls! { for<'tcx> { Constness, } }
+CloneLiftImpls! { for<'tcx> { Constness, traits::WellFormedLoc, } }
pub mod tls {
use super::{ptr_eq, GlobalCtxt, TyCtxt};
#[cfg(not(parallel_compiler))]
thread_local! {
/// A thread local variable that stores a pointer to the current `ImplicitCtxt`.
- static TLV: Cell<usize> = Cell::new(0);
+ static TLV: Cell<usize> = const { Cell::new(0) };
}
/// Sets TLV to `value` during the call to `f`.
if context == 0 {
f(None)
} else {
- // We could get a `ImplicitCtxt` pointer from another thread.
+ // We could get an `ImplicitCtxt` pointer from another thread.
// Ensure that `ImplicitCtxt` is `Sync`.
sync::assert_sync::<ImplicitCtxt<'_, '_>>();
"Const Stability interner: #{}",
self.0.const_stability_interner.len()
)?;
- writeln!(fmt, "Allocation interner: #{}", self.0.allocation_interner.len())?;
+ writeln!(fmt, "Allocation interner: #{}", self.0.interners.allocation.len())?;
writeln!(fmt, "Layout interner: #{}", self.0.layout_interner.len())?;
Ok(())
}
}
-impl<'tcx> Borrow<Binder<PredicateKind<'tcx>>> for Interned<'tcx, PredicateInner<'tcx>> {
- fn borrow<'a>(&'a self) -> &'a Binder<PredicateKind<'tcx>> {
+impl<'tcx> Borrow<Binder<'tcx, PredicateKind<'tcx>>> for Interned<'tcx, PredicateInner<'tcx>> {
+ fn borrow<'a>(&'a self) -> &'a Binder<'tcx, PredicateKind<'tcx>> {
&self.0.kind
}
}
}
}
+impl<'tcx> Borrow<Allocation> for Interned<'tcx, Allocation> {
+ fn borrow<'a>(&'a self) -> &'a Allocation {
+ &self.0
+ }
+}
+
+impl<'tcx> PartialEq for Interned<'tcx, Allocation> {
+ fn eq(&self, other: &Self) -> bool {
+ self.0 == other.0
+ }
+}
+
+impl<'tcx> Eq for Interned<'tcx, Allocation> {}
+
+impl<'tcx> Hash for Interned<'tcx, Allocation> {
+ fn hash<H: Hasher>(&self, s: &mut H) {
+ self.0.hash(s)
+ }
+}
+
macro_rules! direct_interners {
($($name:ident: $method:ident($ty:ty),)+) => {
$(impl<'tcx> PartialEq for Interned<'tcx, $ty> {
substs: _intern_substs(GenericArg<'tcx>),
canonical_var_infos: _intern_canonical_var_infos(CanonicalVarInfo<'tcx>),
poly_existential_predicates:
- _intern_poly_existential_predicates(ty::Binder<ExistentialPredicate<'tcx>>),
+ _intern_poly_existential_predicates(ty::Binder<'tcx, ExistentialPredicate<'tcx>>),
predicates: _intern_predicates(Predicate<'tcx>),
projs: _intern_projs(ProjectionKind),
place_elems: _intern_place_elems(PlaceElem<'tcx>),
+ bound_variable_kinds: _intern_bound_variable_kinds(ty::BoundVariableKind),
);
impl<'tcx> TyCtxt<'tcx> {
self.mk_fn_ptr(sig.map_bound(|sig| ty::FnSig { unsafety: hir::Unsafety::Unsafe, ..sig }))
}
+ /// Given the def_id of a Trait `trait_def_id` and the name of an associated item `assoc_name`
+ /// returns true if the `trait_def_id` defines an associated item of name `assoc_name`.
+ pub fn trait_may_define_assoc_type(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
+ self.super_traits_of(trait_def_id).any(|trait_did| {
+ self.associated_items(trait_did)
+ .find_by_name_and_kind(self, assoc_name, ty::AssocKind::Type, trait_did)
+ .is_some()
+ })
+ }
+
+ /// Computes the def-ids of the transitive super-traits of `trait_def_id`. This (intentionally)
+ /// does not compute the full elaborated super-predicates but just the set of def-ids. It is used
+ /// to identify which traits may define a given associated type to help avoid cycle errors.
+ /// Returns a `DefId` iterator.
+ fn super_traits_of(self, trait_def_id: DefId) -> impl Iterator<Item = DefId> + 'tcx {
+ let mut set = FxHashSet::default();
+ let mut stack = vec![trait_def_id];
+
+ set.insert(trait_def_id);
+
+ iter::from_fn(move || -> Option<DefId> {
+ let trait_did = stack.pop()?;
+ let generic_predicates = self.super_predicates_of(trait_did);
+
+ for (predicate, _) in generic_predicates.predicates {
+ if let ty::PredicateKind::Trait(data) = predicate.kind().skip_binder() {
+ if set.insert(data.def_id()) {
+ stack.push(data.def_id());
+ }
+ }
+ }
+
+ Some(trait_did)
+ })
+ }
+
/// Given a closure signature, returns an equivalent fn signature. Detuples
/// and so forth -- so e.g., if we have a sig with `Fn<(u32, i32)>` then
/// you would get a `fn(u32, i32)`.
}
#[inline]
- pub fn mk_predicate(self, binder: Binder<PredicateKind<'tcx>>) -> Predicate<'tcx> {
+ pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
let inner = self.interners.intern_predicate(binder);
Predicate { inner }
}
pub fn reuse_or_mk_predicate(
self,
pred: Predicate<'tcx>,
- binder: Binder<PredicateKind<'tcx>>,
+ binder: Binder<'tcx, PredicateKind<'tcx>>,
) -> Predicate<'tcx> {
if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
}
let adt_def = self.adt_def(wrapper_def_id);
let substs =
InternalSubsts::for_item(self, wrapper_def_id, |param, substs| match param.kind {
- GenericParamDefKind::Lifetime | GenericParamDefKind::Const => bug!(),
+ GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => bug!(),
GenericParamDefKind::Type { has_default, .. } => {
if param.index == 0 {
ty_param.into()
self.mk_ptr(TypeAndMut { ty, mutbl: hir::Mutability::Not })
}
- #[inline]
- pub fn mk_nil_ptr(self) -> Ty<'tcx> {
- self.mk_imm_ptr(self.mk_unit())
- }
-
#[inline]
pub fn mk_array(self, ty: Ty<'tcx>, n: u64) -> Ty<'tcx> {
self.mk_ty(Array(ty, ty::Const::from_usize(self, n)))
#[inline]
pub fn mk_dynamic(
self,
- obj: &'tcx List<ty::Binder<ExistentialPredicate<'tcx>>>,
+ obj: &'tcx List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>>,
reg: ty::Region<'tcx>,
) -> Ty<'tcx> {
self.mk_ty(Dynamic(obj, reg))
}
#[inline]
- pub fn mk_generator_witness(self, types: ty::Binder<&'tcx List<Ty<'tcx>>>) -> Ty<'tcx> {
+ pub fn mk_generator_witness(self, types: ty::Binder<'tcx, &'tcx List<Ty<'tcx>>>) -> Ty<'tcx> {
self.mk_ty(GeneratorWitness(types))
}
self.mk_region(ty::ReEarlyBound(param.to_early_bound_region_data())).into()
}
GenericParamDefKind::Type { .. } => self.mk_ty_param(param.index, param.name).into(),
- GenericParamDefKind::Const => {
+ GenericParamDefKind::Const { .. } => {
self.mk_const_param(param.index, param.name, self.type_of(param.def_id)).into()
}
}
pub fn intern_poly_existential_predicates(
self,
- eps: &[ty::Binder<ExistentialPredicate<'tcx>>],
- ) -> &'tcx List<ty::Binder<ExistentialPredicate<'tcx>>> {
+ eps: &[ty::Binder<'tcx, ExistentialPredicate<'tcx>>],
+ ) -> &'tcx List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>> {
assert!(!eps.is_empty());
assert!(
eps.array_windows()
if ts.is_empty() { List::empty() } else { self._intern_canonical_var_infos(ts) }
}
+ pub fn intern_bound_variable_kinds(
+ self,
+ ts: &[ty::BoundVariableKind],
+ ) -> &'tcx List<ty::BoundVariableKind> {
+ if ts.is_empty() { List::empty() } else { self._intern_bound_variable_kinds(ts) }
+ }
+
pub fn mk_fn_sig<I>(
self,
inputs: I,
pub fn mk_poly_existential_predicates<
I: InternAs<
- [ty::Binder<ExistentialPredicate<'tcx>>],
- &'tcx List<ty::Binder<ExistentialPredicate<'tcx>>>,
+ [ty::Binder<'tcx, ExistentialPredicate<'tcx>>],
+ &'tcx List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>>,
>,
>(
self,
self.mk_substs(iter::once(self_ty.into()).chain(rest.iter().cloned()))
}
+ pub fn mk_bound_variable_kinds<
+ I: InternAs<[ty::BoundVariableKind], &'tcx List<ty::BoundVariableKind>>,
+ >(
+ self,
+ iter: I,
+ ) -> I::Output {
+ iter.intern_with(|xs| self.intern_bound_variable_kinds(xs))
+ }
+
/// Walks upwards from `id` to find a node which might change lint levels with attributes.
/// It stops at `bound` and just returns it if reached.
pub fn maybe_lint_level_root_bounded(self, mut id: HirId, bound: HirId) -> HirId {
lint: &'static Lint,
mut id: hir::HirId,
) -> (Level, LintLevelSource) {
- let sets = self.lint_levels(LOCAL_CRATE);
+ let sets = self.lint_levels(());
loop {
if let Some(pair) = sets.level_and_source(lint, id, self.sess) {
return pair;
struct_lint_level(self.sess, lint, level, src, None, decorate);
}
- pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx StableVec<TraitCandidate>> {
- self.in_scope_traits_map(id.owner).and_then(|map| map.get(&id.local_id))
+ pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> {
+ let map = self.in_scope_traits_map(id.owner)?;
+ let candidates = map.get(&id.local_id)?;
+ Some(&*candidates)
}
pub fn named_region(self, id: HirId) -> Option<resolve_lifetime::Region> {
+ debug!(?id, "named_region");
self.named_region_map(id.owner).and_then(|map| map.get(&id.local_id).cloned())
}
.map_or(false, |(owner, set)| owner == id.owner && set.contains(&id.local_id))
}
- pub fn object_lifetime_defaults(self, id: HirId) -> Option<&'tcx [ObjectLifetimeDefault]> {
+ pub fn object_lifetime_defaults(self, id: HirId) -> Option<Vec<ObjectLifetimeDefault>> {
self.object_lifetime_defaults_map(id.owner)
- .and_then(|map| map.get(&id.local_id).map(|v| &**v))
+ }
+
+ pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
+ self.mk_bound_variable_kinds(
+ self.late_bound_vars_map(id.owner)
+ .and_then(|map| map.get(&id.local_id).cloned())
+ .unwrap_or_else(|| {
+ bug!("No bound vars found for {:?} ({:?})", self.hir().node_to_string(id), id)
+ })
+ .iter(),
+ )
+ }
+
+ pub fn lifetime_scope(self, id: HirId) -> Option<LifetimeScopeForPath> {
+ self.lifetime_scope_map(id.owner).and_then(|mut map| map.remove(&id.local_id))
}
}
}
pub fn provide(providers: &mut ty::query::Providers) {
- providers.in_scope_traits_map = |tcx, id| tcx.gcx.trait_map.get(&id);
- providers.module_exports = |tcx, id| tcx.gcx.export_map.get(&id).map(|v| &v[..]);
+ providers.in_scope_traits_map = |tcx, id| tcx.hir_crate(()).trait_map.get(&id);
+ providers.resolutions = |tcx, ()| &tcx.untracked_resolutions;
+ providers.module_exports = |tcx, id| tcx.resolutions(()).export_map.get(&id).map(|v| &v[..]);
providers.crate_name = |tcx, id| {
assert_eq!(id, LOCAL_CRATE);
tcx.crate_name
};
- providers.maybe_unused_trait_import = |tcx, id| tcx.maybe_unused_trait_imports.contains(&id);
- providers.maybe_unused_extern_crates = |tcx, cnum| {
- assert_eq!(cnum, LOCAL_CRATE);
- &tcx.maybe_unused_extern_crates[..]
+ providers.maybe_unused_trait_import =
+ |tcx, id| tcx.resolutions(()).maybe_unused_trait_imports.contains(&id);
+ providers.maybe_unused_extern_crates =
+ |tcx, ()| &tcx.resolutions(()).maybe_unused_extern_crates[..];
+ providers.names_imported_by_glob_use = |tcx, id| {
+ tcx.arena.alloc(tcx.resolutions(()).glob_map.get(&id).cloned().unwrap_or_default())
};
- providers.names_imported_by_glob_use =
- |tcx, id| tcx.arena.alloc(tcx.glob_map.get(&id).cloned().unwrap_or_default());
- providers.lookup_stability = |tcx, id| {
- let id = tcx.hir().local_def_id_to_hir_id(id.expect_local());
- tcx.stability().local_stability(id)
- };
- providers.lookup_const_stability = |tcx, id| {
- let id = tcx.hir().local_def_id_to_hir_id(id.expect_local());
- tcx.stability().local_const_stability(id)
- };
- providers.lookup_deprecation_entry = |tcx, id| {
- let id = tcx.hir().local_def_id_to_hir_id(id.expect_local());
- tcx.stability().local_deprecation_entry(id)
- };
- providers.extern_mod_stmt_cnum = |tcx, id| tcx.extern_crate_map.get(&id).cloned();
- providers.all_crate_nums = |tcx, cnum| {
- assert_eq!(cnum, LOCAL_CRATE);
- tcx.arena.alloc_slice(&tcx.cstore.crates_untracked())
- };
- providers.output_filenames = |tcx, cnum| {
- assert_eq!(cnum, LOCAL_CRATE);
- tcx.output_filenames.clone()
- };
- providers.features_query = |tcx, cnum| {
- assert_eq!(cnum, LOCAL_CRATE);
- tcx.sess.features_untracked()
- };
+ providers.lookup_stability = |tcx, id| tcx.stability().local_stability(id.expect_local());
+ providers.lookup_const_stability =
+ |tcx, id| tcx.stability().local_const_stability(id.expect_local());
+ providers.lookup_deprecation_entry =
+ |tcx, id| tcx.stability().local_deprecation_entry(id.expect_local());
+ providers.extern_mod_stmt_cnum =
+ |tcx, id| tcx.resolutions(()).extern_crate_map.get(&id).cloned();
+ providers.output_filenames = |tcx, ()| tcx.output_filenames.clone();
+ providers.features_query = |tcx, ()| tcx.sess.features_untracked();
providers.is_panic_runtime = |tcx, cnum| {
assert_eq!(cnum, LOCAL_CRATE);
tcx.sess.contains_name(tcx.hir().krate_attrs(), sym::panic_runtime)