use hir::map::DefPathHash;
use lint::{self, Lint};
use ich::{StableHashingContext, NodeIdHashingMode};
-use infer::canonical::{CanonicalVarInfo, CanonicalVarInfos};
+use infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos};
use infer::outlives::free_region_map::FreeRegionMap;
use middle::cstore::CrateStoreDyn;
use middle::cstore::EncodedMetadata;
use middle::stability;
use mir::{self, Mir, interpret, ProjectionKind};
use mir::interpret::Allocation;
-use ty::subst::{CanonicalUserSubsts, Kind, Substs, Subst};
+use ty::subst::{Kind, Substs, Subst};
use ty::ReprOptions;
use traits;
use traits::{Clause, Clauses, GoalKind, Goal, Goals};
use ty::{self, Ty, TypeAndMut};
use ty::{TyS, TyKind, List};
-use ty::{AdtKind, AdtDef, ClosureSubsts, GeneratorSubsts, Region, Const};
+use ty::{AdtKind, AdtDef, ClosureSubsts, GeneratorSubsts, Region, Const, LazyConst};
use ty::{PolyFnSig, InferTy, ParamTy, ProjectionTy, ExistentialPredicate, Predicate};
use ty::RegionKind;
use ty::{TyVar, TyVid, IntVar, IntVid, FloatVar, FloatVid};
use ty::layout::{LayoutDetails, TargetDataLayout, VariantIdx};
use ty::query;
use ty::steal::Steal;
-use ty::BindingMode;
-use ty::CanonicalTy;
+use ty::subst::{UserSubsts, UnpackedKind};
+use ty::{BoundVar, BindingMode};
use ty::CanonicalPolyFnSig;
use util::nodemap::{DefIdMap, DefIdSet, ItemLocalMap};
use util::nodemap::{FxHashMap, FxHashSet};
StableHasher, StableHasherResult,
StableVec};
use arena::{TypedArena, SyncDroplessArena};
-use rustc_data_structures::indexed_vec::IndexVec;
+use rustc_data_structures::indexed_vec::{Idx, IndexVec};
use rustc_data_structures::sync::{self, Lrc, Lock, WorkerLocal};
use std::any::Any;
use std::borrow::Borrow;
region: InternedSet<'tcx, RegionKind>,
existential_predicates: InternedSet<'tcx, List<ExistentialPredicate<'tcx>>>,
predicates: InternedSet<'tcx, List<Predicate<'tcx>>>,
- const_: InternedSet<'tcx, Const<'tcx>>,
clauses: InternedSet<'tcx, List<Clause<'tcx>>>,
goal: InternedSet<'tcx, GoalKind<'tcx>>,
goal_list: InternedSet<'tcx, List<Goal<'tcx>>>,
existential_predicates: Default::default(),
canonical_var_infos: Default::default(),
predicates: Default::default(),
- const_: Default::default(),
clauses: Default::default(),
goal: Default::default(),
goal_list: Default::default(),
/// other items.
node_substs: ItemLocalMap<&'tcx Substs<'tcx>>,
- /// Stores the canonicalized types provided by the user. See also
- /// `AscribeUserType` statement in MIR.
- user_provided_tys: ItemLocalMap<CanonicalTy<'tcx>>,
+ /// This will either store the canonicalized types provided by the user
+ /// or the substitutions that the user explicitly gave (if any) attached
+ /// to `id`. These will not include any inferred values. The canonical form
+ /// is used to capture things like `_` or other unspecified values.
+ ///
+ /// For example, if the user wrote `foo.collect::<Vec<_>>()`, then the
+ /// canonical substitutions would include only `for<X> { Vec<X> }`.
+ ///
+ /// See also `AscribeUserType` statement in MIR.
+ user_provided_types: ItemLocalMap<CanonicalUserTypeAnnotation<'tcx>>,
/// Stores the canonicalized types provided by the user. See also
/// `AscribeUserType` statement in MIR.
pub user_provided_sigs: DefIdMap<CanonicalPolyFnSig<'tcx>>,
- /// Stores the substitutions that the user explicitly gave (if any)
- /// attached to `id`. These will not include any inferred
- /// values. The canonical form is used to capture things like `_`
- /// or other unspecified values.
- ///
- /// Example:
- ///
- /// If the user wrote `foo.collect::<Vec<_>>()`, then the
- /// canonical substitutions would include only `for<X> { Vec<X>
- /// }`.
- user_substs: ItemLocalMap<CanonicalUserSubsts<'tcx>>,
-
adjustments: ItemLocalMap<Vec<ty::adjustment::Adjustment<'tcx>>>,
/// Stores the actual binding mode for all instances of hir::BindingAnnotation.
local_id_root,
type_dependent_defs: Default::default(),
field_indices: Default::default(),
- user_provided_tys: Default::default(),
+ user_provided_types: Default::default(),
user_provided_sigs: Default::default(),
node_types: Default::default(),
node_substs: Default::default(),
- user_substs: Default::default(),
adjustments: Default::default(),
pat_binding_modes: Default::default(),
pat_adjustments: Default::default(),
}
}
- pub fn user_provided_tys(&self) -> LocalTableInContext<'_, CanonicalTy<'tcx>> {
+ pub fn user_provided_types(
+ &self
+ ) -> LocalTableInContext<'_, CanonicalUserTypeAnnotation<'tcx>> {
LocalTableInContext {
local_id_root: self.local_id_root,
- data: &self.user_provided_tys
+ data: &self.user_provided_types
}
}
- pub fn user_provided_tys_mut(&mut self) -> LocalTableInContextMut<'_, CanonicalTy<'tcx>> {
+ pub fn user_provided_types_mut(
+ &mut self
+ ) -> LocalTableInContextMut<'_, CanonicalUserTypeAnnotation<'tcx>> {
LocalTableInContextMut {
local_id_root: self.local_id_root,
- data: &mut self.user_provided_tys
+ data: &mut self.user_provided_types
}
}
self.node_substs.get(&id.local_id).cloned()
}
- pub fn user_substs_mut(&mut self) -> LocalTableInContextMut<'_, CanonicalUserSubsts<'tcx>> {
- LocalTableInContextMut {
- local_id_root: self.local_id_root,
- data: &mut self.user_substs
- }
- }
-
- pub fn user_substs(&self, id: hir::HirId) -> Option<CanonicalUserSubsts<'tcx>> {
- validate_hir_id_for_typeck_tables(self.local_id_root, id, false);
- self.user_substs.get(&id.local_id).cloned()
- }
-
// Returns the type of a pattern as a monotype. Like @expr_ty, this function
// doesn't provide type parameter substitutions.
pub fn pat_ty(&self, pat: &hir::Pat) -> Ty<'tcx> {
local_id_root,
ref type_dependent_defs,
ref field_indices,
- ref user_provided_tys,
+ ref user_provided_types,
ref user_provided_sigs,
ref node_types,
ref node_substs,
- ref user_substs,
ref adjustments,
ref pat_binding_modes,
ref pat_adjustments,
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
type_dependent_defs.hash_stable(hcx, hasher);
field_indices.hash_stable(hcx, hasher);
- user_provided_tys.hash_stable(hcx, hasher);
+ user_provided_types.hash_stable(hcx, hasher);
user_provided_sigs.hash_stable(hcx, hasher);
node_types.hash_stable(hcx, hasher);
node_substs.hash_stable(hcx, hasher);
- user_substs.hash_stable(hcx, hasher);
adjustments.hash_stable(hcx, hasher);
pat_binding_modes.hash_stable(hcx, hasher);
pat_adjustments.hash_stable(hcx, hasher);
}
}
+newtype_index! {
+ pub struct UserTypeAnnotationIndex {
+ DEBUG_FORMAT = "UserTypeAnnotation({})",
+ const START_INDEX = 0,
+ }
+}
+
+/// Mapping of type annotation indices to canonical user type annotations.
+pub type CanonicalUserTypeAnnotations<'tcx> =
+ IndexVec<UserTypeAnnotationIndex, (Span, CanonicalUserTypeAnnotation<'tcx>)>;
+
+/// Canonicalized user type annotation.
+pub type CanonicalUserTypeAnnotation<'gcx> = Canonical<'gcx, UserTypeAnnotation<'gcx>>;
+
+impl CanonicalUserTypeAnnotation<'gcx> {
+ /// Returns `true` if this represents a substitution of the form `[?0, ?1, ?2]`,
+ /// i.e. each thing is mapped to a canonical variable with the same index.
+ pub fn is_identity(&self) -> bool {
+ match self.value {
+ UserTypeAnnotation::Ty(_) => false,
+ UserTypeAnnotation::TypeOf(_, user_substs) => {
+ if user_substs.user_self_ty.is_some() {
+ return false;
+ }
+
+ user_substs.substs.iter().zip(BoundVar::new(0)..).all(|(kind, cvar)| {
+ match kind.unpack() {
+ UnpackedKind::Type(ty) => match ty.sty {
+ ty::Bound(debruijn, b) => {
+ // We only allow a `ty::INNERMOST` index in substitutions.
+ assert_eq!(debruijn, ty::INNERMOST);
+ cvar == b.var
+ }
+ _ => false,
+ },
+
+ UnpackedKind::Lifetime(r) => match r {
+ ty::ReLateBound(debruijn, br) => {
+ // We only allow a `ty::INNERMOST` index in substitutions.
+ assert_eq!(*debruijn, ty::INNERMOST);
+ cvar == br.assert_bound_var()
+ }
+ _ => false,
+ },
+ }
+ })
+ },
+ }
+ }
+}
+
+/// A user-given type annotation attached to a constant. These arise
+/// from constants that are named via paths, like `Foo::<A>::new` and
+/// so forth.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+pub enum UserTypeAnnotation<'tcx> {
+ Ty(Ty<'tcx>),
+
+ /// The canonical type is the result of `type_of(def_id)` with the
+ /// given substitutions applied.
+ TypeOf(DefId, UserSubsts<'tcx>),
+}
+
+EnumTypeFoldableImpl! {
+ impl<'tcx> TypeFoldable<'tcx> for UserTypeAnnotation<'tcx> {
+ (UserTypeAnnotation::Ty)(ty),
+ (UserTypeAnnotation::TypeOf)(def, substs),
+ }
+}
+
+EnumLiftImpl! {
+ impl<'a, 'tcx> Lift<'tcx> for UserTypeAnnotation<'a> {
+ type Lifted = UserTypeAnnotation<'tcx>;
+ (UserTypeAnnotation::Ty)(ty),
+ (UserTypeAnnotation::TypeOf)(def, substs),
+ }
+}
+
impl<'tcx> CommonTypes<'tcx> {
fn new(interners: &CtxtInterners<'tcx>) -> CommonTypes<'tcx> {
let mk = |sty| CtxtInterners::intern_ty(interners, interners, sty);
self.global_arenas.adt_def.alloc(def)
}
- pub fn alloc_byte_array(self, bytes: &[u8]) -> &'gcx [u8] {
- if bytes.is_empty() {
- &[]
- } else {
- self.global_interners.arena.alloc_slice(bytes)
- }
- }
-
- pub fn alloc_const_slice(self, values: &[&'tcx ty::Const<'tcx>])
- -> &'tcx [&'tcx ty::Const<'tcx>] {
- if values.is_empty() {
- &[]
- } else {
- self.interners.arena.alloc_slice(values)
- }
- }
-
- pub fn alloc_name_const_slice(self, values: &[(ast::Name, &'tcx ty::Const<'tcx>)])
- -> &'tcx [(ast::Name, &'tcx ty::Const<'tcx>)] {
- if values.is_empty() {
- &[]
- } else {
- self.interners.arena.alloc_slice(values)
- }
- }
-
pub fn intern_const_alloc(
self,
alloc: Allocation,
})
}
+ pub fn intern_lazy_const(self, c: ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> {
+ self.global_interners.arena.alloc(c)
+ }
+
pub fn intern_layout(self, layout: LayoutDetails) -> &'gcx LayoutDetails {
self.layout_interner.borrow_mut().intern(layout, |layout| {
self.global_arenas.layout.alloc(layout)
sync::assert_send_val(&gcx);
- tls::enter_global(gcx, f)
+ let r = tls::enter_global(gcx, f);
+
+ gcx.queries.record_computed_queries(s);
+
+ r
}
pub fn consider_optimizing<T: Fn() -> String>(&self, msg: T) -> bool {
let new_icx = ty::tls::ImplicitCtxt {
tcx,
query: icx.query.clone(),
+ diagnostics: icx.diagnostics,
layout_depth: icx.layout_depth,
- task: icx.task,
+ task_deps: icx.task_deps,
};
ty::tls::enter_context(&new_icx, |_| {
f(tcx)
fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted>;
}
-impl<'a, 'tcx> Lift<'tcx> for Ty<'a> {
- type Lifted = Ty<'tcx>;
- fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Ty<'tcx>> {
- if tcx.interners.arena.in_arena(*self as *const _) {
- return Some(unsafe { mem::transmute(*self) });
- }
- // Also try in the global tcx if we're not that.
- if !tcx.is_global() {
- self.lift_to_tcx(tcx.global_tcx())
- } else {
- None
- }
- }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for Region<'a> {
- type Lifted = Region<'tcx>;
- fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Region<'tcx>> {
- if tcx.interners.arena.in_arena(*self as *const _) {
- return Some(unsafe { mem::transmute(*self) });
- }
- // Also try in the global tcx if we're not that.
- if !tcx.is_global() {
- self.lift_to_tcx(tcx.global_tcx())
- } else {
- None
- }
- }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for Goal<'a> {
- type Lifted = Goal<'tcx>;
- fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Goal<'tcx>> {
- if tcx.interners.arena.in_arena(*self as *const _) {
- return Some(unsafe { mem::transmute(*self) });
- }
- // Also try in the global tcx if we're not that.
- if !tcx.is_global() {
- self.lift_to_tcx(tcx.global_tcx())
- } else {
- None
- }
- }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for &'a List<Goal<'a>> {
- type Lifted = &'tcx List<Goal<'tcx>>;
- fn lift_to_tcx<'b, 'gcx>(
- &self,
- tcx: TyCtxt<'b, 'gcx, 'tcx>,
- ) -> Option<&'tcx List<Goal<'tcx>>> {
- if self.is_empty() {
- return Some(List::empty());
- }
- if tcx.interners.arena.in_arena(*self as *const _) {
- return Some(unsafe { mem::transmute(*self) });
- }
- // Also try in the global tcx if we're not that.
- if !tcx.is_global() {
- self.lift_to_tcx(tcx.global_tcx())
- } else {
- None
- }
- }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for &'a List<Clause<'a>> {
- type Lifted = &'tcx List<Clause<'tcx>>;
- fn lift_to_tcx<'b, 'gcx>(
- &self,
- tcx: TyCtxt<'b, 'gcx, 'tcx>,
- ) -> Option<&'tcx List<Clause<'tcx>>> {
- if self.is_empty() {
- return Some(List::empty());
- }
-
- if tcx.interners.arena.in_arena(*self as *const _) {
- return Some(unsafe { mem::transmute(*self) });
- }
- // Also try in the global tcx if we're not that.
- if !tcx.is_global() {
- self.lift_to_tcx(tcx.global_tcx())
- } else {
- None
- }
- }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for &'a Const<'a> {
- type Lifted = &'tcx Const<'tcx>;
- fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<&'tcx Const<'tcx>> {
- if tcx.interners.arena.in_arena(*self as *const _) {
- return Some(unsafe { mem::transmute(*self) });
- }
- // Also try in the global tcx if we're not that.
- if !tcx.is_global() {
- self.lift_to_tcx(tcx.global_tcx())
- } else {
- None
- }
- }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for &'a Substs<'a> {
- type Lifted = &'tcx Substs<'tcx>;
- fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<&'tcx Substs<'tcx>> {
- if self.len() == 0 {
- return Some(List::empty());
- }
- if tcx.interners.arena.in_arena(&self[..] as *const _) {
- return Some(unsafe { mem::transmute(*self) });
- }
- // Also try in the global tcx if we're not that.
- if !tcx.is_global() {
- self.lift_to_tcx(tcx.global_tcx())
- } else {
- None
+macro_rules! nop_lift {
+ ($ty:ty => $lifted:ty) => {
+ impl<'a, 'tcx> Lift<'tcx> for $ty {
+ type Lifted = $lifted;
+ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
+ if tcx.interners.arena.in_arena(*self as *const _) {
+ return Some(unsafe { mem::transmute(*self) });
+ }
+ // Also try in the global tcx if we're not that.
+ if !tcx.is_global() {
+ self.lift_to_tcx(tcx.global_tcx())
+ } else {
+ None
+ }
+ }
}
- }
+ };
}
-impl<'a, 'tcx> Lift<'tcx> for &'a List<Ty<'a>> {
- type Lifted = &'tcx List<Ty<'tcx>>;
- fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
- -> Option<&'tcx List<Ty<'tcx>>> {
- if self.len() == 0 {
- return Some(List::empty());
- }
- if tcx.interners.arena.in_arena(*self as *const _) {
- return Some(unsafe { mem::transmute(*self) });
- }
- // Also try in the global tcx if we're not that.
- if !tcx.is_global() {
- self.lift_to_tcx(tcx.global_tcx())
- } else {
- None
+macro_rules! nop_list_lift {
+ ($ty:ty => $lifted:ty) => {
+ impl<'a, 'tcx> Lift<'tcx> for &'a List<$ty> {
+ type Lifted = &'tcx List<$lifted>;
+ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
+ if self.is_empty() {
+ return Some(List::empty());
+ }
+ if tcx.interners.arena.in_arena(*self as *const _) {
+ return Some(unsafe { mem::transmute(*self) });
+ }
+ // Also try in the global tcx if we're not that.
+ if !tcx.is_global() {
+ self.lift_to_tcx(tcx.global_tcx())
+ } else {
+ None
+ }
+ }
}
- }
+ };
}
-impl<'a, 'tcx> Lift<'tcx> for &'a List<ExistentialPredicate<'a>> {
- type Lifted = &'tcx List<ExistentialPredicate<'tcx>>;
- fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
- -> Option<&'tcx List<ExistentialPredicate<'tcx>>> {
- if self.is_empty() {
- return Some(List::empty());
- }
- if tcx.interners.arena.in_arena(*self as *const _) {
- return Some(unsafe { mem::transmute(*self) });
- }
- // Also try in the global tcx if we're not that.
- if !tcx.is_global() {
- self.lift_to_tcx(tcx.global_tcx())
- } else {
- None
- }
- }
-}
+nop_lift!{Ty<'a> => Ty<'tcx>}
+nop_lift!{Region<'a> => Region<'tcx>}
+nop_lift!{Goal<'a> => Goal<'tcx>}
+nop_lift!{&'a LazyConst<'a> => &'tcx LazyConst<'tcx>}
-impl<'a, 'tcx> Lift<'tcx> for &'a List<Predicate<'a>> {
- type Lifted = &'tcx List<Predicate<'tcx>>;
- fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
- -> Option<&'tcx List<Predicate<'tcx>>> {
- if self.is_empty() {
- return Some(List::empty());
- }
- if tcx.interners.arena.in_arena(*self as *const _) {
- return Some(unsafe { mem::transmute(*self) });
- }
- // Also try in the global tcx if we're not that.
- if !tcx.is_global() {
- self.lift_to_tcx(tcx.global_tcx())
- } else {
- None
- }
- }
-}
+nop_list_lift!{Goal<'a> => Goal<'tcx>}
+nop_list_lift!{Clause<'a> => Clause<'tcx>}
+nop_list_lift!{Ty<'a> => Ty<'tcx>}
+nop_list_lift!{ExistentialPredicate<'a> => ExistentialPredicate<'tcx>}
+nop_list_lift!{Predicate<'a> => Predicate<'tcx>}
+nop_list_lift!{CanonicalVarInfo => CanonicalVarInfo}
+nop_list_lift!{ProjectionKind<'a> => ProjectionKind<'tcx>}
-impl<'a, 'tcx> Lift<'tcx> for &'a List<CanonicalVarInfo> {
- type Lifted = &'tcx List<CanonicalVarInfo>;
- fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
- if self.len() == 0 {
- return Some(List::empty());
- }
- if tcx.interners.arena.in_arena(*self as *const _) {
- return Some(unsafe { mem::transmute(*self) });
- }
- // Also try in the global tcx if we're not that.
- if !tcx.is_global() {
- self.lift_to_tcx(tcx.global_tcx())
- } else {
- None
- }
- }
-}
+// this is the impl for `&'a Substs<'a>`
+nop_list_lift!{Kind<'a> => Kind<'tcx>}
-impl<'a, 'tcx> Lift<'tcx> for &'a List<ProjectionKind<'a>> {
- type Lifted = &'tcx List<ProjectionKind<'tcx>>;
+impl<'a, 'tcx> Lift<'tcx> for &'a mir::interpret::Allocation {
+ type Lifted = &'tcx mir::interpret::Allocation;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
- if self.len() == 0 {
- return Some(List::empty());
- }
- if tcx.interners.arena.in_arena(*self as *const _) {
- return Some(unsafe { mem::transmute(*self) });
- }
- // Also try in the global tcx if we're not that.
- if !tcx.is_global() {
- self.lift_to_tcx(tcx.global_tcx())
- } else {
- None
- }
+ assert!(tcx.global_arenas.const_allocs.in_arena(*self as *const _));
+ Some(unsafe { mem::transmute(*self) })
}
}
use errors::{Diagnostic, TRACK_DIAGNOSTICS};
use rustc_data_structures::OnDrop;
use rustc_data_structures::sync::{self, Lrc, Lock};
- use dep_graph::OpenTask;
+ use rustc_data_structures::thin_vec::ThinVec;
+ use dep_graph::TaskDeps;
#[cfg(not(parallel_queries))]
use std::cell::Cell;
/// by `enter_local` with a new local interner
pub tcx: TyCtxt<'tcx, 'gcx, 'tcx>,
- /// The current query job, if any. This is updated by start_job in
+ /// The current query job, if any. This is updated by JobOwner::start in
/// ty::query::plumbing when executing a query
pub query: Option<Lrc<query::QueryJob<'gcx>>>,
+ /// Where to store diagnostics for the current query job, if any.
+ /// This is updated by JobOwner::start in ty::query::plumbing when executing a query
+ pub diagnostics: Option<&'a Lock<ThinVec<Diagnostic>>>,
+
/// Used to prevent layout from recursing too deeply.
pub layout_depth: usize,
/// The current dep graph task. This is used to add dependencies to queries
/// when executing them
- pub task: &'a OpenTask,
+ pub task_deps: Option<&'a Lock<TaskDeps>>,
}
/// Sets Rayon's thread local variable which is preserved for Rayon jobs
fn track_diagnostic(diagnostic: &Diagnostic) {
with_context_opt(|icx| {
if let Some(icx) = icx {
- if let Some(ref query) = icx.query {
- query.diagnostics.lock().push(diagnostic.clone());
+ if let Some(ref diagnostics) = icx.diagnostics {
+ let mut diagnostics = diagnostics.lock();
+ diagnostics.extend(Some(diagnostic.clone()));
}
}
})
let icx = ImplicitCtxt {
tcx,
query: None,
+ diagnostics: None,
layout_depth: 0,
- task: &OpenTask::Ignore,
+ task_deps: None,
};
enter_context(&icx, |_| {
f(tcx)
};
let icx = ImplicitCtxt {
query: None,
+ diagnostics: None,
tcx,
layout_depth: 0,
- task: &OpenTask::Ignore,
+ task_deps: None,
};
enter_context(&icx, |_| f(tcx))
}
direct_interners!('tcx,
region: mk_region(|r: &RegionKind| r.keep_in_local_tcx()) -> RegionKind,
- const_: mk_const(|c: &Const<'_>| keep_local(&c.ty) || keep_local(&c.val)) -> Const<'tcx>,
goal: mk_goal(|c: &GoalKind<'_>| keep_local(c)) -> GoalKind<'tcx>
);
#[inline]
pub fn mk_array(self, ty: Ty<'tcx>, n: u64) -> Ty<'tcx> {
- self.mk_ty(Array(ty, ty::Const::from_usize(self, n)))
+ self.mk_ty(Array(ty, self.intern_lazy_const(
+ ty::LazyConst::Evaluated(ty::Const::from_usize(self.global_tcx(), n))
+ )))
}
#[inline]