]> git.lizzy.rs Git - rust.git/commitdiff
move projection mode into parameter environment
authorNiko Matsakis <niko@alum.mit.edu>
Wed, 17 May 2017 12:01:04 +0000 (08:01 -0400)
committerNiko Matsakis <niko@alum.mit.edu>
Thu, 1 Jun 2017 16:56:30 +0000 (12:56 -0400)
28 files changed:
src/librustc/infer/mod.rs
src/librustc/middle/intrinsicck.rs
src/librustc/traits/mod.rs
src/librustc/traits/project.rs
src/librustc/traits/select.rs
src/librustc/traits/specialize/mod.rs
src/librustc/traits/specialize/specialization_graph.rs
src/librustc/traits/trans/mod.rs
src/librustc/ty/maps.rs
src/librustc/ty/mod.rs
src/librustc/ty/util.rs
src/librustc_const_eval/check_match.rs
src/librustc_const_eval/eval.rs
src/librustc_lint/builtin.rs
src/librustc_lint/types.rs
src/librustc_mir/build/mod.rs
src/librustc_mir/transform/inline.rs
src/librustc_mir/transform/qualify_consts.rs
src/librustc_mir/transform/type_check.rs
src/librustc_passes/consts.rs
src/librustc_trans/context.rs
src/librustc_trans/glue.rs
src/librustc_typeck/check/compare_method.rs
src/librustc_typeck/check/dropck.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/coherence/builtin.rs
src/librustc_typeck/coherence/inherent_impls_overlap.rs
src/librustc_typeck/lib.rs

index f05f411945089d58dafdc3d5e0eba58cfbce7067..5dbf30d8fa8a4c245c54178f7b5fa6a5a733f007 100644 (file)
@@ -174,11 +174,6 @@ pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     // avoid reporting the same error twice.
     pub reported_trait_errors: RefCell<FxHashSet<traits::TraitErrorKey<'tcx>>>,
 
-    // Sadly, the behavior of projection varies a bit depending on the
-    // stage of compilation. The specifics are given in the
-    // documentation for `Reveal`.
-    projection_mode: Reveal,
-
     // When an error occurs, we want to avoid reporting "derived"
     // errors that are due to this original failure. Normally, we
     // handle this with the `err_count_on_creation` count, which
