about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMark Rousskov <mark.simulacrum@gmail.com>2020-07-02 20:52:40 -0400
committerMark Rousskov <mark.simulacrum@gmail.com>2020-07-05 09:51:42 -0400
commitaae1215f7faa3aac5ada7e82585b86f1282cd89e (patch)
tree42b67b641639f5782797a96b7401dffa1db05e70
parent3503f565e1fb7296983757d2716346f48a4a262b (diff)
downloadrust-aae1215f7faa3aac5ada7e82585b86f1282cd89e.tar.gz
rust-aae1215f7faa3aac5ada7e82585b86f1282cd89e.zip
Shrink ParamEnv to 16 bytes
-rw-r--r--src/librustc_infer/infer/outlives/mod.rs2
-rw-r--r--src/librustc_infer/infer/outlives/verify.rs2
-rw-r--r--src/librustc_infer/traits/mod.rs2
-rw-r--r--src/librustc_middle/ty/layout.rs2
-rw-r--r--src/librustc_middle/ty/mod.rs121
-rw-r--r--src/librustc_middle/ty/structural_impls.rs7
-rw-r--r--src/librustc_mir/const_eval/eval_queries.rs10
-rw-r--r--src/librustc_mir/util/elaborate_drops.rs2
-rw-r--r--src/librustc_trait_selection/traits/auto_trait.rs8
-rw-r--r--src/librustc_trait_selection/traits/chalk_fulfill.rs2
-rw-r--r--src/librustc_trait_selection/traits/fulfill.rs2
-rw-r--r--src/librustc_trait_selection/traits/mod.rs8
-rw-r--r--src/librustc_trait_selection/traits/object_safety.rs12
-rw-r--r--src/librustc_trait_selection/traits/project.rs6
-rw-r--r--src/librustc_trait_selection/traits/query/normalize.rs2
-rw-r--r--src/librustc_trait_selection/traits/select/candidate_assembly.rs2
-rw-r--r--src/librustc_trait_selection/traits/select/mod.rs2
-rw-r--r--src/librustc_trait_selection/traits/specialize/mod.rs5
-rw-r--r--src/librustc_ty/instance.rs2
-rw-r--r--src/librustc_typeck/check/compare_method.rs4
-rw-r--r--src/librustc_typeck/check/method/probe.rs37
-rw-r--r--src/librustc_typeck/check/mod.rs24
-rw-r--r--src/librustdoc/clean/auto_trait.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs2
24 files changed, 187 insertions, 83 deletions
diff --git a/src/librustc_infer/infer/outlives/mod.rs b/src/librustc_infer/infer/outlives/mod.rs
index fd3b38e9d67..541a2f18045 100644
--- a/src/librustc_infer/infer/outlives/mod.rs
+++ b/src/librustc_infer/infer/outlives/mod.rs
@@ -11,7 +11,7 @@ pub fn explicit_outlives_bounds<'tcx>(
     param_env: ty::ParamEnv<'tcx>,
 ) -> impl Iterator<Item = OutlivesBound<'tcx>> + 'tcx {
     debug!("explicit_outlives_bounds()");
-    param_env.caller_bounds.into_iter().filter_map(move |predicate| match predicate.kind() {
+    param_env.caller_bounds().into_iter().filter_map(move |predicate| match predicate.kind() {
         ty::PredicateKind::Projection(..)
         | ty::PredicateKind::Trait(..)
         | ty::PredicateKind::Subtype(..)
diff --git a/src/librustc_infer/infer/outlives/verify.rs b/src/librustc_infer/infer/outlives/verify.rs
index 383979f8640..8f20b5743df 100644
--- a/src/librustc_infer/infer/outlives/verify.rs
+++ b/src/librustc_infer/infer/outlives/verify.rs
@@ -221,7 +221,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
         // dubious for projections, but it will work for simple cases
         // like `T` and `T::Item`. It may not work as well for things
         // like `<T as Foo<'a>>::Item`.
-        let c_b = self.param_env.caller_bounds;
+        let c_b = self.param_env.caller_bounds();
         let param_bounds = self.collect_outlives_from_predicate_list(&compare_ty, c_b.into_iter());
 
         // Next, collect regions we scraped from the well-formedness
diff --git a/src/librustc_infer/traits/mod.rs b/src/librustc_infer/traits/mod.rs
index 8cd1eb9957b..7e7c8588ffb 100644
--- a/src/librustc_infer/traits/mod.rs
+++ b/src/librustc_infer/traits/mod.rs
@@ -57,7 +57,7 @@ pub type TraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>;
 
 // `PredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
 #[cfg(target_arch = "x86_64")]
-static_assert_size!(PredicateObligation<'_>, 48);
+static_assert_size!(PredicateObligation<'_>, 40);
 
 pub type Obligations<'tcx, O> = Vec<Obligation<'tcx, O>>;
 pub type PredicateObligations<'tcx> = Vec<PredicateObligation<'tcx>>;
diff --git a/src/librustc_middle/ty/layout.rs b/src/librustc_middle/ty/layout.rs
index 39b8566e7a8..010370c6e41 100644
--- a/src/librustc_middle/ty/layout.rs
+++ b/src/librustc_middle/ty/layout.rs
@@ -1588,7 +1588,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
         // Ignore layouts that are done with non-empty environments or
         // non-monomorphic layouts, as the user only wants to see the stuff
         // resulting from the final codegen session.
-        if layout.ty.has_param_types_or_consts() || !self.param_env.caller_bounds.is_empty() {
+        if layout.ty.has_param_types_or_consts() || !self.param_env.caller_bounds().is_empty() {
             return;
         }
 
diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs
index 03aab2c0f9f..fde99f5c270 100644
--- a/src/librustc_middle/ty/mod.rs
+++ b/src/librustc_middle/ty/mod.rs
@@ -1,3 +1,5 @@
+// ignore-tidy-filelength
+
 pub use self::fold::{TypeFoldable, TypeVisitor};
 pub use self::AssocItemContainer::*;
 pub use self::BorrowKind::*;
@@ -45,6 +47,7 @@ use std::cell::RefCell;
 use std::cmp::Ordering;
 use std::fmt;
 use std::hash::{Hash, Hasher};
+use std::marker::PhantomData;
 use std::ops::Range;
 use std::ptr;
 
@@ -1571,17 +1574,34 @@ pub type PlaceholderConst = Placeholder<BoundVar>;
 /// 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, HashStable, TypeFoldable)]
+#[derive(Copy, Clone)]
 pub struct ParamEnv<'tcx> {
+    // We pack the caller_bounds List pointer and a Reveal enum into this usize.
+    // Specifically, the low bit represents Reveal, with 0 meaning `UserFacing`
+    // and 1 meaning `All`. The rest is the pointer.
+    //
+    // This relies on the List<ty::Predicate<'tcx>> type having at least 2-byte
+    // alignment. Lists start with a usize and are repr(C) so this should be
+    // fine; there is a debug_assert in the constructor as well.
+    //
+    // Note that the choice of 0 for UserFacing is intentional -- since it is the
+    // first variant in Reveal this means that joining the pointer is a simple `or`.
+    packed_data: usize,
+
     /// `Obligation`s that the caller must satisfy. This is basically
     /// the set of bounds on the in-scope type parameters, translated
     /// into `Obligation`s, and elaborated and normalized.
-    pub caller_bounds: &'tcx List<ty::Predicate<'tcx>>,
+    ///
+    /// Note: This is packed into the `packed_data` usize above, use the
+    /// `caller_bounds()` method to access it.
+    caller_bounds: PhantomData<&'tcx List<ty::Predicate<'tcx>>>,
 
     /// Typically, this is `Reveal::UserFacing`, but during codegen we
-    /// want `Reveal::All` -- note that this is always paired with an
-    /// empty environment. To get that, use `ParamEnv::reveal()`.
-    pub reveal: traits::Reveal,
+    /// want `Reveal::All`.
+    ///
+    /// Note: This is packed into the caller_bounds usize above, use the reveal()
+    /// method to access it.
+    reveal: PhantomData<traits::Reveal>,
 
     /// If this `ParamEnv` comes from a call to `tcx.param_env(def_id)`,
     /// register that `def_id` (useful for transitioning to the chalk trait
@@ -1589,6 +1609,57 @@ pub struct ParamEnv<'tcx> {
     pub def_id: Option<DefId>,
 }
 
+impl<'tcx> fmt::Debug for ParamEnv<'tcx> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("ParamEnv")
+            .field("caller_bounds", &self.caller_bounds())
+            .field("reveal", &self.reveal())
+            .field("def_id", &self.def_id)
+            .finish()
+    }
+}
+
+impl<'tcx> Hash for ParamEnv<'tcx> {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        self.caller_bounds().hash(state);
+        self.reveal().hash(state);
+        self.def_id.hash(state);
+    }
+}
+
+impl<'tcx> PartialEq for ParamEnv<'tcx> {
+    fn eq(&self, other: &Self) -> bool {
+        self.caller_bounds() == other.caller_bounds()
+            && self.reveal() == other.reveal()
+            && self.def_id == other.def_id
+    }
+}
+impl<'tcx> Eq for ParamEnv<'tcx> {}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ParamEnv<'tcx> {
+    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
+        self.caller_bounds().hash_stable(hcx, hasher);
+        self.reveal().hash_stable(hcx, hasher);
+        self.def_id.hash_stable(hcx, hasher);
+    }
+}
+
+impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> {
+    fn super_fold_with<F: ty::fold::TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
+        ParamEnv::new(
+            self.caller_bounds().fold_with(folder),
+            self.reveal().fold_with(folder),
+            self.def_id.fold_with(folder),
+        )
+    }
+
+    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
+        self.caller_bounds().visit_with(visitor)
+            || self.reveal().visit_with(visitor)
+            || self.def_id.visit_with(visitor)
+    }
+}
+
 impl<'tcx> ParamEnv<'tcx> {
     /// Construct a trait environment suitable for contexts where
     /// there are no where-clauses in scope. Hidden types (like `impl
@@ -1599,6 +1670,17 @@ impl<'tcx> ParamEnv<'tcx> {
         Self::new(List::empty(), Reveal::UserFacing, None)
     }
 
+    #[inline]
+    pub fn caller_bounds(self) -> &'tcx List<ty::Predicate<'tcx>> {
+        // mask out bottom bit
+        unsafe { &*((self.packed_data & (!1)) as *const _) }
+    }
+
+    #[inline]
+    pub fn reveal(self) -> traits::Reveal {
+        if self.packed_data & 1 == 0 { traits::Reveal::UserFacing } else { traits::Reveal::All }
+    }
+
     /// Construct a trait environment with no where-clauses in scope
     /// where the values of all `impl Trait` and other hidden types
     /// are revealed. This is suitable for monomorphized, post-typeck
@@ -1618,7 +1700,25 @@ impl<'tcx> ParamEnv<'tcx> {
         reveal: Reveal,
         def_id: Option<DefId>,
     ) -> Self {
-        ty::ParamEnv { caller_bounds, reveal, def_id }
+        let packed_data = caller_bounds as *const _ as usize;
+        // Check that we can pack the reveal data into the pointer.
+        debug_assert!(packed_data & 1 == 0);
+        ty::ParamEnv {
+            packed_data: packed_data
+                | match reveal {
+                    Reveal::UserFacing => 0,
+                    Reveal::All => 1,
+                },
+            caller_bounds: PhantomData,
+            reveal: PhantomData,
+            def_id,
+        }
+    }
+
+    pub fn with_user_facing(mut self) -> Self {
+        // clear bottom bit
+        self.packed_data &= !1;
+        self
     }
 
     /// Returns a new parameter environment with the same clauses, but
@@ -1627,13 +1727,14 @@ impl<'tcx> ParamEnv<'tcx> {
     /// the desired behavior during codegen and certain other special
     /// contexts; normally though we want to use `Reveal::UserFacing`,
     /// which is the default.
-    pub fn with_reveal_all(self) -> Self {
-        ty::ParamEnv { reveal: Reveal::All, ..self }
+    pub fn with_reveal_all(mut self) -> Self {
+        self.packed_data |= 1;
+        self
     }
 
     /// Returns this same environment but with no caller bounds.
     pub fn without_caller_bounds(self) -> Self {
-        ty::ParamEnv { caller_bounds: List::empty(), ..self }
+        Self::new(List::empty(), self.reveal(), self.def_id)
     }
 
     /// Creates a suitable environment in which to perform trait
@@ -1649,7 +1750,7 @@ impl<'tcx> ParamEnv<'tcx> {
     /// satisfiable. We generally want to behave as if they were true,
     /// although the surrounding function is never reachable.
     pub fn and<T: TypeFoldable<'tcx>>(self, value: T) -> ParamEnvAnd<'tcx, T> {
-        match self.reveal {
+        match self.reveal() {
             Reveal::UserFacing => ParamEnvAnd { param_env: self, value },
 
             Reveal::All => {
diff --git a/src/librustc_middle/ty/structural_impls.rs b/src/librustc_middle/ty/structural_impls.rs
index 1d3607fe32f..159af277d24 100644
--- a/src/librustc_middle/ty/structural_impls.rs
+++ b/src/librustc_middle/ty/structural_impls.rs
@@ -521,11 +521,8 @@ impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::Binder<T> {
 impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> {
     type Lifted = ty::ParamEnv<'tcx>;
     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&self.caller_bounds).map(|caller_bounds| ty::ParamEnv {
-            reveal: self.reveal,
-            caller_bounds,
-            def_id: self.def_id,
-        })
+        tcx.lift(&self.caller_bounds())
+            .map(|caller_bounds| ty::ParamEnv::new(caller_bounds, self.reveal(), self.def_id))
     }
 }
 
diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/src/librustc_mir/const_eval/eval_queries.rs
index d62300b3f55..d81817377a2 100644
--- a/src/librustc_mir/const_eval/eval_queries.rs
+++ b/src/librustc_mir/const_eval/eval_queries.rs
@@ -226,9 +226,9 @@ pub fn const_eval_validated_provider<'tcx>(
     key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
 ) -> ::rustc_middle::mir::interpret::ConstEvalResult<'tcx> {
     // see comment in const_eval_raw_provider for what we're doing here
-    if key.param_env.reveal == Reveal::All {
+    if key.param_env.reveal() == Reveal::All {
         let mut key = key;
-        key.param_env.reveal = Reveal::UserFacing;
+        key.param_env = key.param_env.with_user_facing();
         match tcx.const_eval_validated(key) {
             // try again with reveal all as requested
             Err(ErrorHandled::TooGeneric) => {}
@@ -267,9 +267,9 @@ pub fn const_eval_raw_provider<'tcx>(
     // information being available.
 
     // In case we fail in the `UserFacing` variant, we just do the real computation.
-    if key.param_env.reveal == Reveal::All {
+    if key.param_env.reveal() == Reveal::All {
         let mut key = key;
-        key.param_env.reveal = Reveal::UserFacing;
+        key.param_env = key.param_env.with_user_facing();
         match tcx.const_eval_raw(key) {
             // try again with reveal all as requested
             Err(ErrorHandled::TooGeneric) => {}
@@ -326,7 +326,7 @@ pub fn const_eval_raw_provider<'tcx>(
                 // this is `Reveal::UserFacing`, then it's expected that we could get a
                 // `TooGeneric` error. When we fall back to `Reveal::All`, then it will either
                 // succeed or we'll report this error then.
-                if key.param_env.reveal == Reveal::All {
+                if key.param_env.reveal() == Reveal::All {
                     tcx.sess.delay_span_bug(
                         err.span,
                         &format!("static eval failure did not emit an error: {:#?}", v),
diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs
index 5f55a812a4e..20c2f5688eb 100644
--- a/src/librustc_mir/util/elaborate_drops.rs
+++ b/src/librustc_mir/util/elaborate_drops.rs
@@ -279,7 +279,7 @@ where
                 let subpath = self.elaborator.field_subpath(variant_path, field);
                 let tcx = self.tcx();
 
-                assert_eq!(self.elaborator.param_env().reveal, Reveal::All);
+                assert_eq!(self.elaborator.param_env().reveal(), Reveal::All);
                 let field_ty =
                     tcx.normalize_erasing_regions(self.elaborator.param_env(), f.ty(tcx, substs));
                 (tcx.mk_place_field(base_place, field, field_ty), subpath)
diff --git a/src/librustc_trait_selection/traits/auto_trait.rs b/src/librustc_trait_selection/traits/auto_trait.rs
index da945a19185..8c8550d377a 100644
--- a/src/librustc_trait_selection/traits/auto_trait.rs
+++ b/src/librustc_trait_selection/traits/auto_trait.rs
@@ -281,8 +281,8 @@ impl AutoTraitFinder<'tcx> {
             },
         }));
 
-        let computed_preds = param_env.caller_bounds.iter();
-        let mut user_computed_preds: FxHashSet<_> = user_env.caller_bounds.iter().collect();
+        let computed_preds = param_env.caller_bounds().iter();
+        let mut user_computed_preds: FxHashSet<_> = user_env.caller_bounds().iter().collect();
 
         let mut new_env = param_env;
         let dummy_cause = ObligationCause::dummy();
@@ -368,12 +368,12 @@ impl AutoTraitFinder<'tcx> {
             )
             .map(|o| o.predicate);
             new_env =
-                ty::ParamEnv::new(tcx.mk_predicates(normalized_preds), param_env.reveal, None);
+                ty::ParamEnv::new(tcx.mk_predicates(normalized_preds), param_env.reveal(), None);
         }
 
         let final_user_env = ty::ParamEnv::new(
             tcx.mk_predicates(user_computed_preds.into_iter()),
-            user_env.reveal,
+            user_env.reveal(),
             None,
         );
         debug!(
diff --git a/src/librustc_trait_selection/traits/chalk_fulfill.rs b/src/librustc_trait_selection/traits/chalk_fulfill.rs
index 2ade4892752..a75240042ad 100644
--- a/src/librustc_trait_selection/traits/chalk_fulfill.rs
+++ b/src/librustc_trait_selection/traits/chalk_fulfill.rs
@@ -137,7 +137,7 @@ fn in_environment(
 
     let environment = match obligation.param_env.def_id {
         Some(def_id) => environment(infcx.tcx, def_id),
-        None if obligation.param_env.caller_bounds.is_empty() => ty::List::empty(),
+        None if obligation.param_env.caller_bounds().is_empty() => ty::List::empty(),
         // FIXME(chalk): this is hit in ui/where-clauses/where-clause-constraints-are-local-for-trait-impl
         // and ui/generics/generic-static-methods
         //_ => bug!("non-empty `ParamEnv` with no def-id"),
diff --git a/src/librustc_trait_selection/traits/fulfill.rs b/src/librustc_trait_selection/traits/fulfill.rs
index 32ab63458e7..800aef7284f 100644
--- a/src/librustc_trait_selection/traits/fulfill.rs
+++ b/src/librustc_trait_selection/traits/fulfill.rs
@@ -84,7 +84,7 @@ pub struct PendingPredicateObligation<'tcx> {
 
 // `PendingPredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
 #[cfg(target_arch = "x86_64")]
-static_assert_size!(PendingPredicateObligation<'_>, 72);
+static_assert_size!(PendingPredicateObligation<'_>, 64);
 
 impl<'a, 'tcx> FulfillmentContext<'tcx> {
     /// Creates a new fulfillment context.
diff --git a/src/librustc_trait_selection/traits/mod.rs b/src/librustc_trait_selection/traits/mod.rs
index 9ab87e6b6ca..78c50a1176a 100644
--- a/src/librustc_trait_selection/traits/mod.rs
+++ b/src/librustc_trait_selection/traits/mod.rs
@@ -297,7 +297,7 @@ pub fn normalize_param_env_or_error<'tcx>(
     );
 
     let mut predicates: Vec<_> =
-        util::elaborate_predicates(tcx, unnormalized_env.caller_bounds.into_iter())
+        util::elaborate_predicates(tcx, unnormalized_env.caller_bounds().into_iter())
             .map(|obligation| obligation.predicate)
             .collect();
 
@@ -305,7 +305,7 @@ pub fn normalize_param_env_or_error<'tcx>(
 
     let elaborated_env = ty::ParamEnv::new(
         tcx.intern_predicates(&predicates),
-        unnormalized_env.reveal,
+        unnormalized_env.reveal(),
         unnormalized_env.def_id,
     );
 
@@ -361,7 +361,7 @@ pub fn normalize_param_env_or_error<'tcx>(
     let outlives_env: Vec<_> =
         non_outlives_predicates.iter().chain(&outlives_predicates).cloned().collect();
     let outlives_env =
-        ty::ParamEnv::new(tcx.intern_predicates(&outlives_env), unnormalized_env.reveal, None);
+        ty::ParamEnv::new(tcx.intern_predicates(&outlives_env), unnormalized_env.reveal(), None);
     let outlives_predicates = match do_normalize_predicates(
         tcx,
         region_context,
@@ -383,7 +383,7 @@ pub fn normalize_param_env_or_error<'tcx>(
     debug!("normalize_param_env_or_error: final predicates={:?}", predicates);
     ty::ParamEnv::new(
         tcx.intern_predicates(&predicates),
-        unnormalized_env.reveal,
+        unnormalized_env.reveal(),
         unnormalized_env.def_id,
     )
 }
diff --git a/src/librustc_trait_selection/traits/object_safety.rs b/src/librustc_trait_selection/traits/object_safety.rs
index 5befc797a51..63714c2bae9 100644
--- a/src/librustc_trait_selection/traits/object_safety.rs
+++ b/src/librustc_trait_selection/traits/object_safety.rs
@@ -631,7 +631,7 @@ fn receiver_is_dispatchable<'tcx>(
     // create a modified param env, with `Self: Unsize<U>` and `U: Trait` added to caller bounds
     // `U: ?Sized` is already implied here
     let param_env = {
-        let mut param_env = tcx.param_env(method.def_id);
+        let param_env = tcx.param_env(method.def_id);
 
         // Self: Unsize<U>
         let unsize_predicate = ty::TraitRef {
@@ -656,15 +656,17 @@ fn receiver_is_dispatchable<'tcx>(
         };
 
         let caller_bounds: Vec<Predicate<'tcx>> = param_env
-            .caller_bounds
+            .caller_bounds()
             .iter()
             .chain(iter::once(unsize_predicate))
             .chain(iter::once(trait_predicate))
             .collect();
 
-        param_env.caller_bounds = tcx.intern_predicates(&caller_bounds);
-
-        param_env
+        ty::ParamEnv::new(
+            tcx.intern_predicates(&caller_bounds),
+            param_env.reveal(),
+            param_env.def_id,
+        )
     };
 
     // Receiver: DispatchFromDyn<Receiver[Self => U]>
diff --git a/src/librustc_trait_selection/traits/project.rs b/src/librustc_trait_selection/traits/project.rs
index f71b3fcf129..bd86109e5a4 100644
--- a/src/librustc_trait_selection/traits/project.rs
+++ b/src/librustc_trait_selection/traits/project.rs
@@ -326,7 +326,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
             ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
                 // (*)
                 // Only normalize `impl Trait` after type-checking, usually in codegen.
-                match self.param_env.reveal {
+                match self.param_env.reveal() {
                     Reveal::UserFacing => ty,
 
                     Reveal::All => {
@@ -869,7 +869,7 @@ fn assemble_candidates_from_param_env<'cx, 'tcx>(
         obligation_trait_ref,
         candidate_set,
         ProjectionTyCandidate::ParamEnv,
-        obligation.param_env.caller_bounds.iter(),
+        obligation.param_env.caller_bounds().iter(),
     );
 }
 
@@ -1028,7 +1028,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
                     // and the obligation is monomorphic, otherwise passes such as
                     // transmute checking and polymorphic MIR optimizations could
                     // get a result which isn't correct for all monomorphizations.
-                    if obligation.param_env.reveal == Reveal::All {
+                    if obligation.param_env.reveal() == Reveal::All {
                         // NOTE(eddyb) inference variables can resolve to parameters, so
                         // assume `poly_trait_ref` isn't monomorphic, if it contains any.
                         let poly_trait_ref =
diff --git a/src/librustc_trait_selection/traits/query/normalize.rs b/src/librustc_trait_selection/traits/query/normalize.rs
index ca49ff5884f..59fa4c1598d 100644
--- a/src/librustc_trait_selection/traits/query/normalize.rs
+++ b/src/librustc_trait_selection/traits/query/normalize.rs
@@ -104,7 +104,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
             ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
                 // (*)
                 // Only normalize `impl Trait` after type-checking, usually in codegen.
-                match self.param_env.reveal {
+                match self.param_env.reveal() {
                     Reveal::UserFacing => ty,
 
                     Reveal::All => {
diff --git a/src/librustc_trait_selection/traits/select/candidate_assembly.rs b/src/librustc_trait_selection/traits/select/candidate_assembly.rs
index 597a7a58022..1d5441b8eff 100644
--- a/src/librustc_trait_selection/traits/select/candidate_assembly.rs
+++ b/src/librustc_trait_selection/traits/select/candidate_assembly.rs
@@ -186,7 +186,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         let all_bounds = stack
             .obligation
             .param_env
-            .caller_bounds
+            .caller_bounds()
             .iter()
             .filter_map(|o| o.to_opt_poly_trait_ref());
 
diff --git a/src/librustc_trait_selection/traits/select/mod.rs b/src/librustc_trait_selection/traits/select/mod.rs
index c41a27c6f43..ba5e60012da 100644
--- a/src/librustc_trait_selection/traits/select/mod.rs
+++ b/src/librustc_trait_selection/traits/select/mod.rs
@@ -552,7 +552,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
         if !self.intercrate
             && obligation.is_global()
-            && obligation.param_env.caller_bounds.iter().all(|bound| bound.needs_subst())
+            && obligation.param_env.caller_bounds().iter().all(|bound| bound.needs_subst())
         {
             // If a param env has no global bounds, global obligations do not
             // depend on its particular value in order to work, so we can clear
diff --git a/src/librustc_trait_selection/traits/specialize/mod.rs b/src/librustc_trait_selection/traits/specialize/mod.rs
index 42901102c10..9b737d46417 100644
--- a/src/librustc_trait_selection/traits/specialize/mod.rs
+++ b/src/librustc_trait_selection/traits/specialize/mod.rs
@@ -231,7 +231,10 @@ fn fulfill_implication<'a, 'tcx>(
                 debug!(
                     "fulfill_implication: for impls on {:?} and {:?}, \
                      could not fulfill: {:?} given {:?}",
-                    source_trait_ref, target_trait_ref, errors, param_env.caller_bounds
+                    source_trait_ref,
+                    target_trait_ref,
+                    errors,
+                    param_env.caller_bounds()
                 );
                 Err(())
             }
diff --git a/src/librustc_ty/instance.rs b/src/librustc_ty/instance.rs
index 0acf7691681..de4cdbb3b79 100644
--- a/src/librustc_ty/instance.rs
+++ b/src/librustc_ty/instance.rs
@@ -126,7 +126,7 @@ fn resolve_associated_item<'tcx>(
                 // and the obligation is monomorphic, otherwise passes such as
                 // transmute checking and polymorphic MIR optimizations could
                 // get a result which isn't correct for all monomorphizations.
-                if param_env.reveal == Reveal::All {
+                if param_env.reveal() == Reveal::All {
                     !trait_ref.still_further_specializable()
                 } else {
                     false
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index e6217e0cc1b..a90ed455d04 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -218,7 +218,7 @@ fn compare_predicate_entailment<'tcx>(
         let inh = Inherited::new(infcx, impl_m.def_id.expect_local());
         let infcx = &inh.infcx;
 
-        debug!("compare_impl_method: caller_bounds={:?}", param_env.caller_bounds);
+        debug!("compare_impl_method: caller_bounds={:?}", param_env.caller_bounds());
 
         let mut selcx = traits::SelectionContext::new(&infcx);
 
@@ -1141,7 +1141,7 @@ fn compare_type_predicate_entailment<'tcx>(
         let inh = Inherited::new(infcx, impl_ty.def_id.expect_local());
         let infcx = &inh.infcx;
 
-        debug!("compare_type_predicate_entailment: caller_bounds={:?}", param_env.caller_bounds);
+        debug!("compare_type_predicate_entailment: caller_bounds={:?}", param_env.caller_bounds());
 
         let mut selcx = traits::SelectionContext::new(&infcx);
 
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index 8842ca87726..78bf973e9e3 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -798,26 +798,25 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         // FIXME: do we want to commit to this behavior for param bounds?
         debug!("assemble_inherent_candidates_from_param(param_ty={:?})", param_ty);
 
-        let bounds =
-            self.param_env.caller_bounds.iter().filter_map(|predicate| match predicate.kind() {
-                ty::PredicateKind::Trait(ref trait_predicate, _) => {
-                    match trait_predicate.skip_binder().trait_ref.self_ty().kind {
-                        ty::Param(ref p) if *p == param_ty => {
-                            Some(trait_predicate.to_poly_trait_ref())
-                        }
-                        _ => None,
-                    }
+        let bounds = self.param_env.caller_bounds().iter().filter_map(|predicate| match predicate
+            .kind()
+        {
+            ty::PredicateKind::Trait(ref trait_predicate, _) => {
+                match trait_predicate.skip_binder().trait_ref.self_ty().kind {
+                    ty::Param(ref p) if *p == param_ty => Some(trait_predicate.to_poly_trait_ref()),
+                    _ => None,
                 }
-                ty::PredicateKind::Subtype(..)
-                | ty::PredicateKind::Projection(..)
-                | ty::PredicateKind::RegionOutlives(..)
-                | ty::PredicateKind::WellFormed(..)
-                | ty::PredicateKind::ObjectSafe(..)
-                | ty::PredicateKind::ClosureKind(..)
-                | ty::PredicateKind::TypeOutlives(..)
-                | ty::PredicateKind::ConstEvaluatable(..)
-                | ty::PredicateKind::ConstEquate(..) => None,
-            });
+            }
+            ty::PredicateKind::Subtype(..)
+            | ty::PredicateKind::Projection(..)
+            | ty::PredicateKind::RegionOutlives(..)
+            | ty::PredicateKind::WellFormed(..)
+            | ty::PredicateKind::ObjectSafe(..)
+            | ty::PredicateKind::ClosureKind(..)
+            | ty::PredicateKind::TypeOutlives(..)
+            | ty::PredicateKind::ConstEvaluatable(..)
+            | ty::PredicateKind::ConstEquate(..) => None,
+        });
 
         self.elaborate_bounds(bounds, |this, poly_trait_ref, item| {
             let trait_ref = this.erase_late_bound_regions(&poly_trait_ref);
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 58fd0f989c6..4ddfd8cdd98 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2927,18 +2927,20 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
         let index = generics.param_def_id_to_index[&def_id];
         ty::GenericPredicates {
             parent: None,
-            predicates: tcx.arena.alloc_from_iter(self.param_env.caller_bounds.iter().filter_map(
-                |predicate| match predicate.kind() {
-                    ty::PredicateKind::Trait(ref data, _)
-                        if data.skip_binder().self_ty().is_param(index) =>
-                    {
-                        // HACK(eddyb) should get the original `Span`.
-                        let span = tcx.def_span(def_id);
-                        Some((predicate, span))
+            predicates: tcx.arena.alloc_from_iter(
+                self.param_env.caller_bounds().iter().filter_map(|predicate| {
+                    match predicate.kind() {
+                        ty::PredicateKind::Trait(ref data, _)
+                            if data.skip_binder().self_ty().is_param(index) =>
+                        {
+                            // HACK(eddyb) should get the original `Span`.
+                            let span = tcx.def_span(def_id);
+                            Some((predicate, span))
+                        }
+                        _ => None,
                     }
-                    _ => None,
-                },
-            )),
+                }),
+            ),
         }
     }
 
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index 423160f3a9e..3a798158c8b 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -459,9 +459,9 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
         let mut replacer = RegionReplacer { vid_to_region: &vid_to_region, tcx };
 
         let orig_bounds: FxHashSet<_> =
-            self.cx.tcx.param_env(param_env_def_id).caller_bounds.iter().collect();
+            self.cx.tcx.param_env(param_env_def_id).caller_bounds().iter().collect();
         let clean_where_predicates = param_env
-            .caller_bounds
+            .caller_bounds()
             .iter()
             .filter(|p| {
                 !orig_bounds.contains(p)
diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
index 6954f0cc683..2c68ebc1f8a 100644
--- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
@@ -111,7 +111,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
 
         let fn_def_id = cx.tcx.hir().local_def_id(hir_id);
 
-        let preds = traits::elaborate_predicates(cx.tcx, cx.param_env.caller_bounds.iter())
+        let preds = traits::elaborate_predicates(cx.tcx, cx.param_env.caller_bounds().iter())
             .filter(|p| !p.is_global())
             .filter_map(|obligation| {
                 if let ty::PredicateKind::Trait(poly_trait_ref, _) = obligation.predicate.kind() {