From 1b7acb6f34bb255d709fa153a49c77a570e6bbec Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 10 May 2017 10:28:06 -0400 Subject: [PATCH 01/14] 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 15c4469b74694..d268c8787ccee 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 @@ impl DepNode { // 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 1ecc277c7ca4d..7dcad0122e8a6 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -28,7 +28,7 @@ use middle::lang_items; 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 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { } 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 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.tables.borrow().upvar_capture_map.get(&upvar_id).cloned() } - pub fn param_env(&self) -> &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 1823373348bad..9e3381d8450d3 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 cccc20e5b296b..5be07e712b695 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -315,7 +315,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'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 bd38a6c3fd39a..66935dd3a3bb8 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -1079,7 +1079,7 @@ impl<'a, 'gcx, 'tcx> Layout { 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 @@ impl<'a, 'gcx, 'tcx> Layout { 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 85462bd9b1273..b0868ac389b46 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 @@ impl Key for (MirSuite, MirPassIndex, DefId) { } } +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 @@ define_maps! { <'tcx> -> 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 359722ce96ec9..9036db9e3d543 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -35,7 +35,7 @@ use util::common::ErrorReported; 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 @@ bitflags! { // 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 @@ impl<'tcx> InstantiatedPredicates<'tcx> { } /// 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 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } } - /// 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 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // 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 c6c6a0e47003d..b9276281a54e6 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -15,20 +15,19 @@ use hir::map::DefPathData; 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::ast::{self, Name}; 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 @@ impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W> } 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 @@ impl<'a, 'tcx> ty::TyS<'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 @@ impl<'a, 'tcx> ty::TyS<'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 @@ impl<'a, 'tcx> ty::TyS<'tcx> { 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 @@ impl<'a, 'tcx> ty::TyS<'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 8ca699339d36e..340e4f2cfccbc 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -504,13 +504,7 @@ impl<'tcx> fmt::Debug for ty::ClosureUpvar<'tcx> { } } -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 520a90d940b39..0178aa818d6a2 100644 --- a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs +++ b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs @@ -45,7 +45,7 @@ impl MirPass for ElaborateDrops { } 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 @@ impl<'a, 'b, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, 'b, '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 ed5e539f245f1..ebaae1b30d7d1 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 @@ impl<'tcx> MovePathLookup<'tcx> { 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 @@ impl<'a, 'tcx> MoveData<'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 fbaa60f84450b..003fc2ae9c25c 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 a18f91a9ee391..6e2a13a9a0d7e 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -52,7 +52,7 @@ impl<'a, 'tcx> Visitor<'tcx> for OuterVisitor<'a, 'tcx> { 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 6423d65a4c23f..d67f7bc901fe1 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -527,13 +527,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingCopyImplementations { 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 @@ impl LintPass for UnionsWithDropFields { 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 9ffce18fe150e..d14d4d6c5310c 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -168,7 +168,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { 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 6f4480bf6dd16..e80764b7af2da 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 e6d62dc646072..e2c10c1a547d9 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -253,7 +253,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> { // 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 72edf68f4034c..9737c60398795 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 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { /// 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 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { 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 9d7c7ec63cfc5..0573a4e2ee153 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 a0998b1bd1bfb..9a8ea52a6654b 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -38,7 +38,7 @@ use rustc::middle::expr_use_visitor as euv; 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 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> { // 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 c2f2c63790a4c..7baaf25cf2528 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -24,7 +24,7 @@ use partitioning::CodegenUnit; 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 @@ impl 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 @@ impl<'b, 'tcx> SharedCrateContext<'b, '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 @@ impl<'b, 'tcx> SharedCrateContext<'b, '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 d9f77e8f04f1c..320884b82f4c3 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; From 194d4bc15dd9938e1c77e7f4abdfcb51534da8b5 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 11 May 2017 17:40:03 -0400 Subject: [PATCH 02/14] make parameter-environment a query --- src/librustc/dep_graph/dep_node.rs | 2 + src/librustc/ty/maps.rs | 2 + src/librustc/ty/mod.rs | 63 +++++++++++++++--------------- 3 files changed, 35 insertions(+), 32 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index d268c8787ccee..2620a9c8f2d0e 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -162,6 +162,7 @@ pub enum DepNode { // not a hotspot. ProjectionCache { def_ids: Vec }, + ParameterEnvironment(D), DescribeDef(D), DefSpan(D), Stability(D), @@ -290,6 +291,7 @@ impl DepNode { let def_ids: Option> = def_ids.iter().map(op).collect(); def_ids.map(|d| ProjectionCache { def_ids: d }) } + ParameterEnvironment(ref d) => op(d).map(ParameterEnvironment), DescribeDef(ref d) => op(d).map(DescribeDef), DefSpan(ref d) => op(d).map(DefSpan), Stability(ref d) => op(d).map(Stability), diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index b0868ac389b46..2c3dae8493ac6 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -884,6 +884,8 @@ define_maps! { <'tcx> [] specialization_graph_of: SpecializationGraph(DefId) -> Rc, [] is_object_safe: ObjectSafety(DefId) -> bool, + [] parameter_environment: ParameterEnvironment(DefId) -> ty::ParameterEnvironment<'tcx>, + // 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, diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 9036db9e3d543..1071fa1c0f644 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2344,38 +2344,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } } - /// See `ParameterEnvironment` struct def'n for details. - pub fn parameter_environment(self, def_id: DefId) -> ParameterEnvironment<'gcx> { - // - // Compute the bounds on Self and the type parameters. - // - - let tcx = self.global_tcx(); - let bounds = tcx.predicates_of(def_id).instantiate_identity(tcx); - let predicates = bounds.predicates; - - // Finally, we have to normalize the bounds in the environment, in - // case they contain any associated type projections. This process - // can yield errors if the put in illegal associated types, like - // `::Bar` where `i32` does not implement `Foo`. We - // report these errors right here; this doesn't actually feel - // right to me, because constructing the environment feels like a - // kind of a "idempotent" action, but I'm not sure where would be - // a better place. In practice, we construct environments for - // every fn once during type checking, and we'll abort if there - // are any errors at that point, so after type checking you can be - // sure that this will succeed without errors anyway. - // - - 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) - }); - let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id); - traits::normalize_param_env_or_error(tcx, def_id, unnormalized_env, cause) - } - pub fn node_scope_region(self, id: NodeId) -> Region<'tcx> { self.mk_region(ty::ReScope(CodeExtent::Misc(id))) } @@ -2535,6 +2503,35 @@ fn trait_of_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Option }) } +/// See `ParameterEnvironment` struct def'n for details. +fn parameter_environment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + def_id: DefId) + -> ParameterEnvironment<'tcx> { + // Compute the bounds on Self and the type parameters. + + let bounds = tcx.predicates_of(def_id).instantiate_identity(tcx); + let predicates = bounds.predicates; + + // Finally, we have to normalize the bounds in the environment, in + // case they contain any associated type projections. This process + // can yield errors if the put in illegal associated types, like + // `::Bar` where `i32` does not implement `Foo`. We + // report these errors right here; this doesn't actually feel + // right to me, because constructing the environment feels like a + // kind of a "idempotent" action, but I'm not sure where would be + // a better place. In practice, we construct environments for + // every fn once during type checking, and we'll abort if there + // are any errors at that point, so after type checking you can be + // sure that this will succeed without errors anyway. + + let unnormalized_env = ty::ParameterEnvironment::new(tcx.intern_predicates(&predicates)); + + let body_id = tcx.hir.as_local_node_id(def_id).map_or(DUMMY_NODE_ID, |id| { + tcx.hir.maybe_body_owned_by(id).map_or(id, |body| body.node_id) + }); + let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id); + traits::normalize_param_env_or_error(tcx, def_id, unnormalized_env, cause) +} pub fn provide(providers: &mut ty::maps::Providers) { util::provide(providers); @@ -2544,6 +2541,7 @@ pub fn provide(providers: &mut ty::maps::Providers) { adt_sized_constraint, adt_dtorck_constraint, def_span, + parameter_environment, trait_of_item, trait_impls_of: trait_def::trait_impls_of_provider, relevant_trait_impls_for: trait_def::relevant_trait_impls_provider, @@ -2557,6 +2555,7 @@ pub fn provide_extern(providers: &mut ty::maps::Providers) { adt_dtorck_constraint, trait_impls_of: trait_def::trait_impls_of_provider, relevant_trait_impls_for: trait_def::relevant_trait_impls_provider, + parameter_environment, ..*providers }; } From 5a5c265e24cc79a8e28f01930380cb8a2481165c Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 12 May 2017 11:44:00 -0400 Subject: [PATCH 03/14] refactor common logic into `ParameterEnvironment::and()` --- src/librustc/ty/mod.rs | 31 +++++++++++++++++++++++++++---- src/librustc/ty/util.rs | 18 +++--------------- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 1071fa1c0f644..8264809e9c9d8 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1259,10 +1259,33 @@ pub struct ParameterEnvironment<'tcx> { } impl<'tcx> ParameterEnvironment<'tcx> { - pub fn and(self, value: T) -> ParameterEnvironmentAnd<'tcx, T> { - ParameterEnvironmentAnd { - param_env: self, - value: value, + /// Creates a suitable environment in which to perform trait + /// queries on the given value. This will either be `self` *or* + /// the empty environment, depending on whether `value` references + /// type parameters that are in scope. (If it doesn't, then any + /// judgements should be completely independent of the context, + /// and hence we can safely use the empty environment so as to + /// enable more sharing across functions.) + /// + /// NB: This is a mildly dubious thing to do, in that a function + /// (or other environment) might have wacky where-clauses like + /// `where Box: Copy`, which are clearly never + /// satisfiable. The code will at present ignore these, + /// effectively, when type-checking the body of said + /// function. This preserves existing behavior in any + /// case. --nmatsakis + pub fn and>(self, value: T) -> ParameterEnvironmentAnd<'tcx, T> { + assert!(!value.needs_infer()); + if value.has_param_types() || value.has_self_ty() { + ParameterEnvironmentAnd { + param_env: self, + value: value, + } + } else { + ParameterEnvironmentAnd { + param_env: ParameterEnvironment::empty(), + value: value, + } } } } diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index b9276281a54e6..da2552d37e2dc 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -724,11 +724,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> { param_env: ParameterEnvironment<'tcx>, span: Span) -> bool { - if self.has_param_types() || self.has_self_ty() { - !tcx.at(span).is_copy_raw(param_env.and(self)) - } else { - !tcx.is_copy_raw(ParameterEnvironment::empty().and(self)) - } + !tcx.at(span).is_copy_raw(param_env.and(self)) } pub fn is_sized(&'tcx self, @@ -736,11 +732,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> { param_env: ParameterEnvironment<'tcx>, span: Span)-> bool { - 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)) - } + tcx.at(span).is_sized_raw(param_env.and(self)) } pub fn is_freeze(&'tcx self, @@ -748,11 +740,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> { param_env: ParameterEnvironment<'tcx>, span: Span)-> bool { - 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)) - } + tcx.at(span).is_freeze_raw(param_env.and(self)) } /// If `ty.needs_drop(...)` returns `true`, then `ty` is definitely From b46c1a95d0fd309c4d6a8e42da7cc2da034326b9 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 12 May 2017 11:44:31 -0400 Subject: [PATCH 04/14] move `needs_drop` into a query --- src/librustc/dep_graph/dep_node.rs | 2 + src/librustc/ty/maps.rs | 12 ++ src/librustc/ty/util.rs | 178 ++++++++++++----------------- 3 files changed, 86 insertions(+), 106 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 2620a9c8f2d0e..12a3e5bfaa06a 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -111,6 +111,7 @@ pub enum DepNode { IsCopy(D), IsSized(D), IsFreeze(D), + NeedsDrop(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 @@ -240,6 +241,7 @@ impl DepNode { IsCopy(ref d) => op(d).map(IsCopy), IsSized(ref d) => op(d).map(IsSized), IsFreeze(ref d) => op(d).map(IsFreeze), + NeedsDrop(ref d) => op(d).map(NeedsDrop), 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/ty/maps.rs b/src/librustc/ty/maps.rs index 2c3dae8493ac6..5f2bc03ed9ea9 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -271,6 +271,12 @@ impl<'tcx> QueryDescription for queries::is_freeze_raw<'tcx> { } } +impl<'tcx> QueryDescription for queries::needs_drop_raw<'tcx> { + fn describe(_tcx: TyCtxt, env: ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) -> String { + format!("computing whether `{}` needs drop", env.value) + } +} + impl<'tcx> QueryDescription for queries::super_predicates_of<'tcx> { fn describe(tcx: TyCtxt, def_id: DefId) -> String { format!("computing the supertraits of `{}`", @@ -891,6 +897,7 @@ define_maps! { <'tcx> [] 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, + [] needs_drop_raw: needs_drop_dep_node(ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) -> bool, } fn coherent_trait_dep_node((_, def_id): (CrateNum, DefId)) -> DepNode { @@ -949,3 +956,8 @@ fn is_freeze_dep_node<'tcx>(_: ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) -> D let krate_def_id = DefId::local(CRATE_DEF_INDEX); DepNode::IsSized(krate_def_id) } + +fn needs_drop_dep_node<'tcx>(_: ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) -> DepNode { + let krate_def_id = DefId::local(CRATE_DEF_INDEX); + DepNode::NeedsDrop(krate_def_id) +} diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index da2552d37e2dc..0c2f4efccd531 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -15,14 +15,13 @@ use hir::map::DefPathData; use infer::InferCtxt; use ich::{StableHashingContext, NodeIdHashingMode}; use traits::{self, Reveal}; -use ty::{self, Ty, TyCtxt, TypeFlags, TypeFoldable}; +use ty::{self, Ty, TyCtxt, 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::FxHashSet; use middle::lang_items; use rustc_const_math::{ConstInt, ConstIsize, ConstUsize}; @@ -754,110 +753,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> { 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); - } - - self.needs_drop_uncached(tcx, param_env, &mut FxHashSet()) - } - - fn needs_drop_inner(&'tcx self, - tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: ty::ParameterEnvironment<'tcx>, - stack: &mut FxHashSet>) - -> bool { - if self.flags.get().intersects(TypeFlags::NEEDS_DROP_CACHED) { - return self.flags.get().intersects(TypeFlags::NEEDS_DROP); - } - - // This should be reported as an error by `check_representable`. - // - // Consider the type as not needing drop in the meanwhile to avoid - // further errors. - if let Some(_) = stack.replace(self) { - return false; - } - - let needs_drop = self.needs_drop_uncached(tcx, param_env, stack); - - // "Pop" the cycle detection "stack". - stack.remove(self); - - needs_drop - } - - fn needs_drop_uncached(&'tcx self, - tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: ty::ParameterEnvironment<'tcx>, - stack: &mut FxHashSet>) - -> bool { - assert!(!self.needs_infer()); - - let result = match self.sty { - // Fast-path for primitive types - ty::TyInfer(ty::FreshIntTy(_)) | ty::TyInfer(ty::FreshFloatTy(_)) | - ty::TyBool | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) | ty::TyNever | - ty::TyFnDef(..) | ty::TyFnPtr(_) | ty::TyChar | - ty::TyRawPtr(_) | ty::TyRef(..) | ty::TyStr => false, - - // Issue #22536: We first query type_moves_by_default. It sees a - // normalized version of the type, and therefore will definitely - // know whether the type implements Copy (and thus needs no - // cleanup/drop/zeroing) ... - _ if !self.moves_by_default(tcx, param_env, DUMMY_SP) => false, - - // ... (issue #22536 continued) but as an optimization, still use - // prior logic of asking for the structural "may drop". - - // FIXME(#22815): Note that this is a conservative heuristic; - // it may report that the type "may drop" when actual type does - // not actually have a destructor associated with it. But since - // the type absolutely did not have the `Copy` bound attached - // (see above), it is sound to treat it as having a destructor. - - // User destructors are the only way to have concrete drop types. - ty::TyAdt(def, _) if def.has_dtor(tcx) => true, - - // Can refer to a type which may drop. - // FIXME(eddyb) check this against a ParameterEnvironment. - ty::TyDynamic(..) | ty::TyProjection(..) | ty::TyParam(_) | - ty::TyAnon(..) | ty::TyInfer(_) | ty::TyError => true, - - // Structural recursion. - ty::TyArray(ty, _) | ty::TySlice(ty) => { - ty.needs_drop_inner(tcx, param_env, stack) - } - - ty::TyClosure(def_id, ref substs) => { - substs.upvar_tys(def_id, tcx) - .any(|ty| ty.needs_drop_inner(tcx, param_env, stack)) - } - - ty::TyTuple(ref tys, _) => { - tys.iter().any(|ty| ty.needs_drop_inner(tcx, param_env, stack)) - } - - // unions don't have destructors regardless of the child types - ty::TyAdt(def, _) if def.is_union() => false, - - ty::TyAdt(def, substs) => { - def.variants.iter().any(|v| { - v.fields.iter().any(|f| { - f.ty(tcx, substs).needs_drop_inner(tcx, param_env, stack) - }) - }) - } - }; - - if !self.has_param_types() && !self.has_self_ty() { - self.flags.set(self.flags.get() | if result { - TypeFlags::NEEDS_DROP_CACHED | TypeFlags::NEEDS_DROP - } else { - TypeFlags::NEEDS_DROP_CACHED - }); - } - - result + tcx.needs_drop_raw(param_env.and(self)) } #[inline] @@ -1075,11 +971,81 @@ fn is_freeze_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, .enter(|infcx| traits::type_known_to_meet_bound(&infcx, ty, trait_def_id, DUMMY_SP)) } +fn needs_drop_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + query: ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) + -> bool +{ + let (param_env, ty) = query.into_parts(); + + let needs_drop = |ty: Ty<'tcx>| -> bool { + match ty::queries::needs_drop_raw::try_get(tcx, DUMMY_SP, param_env.and(ty)) { + Ok(v) => v, + Err(_) => { + // Cycles should be reported as an error by `check_representable`. + // + // Consider the type as not needing drop in the meanwhile to avoid + // further errors. + false + } + } + }; + + assert!(!ty.needs_infer()); + + match ty.sty { + // Fast-path for primitive types + ty::TyInfer(ty::FreshIntTy(_)) | ty::TyInfer(ty::FreshFloatTy(_)) | + ty::TyBool | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) | ty::TyNever | + ty::TyFnDef(..) | ty::TyFnPtr(_) | ty::TyChar | + ty::TyRawPtr(_) | ty::TyRef(..) | ty::TyStr => false, + + // Issue #22536: We first query type_moves_by_default. It sees a + // normalized version of the type, and therefore will definitely + // know whether the type implements Copy (and thus needs no + // cleanup/drop/zeroing) ... + _ if !ty.moves_by_default(tcx, param_env, DUMMY_SP) => false, + + // ... (issue #22536 continued) but as an optimization, still use + // prior logic of asking for the structural "may drop". + + // FIXME(#22815): Note that this is a conservative heuristic; + // it may report that the type "may drop" when actual type does + // not actually have a destructor associated with it. But since + // the type absolutely did not have the `Copy` bound attached + // (see above), it is sound to treat it as having a destructor. + + // User destructors are the only way to have concrete drop types. + ty::TyAdt(def, _) if def.has_dtor(tcx) => true, + + // Can refer to a type which may drop. + // FIXME(eddyb) check this against a ParameterEnvironment. + ty::TyDynamic(..) | ty::TyProjection(..) | ty::TyParam(_) | + ty::TyAnon(..) | ty::TyInfer(_) | ty::TyError => true, + + // Structural recursion. + ty::TyArray(ty, _) | ty::TySlice(ty) => needs_drop(ty), + + ty::TyClosure(def_id, ref substs) => substs.upvar_tys(def_id, tcx).any(needs_drop), + + ty::TyTuple(ref tys, _) => tys.iter().cloned().any(needs_drop), + + // unions don't have destructors regardless of the child types + ty::TyAdt(def, _) if def.is_union() => false, + + ty::TyAdt(def, substs) => + def.variants.iter().any( + |variant| variant.fields.iter().any( + |field| needs_drop(field.ty(tcx, substs)))), + } +} + + pub fn provide(providers: &mut ty::maps::Providers) { *providers = ty::maps::Providers { is_copy_raw, is_sized_raw, is_freeze_raw, + needs_drop_raw, ..*providers }; } From 4464dcc7ce76dbd98be203b792cce89c1e5ab05f Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 12 May 2017 12:01:43 -0400 Subject: [PATCH 05/14] remove the cell from type flags completely --- src/librustc/ty/context.rs | 6 +++--- src/librustc/ty/flags.rs | 2 +- src/librustc/ty/fold.rs | 5 ++--- src/librustc/ty/mod.rs | 3 +-- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index b9355c264b3ef..5ee0b1c9e5ea4 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -138,7 +138,7 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> { let flags = super::flags::FlagComputation::for_sty(&st); let ty_struct = TyS { sty: st, - flags: Cell::new(flags.flags), + flags: flags.flags, region_depth: flags.depth, }; @@ -978,8 +978,8 @@ macro_rules! sty_debug_print { ty::TyError => /* unimportant */ continue, $(ty::$variant(..) => &mut $variant,)* }; - let region = t.flags.get().intersects(ty::TypeFlags::HAS_RE_INFER); - let ty = t.flags.get().intersects(ty::TypeFlags::HAS_TY_INFER); + let region = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER); + let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER); variant.total += 1; total.total += 1; diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index 686b99ba68094..46afa6ee7d011 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -167,7 +167,7 @@ impl FlagComputation { } fn add_ty(&mut self, ty: Ty) { - self.add_flags(ty.flags.get()); + self.add_flags(ty.flags); self.add_depth(ty.region_depth); } diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index 6de3c018bda0e..c17a54f4f69bb 100644 --- a/src/librustc/ty/fold.rs +++ b/src/librustc/ty/fold.rs @@ -625,9 +625,8 @@ struct HasTypeFlagsVisitor { impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor { fn visit_ty(&mut self, t: Ty) -> bool { - let flags = t.flags.get(); - debug!("HasTypeFlagsVisitor: t={:?} t.flags={:?} self.flags={:?}", t, flags, self.flags); - flags.intersects(self.flags) + debug!("HasTypeFlagsVisitor: t={:?} t.flags={:?} self.flags={:?}", t, t.flags, self.flags); + t.flags.intersects(self.flags) } fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool { diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 8264809e9c9d8..897b28986a54d 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -35,7 +35,6 @@ use util::common::ErrorReported; use util::nodemap::{NodeSet, DefIdMap, FxHashMap, FxHashSet}; use serialize::{self, Encodable, Encoder}; -use std::cell::Cell; use std::collections::BTreeMap; use std::cmp; use std::fmt; @@ -516,7 +515,7 @@ bitflags! { pub struct TyS<'tcx> { pub sty: TypeVariants<'tcx>, - pub flags: Cell, + pub flags: TypeFlags, // the maximal depth of any bound regions appearing in this type. region_depth: u32, From aa5232bca7f8d9107309bde9398d9c01db555b84 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 12 May 2017 12:03:43 -0400 Subject: [PATCH 06/14] kill SIZEDNESS_CACHED --- src/librustc/ty/mod.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 897b28986a54d..60783db99b9bf 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -504,8 +504,6 @@ bitflags! { TypeFlags::KEEP_IN_LOCAL_TCX.bits, // Caches for type_is_sized, type_moves_by_default - const SIZEDNESS_CACHED = 1 << 16, - const IS_SIZED = 1 << 17, const FREEZENESS_CACHED = 1 << 20, const IS_FREEZE = 1 << 21, const NEEDS_DROP_CACHED = 1 << 22, From 25ea618e41ab5273a22778bff3e366d827aa72da Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 12 May 2017 12:04:07 -0400 Subject: [PATCH 07/14] kill FREEZENESS_CACHED --- src/librustc/ty/mod.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 60783db99b9bf..0c93f8a7f2cc0 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -504,8 +504,6 @@ bitflags! { TypeFlags::KEEP_IN_LOCAL_TCX.bits, // Caches for type_is_sized, type_moves_by_default - const FREEZENESS_CACHED = 1 << 20, - const IS_FREEZE = 1 << 21, const NEEDS_DROP_CACHED = 1 << 22, const NEEDS_DROP = 1 << 23, } From ca65a8a80844f6aabb47d9239c5b65b43b58e539 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 12 May 2017 12:04:27 -0400 Subject: [PATCH 08/14] kill NEEDS_DROP_CACHED --- src/librustc/ty/mod.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 0c93f8a7f2cc0..357944c6a9e2d 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -502,10 +502,6 @@ bitflags! { TypeFlags::HAS_TY_CLOSURE.bits | TypeFlags::HAS_LOCAL_NAMES.bits | TypeFlags::KEEP_IN_LOCAL_TCX.bits, - - // Caches for type_is_sized, type_moves_by_default - const NEEDS_DROP_CACHED = 1 << 22, - const NEEDS_DROP = 1 << 23, } } From 226358e2fb2541678c21bdddc603311863a5ab93 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 15 May 2017 17:57:30 -0400 Subject: [PATCH 09/14] rename `ParameterEnvironment` to `ParamEnv` --- src/librustc/dep_graph/dep_node.rs | 4 +-- src/librustc/infer/mod.rs | 30 +++++++++---------- src/librustc/traits/README.md | 2 +- src/librustc/traits/mod.rs | 10 +++---- src/librustc/traits/select.rs | 2 +- src/librustc/ty/maps.rs | 28 ++++++++--------- src/librustc/ty/mod.rs | 28 ++++++++--------- src/librustc/ty/util.rs | 24 +++++++-------- src/librustc_borrowck/borrowck/check_loans.rs | 2 +- .../borrowck/mir/elaborate_drops.rs | 4 +-- .../borrowck/mir/gather_moves.rs | 10 +++---- src/librustc_borrowck/borrowck/mir/mod.rs | 2 +- src/librustc_borrowck/borrowck/mod.rs | 2 +- src/librustc_const_eval/check_match.rs | 2 +- src/librustc_lint/builtin.rs | 2 +- src/librustc_mir/shim.rs | 4 +-- 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 | 6 ++-- src/librustc_trans/context.rs | 8 ++--- src/librustc_typeck/check/compare_method.rs | 2 +- 22 files changed, 91 insertions(+), 91 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 12a3e5bfaa06a..291d0d7c937ed 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -163,7 +163,7 @@ pub enum DepNode { // not a hotspot. ProjectionCache { def_ids: Vec }, - ParameterEnvironment(D), + ParamEnv(D), DescribeDef(D), DefSpan(D), Stability(D), @@ -293,7 +293,7 @@ impl DepNode { let def_ids: Option> = def_ids.iter().map(op).collect(); def_ids.map(|d| ProjectionCache { def_ids: d }) } - ParameterEnvironment(ref d) => op(d).map(ParameterEnvironment), + ParamEnv(ref d) => op(d).map(ParamEnv), DescribeDef(ref d) => op(d).map(DescribeDef), DefSpan(ref d) => op(d).map(DefSpan), Stability(ref d) => op(d).map(Stability), diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 7dcad0122e8a6..090ad4c2661ad 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -28,7 +28,7 @@ use middle::lang_items; use mir::tcx::LvalueTy; use ty::subst::{Kind, Subst, Substs}; use ty::{TyVid, IntVid, FloatVid}; -use ty::{self, ParameterEnvironment, Ty, TyCtxt}; +use ty::{self, ParamEnv, Ty, TyCtxt}; use ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric}; use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use ty::relate::{Relate, RelateResult, TypeRelation}; @@ -161,7 +161,7 @@ pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { // For region variables. region_vars: RegionVarBindings<'a, 'gcx, 'tcx>, - pub parameter_environment: ty::ParameterEnvironment<'gcx>, + pub parameter_environment: ty::ParamEnv<'gcx>, /// Caches the results of trait selection. This cache is used /// for things that have to do with the parameters in scope. @@ -406,41 +406,41 @@ pub trait InferEnv<'a, 'tcx> { fn to_parts(self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> (Option<&'a ty::TypeckTables<'tcx>>, Option>, - Option>); + Option>); } impl<'a, 'tcx> InferEnv<'a, 'tcx> for () { fn to_parts(self, _: TyCtxt<'a, 'tcx, 'tcx>) -> (Option<&'a ty::TypeckTables<'tcx>>, Option>, - Option>) { + Option>) { (None, None, None) } } -impl<'a, 'tcx> InferEnv<'a, 'tcx> for ty::ParameterEnvironment<'tcx> { +impl<'a, 'tcx> InferEnv<'a, 'tcx> for ty::ParamEnv<'tcx> { fn to_parts(self, _: TyCtxt<'a, 'tcx, 'tcx>) -> (Option<&'a ty::TypeckTables<'tcx>>, Option>, - Option>) { + Option>) { (None, None, Some(self)) } } -impl<'a, 'tcx> InferEnv<'a, 'tcx> for (&'a ty::TypeckTables<'tcx>, ty::ParameterEnvironment<'tcx>) { +impl<'a, 'tcx> InferEnv<'a, 'tcx> for (&'a ty::TypeckTables<'tcx>, ty::ParamEnv<'tcx>) { fn to_parts(self, _: TyCtxt<'a, 'tcx, 'tcx>) -> (Option<&'a ty::TypeckTables<'tcx>>, Option>, - Option>) { + Option>) { (Some(self.0), None, Some(self.1)) } } -impl<'a, 'tcx> InferEnv<'a, 'tcx> for (ty::TypeckTables<'tcx>, ty::ParameterEnvironment<'tcx>) { +impl<'a, 'tcx> InferEnv<'a, 'tcx> for (ty::TypeckTables<'tcx>, ty::ParamEnv<'tcx>) { fn to_parts(self, _: TyCtxt<'a, 'tcx, 'tcx>) -> (Option<&'a ty::TypeckTables<'tcx>>, Option>, - Option>) { + Option>) { (None, Some(self.0), Some(self.1)) } } @@ -449,7 +449,7 @@ impl<'a, 'tcx> InferEnv<'a, 'tcx> for hir::BodyId { fn to_parts(self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> (Option<&'a ty::TypeckTables<'tcx>>, Option>, - Option>) { + Option>) { let def_id = tcx.hir.body_owner_def_id(self); (Some(tcx.typeck_tables_of(def_id)), None, @@ -465,7 +465,7 @@ pub struct InferCtxtBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { arena: DroplessArena, fresh_tables: Option>>, tables: Option<&'a ty::TypeckTables<'gcx>>, - param_env: Option>, + param_env: Option>, projection_mode: Reveal, } @@ -526,7 +526,7 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> { 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(|| ParameterEnvironment::empty()); + let param_env = param_env.take().unwrap_or_else(|| ParamEnv::empty()); global_tcx.enter_local(arena, |tcx| f(InferCtxt { tcx: tcx, tables: tables, @@ -648,7 +648,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { } pub fn normalize_associated_type_in_env( - self, value: &T, env: ty::ParameterEnvironment<'tcx> + self, value: &T, env: ty::ParamEnv<'tcx> ) -> T where T: TransNormalize<'tcx> { @@ -1672,7 +1672,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.tables.borrow().upvar_capture_map.get(&upvar_id).cloned() } - pub fn param_env(&self) -> ty::ParameterEnvironment<'gcx> { + pub fn param_env(&self) -> ty::ParamEnv<'gcx> { self.parameter_environment } diff --git a/src/librustc/traits/README.md b/src/librustc/traits/README.md index ff72f9dd07e36..2e94190203167 100644 --- a/src/librustc/traits/README.md +++ b/src/librustc/traits/README.md @@ -418,7 +418,7 @@ before, and hence the cache lookup would succeed, yielding One subtle interaction is that the results of trait lookup will vary depending on what where clauses are in scope. Therefore, we actually have *two* caches, a local and a global cache. The local cache is -attached to the `ParameterEnvironment` and the global cache attached +attached to ParamEnv` and the global cache attached to the `tcx`. We use the local cache whenever the result might depend on the where clauses that are in scope. The determination of which cache to use is done by the method `pick_candidate_cache` in diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 9e3381d8450d3..fd6efa9fd06c4 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -437,9 +437,9 @@ pub fn type_known_to_meet_bound<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx /// Normalizes the parameter environment, reporting errors if they occur. pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, region_context: DefId, - unnormalized_env: ty::ParameterEnvironment<'tcx>, + unnormalized_env: ty::ParamEnv<'tcx>, cause: ObligationCause<'tcx>) - -> ty::ParameterEnvironment<'tcx> + -> ty::ParamEnv<'tcx> { // I'm not wild about reporting errors here; I'd prefer to // have the errors get reported at a defined place (e.g., @@ -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 = ty::ParameterEnvironment::new(tcx.intern_predicates(&predicates)); + let elaborated_env = ty::ParamEnv::new(tcx.intern_predicates(&predicates)); tcx.infer_ctxt(elaborated_env, Reveal::UserFacing).enter(|infcx| { let predicates = match fully_normalize( @@ -485,7 +485,7 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // You would really want to pass infcx.parameter_environment.caller_bounds here, // but that is an interned slice, and fully_normalize takes &T and returns T, so // without further refactoring, a slice can't be used. Luckily, we still have the - // predicate vector from which we created the ParameterEnvironment in infcx, so we + // predicate vector from which we created the ParamEnv in infcx, so we // can pass that instead. It's roundabout and a bit brittle, but this code path // ought to be refactored anyway, and until then it saves us from having to copy. &predicates, @@ -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); - ty::ParameterEnvironment::new(tcx.intern_predicates(&predicates)) + ty::ParamEnv::new(tcx.intern_predicates(&predicates)) }) } diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 5be07e712b695..7366ed45f31bd 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -315,7 +315,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { self.infcx.tcx } - pub fn param_env(&self) -> ty::ParameterEnvironment<'gcx> { + pub fn param_env(&self) -> ty::ParamEnv<'gcx> { self.infcx.param_env() } diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index 5f2bc03ed9ea9..63f3f2ee2d2e4 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -136,7 +136,7 @@ impl Key for (MirSuite, MirPassIndex, DefId) { } } -impl<'tcx, T: Clone + Hash + Eq + Debug> Key for ty::ParameterEnvironmentAnd<'tcx, T> { +impl<'tcx, T: Clone + Hash + Eq + Debug> Key for ty::ParamEnvAnd<'tcx, T> { fn map_crate(&self) -> CrateNum { LOCAL_CRATE } @@ -254,25 +254,25 @@ impl> QueryDescription for M { } impl<'tcx> QueryDescription for queries::is_copy_raw<'tcx> { - fn describe(_tcx: TyCtxt, env: ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) -> String { + fn describe(_tcx: TyCtxt, env: ty::ParamEnvAnd<'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 { + fn describe(_tcx: TyCtxt, env: ty::ParamEnvAnd<'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 { + fn describe(_tcx: TyCtxt, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String { format!("computing whether `{}` is freeze", env.value) } } impl<'tcx> QueryDescription for queries::needs_drop_raw<'tcx> { - fn describe(_tcx: TyCtxt, env: ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) -> String { + fn describe(_tcx: TyCtxt, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String { format!("computing whether `{}` needs drop", env.value) } } @@ -890,14 +890,14 @@ define_maps! { <'tcx> [] specialization_graph_of: SpecializationGraph(DefId) -> Rc, [] is_object_safe: ObjectSafety(DefId) -> bool, - [] parameter_environment: ParameterEnvironment(DefId) -> ty::ParameterEnvironment<'tcx>, + [] parameter_environment: ParamEnv(DefId) -> ty::ParamEnv<'tcx>, // 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, - [] needs_drop_raw: needs_drop_dep_node(ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) -> bool, + [] is_copy_raw: is_copy_dep_node(ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool, + [] is_sized_raw: is_sized_dep_node(ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool, + [] is_freeze_raw: is_freeze_dep_node(ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool, + [] needs_drop_raw: needs_drop_dep_node(ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool, } fn coherent_trait_dep_node((_, def_id): (CrateNum, DefId)) -> DepNode { @@ -942,22 +942,22 @@ fn relevant_trait_impls_for((def_id, _): (DefId, SimplifiedType)) -> DepNode(_: ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) -> DepNode { +fn is_copy_dep_node<'tcx>(_: ty::ParamEnvAnd<'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 { +fn is_sized_dep_node<'tcx>(_: ty::ParamEnvAnd<'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 { +fn is_freeze_dep_node<'tcx>(_: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepNode { let krate_def_id = DefId::local(CRATE_DEF_INDEX); DepNode::IsSized(krate_def_id) } -fn needs_drop_dep_node<'tcx>(_: ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) -> DepNode { +fn needs_drop_dep_node<'tcx>(_: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepNode { let krate_def_id = DefId::local(CRATE_DEF_INDEX); DepNode::NeedsDrop(krate_def_id) } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 357944c6a9e2d..ec49d7ff2c6ee 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1238,18 +1238,18 @@ impl<'tcx> InstantiatedPredicates<'tcx> { } } -/// When type checking, we use the `ParameterEnvironment` to track +/// When type checking, we use the `ParamEnv` to track /// 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> { +pub struct ParamEnv<'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 Slice>, } -impl<'tcx> ParameterEnvironment<'tcx> { +impl<'tcx> ParamEnv<'tcx> { /// Creates a suitable environment in which to perform trait /// queries on the given value. This will either be `self` *or* /// the empty environment, depending on whether `value` references @@ -1265,16 +1265,16 @@ impl<'tcx> ParameterEnvironment<'tcx> { /// effectively, when type-checking the body of said /// function. This preserves existing behavior in any /// case. --nmatsakis - pub fn and>(self, value: T) -> ParameterEnvironmentAnd<'tcx, T> { + pub fn and>(self, value: T) -> ParamEnvAnd<'tcx, T> { assert!(!value.needs_infer()); if value.has_param_types() || value.has_self_ty() { - ParameterEnvironmentAnd { + ParamEnvAnd { param_env: self, value: value, } } else { - ParameterEnvironmentAnd { - param_env: ParameterEnvironment::empty(), + ParamEnvAnd { + param_env: ParamEnv::empty(), value: value, } } @@ -1282,13 +1282,13 @@ impl<'tcx> ParameterEnvironment<'tcx> { } #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] -pub struct ParameterEnvironmentAnd<'tcx, T> { - pub param_env: ParameterEnvironment<'tcx>, +pub struct ParamEnvAnd<'tcx, T> { + pub param_env: ParamEnv<'tcx>, pub value: T, } -impl<'tcx, T> ParameterEnvironmentAnd<'tcx, T> { - pub fn into_parts(self) -> (ParameterEnvironment<'tcx>, T) { +impl<'tcx, T> ParamEnvAnd<'tcx, T> { + pub fn into_parts(self) -> (ParamEnv<'tcx>, T) { (self.param_env, self.value) } } @@ -2517,10 +2517,10 @@ fn trait_of_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Option }) } -/// See `ParameterEnvironment` struct def'n for details. +/// See `ParamEnv` struct def'n for details. fn parameter_environment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) - -> ParameterEnvironment<'tcx> { + -> ParamEnv<'tcx> { // Compute the bounds on Self and the type parameters. let bounds = tcx.predicates_of(def_id).instantiate_identity(tcx); @@ -2538,7 +2538,7 @@ fn parameter_environment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // are any errors at that point, so after type checking you can be // sure that this will succeed without errors anyway. - let unnormalized_env = ty::ParameterEnvironment::new(tcx.intern_predicates(&predicates)); + let unnormalized_env = ty::ParamEnv::new(tcx.intern_predicates(&predicates)); let body_id = tcx.hir.as_local_node_id(def_id).map_or(DUMMY_NODE_ID, |id| { tcx.hir.maybe_body_owned_by(id).map_or(id, |body| body.node_id) diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 0c2f4efccd531..d18b0a69ade22 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -16,7 +16,7 @@ use infer::InferCtxt; use ich::{StableHashingContext, NodeIdHashingMode}; use traits::{self, Reveal}; use ty::{self, Ty, TyCtxt, TypeFoldable}; -use ty::ParameterEnvironment; +use ty::ParamEnv; use ty::fold::TypeVisitor; use ty::layout::{Layout, LayoutError}; use ty::subst::{Subst, Kind}; @@ -148,7 +148,7 @@ pub enum Representability { SelfRecursive(Vec), } -impl<'tcx> ParameterEnvironment<'tcx> { +impl<'tcx> ParamEnv<'tcx> { /// Construct a trait environment suitable for contexts where /// there are no where clauses in scope. pub fn empty() -> Self { @@ -157,7 +157,7 @@ impl<'tcx> ParameterEnvironment<'tcx> { /// Construct a trait environment with the given set of predicates. pub fn new(caller_bounds: &'tcx ty::Slice>) -> Self { - ty::ParameterEnvironment { caller_bounds } + ty::ParamEnv { caller_bounds } } pub fn can_type_implement_copy<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, @@ -720,7 +720,7 @@ impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W> impl<'a, 'tcx> ty::TyS<'tcx> { pub fn moves_by_default(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: ParameterEnvironment<'tcx>, + param_env: ParamEnv<'tcx>, span: Span) -> bool { !tcx.at(span).is_copy_raw(param_env.and(self)) @@ -728,7 +728,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> { pub fn is_sized(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: ParameterEnvironment<'tcx>, + param_env: ParamEnv<'tcx>, span: Span)-> bool { tcx.at(span).is_sized_raw(param_env.and(self)) @@ -736,7 +736,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> { pub fn is_freeze(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: ParameterEnvironment<'tcx>, + param_env: ParamEnv<'tcx>, span: Span)-> bool { tcx.at(span).is_freeze_raw(param_env.and(self)) @@ -751,7 +751,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> { #[inline] pub fn needs_drop(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: ty::ParameterEnvironment<'tcx>) + param_env: ty::ParamEnv<'tcx>) -> bool { tcx.needs_drop_raw(param_env.and(self)) } @@ -942,7 +942,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> { } fn is_copy_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - query: ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) + query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { let (param_env, ty) = query.into_parts(); @@ -952,7 +952,7 @@ fn is_copy_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } fn is_sized_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - query: ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) + query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { let (param_env, ty) = query.into_parts(); @@ -962,7 +962,7 @@ fn is_sized_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } fn is_freeze_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - query: ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) + query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { let (param_env, ty) = query.into_parts(); @@ -972,7 +972,7 @@ fn is_freeze_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } fn needs_drop_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - query: ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) + query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { let (param_env, ty) = query.into_parts(); @@ -1018,7 +1018,7 @@ fn needs_drop_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty::TyAdt(def, _) if def.has_dtor(tcx) => true, // Can refer to a type which may drop. - // FIXME(eddyb) check this against a ParameterEnvironment. + // FIXME(eddyb) check this against a ParamEnv. ty::TyDynamic(..) | ty::TyProjection(..) | ty::TyParam(_) | ty::TyAnon(..) | ty::TyInfer(_) | ty::TyError => true, diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index eeb5a3fb957fa..fd632d0c7418b 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -90,7 +90,7 @@ struct CheckLoanCtxt<'a, 'tcx: 'a> { dfcx_loans: &'a LoanDataFlow<'a, 'tcx>, move_data: &'a move_data::FlowedMoveData<'a, 'tcx>, all_loans: &'a [Loan<'tcx>], - param_env: &'a ty::ParameterEnvironment<'tcx>, + param_env: &'a ty::ParamEnv<'tcx>, } impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> { diff --git a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs index 0178aa818d6a2..5f13a080909ff 100644 --- a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs +++ b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs @@ -196,7 +196,7 @@ impl<'a, 'b, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, 'b, 'tcx> { self.ctxt.tcx } - fn param_env(&self) -> ty::ParameterEnvironment<'tcx> { + fn param_env(&self) -> ty::ParamEnv<'tcx> { self.ctxt.param_env() } @@ -290,7 +290,7 @@ 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) -> ty::ParameterEnvironment<'tcx> { + fn param_env(&self) -> ty::ParamEnv<'tcx> { self.env.param_env } diff --git a/src/librustc_borrowck/borrowck/mir/gather_moves.rs b/src/librustc_borrowck/borrowck/mir/gather_moves.rs index ebaae1b30d7d1..cf56a705839f6 100644 --- a/src/librustc_borrowck/borrowck/mir/gather_moves.rs +++ b/src/librustc_borrowck/borrowck/mir/gather_moves.rs @@ -9,7 +9,7 @@ // except according to those terms. -use rustc::ty::{self, TyCtxt, ParameterEnvironment}; +use rustc::ty::{self, TyCtxt, ParamEnv}; use rustc::mir::*; use rustc::util::nodemap::FxHashMap; use rustc_data_structures::indexed_vec::{IndexVec}; @@ -191,7 +191,7 @@ pub struct MovePathLookup<'tcx> { struct MoveDataBuilder<'a, 'tcx: 'a> { mir: &'a Mir<'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: ParameterEnvironment<'tcx>, + param_env: ParamEnv<'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: ParameterEnvironment<'tcx>) + param_env: ParamEnv<'tcx>) -> Self { let mut move_paths = IndexVec::new(); let mut path_map = IndexVec::new(); @@ -370,7 +370,7 @@ impl<'tcx> MovePathLookup<'tcx> { impl<'a, 'tcx> MoveData<'tcx> { pub fn gather_moves(mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: ParameterEnvironment<'tcx>) + param_env: ParamEnv<'tcx>) -> Self { gather_moves(mir, tcx, param_env) } @@ -378,7 +378,7 @@ impl<'a, 'tcx> MoveData<'tcx> { fn gather_moves<'a, 'tcx>(mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: ParameterEnvironment<'tcx>) + param_env: ParamEnv<'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 003fc2ae9c25c..aa7952e493ce9 100644 --- a/src/librustc_borrowck/borrowck/mir/mod.rs +++ b/src/librustc_borrowck/borrowck/mir/mod.rs @@ -51,7 +51,7 @@ fn has_rustc_mir_with(attrs: &[ast::Attribute], name: &str) -> Option pub struct MoveDataParamEnv<'tcx> { move_data: MoveData<'tcx>, - param_env: ty::ParameterEnvironment<'tcx>, + param_env: ty::ParamEnv<'tcx>, } pub fn borrowck_mir(bcx: &mut BorrowckCtxt, diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index c28d45be18d9e..f7c20542cbf2e 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -535,7 +535,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { lp: &LoanPath<'tcx>, the_move: &move_data::Move, moved_lp: &LoanPath<'tcx>, - _param_env: &ty::ParameterEnvironment<'tcx>) { + _param_env: &ty::ParamEnv<'tcx>) { let (verb, verb_participle) = match use_kind { MovedInUse => ("use", "used"), MovedInCapture => ("capture", "captured"), diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index 6e2a13a9a0d7e..91886b221fe1a 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -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: ty::ParameterEnvironment<'tcx>, + param_env: ty::ParamEnv<'tcx>, region_maps: &'a RegionMaps, } diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index d67f7bc901fe1..1a56a2d0777d4 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -527,7 +527,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingCopyImplementations { if def.has_dtor(cx.tcx) { return; } - let param_env = ty::ParameterEnvironment::empty(); + let param_env = ty::ParamEnv::empty(); if !ty.moves_by_default(cx.tcx, param_env, item.span) { return; } diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index e80764b7af2da..14d7be67d6446 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -217,7 +217,7 @@ pub struct DropShimElaborator<'a, 'tcx: 'a> { mir: &'a Mir<'tcx>, patch: MirPatch<'tcx>, tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, - param_env: ty::ParameterEnvironment<'tcx>, + param_env: ty::ParamEnv<'tcx>, } impl<'a, 'tcx> fmt::Debug for DropShimElaborator<'a, 'tcx> { @@ -232,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) -> ty::ParameterEnvironment<'tcx> { self.param_env } + fn param_env(&self) -> ty::ParamEnv<'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 e2c10c1a547d9..5516d84e121ad 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -545,7 +545,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> { } } -fn type_size_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, param_env: ty::ParameterEnvironment<'tcx>, +fn type_size_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> Option { tcx.infer_ctxt(param_env, traits::Reveal::All).enter(|infcx| { ty.layout(&infcx).ok().map(|layout| { diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 9737c60398795..c839061df16f7 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::ParamEnv<'tcx>) { if ty.is_freeze(tcx, param_env, DUMMY_SP) { *self = *self - Qualif::MUTABLE_INTERIOR; } @@ -128,7 +128,7 @@ struct Qualifier<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { mir: &'a Mir<'tcx>, rpo: ReversePostorder<'a, 'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>, - param_env: ty::ParameterEnvironment<'tcx>, + param_env: ty::ParamEnv<'tcx>, temp_qualif: IndexVec>, return_qualif: Option, qualif: Qualif, @@ -139,7 +139,7 @@ struct Qualifier<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: ty::ParameterEnvironment<'tcx>, + param_env: ty::ParamEnv<'tcx>, def_id: DefId, mir: &'a Mir<'tcx>, mode: Mode) diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index 0573a4e2ee153..585840ce1e509 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) -> ty::ParameterEnvironment<'tcx>; + fn param_env(&self) -> ty::ParamEnv<'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 9a8ea52a6654b..8b58e71a0d6d4 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -38,7 +38,7 @@ use rustc::middle::expr_use_visitor as euv; use rustc::middle::mem_categorization as mc; use rustc::middle::mem_categorization::Categorization; use rustc::mir::transform::MirSource; -use rustc::ty::{self, ParameterEnvironment, Ty, TyCtxt}; +use rustc::ty::{self, ParamEnv, Ty, TyCtxt}; use rustc::traits::Reveal; use rustc::util::common::ErrorReported; use rustc::util::nodemap::NodeSet; @@ -58,7 +58,7 @@ struct CheckCrateVisitor<'a, 'tcx: 'a> { in_fn: bool, promotable: bool, mut_rvalue_borrows: NodeSet, - param_env: ty::ParameterEnvironment<'tcx>, + param_env: ty::ParamEnv<'tcx>, tables: &'a ty::TypeckTables<'tcx>, } @@ -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: ParameterEnvironment::empty(), + param_env: ParamEnv::empty(), }.as_deep_visitor()); tcx.sess.abort_if_errors(); } diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index 7baaf25cf2528..5a1b8d96cbce6 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -24,7 +24,7 @@ use partitioning::CodegenUnit; use type_::Type; use rustc_data_structures::base_n; use rustc::ty::subst::Substs; -use rustc::ty::{self, ParameterEnvironment, Ty, TyCtxt}; +use rustc::ty::{self, ParamEnv, Ty, TyCtxt}; use rustc::ty::layout::{LayoutTyper, TyLayout}; use session::config::NoDebugInfo; use session::Session; @@ -321,15 +321,15 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> { } pub fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool { - ty.needs_drop(self.tcx, ParameterEnvironment::empty()) + ty.needs_drop(self.tcx, ParamEnv::empty()) } pub fn type_is_sized(&self, ty: Ty<'tcx>) -> bool { - ty.is_sized(self.tcx, ParameterEnvironment::empty(), DUMMY_SP) + ty.is_sized(self.tcx, ParamEnv::empty(), DUMMY_SP) } pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool { - ty.is_freeze(self.tcx, ParameterEnvironment::empty(), DUMMY_SP) + ty.is_freeze(self.tcx, ParamEnv::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 320884b82f4c3..d89a5e7a51912 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -212,7 +212,7 @@ 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 param_env = ty::ParameterEnvironment::new(tcx.intern_predicates(&hybrid_preds.predicates)); + let param_env = ty::ParamEnv::new(tcx.intern_predicates(&hybrid_preds.predicates)); let param_env = traits::normalize_param_env_or_error(tcx, impl_m.def_id, param_env, From 697146bf406deaa790915da346b6188220e562be Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 15 May 2017 17:58:58 -0400 Subject: [PATCH 10/14] use `ParamEnv` from `ty` rather than importing --- src/librustc/infer/mod.rs | 4 ++-- src/librustc_borrowck/borrowck/mir/gather_moves.rs | 10 +++++----- src/librustc_passes/consts.rs | 4 ++-- src/librustc_trans/context.rs | 8 ++++---- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 090ad4c2661ad..88606f977ba09 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -28,7 +28,7 @@ use middle::lang_items; use mir::tcx::LvalueTy; use ty::subst::{Kind, Subst, Substs}; use ty::{TyVid, IntVid, FloatVid}; -use ty::{self, ParamEnv, Ty, TyCtxt}; +use ty::{self, Ty, TyCtxt}; use ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric}; use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use ty::relate::{Relate, RelateResult, TypeRelation}; @@ -526,7 +526,7 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> { 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(|| ParamEnv::empty()); + let param_env = param_env.take().unwrap_or_else(|| ty::ParamEnv::empty()); global_tcx.enter_local(arena, |tcx| f(InferCtxt { tcx: tcx, tables: tables, diff --git a/src/librustc_borrowck/borrowck/mir/gather_moves.rs b/src/librustc_borrowck/borrowck/mir/gather_moves.rs index cf56a705839f6..931cdf4f68612 100644 --- a/src/librustc_borrowck/borrowck/mir/gather_moves.rs +++ b/src/librustc_borrowck/borrowck/mir/gather_moves.rs @@ -9,7 +9,7 @@ // except according to those terms. -use rustc::ty::{self, TyCtxt, ParamEnv}; +use rustc::ty::{self, TyCtxt}; use rustc::mir::*; use rustc::util::nodemap::FxHashMap; use rustc_data_structures::indexed_vec::{IndexVec}; @@ -191,7 +191,7 @@ pub struct MovePathLookup<'tcx> { struct MoveDataBuilder<'a, 'tcx: 'a> { mir: &'a Mir<'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: ParamEnv<'tcx>, + param_env: ty::ParamEnv<'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: ParamEnv<'tcx>) + param_env: ty::ParamEnv<'tcx>) -> Self { let mut move_paths = IndexVec::new(); let mut path_map = IndexVec::new(); @@ -370,7 +370,7 @@ impl<'tcx> MovePathLookup<'tcx> { impl<'a, 'tcx> MoveData<'tcx> { pub fn gather_moves(mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: ParamEnv<'tcx>) + param_env: ty::ParamEnv<'tcx>) -> Self { gather_moves(mir, tcx, param_env) } @@ -378,7 +378,7 @@ impl<'a, 'tcx> MoveData<'tcx> { fn gather_moves<'a, 'tcx>(mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: ParamEnv<'tcx>) + param_env: ty::ParamEnv<'tcx>) -> MoveData<'tcx> { let mut builder = MoveDataBuilder::new(mir, tcx, param_env); diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index 8b58e71a0d6d4..6f966be857a1e 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -38,7 +38,7 @@ use rustc::middle::expr_use_visitor as euv; use rustc::middle::mem_categorization as mc; use rustc::middle::mem_categorization::Categorization; use rustc::mir::transform::MirSource; -use rustc::ty::{self, ParamEnv, Ty, TyCtxt}; +use rustc::ty::{self, Ty, TyCtxt}; use rustc::traits::Reveal; use rustc::util::common::ErrorReported; use rustc::util::nodemap::NodeSet; @@ -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: ParamEnv::empty(), + param_env: ty::ParamEnv::empty(), }.as_deep_visitor()); tcx.sess.abort_if_errors(); } diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index 5a1b8d96cbce6..0dece586c930d 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -24,7 +24,7 @@ use partitioning::CodegenUnit; use type_::Type; use rustc_data_structures::base_n; use rustc::ty::subst::Substs; -use rustc::ty::{self, ParamEnv, Ty, TyCtxt}; +use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::layout::{LayoutTyper, TyLayout}; use session::config::NoDebugInfo; use session::Session; @@ -321,15 +321,15 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> { } pub fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool { - ty.needs_drop(self.tcx, ParamEnv::empty()) + ty.needs_drop(self.tcx, ty::ParamEnv::empty()) } pub fn type_is_sized(&self, ty: Ty<'tcx>) -> bool { - ty.is_sized(self.tcx, ParamEnv::empty(), DUMMY_SP) + ty.is_sized(self.tcx, ty::ParamEnv::empty(), DUMMY_SP) } pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool { - ty.is_freeze(self.tcx, ParamEnv::empty(), DUMMY_SP) + ty.is_freeze(self.tcx, ty::ParamEnv::empty(), DUMMY_SP) } pub fn exported_symbols<'a>(&'a self) -> &'a NodeSet { From 45dd0632bc63a04cdc1499a392d83139e2e8c348 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 15 May 2017 18:00:35 -0400 Subject: [PATCH 11/14] rename `parameter_environment` to `param_env` --- src/librustc/infer/mod.rs | 10 +++++----- src/librustc/traits/mod.rs | 8 ++++---- src/librustc/traits/specialize/mod.rs | 4 ++-- src/librustc/ty/layout.rs | 4 ++-- src/librustc/ty/maps.rs | 2 +- src/librustc/ty/mod.rs | 6 +++--- src/librustc_borrowck/borrowck/check_loans.rs | 2 +- src/librustc_borrowck/borrowck/mir/elaborate_drops.rs | 2 +- src/librustc_borrowck/borrowck/mir/mod.rs | 2 +- src/librustc_const_eval/check_match.rs | 2 +- src/librustc_lint/builtin.rs | 4 ++-- src/librustc_mir/build/mod.rs | 2 +- src/librustc_mir/hair/cx/mod.rs | 2 +- src/librustc_mir/shim.rs | 2 +- src/librustc_mir/transform/inline.rs | 2 +- src/librustc_mir/transform/qualify_consts.rs | 4 ++-- src/librustc_mir/transform/type_check.rs | 2 +- src/librustc_passes/consts.rs | 2 +- src/librustc_typeck/check/compare_method.rs | 4 ++-- src/librustc_typeck/check/dropck.rs | 2 +- src/librustc_typeck/check/method/probe.rs | 4 ++-- src/librustc_typeck/check/mod.rs | 4 ++-- src/librustc_typeck/check/regionck.rs | 6 +++--- src/librustc_typeck/coherence/builtin.rs | 6 +++--- 24 files changed, 44 insertions(+), 44 deletions(-) diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 88606f977ba09..270430f40df02 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -161,7 +161,7 @@ pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { // For region variables. region_vars: RegionVarBindings<'a, 'gcx, 'tcx>, - pub parameter_environment: ty::ParamEnv<'gcx>, + pub param_env: ty::ParamEnv<'gcx>, /// Caches the results of trait selection. This cache is used /// for things that have to do with the parameters in scope. @@ -453,7 +453,7 @@ impl<'a, 'tcx> InferEnv<'a, 'tcx> for hir::BodyId { let def_id = tcx.hir.body_owner_def_id(self); (Some(tcx.typeck_tables_of(def_id)), None, - Some(tcx.parameter_environment(def_id))) + Some(tcx.param_env(def_id))) } } @@ -498,7 +498,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> { int_unification_table: RefCell::new(UnificationTable::new()), float_unification_table: RefCell::new(UnificationTable::new()), region_vars: RegionVarBindings::new(self), - parameter_environment: param_env.unwrap(), + param_env: param_env.unwrap(), selection_cache: traits::SelectionCache::new(), evaluation_cache: traits::EvaluationCache::new(), projection_cache: RefCell::new(traits::ProjectionCache::new()), @@ -535,7 +535,7 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> { int_unification_table: RefCell::new(UnificationTable::new()), float_unification_table: RefCell::new(UnificationTable::new()), region_vars: RegionVarBindings::new(tcx), - parameter_environment: param_env, + param_env: param_env, selection_cache: traits::SelectionCache::new(), evaluation_cache: traits::EvaluationCache::new(), reported_trait_errors: RefCell::new(FxHashSet()), @@ -1673,7 +1673,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } pub fn param_env(&self) -> ty::ParamEnv<'gcx> { - self.parameter_environment + self.param_env } pub fn closure_kind(&self, diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index fd6efa9fd06c4..e358f39bd9a3a 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -482,7 +482,7 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx.infer_ctxt(elaborated_env, Reveal::UserFacing).enter(|infcx| { let predicates = match fully_normalize( &infcx, cause, - // You would really want to pass infcx.parameter_environment.caller_bounds here, + // You would really want to pass infcx.param_env.caller_bounds here, // but that is an interned slice, and fully_normalize takes &T and returns T, so // without further refactoring, a slice can't be used. Luckily, we still have the // predicate vector from which we created the ParamEnv in infcx, so we @@ -494,7 +494,7 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, Err(errors) => { infcx.report_fulfillment_errors(&errors); // An unnormalized env is better than nothing. - return infcx.parameter_environment; + return infcx.param_env; } }; @@ -516,13 +516,13 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // all things considered. tcx.sess.span_err(span, &fixup_err.to_string()); // An unnormalized env is better than nothing. - return infcx.parameter_environment; + return infcx.param_env; } }; let predicates = match tcx.lift_to_global(&predicates) { Some(predicates) => predicates, - None => return infcx.parameter_environment + None => return infcx.param_env }; debug!("normalize_param_env_or_error: resolved predicates={:?}", diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index 0e5779f9d1793..e0f28e3b49e91 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -180,7 +180,7 @@ pub fn specializes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } // create a parameter environment corresponding to a (skolemized) instantiation of impl1 - let penv = tcx.parameter_environment(impl1_def_id); + let penv = tcx.param_env(impl1_def_id); let impl1_trait_ref = tcx.impl_trait_ref(impl1_def_id).unwrap(); // Create a infcx, taking the predicates of impl1 as assumptions: @@ -250,7 +250,7 @@ fn fulfill_implication<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, source_trait_ref, target_trait_ref, errors, - infcx.parameter_environment.caller_bounds); + infcx.param_env.caller_bounds); Err(()) } diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 66935dd3a3bb8..1a8c74ff1f943 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -1079,7 +1079,7 @@ impl<'a, 'gcx, 'tcx> Layout { 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.param_env, DUMMY_SP) { Ok(Scalar { value: Pointer, non_zero: non_zero }) } else { let unsized_part = tcx.struct_tail(pointee); @@ -1268,7 +1268,7 @@ impl<'a, 'gcx, 'tcx> Layout { let kind = if def.is_enum() || def.variants[0].fields.len() == 0{ StructKind::AlwaysSizedUnivariant } else { - let param_env = tcx.parameter_environment(def.did); + let param_env = tcx.param_env(def.did); let fields = &def.variants[0].fields; let last_field = &fields[fields.len()-1]; let always_sized = tcx.type_of(last_field.did) diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index 63f3f2ee2d2e4..31492a8624da6 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -890,7 +890,7 @@ define_maps! { <'tcx> [] specialization_graph_of: SpecializationGraph(DefId) -> Rc, [] is_object_safe: ObjectSafety(DefId) -> bool, - [] parameter_environment: ParamEnv(DefId) -> ty::ParamEnv<'tcx>, + [] param_env: ParamEnv(DefId) -> ty::ParamEnv<'tcx>, // 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. diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index ec49d7ff2c6ee..fa731f6dde638 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2518,7 +2518,7 @@ fn trait_of_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Option } /// See `ParamEnv` struct def'n for details. -fn parameter_environment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, +fn param_env<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ParamEnv<'tcx> { // Compute the bounds on Self and the type parameters. @@ -2555,7 +2555,7 @@ pub fn provide(providers: &mut ty::maps::Providers) { adt_sized_constraint, adt_dtorck_constraint, def_span, - parameter_environment, + param_env, trait_of_item, trait_impls_of: trait_def::trait_impls_of_provider, relevant_trait_impls_for: trait_def::relevant_trait_impls_provider, @@ -2569,7 +2569,7 @@ pub fn provide_extern(providers: &mut ty::maps::Providers) { adt_dtorck_constraint, trait_impls_of: trait_def::trait_impls_of_provider, relevant_trait_impls_for: trait_def::relevant_trait_impls_provider, - parameter_environment, + param_env, ..*providers }; } diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index fd632d0c7418b..722ec6424fece 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -197,7 +197,7 @@ pub fn check_loans<'a, 'b, 'c, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, dfcx_loans: dfcx_loans, move_data: move_data, all_loans: all_loans, - param_env: &infcx.parameter_environment + param_env: &infcx.param_env }; euv::ExprUseVisitor::new(&mut clcx, &bccx.region_maps, &infcx).consume_body(body); } diff --git a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs index 5f13a080909ff..e0d86ff23f862 100644 --- a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs +++ b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs @@ -44,7 +44,7 @@ impl MirPass for ElaborateDrops { _ => return } let id = src.item_id(); - let param_env = tcx.parameter_environment(tcx.hir.local_def_id(id)); + let param_env = tcx.param_env(tcx.hir.local_def_id(id)); let move_data = MoveData::gather_moves(mir, tcx, param_env); let elaborate_patch = { let mir = &*mir; diff --git a/src/librustc_borrowck/borrowck/mir/mod.rs b/src/librustc_borrowck/borrowck/mir/mod.rs index aa7952e493ce9..2eb064305e87c 100644 --- a/src/librustc_borrowck/borrowck/mir/mod.rs +++ b/src/librustc_borrowck/borrowck/mir/mod.rs @@ -65,7 +65,7 @@ pub fn borrowck_mir(bcx: &mut BorrowckCtxt, // steals it, but it forces the `borrowck` query. let mir = &tcx.mir_validated(def_id).borrow(); - let param_env = tcx.parameter_environment(def_id); + let param_env = tcx.param_env(def_id); 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()); diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index 91886b221fe1a..7ed5f620816e1 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -52,7 +52,7 @@ impl<'a, 'tcx> Visitor<'tcx> for OuterVisitor<'a, 'tcx> { 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.param_env(def_id) }.visit_body(self.tcx.hir.body(b)); } } diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 1a56a2d0777d4..39b8e568ab48d 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -988,7 +988,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion { traits::Obligation::new(traits::ObligationCause::misc(span, expr_id), trait_ref.to_poly_trait_predicate()); - let param_env = tcx.parameter_environment(method.def_id); + let param_env = tcx.param_env(method.def_id); tcx.infer_ctxt(param_env, Reveal::UserFacing).enter(|infcx| { let mut selcx = traits::SelectionContext::new(&infcx); match selcx.select(&obligation) { @@ -1257,7 +1257,7 @@ 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 item_def_id = ctx.tcx.hir.local_def_id(item.id); - let param_env = ctx.tcx.parameter_environment(item_def_id); + let param_env = ctx.tcx.param_env(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/build/mod.rs b/src/librustc_mir/build/mod.rs index fb173e2487bff..9e151596a1ab5 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -172,7 +172,7 @@ fn create_constructor_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, { let span = tcx.hir.span(ctor_id); if let hir::VariantData::Tuple(ref fields, ctor_id) = *v { - let pe = tcx.parameter_environment(tcx.hir.local_def_id(ctor_id)); + let pe = tcx.param_env(tcx.hir.local_def_id(ctor_id)); tcx.infer_ctxt(pe, Reveal::UserFacing).enter(|infcx| { let (mut mir, src) = shim::build_adt_ctor(&infcx, ctor_id, fields, span); diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index d14d4d6c5310c..f61e2545f71fe 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -168,7 +168,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { 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.param_env) } pub fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> { diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 14d7be67d6446..428685d7f5058 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -186,7 +186,7 @@ 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 param_env = tcx.param_env(def_id); let mut elaborator = DropShimElaborator { mir: &mir, patch: MirPatch::new(&mir), diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 5516d84e121ad..edb2f44d18e35 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -220,7 +220,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> { // FIXME: Give a bonus to functions with only a single caller let def_id = tcx.hir.local_def_id(self.source.item_id()); - let param_env = tcx.parameter_environment(def_id); + let param_env = tcx.param_env(def_id); let mut first_block = true; let mut cost = 0; diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index c839061df16f7..4e84cbe6fecb1 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -937,7 +937,7 @@ fn mir_const_qualif<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, return Qualif::NOT_CONST.bits(); } - let param_env = tcx.parameter_environment(def_id); + let param_env = tcx.param_env(def_id); let mut qualifier = Qualifier::new(tcx, param_env, def_id, mir, Mode::Const); qualifier.qualify_const().bits() @@ -965,7 +965,7 @@ impl MirPass for QualifyAndPromoteConstants { MirSource::Const(_) | MirSource::Promoted(..) => return }; - let param_env = tcx.parameter_environment(def_id); + let param_env = tcx.param_env(def_id); if mode == Mode::Fn || mode == Mode::ConstFn { // This is ugly because Qualifier holds onto mir, diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs index 82c0d2c1b01c6..6d9603ea459d4 100644 --- a/src/librustc_mir/transform/type_check.rs +++ b/src/librustc_mir/transform/type_check.rs @@ -751,7 +751,7 @@ impl MirPass for TypeckMir { // broken MIR, so try not to report duplicate errors. return; } - let param_env = tcx.parameter_environment(def_id); + let param_env = tcx.param_env(def_id); tcx.infer_ctxt(param_env, Reveal::UserFacing).enter(|infcx| { let mut checker = TypeChecker::new(&infcx, item_id); { diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index 6f966be857a1e..25845c5768e8c 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -139,7 +139,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> { } let outer_penv = self.tcx.infer_ctxt(body_id, Reveal::UserFacing).enter(|infcx| { - let param_env = infcx.parameter_environment.clone(); + let param_env = infcx.param_env.clone(); let outer_penv = mem::replace(&mut self.param_env, param_env); let region_maps = &self.tcx.region_maps(item_def_id);; euv::ExprUseVisitor::new(self, region_maps, &infcx).consume_body(body); diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index d89a5e7a51912..767cf8f48cfea 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -223,7 +223,7 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let infcx = &inh.infcx; debug!("compare_impl_method: caller_bounds={:?}", - infcx.parameter_environment.caller_bounds); + infcx.param_env.caller_bounds); let mut selcx = traits::SelectionContext::new(&infcx); @@ -345,7 +345,7 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let region_maps = RegionMaps::new(); let mut free_regions = FreeRegionMap::new(); free_regions.relate_free_regions_from_predicates( - &infcx.parameter_environment.caller_bounds); + &infcx.param_env.caller_bounds); infcx.resolve_regions_and_report_errors(impl_m.def_id, ®ion_maps, &free_regions); } else { let fcx = FnCtxt::new(&inh, impl_m_node_id); diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index e029332559635..3ed0da05dc2c2 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -79,7 +79,7 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>( // check that the impl type can be made to match the trait type. - let impl_param_env = tcx.parameter_environment(self_type_did); + let impl_param_env = tcx.param_env(self_type_did); tcx.infer_ctxt(impl_param_env, Reveal::UserFacing).enter(|ref infcx| { let tcx = infcx.tcx; let mut fulfillment_cx = traits::FulfillmentContext::new(); diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index c1cf5192877c0..9ad72b2a137ea 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -566,7 +566,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { param_ty: ty::ParamTy) { // FIXME -- Do we want to commit to this behavior for param bounds? - let bounds: Vec<_> = self.parameter_environment + let bounds: Vec<_> = self.param_env .caller_bounds .iter() .filter_map(|predicate| { @@ -893,7 +893,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { debug!("assemble_where_clause_candidates(trait_def_id={:?})", trait_def_id); - let caller_predicates = self.parameter_environment.caller_bounds.to_vec(); + let caller_predicates = self.param_env.caller_bounds.to_vec(); for poly_bound in traits::elaborate_predicates(self.tcx, caller_predicates) .filter_map(|p| p.to_opt_poly_trait_ref()) .filter(|b| b.def_id() == trait_def_id) { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index d304d79bc52c8..24a88140cf041 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -539,7 +539,7 @@ impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> { pub fn build(tcx: TyCtxt<'a, 'gcx, 'gcx>, def_id: DefId) -> InheritedBuilder<'a, 'gcx, 'tcx> { let tables = ty::TypeckTables::empty(); - let param_env = tcx.parameter_environment(def_id); + let param_env = tcx.param_env(def_id); InheritedBuilder { infcx: tcx.infer_ctxt((tables, param_env), Reveal::UserFacing), def_id, @@ -1561,7 +1561,7 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> { let index = generics.type_param_to_index[&def_id.index]; ty::GenericPredicates { parent: None, - predicates: self.parameter_environment.caller_bounds.iter().filter(|predicate| { + predicates: self.param_env.caller_bounds.iter().filter(|predicate| { match **predicate { ty::Predicate::Trait(ref data) => { data.0.self_ty().is_param(index) diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 754bd288bfaa7..b29bf01ba1996 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -138,7 +138,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let subject = self.tcx.hir.local_def_id(item_id); let mut rcx = RegionCtxt::new(self, RepeatingScope(item_id), item_id, Subject(subject)); rcx.free_region_map.relate_free_regions_from_predicates( - &self.parameter_environment.caller_bounds); + &self.param_env.caller_bounds); rcx.relate_free_regions(wf_tys, item_id, span); rcx.visit_region_obligations(item_id); rcx.resolve_regions_and_report_errors(); @@ -158,7 +158,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } rcx.free_region_map.relate_free_regions_from_predicates( - &self.parameter_environment.caller_bounds); + &self.param_env.caller_bounds); rcx.resolve_regions_and_report_errors(); @@ -1682,7 +1682,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { fn declared_generic_bounds_from_env(&self, generic: GenericKind<'tcx>) -> Vec> { - let param_env = &self.parameter_environment; + let param_env = &self.param_env; // To start, collect bounds from user: let mut param_bounds = self.tcx.required_region_bounds(generic.to_ty(self.tcx), diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index 556bd618c78cb..ff5599fb1bdbf 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/src/librustc_typeck/coherence/builtin.rs @@ -105,7 +105,7 @@ fn visit_implementation_of_copy<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, self_type); let span = tcx.hir.span(impl_node_id); - let param_env = tcx.parameter_environment(impl_did); + let param_env = tcx.param_env(impl_did); assert!(!self_type.has_escaping_regions()); debug!("visit_implementation_of_copy: self_type={:?} (free)", @@ -199,7 +199,7 @@ pub fn coerce_unsized_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, target); let span = tcx.hir.span(impl_node_id); - let param_env = tcx.parameter_environment(impl_did); + let param_env = tcx.param_env(impl_did); assert!(!source.has_escaping_regions()); let err_info = CoerceUnsizedInfo { custom_kind: None }; @@ -387,7 +387,7 @@ pub fn coerce_unsized_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Finally, resolve all regions. let region_maps = RegionMaps::new(); let mut free_regions = FreeRegionMap::new(); - free_regions.relate_free_regions_from_predicates(&infcx.parameter_environment + free_regions.relate_free_regions_from_predicates(&infcx.param_env .caller_bounds); infcx.resolve_regions_and_report_errors(impl_did, ®ion_maps, &free_regions); From 9317d372c4eb262a506f48836a83c3b6430ca2b9 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 15 May 2017 19:36:45 -0400 Subject: [PATCH 12/14] two more style nits --- src/librustc/traits/README.md | 20 ++++++++++---------- src/librustc/ty/util.rs | 9 ++++----- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/librustc/traits/README.md b/src/librustc/traits/README.md index 2e94190203167..c49df4b1ad9ea 100644 --- a/src/librustc/traits/README.md +++ b/src/librustc/traits/README.md @@ -418,16 +418,16 @@ before, and hence the cache lookup would succeed, yielding One subtle interaction is that the results of trait lookup will vary depending on what where clauses are in scope. Therefore, we actually have *two* caches, a local and a global cache. The local cache is -attached to ParamEnv` and the global cache attached -to the `tcx`. We use the local cache whenever the result might depend -on the where clauses that are in scope. The determination of which -cache to use is done by the method `pick_candidate_cache` in -`select.rs`. At the moment, we use a very simple, conservative rule: -if there are any where-clauses in scope, then we use the local cache. -We used to try and draw finer-grained distinctions, but that led to a -serious of annoying and weird bugs like #22019 and #18290. This simple -rule seems to be pretty clearly safe and also still retains a very -high hit rate (~95% when compiling rustc). +attached to the `ParamEnv` and the global cache attached to the +`tcx`. We use the local cache whenever the result might depend on the +where clauses that are in scope. The determination of which cache to +use is done by the method `pick_candidate_cache` in `select.rs`. At +the moment, we use a very simple, conservative rule: if there are any +where-clauses in scope, then we use the local cache. We used to try +and draw finer-grained distinctions, but that led to a serious of +annoying and weird bugs like #22019 and #18290. This simple rule seems +to be pretty clearly safe and also still retains a very high hit rate +(~95% when compiling rustc). # Specialization diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index d18b0a69ade22..01fed11fc97af 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -16,7 +16,6 @@ use infer::InferCtxt; use ich::{StableHashingContext, NodeIdHashingMode}; use traits::{self, Reveal}; use ty::{self, Ty, TyCtxt, TypeFoldable}; -use ty::ParamEnv; use ty::fold::TypeVisitor; use ty::layout::{Layout, LayoutError}; use ty::subst::{Subst, Kind}; @@ -148,7 +147,7 @@ pub enum Representability { SelfRecursive(Vec), } -impl<'tcx> ParamEnv<'tcx> { +impl<'tcx> ty::ParamEnv<'tcx> { /// Construct a trait environment suitable for contexts where /// there are no where clauses in scope. pub fn empty() -> Self { @@ -720,7 +719,7 @@ impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W> impl<'a, 'tcx> ty::TyS<'tcx> { pub fn moves_by_default(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: ParamEnv<'tcx>, + param_env: ty::ParamEnv<'tcx>, span: Span) -> bool { !tcx.at(span).is_copy_raw(param_env.and(self)) @@ -728,7 +727,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> { pub fn is_sized(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: ParamEnv<'tcx>, + param_env: ty::ParamEnv<'tcx>, span: Span)-> bool { tcx.at(span).is_sized_raw(param_env.and(self)) @@ -736,7 +735,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> { pub fn is_freeze(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: ParamEnv<'tcx>, + param_env: ty::ParamEnv<'tcx>, span: Span)-> bool { tcx.at(span).is_freeze_raw(param_env.and(self)) From 04367100cd75d1136445e11e93786e875f38a2de Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 15 May 2017 23:23:40 -0400 Subject: [PATCH 13/14] fix DepNode Ideally, we'd have the `Ty` inserted directly in the dep-node, but since we can't do that yet, we extract the characteristic def-id of the type in question. --- src/librustc/ty/maps.rs | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index 31492a8624da6..fb352e5be8938 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -942,22 +942,26 @@ fn relevant_trait_impls_for((def_id, _): (DefId, SimplifiedType)) -> DepNode(_: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepNode { - let krate_def_id = DefId::local(CRATE_DEF_INDEX); - DepNode::IsCopy(krate_def_id) +fn is_copy_dep_node<'tcx>(key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepNode { + let def_id = ty::item_path::characteristic_def_id_of_type(key.value) + .unwrap_or(DefId::local(CRATE_DEF_INDEX)); + DepNode::IsCopy(def_id) } -fn is_sized_dep_node<'tcx>(_: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepNode { - let krate_def_id = DefId::local(CRATE_DEF_INDEX); - DepNode::IsSized(krate_def_id) +fn is_sized_dep_node<'tcx>(key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepNode { + let def_id = ty::item_path::characteristic_def_id_of_type(key.value) + .unwrap_or(DefId::local(CRATE_DEF_INDEX)); + DepNode::IsSized(def_id) } -fn is_freeze_dep_node<'tcx>(_: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepNode { - let krate_def_id = DefId::local(CRATE_DEF_INDEX); - DepNode::IsSized(krate_def_id) +fn is_freeze_dep_node<'tcx>(key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepNode { + let def_id = ty::item_path::characteristic_def_id_of_type(key.value) + .unwrap_or(DefId::local(CRATE_DEF_INDEX)); + DepNode::IsFreeze(def_id) } -fn needs_drop_dep_node<'tcx>(_: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepNode { - let krate_def_id = DefId::local(CRATE_DEF_INDEX); - DepNode::NeedsDrop(krate_def_id) +fn needs_drop_dep_node<'tcx>(key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepNode { + let def_id = ty::item_path::characteristic_def_id_of_type(key.value) + .unwrap_or(DefId::local(CRATE_DEF_INDEX)); + DepNode::NeedsDrop(def_id) } From 83641a9b6d2a622f5705ab76152cffb41d60fa3a Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 16 May 2017 08:43:23 -0400 Subject: [PATCH 14/14] fix `atomic_lock_free` test case --- src/test/run-make/atomic-lock-free/atomic_lock_free.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/run-make/atomic-lock-free/atomic_lock_free.rs b/src/test/run-make/atomic-lock-free/atomic_lock_free.rs index 023f2218b87ae..b41e8e9226b32 100644 --- a/src/test/run-make/atomic-lock-free/atomic_lock_free.rs +++ b/src/test/run-make/atomic-lock-free/atomic_lock_free.rs @@ -20,6 +20,8 @@ extern "rust-intrinsic" { trait Sized {} #[lang = "copy"] trait Copy {} +#[lang = "freeze"] +trait Freeze {} #[cfg(target_has_atomic = "8")] pub unsafe fn atomic_u8(x: *mut u8) {