@@ -406,15 +401,15 @@ pub trait InferEnv<'a, 'tcx> {
     fn to_parts(self, tcx: TyCtxt<'a, 'tcx, 'tcx>)
                 -> (Option<&'a ty::TypeckTables<'tcx>>,
                     Option<ty::TypeckTables<'tcx>>,
-                    Option<ty::ParamEnv<'tcx>>);
+                    ty::ParamEnv<'tcx>);
 }
 
-impl<'a, 'tcx> InferEnv<'a, 'tcx> for () {
+impl<'a, 'tcx> InferEnv<'a, 'tcx> for Reveal {
     fn to_parts(self, _: TyCtxt<'a, 'tcx, 'tcx>)
                 -> (Option<&'a ty::TypeckTables<'tcx>>,
                     Option<ty::TypeckTables<'tcx>>,
-                    Option<ty::ParamEnv<'tcx>>) {
-        (None, None, None)
+                    ty::ParamEnv<'tcx>) {
+        (None, None, ty::ParamEnv::empty(self))
     }
 }
 
@@ -422,8 +417,8 @@ impl<'a, 'tcx> InferEnv<'a, 'tcx> for ty::ParamEnv<'tcx> {
     fn to_parts(self, _: TyCtxt<'a, 'tcx, 'tcx>)
                 -> (Option<&'a ty::TypeckTables<'tcx>>,
                     Option<ty::TypeckTables<'tcx>>,
-                    Option<ty::ParamEnv<'tcx>>) {
-        (None, None, Some(self))
+                    ty::ParamEnv<'tcx>) {
+        (None, None, self)
     }
 }
 
@@ -431,8 +426,8 @@ impl<'a, 'tcx> InferEnv<'a, 'tcx> for (&'a ty::TypeckTables<'tcx>, ty::ParamEnv<
     fn to_parts(self, _: TyCtxt<'a, 'tcx, 'tcx>)
                 -> (Option<&'a ty::TypeckTables<'tcx>>,
                     Option<ty::TypeckTables<'tcx>>,
-                    Option<ty::ParamEnv<'tcx>>) {
-        (Some(self.0), None, Some(self.1))
+                    ty::ParamEnv<'tcx>) {
+        (Some(self.0), None, self.1)
     }
 }
 
@@ -440,8 +435,8 @@ 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<ty::TypeckTables<'tcx>>,
-                    Option<ty::ParamEnv<'tcx>>) {
-        (None, Some(self.0), Some(self.1))
+                    ty::ParamEnv<'tcx>) {
+        (None, Some(self.0), self.1)
     }
 }
 
@@ -449,11 +444,11 @@ impl<'a, 'tcx> InferEnv<'a, 'tcx> for hir::BodyId {
     fn to_parts(self, tcx: TyCtxt<'a, 'tcx, 'tcx>)
                 -> (Option<&'a ty::TypeckTables<'tcx>>,
                     Option<ty::TypeckTables<'tcx>>,
-                    Option<ty::ParamEnv<'tcx>>) {
+                    ty::ParamEnv<'tcx>) {
         let def_id = tcx.hir.body_owner_def_id(self);
         (Some(tcx.typeck_tables_of(def_id)),
          None,
-         Some(tcx.param_env(def_id)))
+         tcx.param_env(def_id))
     }
 }
 
@@ -465,15 +460,11 @@ pub struct InferCtxtBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     arena: DroplessArena,
     fresh_tables: Option<RefCell<ty::TypeckTables<'tcx>>>,
     tables: Option<&'a ty::TypeckTables<'gcx>>,
-    param_env: Option<ty::ParamEnv<'gcx>>,
-    projection_mode: Reveal,
+    param_env: ty::ParamEnv<'gcx>,
 }
 
 impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> {
-    pub fn infer_ctxt<E: InferEnv<'a, 'gcx>>(self,
-                                             env: E,
-                                             projection_mode: Reveal)
-                                             -> InferCtxtBuilder<'a, 'gcx, 'tcx> {
+    pub fn infer_ctxt<E: InferEnv<'a, 'gcx>>(self, env: E) -> InferCtxtBuilder<'a, 'gcx, 'tcx> {
         let (tables, fresh_tables, param_env) = env.to_parts(self);
         InferCtxtBuilder {
             global_tcx: self,
@@ -481,7 +472,6 @@ pub fn infer_ctxt<E: InferEnv<'a, 'gcx>>(self,
             fresh_tables: fresh_tables.map(RefCell::new),
             tables: tables,
             param_env: param_env,
-            projection_mode: projection_mode,
         }
     }
 
@@ -498,12 +488,11 @@ pub fn borrowck_fake_infer_ctxt(self, body: hir::BodyId)
             int_unification_table: RefCell::new(UnificationTable::new()),
             float_unification_table: RefCell::new(UnificationTable::new()),
             region_vars: RegionVarBindings::new(self),
-            param_env: param_env.unwrap(),
+            param_env: param_env,
             selection_cache: traits::SelectionCache::new(),
             evaluation_cache: traits::EvaluationCache::new(),
             projection_cache: RefCell::new(traits::ProjectionCache::new()),
             reported_trait_errors: RefCell::new(FxHashSet()),
-            projection_mode: Reveal::UserFacing,
             tainted_by_errors_flag: Cell::new(false),
             err_count_on_creation: self.sess.err_count(),
             in_snapshot: Cell::new(false),
@@ -520,13 +509,11 @@ pub fn enter<F, R>(&'tcx mut self, f: F) -> R
             ref arena,
             ref fresh_tables,
             tables,
-            ref mut param_env,
-            projection_mode,
+            param_env,
         } = *self;
         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(|| ty::ParamEnv::empty());
         global_tcx.enter_local(arena, |tcx| f(InferCtxt {
             tcx: tcx,
             tables: tables,
@@ -539,7 +526,6 @@ pub fn enter<F, R>(&'tcx mut self, f: F) -> R
             selection_cache: traits::SelectionCache::new(),
             evaluation_cache: traits::EvaluationCache::new(),
             reported_trait_errors: RefCell::new(FxHashSet()),
-            projection_mode: projection_mode,
             tainted_by_errors_flag: Cell::new(false),
             err_count_on_creation: tcx.sess.err_count(),
             in_snapshot: Cell::new(false),
@@ -643,11 +629,15 @@ pub fn normalize_associated_type<T>(self, value: &T) -> T
             return value;
         }
 
-        self.infer_ctxt((), Reveal::All).enter(|infcx| {
+        self.infer_ctxt(Reveal::All).enter(|infcx| {
             value.trans_normalize(&infcx)
         })
     }
 
+    /// Does a best-effort to normalize any associated types in
+    /// `value`; this includes revealing specializable types, so this
+    /// should be not be used during type-checking, but only during
+    /// optimization and code generation.
     pub fn normalize_associated_type_in_env<T>(
         self, value: &T, env: ty::ParamEnv<'tcx>
     ) -> T
@@ -661,7 +651,7 @@ pub fn normalize_associated_type_in_env<T>(
             return value;
         }
 
-        self.infer_ctxt(env, Reveal::All).enter(|infcx| {
+        self.infer_ctxt(env.reveal_all()).enter(|infcx| {
             value.trans_normalize(&infcx)
        })
     }
@@ -728,10 +718,6 @@ pub fn drain_fulfillment_cx_or_panic<T>(&self,
         }
     }
 
-    pub fn projection_mode(&self) -> Reveal {
-        self.projection_mode
-    }
-
     pub fn is_in_snapshot(&self) -> bool {
         self.in_snapshot.get()
     }
index a759a9061f8428874475d8a2f61be1e8426d6057..08f731ae34defdcc774826be8c0cfc54507025d3 100644 (file)
@@ -11,7 +11,6 @@
 use hir::def::Def;
 use hir::def_id::DefId;
 use infer::InferCtxt;
-use traits::Reveal;
 use ty::{self, Ty, TyCtxt};
 use ty::layout::{LayoutError, Pointer, SizeSkeleton};
 
@@ -140,7 +139,7 @@ fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
 
     fn visit_nested_body(&mut self, body_id: hir::BodyId) {
         let body = self.tcx.hir.body(body_id);
-        self.tcx.infer_ctxt(body_id, Reveal::All).enter(|infcx| {
+        self.tcx.infer_ctxt(body_id).enter(|infcx| {
             let mut visitor = ExprVisitor {
                 infcx: &infcx
             };
index e358f39bd9a3a1356fb2130b3ea15cb1b382bcb9..fee6ce95a3f7ff038c209a631f59ff952b72a481 100644 (file)
@@ -477,9 +477,10 @@ 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::ParamEnv::new(tcx.intern_predicates(&predicates));
+    let elaborated_env = ty::ParamEnv::new(tcx.intern_predicates(&predicates),
+                                           unnormalized_env.reveal);
 
-    tcx.infer_ctxt(elaborated_env, Reveal::UserFacing).enter(|infcx| {
+    tcx.infer_ctxt(elaborated_env).enter(|infcx| {
         let predicates = match fully_normalize(
                 &infcx, cause,
                 // You would really want to pass infcx.param_env.caller_bounds here,
@@ -528,7 +529,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::ParamEnv::new(tcx.intern_predicates(&predicates))
+        ty::ParamEnv::new(tcx.intern_predicates(&predicates), unnormalized_env.reveal)
     })
 }
 
@@ -590,7 +591,7 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     debug!("normalize_and_test_predicates(predicates={:?})",
            predicates);
 
-    tcx.infer_ctxt((), Reveal::All).enter(|infcx| {
+    tcx.infer_ctxt(Reveal::All).enter(|infcx| {
         let mut selcx = SelectionContext::new(&infcx);
         let mut fulfill_cx = FulfillmentContext::new();
         let cause = ObligationCause::dummy();
index f5672ffbdc53498dc5eec9c959db753569d254ce..467783fcd7d869878d48d46ed0e4e5ceb3b53bde 100644 (file)
@@ -36,7 +36,7 @@
 
 /// Depending on the stage of compilation, we want projection to be
 /// more or less conservative.
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
 pub enum Reveal {
     /// At type-checking time, we refuse to project any associated
     /// type that is marked `default`. Non-`default` ("final") types
@@ -278,12 +278,14 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
         match ty.sty {
             ty::TyAnon(def_id, substs) if !substs.has_escaping_regions() => { // (*)
                 // Only normalize `impl Trait` after type-checking, usually in trans.
-                if self.selcx.projection_mode() == Reveal::All {
-                    let generic_ty = self.tcx().type_of(def_id);
-                    let concrete_ty = generic_ty.subst(self.tcx(), substs);
-                    self.fold_ty(concrete_ty)
-                } else {
-                    ty
+                match self.param_env.reveal {
+                    Reveal::UserFacing => ty,
+
+                    Reveal::All => {
+                        let generic_ty = self.tcx().type_of(def_id);
+                        let concrete_ty = generic_ty.subst(self.tcx(), substs);
+                        self.fold_ty(concrete_ty)
+                    }
                 }
             }
 
index 7366ed45f31bd514f96279377cbd36433dfe1e26..12f9e2f355bb9cd25a88fc5c6fb35a4ff0b2099b 100644 (file)
@@ -324,7 +324,7 @@ pub fn closure_typer(&self) -> &'cx InferCtxt<'cx, 'gcx, 'tcx> {
     }
 
     pub fn projection_mode(&self) -> Reveal {
-        self.infcx.projection_mode()
+        self.param_env().reveal
     }
 
     /// Wraps the inference context's in_snapshot s.t. snapshot handling is only from the selection
index e0f28e3b49e919832a56b8bc738e0b2f6d983fe2..4d7fdbd881ec34efd0201d1dd56bd494adfdf39e 100644 (file)
@@ -122,7 +122,7 @@ pub fn find_associated_item<'a, 'tcx>(
     let ancestors = trait_def.ancestors(tcx, impl_data.impl_def_id);
     match ancestors.defs(tcx, item.name, item.kind).next() {
         Some(node_item) => {
-            let substs = tcx.infer_ctxt((), Reveal::All).enter(|infcx| {
+            let substs = tcx.infer_ctxt(Reveal::All).enter(|infcx| {
                 let substs = substs.rebase_onto(tcx, trait_def_id, impl_data.substs);
                 let substs = translate_substs(&infcx, impl_data.impl_def_id,
                                               substs, node_item.node);
@@ -184,7 +184,7 @@ pub fn specializes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let impl1_trait_ref = tcx.impl_trait_ref(impl1_def_id).unwrap();
 
     // Create a infcx, taking the predicates of impl1 as assumptions:
-    let result = tcx.infer_ctxt(penv, Reveal::UserFacing).enter(|infcx| {
+    let result = tcx.infer_ctxt(penv).enter(|infcx| {
         // Normalize the trait reference. The WF rules ought to ensure
         // that this always succeeds.
         let impl1_trait_ref =
index 87c98a0ef0ed6daf16839d7a96f712dd99bde1f4..aa35dfd1d70ad3af4acfb030b83258061ee8a365 100644 (file)
@@ -109,7 +109,7 @@ fn insert(&mut self,
             let possible_sibling = *slot;
 
             let tcx = tcx.global_tcx();
-            let (le, ge) = tcx.infer_ctxt((), Reveal::UserFacing).enter(|infcx| {
+            let (le, ge) = tcx.infer_ctxt(Reveal::UserFacing).enter(|infcx| {
                 let overlap = traits::overlapping_impls(&infcx,
                                                         possible_sibling,
                                                         impl_def_id);
index e38306aed2a91b9e7a0ffeac8bbe57bf32547ef1..4cffe6af083b6afa687f30cf0d203432fcea1e64 100644 (file)
@@ -46,7 +46,7 @@ pub fn trans_fulfill_obligation(self,
 
             // Do the initial selection for the obligation. This yields the
             // shallow result we are looking for -- that is, what specific impl.
-            self.infer_ctxt((), Reveal::All).enter(|infcx| {
+            self.infer_ctxt(Reveal::All).enter(|infcx| {
                 let mut selcx = SelectionContext::new(&infcx);
 
                 let obligation_cause = ObligationCause::misc(span,
index cfb9e648d3b7eb1dd4c0d18c649080decd35403d..da85d40b2c3e87cbec4bb6d3281741919acd9cd4 100644 (file)
@@ -906,6 +906,12 @@ fn default() -> Self {
     [] specialization_graph_of: SpecializationGraph(DefId) -> Rc<specialization_graph::Graph>,
     [] is_object_safe: ObjectSafety(DefId) -> bool,
 
+    // Get the ParameterEnvironment for a given item; this environment
+    // will be in "user-facing" mode, meaning that it is suitabe for
+    // type-checking etc, and it does not normalize specializable
+    // associated types. This is almost always what you want,
+    // unless you are doing MIR optimizations, in which case you
+    // might want to use `reveal_all()` method to change modes.
     [] param_env: ParamEnv(DefId) -> ty::ParamEnv<'tcx>,
 
     // Trait selection queries. These are best used by invoking `ty.moves_by_default()`,
index b495b5ee81a9a644fb759262a7c4836e14d58e14..0a25cd638cc30b761a0a105a1d84be0ae12c2f29 100644 (file)
@@ -1191,6 +1191,11 @@ pub struct ParamEnv<'tcx> {
     /// the set of bounds on the in-scope type parameters, translated
     /// into Obligations, and elaborated and normalized.
     pub caller_bounds: &'tcx Slice<ty::Predicate<'tcx>>,
+
+    /// Typically, this is `Reveal::UserFacing`, but during trans we
+    /// want `Reveal::All` -- note that this is always paired with an
+    /// empty environment. To get that, use `ParamEnv::reveal()`.
+    pub reveal: traits::Reveal,
 }
 
 impl<'tcx> ParamEnv<'tcx> {
@@ -1218,7 +1223,7 @@ pub fn and<T: TypeFoldable<'tcx>>(self, value: T) -> ParamEnvAnd<'tcx, T> {
             }
         } else {
             ParamEnvAnd {
-                param_env: ParamEnv::empty(),
+                param_env: ParamEnv::empty(self.reveal),
                 value: value,
             }
         }
@@ -2467,8 +2472,8 @@ fn trait_of_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Option
 
 /// See `ParamEnv` struct def'n for details.
 fn param_env<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                   def_id: DefId)
-                                   -> ParamEnv<'tcx> {
+                       def_id: DefId)
+                       -> ParamEnv<'tcx> {
     // Compute the bounds on Self and the type parameters.
 
     let bounds = tcx.predicates_of(def_id).instantiate_identity(tcx);
@@ -2486,7 +2491,8 @@ fn param_env<'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::ParamEnv::new(tcx.intern_predicates(&predicates));
+    let unnormalized_env = ty::ParamEnv::new(tcx.intern_predicates(&predicates),
+                                             traits::Reveal::UserFacing);
 
     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)
index ce0f1ed5bb86c884c6dc33cc9efc768eb7bc9ae1..31c099c661df05d9a80a4f4ae3c90599e8c48324 100644 (file)
@@ -150,20 +150,32 @@ pub enum Representability {
 impl<'tcx> ty::ParamEnv<'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())
+    pub fn empty(reveal: Reveal) -> Self {
+        Self::new(ty::Slice::empty(), reveal)
     }
 
     /// Construct a trait environment with the given set of predicates.
-    pub fn new(caller_bounds: &'tcx ty::Slice<ty::Predicate<'tcx>>) -> Self {
-        ty::ParamEnv { caller_bounds }
+    pub fn new(caller_bounds: &'tcx ty::Slice<ty::Predicate<'tcx>>,
+               reveal: Reveal)
+               -> Self {
+        ty::ParamEnv { caller_bounds, reveal }
+    }
+
+    /// Returns a new parameter environment with the same clauses, but
+    /// which "reveals" the true results of projections in all cases
+    /// (even for associated types that are specializable).  This is
+    /// the desired behavior during trans and certain other special
+    /// contexts; normally though we want to use `Reveal::UserFacing`,
+    /// which is the default.
+    pub fn reveal_all(self) -> Self {
+        ty::ParamEnv { reveal: Reveal::All, ..self }
     }
 
     pub fn can_type_implement_copy<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                        self_type: Ty<'tcx>, span: Span)
                                        -> Result<(), CopyImplementationError> {
         // FIXME: (@jroesch) float this code up
-        tcx.infer_ctxt(self.clone(), Reveal::UserFacing).enter(|infcx| {
+        tcx.infer_ctxt(self.clone()).enter(|infcx| {
             let (adt, substs) = match self_type.sty {
                 ty::TyAdt(adt, substs) => (adt, substs),
                 _ => return Err(CopyImplementationError::NotAnAdt),
@@ -970,7 +982,7 @@ fn is_copy_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 {
     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)
+    tcx.infer_ctxt(param_env)
        .enter(|infcx| traits::type_known_to_meet_bound(&infcx, ty, trait_def_id, DUMMY_SP))
 }
 
@@ -980,7 +992,7 @@ fn is_sized_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 {
     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)
+    tcx.infer_ctxt(param_env)
        .enter(|infcx| traits::type_known_to_meet_bound(&infcx, ty, trait_def_id, DUMMY_SP))
 }
 
@@ -990,7 +1002,7 @@ fn is_freeze_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 {
     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)
+    tcx.infer_ctxt(param_env)
        .enter(|infcx| traits::type_known_to_meet_bound(&infcx, ty, trait_def_id, DUMMY_SP))
 }
 
index b35b0865991659d29b461f44f441bc2991ab9d2d..39db384e2ded22116eeb90293095b14b8035a939 100644 (file)
@@ -20,7 +20,6 @@
 use rustc::middle::mem_categorization::{cmt};
 use rustc::middle::region::RegionMaps;
 use rustc::session::Session;
-use rustc::traits::Reveal;
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::lint;
 use rustc_errors::{Diagnostic, Level, DiagnosticBuilder};
@@ -518,7 +517,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), Reveal::UserFacing).enter(|infcx| {
+    cx.tcx.infer_ctxt((cx.tables, cx.param_env)).enter(|infcx| {
         let mut checker = MutationChecker {
             cx: cx,
         };
index a6b39f22277de0c852024512b15f0ca6c43d3c06..1364898b549d4705b70e004164576af440664cca 100644 (file)
@@ -483,7 +483,7 @@ fn resolve_trait_associated_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     debug!("resolve_trait_associated_const: trait_ref={:?}",
            trait_ref);
 
-    tcx.infer_ctxt((), Reveal::UserFacing).enter(|infcx| {
+    tcx.infer_ctxt(Reveal::UserFacing).enter(|infcx| {
         let mut selcx = traits::SelectionContext::new(&infcx);
         let obligation = traits::Obligation::new(traits::ObligationCause::dummy(),
                                                  trait_ref.to_poly_trait_predicate());
index 12bfb1e02cf6f48cfefa41a7291706a54fb9b6b2..619e7ec6a4f6095f3c67fb6af57da2372a82113b 100644 (file)
@@ -488,7 +488,7 @@ fn check_item(&mut self, cx: &LateContext, item: &hir::Item) {
         if def.has_dtor(cx.tcx) {
             return;
         }
-        let param_env = ty::ParamEnv::empty();
+        let param_env = ty::ParamEnv::empty(Reveal::UserFacing);
         if !ty.moves_by_default(cx.tcx, param_env, item.span) {
             return;
         }
@@ -956,7 +956,7 @@ fn method_call_refers_to_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                                 trait_ref.to_poly_trait_predicate());
 
                     let param_env = tcx.param_env(method.def_id);
-                    tcx.infer_ctxt(param_env, Reveal::UserFacing).enter(|infcx| {
+                    tcx.infer_ctxt(param_env).enter(|infcx| {
                         let mut selcx = traits::SelectionContext::new(&infcx);
                         match selcx.select(&obligation) {
                             // The method comes from a `T: Trait` bound.
index c2181c9764c6cdfe97ab27138216502ef3fbb543..1b86085d99d1b0a86239fea6d9d84f887f591992 100644 (file)
@@ -725,7 +725,7 @@ fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
             if gens.ty_params.is_empty() {
                 // sizes only make sense for non-generic types
                 let t = cx.tcx.type_of(cx.tcx.hir.local_def_id(it.id));
-                let layout = cx.tcx.infer_ctxt((), Reveal::All).enter(|infcx| {
+                let layout = cx.tcx.infer_ctxt(Reveal::All).enter(|infcx| {
                     let ty = cx.tcx.erase_regions(&t);
                     ty.layout(&infcx).unwrap_or_else(|e| {
                         bug!("failed to get layout for `{}`: {}", t, e)
index 407b08d2831497b3456a2fdf0a7f9795c2f9d348..e9cf3115ddab1cd20da46efa45d9bb532b33ee74 100644 (file)
@@ -18,7 +18,6 @@
 use rustc::mir::*;
 use rustc::mir::transform::MirSource;
 use rustc::mir::visit::MutVisitor;
-use rustc::traits::Reveal;
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::subst::Substs;
 use rustc::util::nodemap::NodeMap;
@@ -84,7 +83,7 @@ pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Mir<'t
     };
 
     let src = MirSource::from_node(tcx, id);
-    tcx.infer_ctxt(body_id, Reveal::UserFacing).enter(|infcx| {
+    tcx.infer_ctxt(body_id).enter(|infcx| {
         let cx = Cx::new(&infcx, src);
         let mut mir = if cx.tables().tainted_by_errors {
             build::construct_error(cx, body_id)
@@ -173,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.param_env(tcx.hir.local_def_id(ctor_id));
-        tcx.infer_ctxt(pe, Reveal::UserFacing).enter(|infcx| {
+        tcx.infer_ctxt(pe).enter(|infcx| {
             let (mut mir, src) =
                 shim::build_adt_ctor(&infcx, ctor_id, fields, span);
 
index edb2f44d18e35423afe37ec1bebed8a9bca2f5d8..8842d30b65c2740343af08086d1cd7c6abf38fe8 100644 (file)
@@ -18,7 +18,6 @@
 use rustc::mir::*;
 use rustc::mir::transform::{MirPass, MirSource};
 use rustc::mir::visit::*;
-use rustc::traits;
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::subst::{Subst,Substs};
 
@@ -545,9 +544,10 @@ fn make_call_args(&self, args: Vec<Operand<'tcx>>,
     }
 }
 
-fn type_size_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, param_env: ty::ParamEnv<'tcx>,
+fn type_size_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                          param_env: ty::ParamEnv<'tcx>,
                           ty: Ty<'tcx>) -> Option<u64> {
-    tcx.infer_ctxt(param_env, traits::Reveal::All).enter(|infcx| {
+    tcx.infer_ctxt(param_env.reveal_all()).enter(|infcx| {
         ty.layout(&infcx).ok().map(|layout| {
             layout.size(&tcx.data_layout).bytes()
         })
index 3b1c54f68e49b878889ba43261671bbb115d0641..7c49a11ca1f7195ede9c153819c4c7009117c0fd 100644 (file)
@@ -998,7 +998,7 @@ fn run_pass<'a, 'tcx>(&self,
         // Statics must be Sync.
         if mode == Mode::Static {
             let ty = mir.return_ty;
-            tcx.infer_ctxt((), Reveal::UserFacing).enter(|infcx| {
+            tcx.infer_ctxt(Reveal::UserFacing).enter(|infcx| {
                 let cause = traits::ObligationCause::new(mir.span, id, traits::SharedStatic);
                 let mut fulfillment_cx = traits::FulfillmentContext::new();
                 fulfillment_cx.register_bound(&infcx, ty,
index 8258627748f3008df8b7f567fce5345c6604a966..f7055f90f0f830d757add822f3b6222d42a094d6 100644 (file)
@@ -12,7 +12,7 @@
 #![allow(unreachable_code)]
 
 use rustc::infer::{self, InferCtxt, InferOk};
-use rustc::traits::{self, Reveal};
+use rustc::traits;
 use rustc::ty::fold::TypeFoldable;
 use rustc::ty::{self, Ty, TyCtxt, TypeVariants};
 use rustc::middle::const_val::ConstVal;
@@ -752,7 +752,7 @@ fn run_pass<'a, 'tcx>(&self,
             return;
         }
         let param_env = tcx.param_env(def_id);
-        tcx.infer_ctxt(param_env, Reveal::UserFacing).enter(|infcx| {
+        tcx.infer_ctxt(param_env).enter(|infcx| {
             let mut checker = TypeChecker::new(&infcx, item_id);
             {
                 let mut verifier = TypeVerifier::new(&mut checker, mir);
index fecde3a636cda0893fddd203e8b089286995bb9b..2a4a13932e3fa5752edbafb6b883d49f3a7bb529 100644 (file)
@@ -138,7 +138,7 @@ fn visit_nested_body(&mut self, body_id: hir::BodyId) {
             self.check_const_eval(&body.value);
         }
 
-        let outer_penv = self.tcx.infer_ctxt(body_id, Reveal::UserFacing).enter(|infcx| {
+        let outer_penv = self.tcx.infer_ctxt(body_id).enter(|infcx| {
             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);
@@ -468,7 +468,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
         in_fn: false,
         promotable: false,
         mut_rvalue_borrows: NodeSet(),
-        param_env: ty::ParamEnv::empty(),
+        param_env: ty::ParamEnv::empty(Reveal::UserFacing),
     }.as_deep_visitor());
     tcx.sess.abort_if_errors();
 }
index c3b16c2d07d0733ddc43b0c403ab7dc426a38455..56f51cae147ad786729659b15a172328cdafc78b 100644 (file)
@@ -320,15 +320,15 @@ pub fn new(tcx: TyCtxt<'b, 'tcx, 'tcx>,
     }
 
     pub fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool {
-        ty.needs_drop(self.tcx, ty::ParamEnv::empty())
+        ty.needs_drop(self.tcx, ty::ParamEnv::empty(traits::Reveal::All))
     }
 
     pub fn type_is_sized(&self, ty: Ty<'tcx>) -> bool {
-        ty.is_sized(self.tcx, ty::ParamEnv::empty(), DUMMY_SP)
+        ty.is_sized(self.tcx, ty::ParamEnv::empty(traits::Reveal::All), DUMMY_SP)
     }
 
     pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
-        ty.is_freeze(self.tcx, ty::ParamEnv::empty(), DUMMY_SP)
+        ty.is_freeze(self.tcx, ty::ParamEnv::empty(traits::Reveal::All), DUMMY_SP)
     }
 
     pub fn exported_symbols<'a>(&'a self) -> &'a NodeSet {
@@ -735,7 +735,7 @@ fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
             return TyLayout { ty: ty, layout: layout, variant_index: None };
         }
 
-        self.tcx().infer_ctxt((), traits::Reveal::All).enter(|infcx| {
+        self.tcx().infer_ctxt(traits::Reveal::All).enter(|infcx| {
             infcx.layout_of(ty).unwrap_or_else(|e| {
                 match e {
                     ty::layout::LayoutError::SizeOverflow(_) =>
index fa400b54d2708ed98b4d2e7f0d7df0bc54617ec9..f473d957a9031243372524e2e737cce1fb144103 100644 (file)
@@ -46,7 +46,7 @@ pub fn needs_drop_glue<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, t: Ty<'tcx>
         ty::TyAdt(def, _) if def.is_box() => {
             let typ = t.boxed_ty();
             if !scx.type_needs_drop(typ) && scx.type_is_sized(typ) {
-                scx.tcx().infer_ctxt((), traits::Reveal::All).enter(|infcx| {
+                scx.tcx().infer_ctxt(traits::Reveal::All).enter(|infcx| {
                     let layout = t.layout(&infcx).unwrap();
                     if layout.size(scx).bytes() == 0 {
                         // `Box<ZeroSizeType>` does not allocate.
index 3121f4948504eb71dffda0b45a99680996788d11..1d6d7fa61001ad6a84051af60b8a873ed4284027 100644 (file)
@@ -212,13 +212,14 @@ 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::ParamEnv::new(tcx.intern_predicates(&hybrid_preds.predicates));
+    let param_env = ty::ParamEnv::new(tcx.intern_predicates(&hybrid_preds.predicates),
+                                      Reveal::UserFacing);
     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| {
+    tcx.infer_ctxt(param_env).enter(|infcx| {
         let inh = Inherited::new(infcx, impl_m.def_id);
         let infcx = &inh.infcx;
 
@@ -713,7 +714,7 @@ pub fn compare_const_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                     impl_trait_ref: ty::TraitRef<'tcx>) {
     debug!("compare_const_impl(impl_trait_ref={:?})", impl_trait_ref);
 
-    tcx.infer_ctxt((), Reveal::UserFacing).enter(|infcx| {
+    tcx.infer_ctxt(Reveal::UserFacing).enter(|infcx| {
         let inh = Inherited::new(infcx, impl_c.def_id);
         let infcx = &inh.infcx;
 
index 3ed0da05dc2c2f800e8916017a22e047de4e2069..06f405120ae42dd658ae806ce6198e6eabeda376 100644 (file)
@@ -16,7 +16,7 @@
 use rustc::middle::region::{self, RegionMaps};
 use rustc::ty::subst::{Subst, Substs};
 use rustc::ty::{self, Ty, TyCtxt};
-use rustc::traits::{self, ObligationCause, Reveal};
+use rustc::traits::{self, ObligationCause};
 use util::common::ErrorReported;
 use util::nodemap::FxHashSet;
 
@@ -80,7 +80,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.param_env(self_type_did);
-    tcx.infer_ctxt(impl_param_env, Reveal::UserFacing).enter(|ref infcx| {
+    tcx.infer_ctxt(impl_param_env).enter(|ref infcx| {
         let tcx = infcx.tcx;
         let mut fulfillment_cx = traits::FulfillmentContext::new();
 
index 32c3f5c8a5edd98a65207489395fc4c1ec3a16d7..8074c0630e39510ff12e7eaad02e36d1988c60fc 100644 (file)
@@ -93,7 +93,7 @@
 use rustc::infer::type_variable::{TypeVariableOrigin};
 use rustc::middle::region::CodeExtent;
 use rustc::ty::subst::{Kind, Subst, Substs};
-use rustc::traits::{self, FulfillmentContext, ObligationCause, ObligationCauseCode, Reveal};
+use rustc::traits::{self, FulfillmentContext, ObligationCause, ObligationCauseCode};
 use rustc::ty::{ParamTy, LvaluePreference, NoPreference, PreferMutLvalue};
 use rustc::ty::{self, Ty, TyCtxt, Visibility};
 use rustc::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
@@ -530,7 +530,7 @@ pub fn build(tcx: TyCtxt<'a, 'gcx, 'gcx>, def_id: DefId)
         let tables = ty::TypeckTables::empty();
         let param_env = tcx.param_env(def_id);
         InheritedBuilder {
-            infcx: tcx.infer_ctxt((tables, param_env), Reveal::UserFacing),
+            infcx: tcx.infer_ctxt((tables, param_env)),
             def_id,
         }
     }
index ff5599fb1bdbf46c24a1dd0c8474360787035b79..89f2595d1a8fb6a95338c66510ff40165baa192e 100644 (file)
@@ -15,7 +15,7 @@
 use rustc::middle::region::RegionMaps;
 use rustc::middle::lang_items::UnsizeTraitLangItem;
 
-use rustc::traits::{self, ObligationCause, Reveal};
+use rustc::traits::{self, ObligationCause};
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::TypeFoldable;
 use rustc::ty::adjustment::CoerceUnsizedInfo;
@@ -208,7 +208,7 @@ pub fn coerce_unsized_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
            source,
            target);
 
-    tcx.infer_ctxt(param_env, Reveal::UserFacing).enter(|infcx| {
+    tcx.infer_ctxt(param_env).enter(|infcx| {
         let cause = ObligationCause::misc(span, impl_node_id);
         let check_mutbl = |mt_a: ty::TypeAndMut<'tcx>,
                            mt_b: ty::TypeAndMut<'tcx>,
index 2751e1ff38a5090620344d49ded167658087a8e5..4aa12d08f61c50b1bc9e17be8287376319f78805 100644 (file)
@@ -70,7 +70,7 @@ fn check_for_overlapping_inherent_impls(&self, ty_def_id: DefId) {
 
         for (i, &impl1_def_id) in impls.iter().enumerate() {
             for &impl2_def_id in &impls[(i + 1)..] {
-                self.tcx.infer_ctxt((), Reveal::UserFacing).enter(|infcx| {
+                self.tcx.infer_ctxt(Reveal::UserFacing).enter(|infcx| {
                     if traits::overlapping_impls(&infcx, impl1_def_id, impl2_def_id).is_some() {
                         self.check_for_common_items_in_impls(impl1_def_id, impl2_def_id)
                     }
index baef48fe7d2cde82b6f5ef8919af54712c1ec5e3..91dec958a161c02f3ba6a79245650b2b78c6a830 100644 (file)
@@ -155,7 +155,7 @@ fn require_same_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                 expected: Ty<'tcx>,
                                 actual: Ty<'tcx>)
                                 -> bool {
-    tcx.infer_ctxt((), Reveal::UserFacing).enter(|ref infcx| {
+    tcx.infer_ctxt(Reveal::UserFacing).enter(|ref infcx| {
         let mut fulfill_cx = FulfillmentContext::new();
         match infcx.eq_types(false, &cause, expected, actual) {
             Ok(InferOk { obligations, .. }) => {