From 1b7acb6f34bb255d709fa153a49c77a570e6bbec Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 10 May 2017 10:28:06 -0400 Subject: [PATCH] centralize the caching for is-copy, is-sized, and is-freeze Use the trait-environment+type as the key. Note that these are only invoked on types that live for the entire compilation (no inference artifacts). We no longer need the various special-case bits and caches that were in place before. --- src/librustc/dep_graph/dep_node.rs | 6 + src/librustc/infer/mod.rs | 14 +- src/librustc/traits/mod.rs | 4 +- src/librustc/traits/select.rs | 2 +- src/librustc/ty/layout.rs | 4 +- src/librustc/ty/maps.rs | 50 +++- src/librustc/ty/mod.rs | 74 ++---- src/librustc/ty/util.rs | 227 +++++++----------- src/librustc/util/ppaux.rs | 8 +- .../borrowck/mir/elaborate_drops.rs | 9 +- .../borrowck/mir/gather_moves.rs | 8 +- src/librustc_borrowck/borrowck/mir/mod.rs | 6 +- src/librustc_const_eval/check_match.rs | 6 +- src/librustc_lint/builtin.rs | 11 +- src/librustc_mir/hair/cx/mod.rs | 2 +- src/librustc_mir/shim.rs | 13 +- src/librustc_mir/transform/inline.rs | 2 +- src/librustc_mir/transform/qualify_consts.rs | 6 +- src/librustc_mir/util/elaborate_drops.rs | 2 +- src/librustc_passes/consts.rs | 8 +- src/librustc_trans/context.rs | 10 +- src/librustc_typeck/check/compare_method.rs | 19 +- 22 files changed, 219 insertions(+), 272 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 15c4469b746..d268c8787cc 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -108,6 +108,9 @@ pub enum DepNode { SymbolName(D), SpecializationGraph(D), ObjectSafety(D), + IsCopy(D), + IsSized(D), + IsFreeze(D), // The set of impls for a given trait. Ultimately, it would be // nice to get more fine-grained here (e.g., to include a @@ -233,6 +236,9 @@ pub fn map_def(&self, mut op: OP) -> Option> // they are always absolute. WorkProduct(ref id) => Some(WorkProduct(id.clone())), + IsCopy(ref d) => op(d).map(IsCopy), + IsSized(ref d) => op(d).map(IsSized), + IsFreeze(ref d) => op(d).map(IsFreeze), Hir(ref d) => op(d).map(Hir), HirBody(ref d) => op(d).map(HirBody), MetaData(ref d) => op(d).map(MetaData), diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 1ecc277c7ca..7dcad0122e8 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -28,7 +28,7 @@ use mir::tcx::LvalueTy; use ty::subst::{Kind, Subst, Substs}; use ty::{TyVid, IntVid, FloatVid}; -use ty::{self, Ty, TyCtxt}; +use ty::{self, ParameterEnvironment, Ty, TyCtxt}; use ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric}; use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use ty::relate::{Relate, RelateResult, TypeRelation}; @@ -526,9 +526,7 @@ pub fn enter(&'tcx mut self, f: F) -> R let tables = tables.map(InferTables::Interned).unwrap_or_else(|| { fresh_tables.as_ref().map_or(InferTables::Missing, InferTables::InProgress) }); - let param_env = param_env.take().unwrap_or_else(|| { - global_tcx.empty_parameter_environment() - }); + let param_env = param_env.take().unwrap_or_else(|| ParameterEnvironment::empty()); global_tcx.enter_local(arena, |tcx| f(InferCtxt { tcx: tcx, tables: tables, @@ -650,7 +648,7 @@ pub fn normalize_associated_type(self, value: &T) -> T } pub fn normalize_associated_type_in_env( - self, value: &T, env: &'a ty::ParameterEnvironment<'tcx> + self, value: &T, env: ty::ParameterEnvironment<'tcx> ) -> T where T: TransNormalize<'tcx> { @@ -662,7 +660,7 @@ pub fn normalize_associated_type_in_env( return value; } - self.infer_ctxt(env.clone(), Reveal::All).enter(|infcx| { + self.infer_ctxt(env, Reveal::All).enter(|infcx| { value.trans_normalize(&infcx) }) } @@ -1674,8 +1672,8 @@ pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option &ty::ParameterEnvironment<'gcx> { - &self.parameter_environment + pub fn param_env(&self) -> ty::ParameterEnvironment<'gcx> { + self.parameter_environment } pub fn closure_kind(&self, diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 1823373348b..9e3381d8450 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -477,7 +477,7 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, debug!("normalize_param_env_or_error: elaborated-predicates={:?}", predicates); - let elaborated_env = unnormalized_env.with_caller_bounds(tcx.intern_predicates(&predicates)); + let elaborated_env = ty::ParameterEnvironment::new(tcx.intern_predicates(&predicates)); tcx.infer_ctxt(elaborated_env, Reveal::UserFacing).enter(|infcx| { let predicates = match fully_normalize( @@ -528,7 +528,7 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, debug!("normalize_param_env_or_error: resolved predicates={:?}", predicates); - infcx.parameter_environment.with_caller_bounds(tcx.intern_predicates(&predicates)) + ty::ParameterEnvironment::new(tcx.intern_predicates(&predicates)) }) } diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index cccc20e5b29..5be07e712b6 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -315,7 +315,7 @@ pub fn tcx(&self) -> TyCtxt<'cx, 'gcx, 'tcx> { self.infcx.tcx } - pub fn param_env(&self) -> &'cx ty::ParameterEnvironment<'gcx> { + pub fn param_env(&self) -> ty::ParameterEnvironment<'gcx> { self.infcx.param_env() } diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index bd38a6c3fd3..66935dd3a3b 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -1079,7 +1079,7 @@ pub fn compute_uncached(ty: Ty<'gcx>, let ptr_layout = |pointee: Ty<'gcx>| { let non_zero = !ty.is_unsafe_ptr(); let pointee = infcx.normalize_projections(pointee); - if pointee.is_sized(tcx, &infcx.parameter_environment, DUMMY_SP) { + if pointee.is_sized(tcx, infcx.parameter_environment, DUMMY_SP) { Ok(Scalar { value: Pointer, non_zero: non_zero }) } else { let unsized_part = tcx.struct_tail(pointee); @@ -1272,7 +1272,7 @@ pub fn compute_uncached(ty: Ty<'gcx>, let fields = &def.variants[0].fields; let last_field = &fields[fields.len()-1]; let always_sized = tcx.type_of(last_field.did) - .is_sized(tcx, ¶m_env, DUMMY_SP); + .is_sized(tcx, param_env, DUMMY_SP); if !always_sized { StructKind::MaybeUnsizedUnivariant } else { StructKind::AlwaysSizedUnivariant } }; diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index 85462bd9b12..b0868ac389b 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -9,7 +9,7 @@ // except according to those terms. use dep_graph::{DepGraph, DepNode, DepTrackingMap, DepTrackingMapConfig}; -use hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; +use hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE}; use hir::def::Def; use hir; use middle::const_val; @@ -136,6 +136,15 @@ fn default_span(&self, tcx: TyCtxt) -> Span { } } +impl<'tcx, T: Clone + Hash + Eq + Debug> Key for ty::ParameterEnvironmentAnd<'tcx, T> { + fn map_crate(&self) -> CrateNum { + LOCAL_CRATE + } + fn default_span(&self, _: TyCtxt) -> Span { + DUMMY_SP + } +} + trait Value<'tcx>: Sized { fn from_cycle_error<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self; } @@ -244,6 +253,24 @@ impl> QueryDescription for M { } } +impl<'tcx> QueryDescription for queries::is_copy_raw<'tcx> { + fn describe(_tcx: TyCtxt, env: ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) -> String { + format!("computing whether `{}` is `Copy`", env.value) + } +} + +impl<'tcx> QueryDescription for queries::is_sized_raw<'tcx> { + fn describe(_tcx: TyCtxt, env: ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) -> String { + format!("computing whether `{}` is `Sized`", env.value) + } +} + +impl<'tcx> QueryDescription for queries::is_freeze_raw<'tcx> { + fn describe(_tcx: TyCtxt, env: ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) -> String { + format!("computing whether `{}` is freeze", env.value) + } +} + impl<'tcx> QueryDescription for queries::super_predicates_of<'tcx> { fn describe(tcx: TyCtxt, def_id: DefId) -> String { format!("computing the supertraits of `{}`", @@ -856,6 +883,12 @@ fn default() -> Self { -> ty::trait_def::TraitImpls, [] specialization_graph_of: SpecializationGraph(DefId) -> Rc, [] is_object_safe: ObjectSafety(DefId) -> bool, + + // Trait selection queries. These are best used by invoking `ty.moves_by_default()`, + // `ty.is_copy()`, etc, since that will prune the environment where possible. + [] is_copy_raw: is_copy_dep_node(ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) -> bool, + [] is_sized_raw: is_sized_dep_node(ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) -> bool, + [] is_freeze_raw: is_freeze_dep_node(ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) -> bool, } fn coherent_trait_dep_node((_, def_id): (CrateNum, DefId)) -> DepNode { @@ -899,3 +932,18 @@ fn crate_variances(_: CrateNum) -> DepNode { fn relevant_trait_impls_for((def_id, _): (DefId, SimplifiedType)) -> DepNode { DepNode::TraitImpls(def_id) } + +fn is_copy_dep_node<'tcx>(_: ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) -> DepNode { + let krate_def_id = DefId::local(CRATE_DEF_INDEX); + DepNode::IsCopy(krate_def_id) +} + +fn is_sized_dep_node<'tcx>(_: ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) -> DepNode { + let krate_def_id = DefId::local(CRATE_DEF_INDEX); + DepNode::IsSized(krate_def_id) +} + +fn is_freeze_dep_node<'tcx>(_: ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) -> DepNode { + let krate_def_id = DefId::local(CRATE_DEF_INDEX); + DepNode::IsSized(krate_def_id) +} diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 359722ce96e..9036db9e3d5 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -35,7 +35,7 @@ use util::nodemap::{NodeSet, DefIdMap, FxHashMap, FxHashSet}; use serialize::{self, Encodable, Encoder}; -use std::cell::{Cell, RefCell}; +use std::cell::Cell; use std::collections::BTreeMap; use std::cmp; use std::fmt; @@ -507,8 +507,6 @@ pub enum FragmentInfo { // Caches for type_is_sized, type_moves_by_default const SIZEDNESS_CACHED = 1 << 16, const IS_SIZED = 1 << 17, - const MOVENESS_CACHED = 1 << 18, - const MOVES_BY_DEFAULT = 1 << 19, const FREEZENESS_CACHED = 1 << 20, const IS_FREEZE = 1 << 21, const NEEDS_DROP_CACHED = 1 << 22, @@ -1250,45 +1248,34 @@ pub fn is_empty(&self) -> bool { } /// When type checking, we use the `ParameterEnvironment` to track -/// details about the type/lifetime parameters that are in scope. -/// It primarily stores the bounds information. -/// -/// Note: This information might seem to be redundant with the data in -/// `tcx.ty_param_defs`, but it is not. That table contains the -/// parameter definitions from an "outside" perspective, but this -/// struct will contain the bounds for a parameter as seen from inside -/// the function body. Currently the only real distinction is that -/// bound lifetime parameters are replaced with free ones, but in the -/// future I hope to refine the representation of types so as to make -/// more distinctions clearer. -#[derive(Clone)] +/// details about the set of where-clauses that are in scope at this +/// particular point. +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub struct ParameterEnvironment<'tcx> { /// Obligations that the caller must satisfy. This is basically /// the set of bounds on the in-scope type parameters, translated /// into Obligations, and elaborated and normalized. - pub caller_bounds: &'tcx [ty::Predicate<'tcx>], - - /// A cache for `moves_by_default`. - pub is_copy_cache: RefCell, bool>>, + pub caller_bounds: &'tcx Slice>, +} - /// A cache for `type_is_sized` - pub is_sized_cache: RefCell, bool>>, +impl<'tcx> ParameterEnvironment<'tcx> { + pub fn and(self, value: T) -> ParameterEnvironmentAnd<'tcx, T> { + ParameterEnvironmentAnd { + param_env: self, + value: value, + } + } +} - /// A cache for `type_is_freeze` - pub is_freeze_cache: RefCell, bool>>, +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +pub struct ParameterEnvironmentAnd<'tcx, T> { + pub param_env: ParameterEnvironment<'tcx>, + pub value: T, } -impl<'a, 'tcx> ParameterEnvironment<'tcx> { - pub fn with_caller_bounds(&self, - caller_bounds: &'tcx [ty::Predicate<'tcx>]) - -> ParameterEnvironment<'tcx> - { - ParameterEnvironment { - caller_bounds: caller_bounds, - is_copy_cache: RefCell::new(FxHashMap()), - is_sized_cache: RefCell::new(FxHashMap()), - is_freeze_cache: RefCell::new(FxHashMap()), - } +impl<'tcx, T> ParameterEnvironmentAnd<'tcx, T> { + pub fn into_parts(self) -> (ParameterEnvironment<'tcx>, T) { + (self.param_env, self.value) } } @@ -2357,17 +2344,6 @@ pub fn impl_of_method(self, def_id: DefId) -> Option { } } - /// Construct a parameter environment suitable for static contexts or other contexts where there - /// are no free type/lifetime parameters in scope. - pub fn empty_parameter_environment(self) -> ParameterEnvironment<'tcx> { - ty::ParameterEnvironment { - caller_bounds: Slice::empty(), - is_copy_cache: RefCell::new(FxHashMap()), - is_sized_cache: RefCell::new(FxHashMap()), - is_freeze_cache: RefCell::new(FxHashMap()), - } - } - /// See `ParameterEnvironment` struct def'n for details. pub fn parameter_environment(self, def_id: DefId) -> ParameterEnvironment<'gcx> { // @@ -2391,12 +2367,7 @@ pub fn parameter_environment(self, def_id: DefId) -> ParameterEnvironment<'gcx> // sure that this will succeed without errors anyway. // - let unnormalized_env = ty::ParameterEnvironment { - caller_bounds: tcx.intern_predicates(&predicates), - is_copy_cache: RefCell::new(FxHashMap()), - is_sized_cache: RefCell::new(FxHashMap()), - is_freeze_cache: RefCell::new(FxHashMap()), - }; + let unnormalized_env = ty::ParameterEnvironment::new(tcx.intern_predicates(&predicates)); let body_id = self.hir.as_local_node_id(def_id).map_or(DUMMY_NODE_ID, |id| { self.hir.maybe_body_owned_by(id).map_or(id, |body| body.node_id) @@ -2566,6 +2537,7 @@ fn trait_of_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Option pub fn provide(providers: &mut ty::maps::Providers) { + util::provide(providers); *providers = ty::maps::Providers { associated_item, associated_item_def_ids, diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index c6c6a0e4700..b9276281a54 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -15,20 +15,19 @@ use infer::InferCtxt; use ich::{StableHashingContext, NodeIdHashingMode}; use traits::{self, Reveal}; -use ty::{self, Ty, TyCtxt, TypeAndMut, TypeFlags, TypeFoldable}; +use ty::{self, Ty, TyCtxt, TypeFlags, TypeFoldable}; use ty::ParameterEnvironment; use ty::fold::TypeVisitor; use ty::layout::{Layout, LayoutError}; use ty::subst::{Subst, Kind}; use ty::TypeVariants::*; use util::common::ErrorReported; -use util::nodemap::{FxHashMap, FxHashSet}; +use util::nodemap::FxHashSet; use middle::lang_items; use rustc_const_math::{ConstInt, ConstIsize, ConstUsize}; use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult, HashStable}; -use std::cell::RefCell; use std::cmp; use std::hash::Hash; use std::intrinsics; @@ -36,8 +35,6 @@ use syntax::attr::{self, SignedInt, UnsignedInt}; use syntax_pos::{Span, DUMMY_SP}; -use hir; - type Disr = ConstInt; pub trait IntTypeExt { @@ -153,6 +150,17 @@ pub enum Representability { } impl<'tcx> ParameterEnvironment<'tcx> { + /// Construct a trait environment suitable for contexts where + /// there are no where clauses in scope. + pub fn empty() -> Self { + Self::new(ty::Slice::empty()) + } + + /// Construct a trait environment with the given set of predicates. + pub fn new(caller_bounds: &'tcx ty::Slice>) -> Self { + ty::ParameterEnvironment { caller_bounds } + } + pub fn can_type_implement_copy<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, self_type: Ty<'tcx>, span: Span) -> Result<(), CopyImplementationError> { @@ -711,152 +719,40 @@ fn visit_binder>(&mut self, x: &ty::Binder) -> bool { } impl<'a, 'tcx> ty::TyS<'tcx> { - fn impls_bound(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: &ParameterEnvironment<'tcx>, - def_id: DefId, - cache: &RefCell, bool>>, - span: Span) -> bool - { - if self.has_param_types() || self.has_self_ty() { - if let Some(result) = cache.borrow().get(self) { - return *result; - } - } - let result = - tcx.infer_ctxt(param_env.clone(), Reveal::UserFacing) - .enter(|infcx| { - traits::type_known_to_meet_bound(&infcx, self, def_id, span) - }); + pub fn moves_by_default(&'tcx self, + tcx: TyCtxt<'a, 'tcx, 'tcx>, + param_env: ParameterEnvironment<'tcx>, + span: Span) + -> bool { if self.has_param_types() || self.has_self_ty() { - cache.borrow_mut().insert(self, result); - } - return result; - } - - // FIXME (@jroesch): I made this public to use it, not sure if should be private - pub fn moves_by_default(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: &ParameterEnvironment<'tcx>, - span: Span) -> bool { - if self.flags.get().intersects(TypeFlags::MOVENESS_CACHED) { - return self.flags.get().intersects(TypeFlags::MOVES_BY_DEFAULT); - } - - assert!(!self.needs_infer()); - - // Fast-path for primitive types - let result = match self.sty { - TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) | TyNever | - TyRawPtr(..) | TyFnDef(..) | TyFnPtr(_) | TyRef(_, TypeAndMut { - mutbl: hir::MutImmutable, .. - }) => Some(false), - - TyStr | TyRef(_, TypeAndMut { - mutbl: hir::MutMutable, .. - }) => Some(true), - - TyArray(..) | TySlice(..) | TyDynamic(..) | TyTuple(..) | - TyClosure(..) | TyAdt(..) | TyAnon(..) | - TyProjection(..) | TyParam(..) | TyInfer(..) | TyError => None - }.unwrap_or_else(|| { - !self.impls_bound(tcx, param_env, - tcx.require_lang_item(lang_items::CopyTraitLangItem), - ¶m_env.is_copy_cache, span) }); - - if !self.has_param_types() && !self.has_self_ty() { - self.flags.set(self.flags.get() | if result { - TypeFlags::MOVENESS_CACHED | TypeFlags::MOVES_BY_DEFAULT - } else { - TypeFlags::MOVENESS_CACHED - }); + !tcx.at(span).is_copy_raw(param_env.and(self)) + } else { + !tcx.is_copy_raw(ParameterEnvironment::empty().and(self)) } - - result } - #[inline] - pub fn is_sized(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: &ParameterEnvironment<'tcx>, - span: Span) -> bool + pub fn is_sized(&'tcx self, + tcx: TyCtxt<'a, 'tcx, 'tcx>, + param_env: ParameterEnvironment<'tcx>, + span: Span)-> bool { - if self.flags.get().intersects(TypeFlags::SIZEDNESS_CACHED) { - return self.flags.get().intersects(TypeFlags::IS_SIZED); - } - - self.is_sized_uncached(tcx, param_env, span) - } - - fn is_sized_uncached(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: &ParameterEnvironment<'tcx>, - span: Span) -> bool { - assert!(!self.needs_infer()); - - // Fast-path for primitive types - let result = match self.sty { - TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) | - TyRawPtr(..) | TyRef(..) | TyFnDef(..) | TyFnPtr(_) | - TyArray(..) | TyTuple(..) | TyClosure(..) | TyNever => Some(true), - - TyStr | TyDynamic(..) | TySlice(_) => Some(false), - - TyAdt(..) | TyProjection(..) | TyParam(..) | - TyInfer(..) | TyAnon(..) | TyError => None - }.unwrap_or_else(|| { - self.impls_bound(tcx, param_env, tcx.require_lang_item(lang_items::SizedTraitLangItem), - ¶m_env.is_sized_cache, span) }); - - if !self.has_param_types() && !self.has_self_ty() { - self.flags.set(self.flags.get() | if result { - TypeFlags::SIZEDNESS_CACHED | TypeFlags::IS_SIZED - } else { - TypeFlags::SIZEDNESS_CACHED - }); + if self.has_param_types() || self.has_self_ty() { + tcx.at(span).is_sized_raw(param_env.and(self)) + } else { + tcx.is_sized_raw(ParameterEnvironment::empty().and(self)) } - - result } - /// Returns `true` if and only if there are no `UnsafeCell`s - /// nested within the type (ignoring `PhantomData` or pointers). - #[inline] - pub fn is_freeze(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: &ParameterEnvironment<'tcx>, - span: Span) -> bool + pub fn is_freeze(&'tcx self, + tcx: TyCtxt<'a, 'tcx, 'tcx>, + param_env: ParameterEnvironment<'tcx>, + span: Span)-> bool { - if self.flags.get().intersects(TypeFlags::FREEZENESS_CACHED) { - return self.flags.get().intersects(TypeFlags::IS_FREEZE); - } - - self.is_freeze_uncached(tcx, param_env, span) - } - - fn is_freeze_uncached(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: &ParameterEnvironment<'tcx>, - span: Span) -> bool { - assert!(!self.needs_infer()); - - // Fast-path for primitive types - let result = match self.sty { - TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) | - TyRawPtr(..) | TyRef(..) | TyFnDef(..) | TyFnPtr(_) | - TyStr | TyNever => Some(true), - - TyArray(..) | TySlice(_) | - TyTuple(..) | TyClosure(..) | TyAdt(..) | - TyDynamic(..) | TyProjection(..) | TyParam(..) | - TyInfer(..) | TyAnon(..) | TyError => None - }.unwrap_or_else(|| { - self.impls_bound(tcx, param_env, tcx.require_lang_item(lang_items::FreezeTraitLangItem), - ¶m_env.is_freeze_cache, span) }); - - if !self.has_param_types() && !self.has_self_ty() { - self.flags.set(self.flags.get() | if result { - TypeFlags::FREEZENESS_CACHED | TypeFlags::IS_FREEZE - } else { - TypeFlags::FREEZENESS_CACHED - }); + if self.has_param_types() || self.has_self_ty() { + tcx.at(span).is_freeze_raw(param_env.and(self)) + } else { + tcx.is_freeze_raw(ParameterEnvironment::empty().and(self)) } - - result } /// If `ty.needs_drop(...)` returns `true`, then `ty` is definitely @@ -866,8 +762,10 @@ fn is_freeze_uncached(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, /// (Note that this implies that if `ty` has a destructor attached, /// then `needs_drop` will definitely return `true` for `ty`.) #[inline] - pub fn needs_drop(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: &ty::ParameterEnvironment<'tcx>) -> bool { + pub fn needs_drop(&'tcx self, + tcx: TyCtxt<'a, 'tcx, 'tcx>, + param_env: ty::ParameterEnvironment<'tcx>) + -> bool { if self.flags.get().intersects(TypeFlags::NEEDS_DROP_CACHED) { return self.flags.get().intersects(TypeFlags::NEEDS_DROP); } @@ -877,7 +775,7 @@ pub fn needs_drop(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, fn needs_drop_inner(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: &ty::ParameterEnvironment<'tcx>, + param_env: ty::ParameterEnvironment<'tcx>, stack: &mut FxHashSet>) -> bool { if self.flags.get().intersects(TypeFlags::NEEDS_DROP_CACHED) { @@ -902,7 +800,7 @@ fn needs_drop_inner(&'tcx self, fn needs_drop_uncached(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: &ty::ParameterEnvironment<'tcx>, + param_env: ty::ParameterEnvironment<'tcx>, stack: &mut FxHashSet>) -> bool { assert!(!self.needs_infer()); @@ -1158,3 +1056,42 @@ fn is_type_structurally_recursive<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, r } } + +fn is_copy_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + query: ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) + -> bool +{ + let (param_env, ty) = query.into_parts(); + let trait_def_id = tcx.require_lang_item(lang_items::CopyTraitLangItem); + tcx.infer_ctxt(param_env, Reveal::UserFacing) + .enter(|infcx| traits::type_known_to_meet_bound(&infcx, ty, trait_def_id, DUMMY_SP)) +} + +fn is_sized_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + query: ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) + -> bool +{ + let (param_env, ty) = query.into_parts(); + let trait_def_id = tcx.require_lang_item(lang_items::SizedTraitLangItem); + tcx.infer_ctxt(param_env, Reveal::UserFacing) + .enter(|infcx| traits::type_known_to_meet_bound(&infcx, ty, trait_def_id, DUMMY_SP)) +} + +fn is_freeze_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + query: ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) + -> bool +{ + let (param_env, ty) = query.into_parts(); + let trait_def_id = tcx.require_lang_item(lang_items::FreezeTraitLangItem); + tcx.infer_ctxt(param_env, Reveal::UserFacing) + .enter(|infcx| traits::type_known_to_meet_bound(&infcx, ty, trait_def_id, DUMMY_SP)) +} + +pub fn provide(providers: &mut ty::maps::Providers) { + *providers = ty::maps::Providers { + is_copy_raw, + is_sized_raw, + is_freeze_raw, + ..*providers + }; +} diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 8ca699339d3..340e4f2cfcc 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -504,13 +504,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } -impl<'tcx> fmt::Debug for ty::ParameterEnvironment<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "ParameterEnvironment({:?})", self.caller_bounds) - } -} - -impl<'tcx> fmt::Display for ty::RegionKind { +impl fmt::Display for ty::RegionKind { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if verbose() { return write!(f, "{:?}", *self); diff --git a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs index 520a90d940b..0178aa818d6 100644 --- a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs +++ b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs @@ -45,7 +45,7 @@ fn run_pass<'a, 'tcx>(&self, } let id = src.item_id(); let param_env = tcx.parameter_environment(tcx.hir.local_def_id(id)); - let move_data = MoveData::gather_moves(mir, tcx, ¶m_env); + let move_data = MoveData::gather_moves(mir, tcx, param_env); let elaborate_patch = { let mir = &*mir; let env = MoveDataParamEnv { @@ -196,7 +196,7 @@ fn tcx(&self) -> ty::TyCtxt<'a, 'tcx, 'tcx> { self.ctxt.tcx } - fn param_env(&self) -> &'a ty::ParameterEnvironment<'tcx> { + fn param_env(&self) -> ty::ParameterEnvironment<'tcx> { self.ctxt.param_env() } @@ -289,8 +289,9 @@ struct ElaborateDropsCtxt<'a, 'tcx: 'a> { impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { fn move_data(&self) -> &'b MoveData<'tcx> { &self.env.move_data } - fn param_env(&self) -> &'b ty::ParameterEnvironment<'tcx> { - &self.env.param_env + + fn param_env(&self) -> ty::ParameterEnvironment<'tcx> { + self.env.param_env } fn initialization_data_at(&self, loc: Location) -> InitializationData { diff --git a/src/librustc_borrowck/borrowck/mir/gather_moves.rs b/src/librustc_borrowck/borrowck/mir/gather_moves.rs index ed5e539f245..ebaae1b30d7 100644 --- a/src/librustc_borrowck/borrowck/mir/gather_moves.rs +++ b/src/librustc_borrowck/borrowck/mir/gather_moves.rs @@ -191,7 +191,7 @@ pub struct MovePathLookup<'tcx> { struct MoveDataBuilder<'a, 'tcx: 'a> { mir: &'a Mir<'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: &'a ParameterEnvironment<'tcx>, + param_env: ParameterEnvironment<'tcx>, data: MoveData<'tcx>, } @@ -203,7 +203,7 @@ pub enum MovePathError { impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> { fn new(mir: &'a Mir<'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: &'a ParameterEnvironment<'tcx>) + param_env: ParameterEnvironment<'tcx>) -> Self { let mut move_paths = IndexVec::new(); let mut path_map = IndexVec::new(); @@ -370,7 +370,7 @@ pub fn find(&self, lval: &Lvalue<'tcx>) -> LookupResult { impl<'a, 'tcx> MoveData<'tcx> { pub fn gather_moves(mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: &ParameterEnvironment<'tcx>) + param_env: ParameterEnvironment<'tcx>) -> Self { gather_moves(mir, tcx, param_env) } @@ -378,7 +378,7 @@ pub fn gather_moves(mir: &Mir<'tcx>, fn gather_moves<'a, 'tcx>(mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: &ParameterEnvironment<'tcx>) + param_env: ParameterEnvironment<'tcx>) -> MoveData<'tcx> { let mut builder = MoveDataBuilder::new(mir, tcx, param_env); diff --git a/src/librustc_borrowck/borrowck/mir/mod.rs b/src/librustc_borrowck/borrowck/mir/mod.rs index fbaa60f8445..003fc2ae9c2 100644 --- a/src/librustc_borrowck/borrowck/mir/mod.rs +++ b/src/librustc_borrowck/borrowck/mir/mod.rs @@ -66,7 +66,7 @@ pub fn borrowck_mir(bcx: &mut BorrowckCtxt, let mir = &tcx.mir_validated(def_id).borrow(); let param_env = tcx.parameter_environment(def_id); - let move_data = MoveData::gather_moves(mir, tcx, ¶m_env); + let move_data = MoveData::gather_moves(mir, tcx, param_env); let mdpe = MoveDataParamEnv { move_data: move_data, param_env: param_env }; let dead_unwinds = IdxSetBuf::new_empty(mir.basic_blocks().len()); let flow_inits = @@ -325,7 +325,7 @@ fn on_all_drop_children_bits<'a, 'tcx, F>( let ty = lvalue.ty(mir, tcx).to_ty(tcx); debug!("on_all_drop_children_bits({:?}, {:?} : {:?})", path, lvalue, ty); - if ty.needs_drop(tcx, &ctxt.param_env) { + if ty.needs_drop(tcx, ctxt.param_env) { each_child(child); } else { debug!("on_all_drop_children_bits - skipping") @@ -359,7 +359,7 @@ fn drop_flag_effects_for_location<'a, 'tcx, F>( where F: FnMut(MovePathIndex, DropFlagState) { let move_data = &ctxt.move_data; - let param_env = &ctxt.param_env; + let param_env = ctxt.param_env; debug!("drop_flag_effects_for_location({:?})", loc); // first, move out of the RHS diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index a18f91a9ee3..6e2a13a9a0d 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -52,7 +52,7 @@ fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl, tcx: self.tcx, tables: self.tcx.body_tables(b), region_maps: &self.tcx.region_maps(def_id), - param_env: &self.tcx.parameter_environment(def_id) + param_env: self.tcx.parameter_environment(def_id) }.visit_body(self.tcx.hir.body(b)); } } @@ -69,7 +69,7 @@ fn create_e0004<'a>(sess: &'a Session, sp: Span, error_message: String) -> Diagn struct MatchVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, tables: &'a ty::TypeckTables<'tcx>, - param_env: &'a ty::ParameterEnvironment<'tcx>, + param_env: ty::ParameterEnvironment<'tcx>, region_maps: &'a RegionMaps, } @@ -518,7 +518,7 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor, /// /// FIXME: this should be done by borrowck. fn check_for_mutation_in_guard(cx: &MatchVisitor, guard: &hir::Expr) { - cx.tcx.infer_ctxt((cx.tables, cx.param_env.clone()), Reveal::UserFacing).enter(|infcx| { + cx.tcx.infer_ctxt((cx.tables, cx.param_env), Reveal::UserFacing).enter(|infcx| { let mut checker = MutationChecker { cx: cx, }; diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 6423d65a4c2..d67f7bc901f 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -527,13 +527,11 @@ fn check_item(&mut self, cx: &LateContext, item: &hir::Item) { if def.has_dtor(cx.tcx) { return; } - let parameter_environment = cx.tcx.empty_parameter_environment(); - // FIXME (@jroesch) should probably inver this so that the parameter env still impls this - // method - if !ty.moves_by_default(cx.tcx, ¶meter_environment, item.span) { + let param_env = ty::ParameterEnvironment::empty(); + if !ty.moves_by_default(cx.tcx, param_env, item.span) { return; } - if parameter_environment.can_type_implement_copy(cx.tcx, ty, item.span).is_ok() { + if param_env.can_type_implement_copy(cx.tcx, ty, item.span).is_ok() { cx.span_lint(MISSING_COPY_IMPLEMENTATIONS, item.span, "type could implement `Copy`; consider adding `impl \ @@ -1258,7 +1256,8 @@ fn get_lints(&self) -> LintArray { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnionsWithDropFields { fn check_item(&mut self, ctx: &LateContext, item: &hir::Item) { if let hir::ItemUnion(ref vdata, _) = item.node { - let param_env = &ctx.tcx.parameter_environment(ctx.tcx.hir.local_def_id(item.id)); + let item_def_id = ctx.tcx.hir.local_def_id(item.id); + let param_env = ctx.tcx.parameter_environment(item_def_id); for field in vdata.fields() { let field_ty = ctx.tcx.type_of(ctx.tcx.hir.local_def_id(field.id)); if field_ty.needs_drop(ctx.tcx, param_env) { diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index 9ffce18fe15..d14d4d6c531 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -168,7 +168,7 @@ pub fn needs_drop(&mut self, ty: Ty<'tcx>) -> bool { type with inference types/regions", ty); }); - ty.needs_drop(self.tcx.global_tcx(), &self.infcx.parameter_environment) + ty.needs_drop(self.tcx.global_tcx(), self.infcx.parameter_environment) } pub fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> { diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 6f4480bf6dd..e80764b7af2 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -40,8 +40,6 @@ fn make_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, -> &'tcx Mir<'tcx> { debug!("make_shim({:?})", instance); - let did = instance.def_id(); - let param_env = tcx.parameter_environment(did); let mut result = match instance { ty::InstanceDef::Item(..) => @@ -98,7 +96,7 @@ fn make_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, ) } ty::InstanceDef::DropGlue(def_id, ty) => { - build_drop_shim(tcx, ¶m_env, def_id, ty) + build_drop_shim(tcx, def_id, ty) } ty::InstanceDef::Intrinsic(_) => { bug!("creating shims from intrinsics ({:?}) is unsupported", instance) @@ -144,7 +142,6 @@ fn local_decls_for_sig<'tcx>(sig: &ty::FnSig<'tcx>, span: Span) } fn build_drop_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, - param_env: &ty::ParameterEnvironment<'tcx>, def_id: DefId, ty: Option>) -> Mir<'tcx> @@ -189,10 +186,12 @@ fn build_drop_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, if let Some(..) = ty { let patch = { + let param_env = tcx.parameter_environment(def_id); let mut elaborator = DropShimElaborator { mir: &mir, patch: MirPatch::new(&mir), - tcx, param_env + tcx, + param_env }; let dropee = Lvalue::Local(Local::new(1+0)).deref(); let resume_block = elaborator.patch.resume_block(); @@ -218,7 +217,7 @@ pub struct DropShimElaborator<'a, 'tcx: 'a> { mir: &'a Mir<'tcx>, patch: MirPatch<'tcx>, tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, - param_env: &'a ty::ParameterEnvironment<'tcx>, + param_env: ty::ParameterEnvironment<'tcx>, } impl<'a, 'tcx> fmt::Debug for DropShimElaborator<'a, 'tcx> { @@ -233,7 +232,7 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for DropShimElaborator<'a, 'tcx> { fn patch(&mut self) -> &mut MirPatch<'tcx> { &mut self.patch } fn mir(&self) -> &'a Mir<'tcx> { self.mir } fn tcx(&self) -> ty::TyCtxt<'a, 'tcx, 'tcx> { self.tcx } - fn param_env(&self) -> &'a ty::ParameterEnvironment<'tcx> { self.param_env } + fn param_env(&self) -> ty::ParameterEnvironment<'tcx> { self.param_env } fn drop_style(&self, _path: Self::Path, mode: DropFlagMode) -> DropStyle { if let DropFlagMode::Shallow = mode { diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index e6d62dc6460..e2c10c1a547 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -253,7 +253,7 @@ fn should_inline(&self, // a regular goto. let ty = location.ty(&callee_mir, tcx).subst(tcx, callsite.substs); let ty = ty.to_ty(tcx); - if ty.needs_drop(tcx, ¶m_env) { + if ty.needs_drop(tcx, param_env) { cost += CALL_PENALTY; if let Some(unwind) = unwind { work_list.push(unwind); diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 72edf68f403..9737c603987 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -78,7 +78,7 @@ impl<'a, 'tcx> Qualif { /// Remove flags which are impossible for the given type. fn restrict(&mut self, ty: Ty<'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: &ty::ParameterEnvironment<'tcx>) { + param_env: ty::ParameterEnvironment<'tcx>) { if ty.is_freeze(tcx, param_env, DUMMY_SP) { *self = *self - Qualif::MUTABLE_INTERIOR; } @@ -193,7 +193,7 @@ fn add(&mut self, qualif: Qualif) { /// Add the given type's qualification to self.qualif. fn add_type(&mut self, ty: Ty<'tcx>) { self.add(Qualif::MUTABLE_INTERIOR | Qualif::NEEDS_DROP); - self.qualif.restrict(ty, self.tcx, &self.param_env); + self.qualif.restrict(ty, self.tcx, self.param_env); } /// Within the provided closure, self.qualif will start @@ -544,7 +544,7 @@ fn visit_lvalue(&mut self, static, use a constant instead"); } let ty = lvalue.ty(this.mir, this.tcx).to_ty(this.tcx); - this.qualif.restrict(ty, this.tcx, &this.param_env); + this.qualif.restrict(ty, this.tcx, this.param_env); } ProjectionElem::ConstantIndex {..} | diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index 9d7c7ec63cf..0573a4e2ee1 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -56,7 +56,7 @@ pub trait DropElaborator<'a, 'tcx: 'a> : fmt::Debug { fn patch(&mut self) -> &mut MirPatch<'tcx>; fn mir(&self) -> &'a Mir<'tcx>; fn tcx(&self) -> ty::TyCtxt<'a, 'tcx, 'tcx>; - fn param_env(&self) -> &'a ty::ParameterEnvironment<'tcx>; + fn param_env(&self) -> ty::ParameterEnvironment<'tcx>; fn drop_style(&self, path: Self::Path, mode: DropFlagMode) -> DropStyle; fn get_drop_flag(&mut self, path: Self::Path) -> Option>; diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index a0998b1bd1b..9a8ea52a665 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -38,7 +38,7 @@ use rustc::middle::mem_categorization as mc; use rustc::middle::mem_categorization::Categorization; use rustc::mir::transform::MirSource; -use rustc::ty::{self, Ty, TyCtxt}; +use rustc::ty::{self, ParameterEnvironment, Ty, TyCtxt}; use rustc::traits::Reveal; use rustc::util::common::ErrorReported; use rustc::util::nodemap::NodeSet; @@ -85,11 +85,11 @@ fn check_const_eval(&self, expr: &'gcx hir::Expr) { // Adds the worst effect out of all the values of one type. fn add_type(&mut self, ty: Ty<'gcx>) { - if !ty.is_freeze(self.tcx, &self.param_env, DUMMY_SP) { + if !ty.is_freeze(self.tcx, self.param_env, DUMMY_SP) { self.promotable = false; } - if ty.needs_drop(self.tcx, &self.param_env) { + if ty.needs_drop(self.tcx, self.param_env) { self.promotable = false; } } @@ -466,7 +466,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { in_fn: false, promotable: false, mut_rvalue_borrows: NodeSet(), - param_env: tcx.empty_parameter_environment(), + param_env: ParameterEnvironment::empty(), }.as_deep_visitor()); tcx.sess.abort_if_errors(); } diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index c2f2c63790a..7baaf25cf25 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -24,7 +24,7 @@ use type_::Type; use rustc_data_structures::base_n; use rustc::ty::subst::Substs; -use rustc::ty::{self, Ty, TyCtxt}; +use rustc::ty::{self, ParameterEnvironment, Ty, TyCtxt}; use rustc::ty::layout::{LayoutTyper, TyLayout}; use session::config::NoDebugInfo; use session::Session; @@ -79,7 +79,6 @@ pub fn extend(&mut self, stats: Stats) { pub struct SharedCrateContext<'a, 'tcx: 'a> { exported_symbols: NodeSet, tcx: TyCtxt<'a, 'tcx, 'tcx>, - empty_param_env: ty::ParameterEnvironment<'tcx>, check_overflow: bool, use_dll_storage_attrs: bool, @@ -315,7 +314,6 @@ pub fn new(tcx: TyCtxt<'b, 'tcx, 'tcx>, SharedCrateContext { exported_symbols: exported_symbols, - empty_param_env: tcx.empty_parameter_environment(), tcx: tcx, check_overflow: check_overflow, use_dll_storage_attrs: use_dll_storage_attrs, @@ -323,15 +321,15 @@ pub fn new(tcx: TyCtxt<'b, 'tcx, 'tcx>, } pub fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool { - ty.needs_drop(self.tcx, &self.empty_param_env) + ty.needs_drop(self.tcx, ParameterEnvironment::empty()) } pub fn type_is_sized(&self, ty: Ty<'tcx>) -> bool { - ty.is_sized(self.tcx, &self.empty_param_env, DUMMY_SP) + ty.is_sized(self.tcx, ParameterEnvironment::empty(), DUMMY_SP) } pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool { - ty.is_freeze(self.tcx, &self.empty_param_env, DUMMY_SP) + ty.is_freeze(self.tcx, ParameterEnvironment::empty(), DUMMY_SP) } pub fn exported_symbols<'a>(&'a self) -> &'a NodeSet { diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index d9f77e8f04f..320884b82f4 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -165,10 +165,6 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Finally we register each of these predicates as an obligation in // a fresh FulfillmentCtxt, and invoke select_all_or_error. - // Create a parameter environment that represents the implementation's - // method. - let impl_param_env = tcx.parameter_environment(impl_m.def_id); - // Create mapping from impl to skolemized. let impl_to_skol_substs = Substs::identity_for_item(tcx, impl_m.def_id); @@ -216,14 +212,13 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // The key step here is to update the caller_bounds's predicates to be // the new hybrid bounds we computed. let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_node_id); - let trait_param_env = impl_param_env.with_caller_bounds( - tcx.intern_predicates(&hybrid_preds.predicates)); - let trait_param_env = traits::normalize_param_env_or_error(tcx, - impl_m.def_id, - trait_param_env, - normalize_cause.clone()); - - tcx.infer_ctxt(trait_param_env, Reveal::UserFacing).enter(|infcx| { + let param_env = ty::ParameterEnvironment::new(tcx.intern_predicates(&hybrid_preds.predicates)); + let param_env = traits::normalize_param_env_or_error(tcx, + impl_m.def_id, + param_env, + normalize_cause.clone()); + + tcx.infer_ctxt(param_env, Reveal::UserFacing).enter(|infcx| { let inh = Inherited::new(infcx, impl_m.def_id); let infcx = &inh.infcx; -- 2.44.0