about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduard-Mihai Burtescu <edy.burt@gmail.com>2017-07-26 15:51:53 +0300
committerEduard-Mihai Burtescu <edy.burt@gmail.com>2017-07-27 20:59:40 +0300
commit60cf5428b3c3671da8ebfd7e885f8b06150655eb (patch)
treebf2b303a91ddc2db5555118340ee902414c20da0
parent4c900c52482fd398cbec4d1d433fcc2e6888ff1b (diff)
downloadrust-60cf5428b3c3671da8ebfd7e885f8b06150655eb.tar.gz
rust-60cf5428b3c3671da8ebfd7e885f8b06150655eb.zip
rustc_const_eval: keep track of the appropriate ParamEnv.
-rw-r--r--src/librustc/middle/const_val.rs6
-rw-r--r--src/librustc/ty/maps.rs9
-rw-r--r--src/librustc/ty/mod.rs6
-rw-r--r--src/librustc/ty/structural_impls.rs2
-rw-r--r--src/librustc_const_eval/check_match.rs10
-rw-r--r--src/librustc_const_eval/eval.rs68
-rw-r--r--src/librustc_const_eval/pattern.rs23
-rw-r--r--src/librustc_lint/types.rs4
-rw-r--r--src/librustc_mir/build/mod.rs2
-rw-r--r--src/librustc_mir/hair/cx/block.rs2
-rw-r--r--src/librustc_mir/hair/cx/expr.rs7
-rw-r--r--src/librustc_mir/hair/cx/mod.rs7
-rw-r--r--src/librustc_passes/consts.rs2
-rw-r--r--src/librustc_typeck/collect.rs4
-rw-r--r--src/test/run-pass/issue-43357.rs19
15 files changed, 107 insertions, 64 deletions
diff --git a/src/librustc/middle/const_val.rs b/src/librustc/middle/const_val.rs
index 33e9df1e413..b6b1648f396 100644
--- a/src/librustc/middle/const_val.rs
+++ b/src/librustc/middle/const_val.rs
@@ -14,7 +14,8 @@ pub use rustc_const_math::ConstInt;
 use hir;
 use hir::def::Def;
 use hir::def_id::DefId;
-use ty::{TyCtxt, layout};
+use traits::Reveal;
+use ty::{self, TyCtxt, layout};
 use ty::subst::Substs;
 use util::common::ErrorReported;
 use rustc_const_math::*;
@@ -229,8 +230,9 @@ pub fn eval_length(tcx: TyCtxt,
 {
     let count_expr = &tcx.hir.body(count).value;
     let count_def_id = tcx.hir.body_owner_def_id(count);
+    let param_env = ty::ParamEnv::empty(Reveal::UserFacing);
     let substs = Substs::identity_for_item(tcx.global_tcx(), count_def_id);
-    match tcx.at(count_expr.span).const_eval((count_def_id, substs)) {
+    match tcx.at(count_expr.span).const_eval(param_env.and((count_def_id, substs))) {
         Ok(Integral(Usize(count))) => {
             let val = count.as_u64(tcx.sess.target.uint_type);
             assert_eq!(val as usize as u64, val);
diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs
index e94308f3510..7a45a706ea4 100644
--- a/src/librustc/ty/maps.rs
+++ b/src/librustc/ty/maps.rs
@@ -372,8 +372,8 @@ impl<'tcx> QueryDescription for queries::reachable_set<'tcx> {
 }
 
 impl<'tcx> QueryDescription for queries::const_eval<'tcx> {
-    fn describe(tcx: TyCtxt, (def_id, _): (DefId, &'tcx Substs<'tcx>)) -> String {
-        format!("const-evaluating `{}`", tcx.item_path_str(def_id))
+    fn describe(tcx: TyCtxt, key: ty::ParamEnvAnd<'tcx, (DefId, &'tcx Substs<'tcx>)>) -> String {
+        format!("const-evaluating `{}`", tcx.item_path_str(key.value.0))
     }
 }
 
@@ -935,7 +935,7 @@ define_maps! { <'tcx>
 
     /// Results of evaluating const items or constants embedded in
     /// other items (such as enum variant explicit discriminants).
-    [] const_eval: const_eval_dep_node((DefId, &'tcx Substs<'tcx>))
+    [] const_eval: const_eval_dep_node(ty::ParamEnvAnd<'tcx, (DefId, &'tcx Substs<'tcx>)>)
         -> const_val::EvalResult<'tcx>,
 
     /// Performs the privacy check and computes "access levels".
@@ -1032,8 +1032,9 @@ fn typeck_item_bodies_dep_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
     DepConstructor::TypeckBodiesKrate
 }
 
-fn const_eval_dep_node<'tcx>((def_id, substs): (DefId, &'tcx Substs<'tcx>))
+fn const_eval_dep_node<'tcx>(key: ty::ParamEnvAnd<'tcx, (DefId, &'tcx Substs<'tcx>)>)
                              -> DepConstructor<'tcx> {
+    let (def_id, substs) = key.value;
     DepConstructor::ConstEval { def_id, substs }
 }
 
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 70aee6ffcf3..804f47b5283 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -1582,6 +1582,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
     #[inline]
     pub fn discriminants(&'a self, tcx: TyCtxt<'a, 'gcx, 'tcx>)
                          -> impl Iterator<Item=ConstInt> + 'a {
+        let param_env = ParamEnv::empty(traits::Reveal::UserFacing);
         let repr_type = self.repr.discr_type();
         let initial = repr_type.initial_discriminant(tcx.global_tcx());
         let mut prev_discr = None::<ConstInt>;
@@ -1589,7 +1590,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
             let mut discr = prev_discr.map_or(initial, |d| d.wrap_incr());
             if let VariantDiscr::Explicit(expr_did) = v.discr {
                 let substs = Substs::identity_for_item(tcx.global_tcx(), expr_did);
-                match tcx.const_eval((expr_did, substs)) {
+                match tcx.const_eval(param_env.and((expr_did, substs))) {
                     Ok(ConstVal::Integral(v)) => {
                         discr = v;
                     }
@@ -1617,6 +1618,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
                                     tcx: TyCtxt<'a, 'gcx, 'tcx>,
                                     variant_index: usize)
                                     -> ConstInt {
+        let param_env = ParamEnv::empty(traits::Reveal::UserFacing);
         let repr_type = self.repr.discr_type();
         let mut explicit_value = repr_type.initial_discriminant(tcx.global_tcx());
         let mut explicit_index = variant_index;
@@ -1628,7 +1630,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
                 }
                 ty::VariantDiscr::Explicit(expr_did) => {
                     let substs = Substs::identity_for_item(tcx.global_tcx(), expr_did);
-                    match tcx.const_eval((expr_did, substs)) {
+                    match tcx.const_eval(param_env.and((expr_did, substs))) {
                         Ok(ConstVal::Integral(v)) => {
                             explicit_value = v;
                             break;
diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs
index b81bd595e25..f261a56cdcc 100644
--- a/src/librustc/ty/structural_impls.rs
+++ b/src/librustc/ty/structural_impls.rs
@@ -398,7 +398,7 @@ macro_rules! CopyImpls {
     }
 }
 
-CopyImpls! { (), hir::Unsafety, abi::Abi }
+CopyImpls! { (), hir::Unsafety, abi::Abi, hir::def_id::DefId }
 
 impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) {
     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> (T, U) {
diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs
index e7a12df0a27..95c8613232e 100644
--- a/src/librustc_const_eval/check_match.rs
+++ b/src/librustc_const_eval/check_match.rs
@@ -165,8 +165,9 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> {
 
             let inlined_arms : Vec<(Vec<_>, _)> = arms.iter().map(|arm| (
                 arm.pats.iter().map(|pat| {
-                    let substs = self.identity_substs;
-                    let mut patcx = PatternContext::new(self.tcx, self.tables, substs);
+                    let mut patcx = PatternContext::new(self.tcx,
+                                                        self.param_env.and(self.identity_substs),
+                                                        self.tables);
                     let pattern = expand_pattern(cx, patcx.lower_pattern(&pat));
                     if !patcx.errors.is_empty() {
                         patcx.report_inlining_errors(pat.span);
@@ -233,8 +234,9 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> {
     fn check_irrefutable(&self, pat: &Pat, origin: &str) {
         let module = self.tcx.hir.get_module_parent(pat.id);
         MatchCheckCtxt::create_and_enter(self.tcx, module, |ref mut cx| {
-            let substs = self.identity_substs;
-            let mut patcx = PatternContext::new(self.tcx, self.tables, substs);
+            let mut patcx = PatternContext::new(self.tcx,
+                                                self.param_env.and(self.identity_substs),
+                                                self.tables);
             let pattern = patcx.lower_pattern(pat);
             let pattern_ty = pattern.ty;
             let pats : Matrix = vec![vec![
diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs
index bcf5fd2b13d..463f256fe6c 100644
--- a/src/librustc_const_eval/eval.rs
+++ b/src/librustc_const_eval/eval.rs
@@ -21,7 +21,6 @@ use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::maps::Providers;
 use rustc::ty::util::IntTypeExt;
 use rustc::ty::subst::{Substs, Subst};
-use rustc::traits::Reveal;
 use rustc::util::common::ErrorReported;
 use rustc::util::nodemap::DefIdMap;
 
@@ -49,24 +48,21 @@ macro_rules! math {
     }
 }
 
-/// * `def_id` is the id of the constant.
-/// * `substs` is the monomorphized substitutions for the expression.
-///
-/// `substs` is optional and is used for associated constants.
-/// This generally happens in late/trans const evaluation.
+/// * `DefId` is the id of the constant.
+/// * `Substs` is the monomorphized substitutions for the expression.
 pub fn lookup_const_by_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                    def_id: DefId,
-                                    substs: &'tcx Substs<'tcx>)
+                                    key: ty::ParamEnvAnd<'tcx, (DefId, &'tcx Substs<'tcx>)>)
                                     -> Option<(DefId, &'tcx Substs<'tcx>)> {
+    let (def_id, _) = key.value;
     if let Some(node_id) = tcx.hir.as_local_node_id(def_id) {
         match tcx.hir.find(node_id) {
             Some(hir_map::NodeTraitItem(_)) => {
                 // If we have a trait item and the substitutions for it,
                 // `resolve_trait_associated_const` will select an impl
                 // or the default.
-                resolve_trait_associated_const(tcx, def_id, substs)
+                resolve_trait_associated_const(tcx, key)
             }
-            _ => Some((def_id, substs))
+            _ => Some(key.value)
         }
     } else {
         match tcx.describe_def(def_id) {
@@ -76,12 +72,12 @@ pub fn lookup_const_by_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 // trait-associated const if the caller gives us the
                 // substitutions for the reference to it.
                 if tcx.trait_of_item(def_id).is_some() {
-                    resolve_trait_associated_const(tcx, def_id, substs)
+                    resolve_trait_associated_const(tcx, key)
                 } else {
-                    Some((def_id, substs))
+                    Some(key.value)
                 }
             }
-            _ => Some((def_id, substs))
+            _ => Some(key.value)
         }
     }
 }
@@ -89,18 +85,21 @@ pub fn lookup_const_by_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 pub struct ConstContext<'a, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     tables: &'a ty::TypeckTables<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
     substs: &'tcx Substs<'tcx>,
     fn_args: Option<DefIdMap<ConstVal<'tcx>>>
 }
 
 impl<'a, 'tcx> ConstContext<'a, 'tcx> {
     pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-               tables: &'a ty::TypeckTables<'tcx>,
-               substs: &'tcx Substs<'tcx>) -> Self {
+               param_env_and_substs: ty::ParamEnvAnd<'tcx, &'tcx Substs<'tcx>>,
+               tables: &'a ty::TypeckTables<'tcx>)
+               -> Self {
         ConstContext {
             tcx,
+            param_env: param_env_and_substs.param_env,
             tables,
-            substs,
+            substs: param_env_and_substs.value,
             fn_args: None
         }
     }
@@ -279,7 +278,7 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
           match cx.tables.qpath_def(qpath, e.id) {
               Def::Const(def_id) |
               Def::AssociatedConst(def_id) => {
-                    match tcx.at(e.span).const_eval((def_id, substs)) {
+                    match tcx.at(e.span).const_eval(cx.param_env.and((def_id, substs))) {
                         Ok(val) => val,
                         Err(ConstEvalErr { kind: TypeckError, .. }) => {
                             signal!(e, TypeckError);
@@ -323,10 +322,9 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
 
           if tcx.fn_sig(def_id).abi() == Abi::RustIntrinsic {
             let layout_of = |ty: Ty<'tcx>| {
-                ty.layout(tcx, ty::ParamEnv::empty(traits::Reveal::All))
-                    .map_err(|err| {
-                        ConstEvalErr { span: e.span, kind: LayoutError(err) }
-                    })
+                ty.layout(tcx, cx.param_env).map_err(|err| {
+                    ConstEvalErr { span: e.span, kind: LayoutError(err) }
+                })
             };
             match &tcx.item_name(def_id).as_str()[..] {
                 "size_of" => {
@@ -377,7 +375,8 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
           }
           debug!("const call({:?})", call_args);
           let callee_cx = ConstContext {
-            tcx: tcx,
+            tcx,
+            param_env: cx.param_env,
             tables: tcx.typeck_tables_of(def_id),
             substs: substs,
             fn_args: Some(call_args)
@@ -477,9 +476,10 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
 }
 
 fn resolve_trait_associated_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                            def_id: DefId,
-                                            substs: &'tcx Substs<'tcx>)
+                                            key: ty::ParamEnvAnd<'tcx, (DefId, &'tcx Substs<'tcx>)>)
                                             -> Option<(DefId, &'tcx Substs<'tcx>)> {
+    let param_env = key.param_env;
+    let (def_id, substs) = key.value;
     let trait_item = tcx.associated_item(def_id);
     let trait_id = trait_item.container.id();
     let trait_ref = ty::Binder(ty::TraitRef::new(trait_id, substs));
@@ -487,7 +487,6 @@ fn resolve_trait_associated_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
            trait_ref);
 
     tcx.infer_ctxt().enter(|infcx| {
-        let param_env = ty::ParamEnv::empty(Reveal::UserFacing);
         let mut selcx = traits::SelectionContext::new(&infcx);
         let obligation = traits::Obligation::new(traits::ObligationCause::dummy(),
                                                  param_env,
@@ -506,10 +505,8 @@ fn resolve_trait_associated_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         };
 
         // NOTE: this code does not currently account for specialization, but when
-        // it does so, it should hook into the Reveal to determine when the
-        // constant should resolve; this will also require plumbing through to this
-        // function whether we are in "trans mode" to pick the right Reveal
-        // when constructing the inference context above.
+        // it does so, it should hook into the param_env.reveal to determine when the
+        // constant should resolve.
         match selection {
             traits::VtableImpl(ref impl_data) => {
                 let name = trait_item.name;
@@ -524,15 +521,16 @@ fn resolve_trait_associated_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     }
                     None => {
                         if trait_item.defaultness.has_value() {
-                            Some((def_id, substs))
+                            Some(key.value)
                         } else {
                             None
                         }
                     }
                 }
             }
+            traits::VtableParam(_) => None,
             _ => {
-                bug!("resolve_trait_associated_const: unexpected vtable type")
+                bug!("resolve_trait_associated_const: unexpected vtable type {:?}", selection)
             }
         }
     })
@@ -761,13 +759,13 @@ pub fn provide(providers: &mut Providers) {
 }
 
 fn const_eval<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                        (def_id, substs): (DefId, &'tcx Substs<'tcx>))
+                        key: ty::ParamEnvAnd<'tcx, (DefId, &'tcx Substs<'tcx>)>)
                         -> EvalResult<'tcx> {
-    let (def_id, substs) = if let Some(resolved) = lookup_const_by_id(tcx, def_id, substs) {
+    let (def_id, substs) = if let Some(resolved) = lookup_const_by_id(tcx, key) {
         resolved
     } else {
         return Err(ConstEvalErr {
-            span: tcx.def_span(def_id),
+            span: tcx.def_span(key.value.0),
             kind: TypeckError
         });
     };
@@ -779,5 +777,5 @@ fn const_eval<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     } else {
         tcx.sess.cstore.item_body(tcx, def_id)
     };
-    ConstContext::new(tcx, tables, substs).eval(&body.value)
+    ConstContext::new(tcx, key.param_env.and(substs), tables).eval(&body.value)
 }
diff --git a/src/librustc_const_eval/pattern.rs b/src/librustc_const_eval/pattern.rs
index 07c45d3ee51..ab919da8152 100644
--- a/src/librustc_const_eval/pattern.rs
+++ b/src/librustc_const_eval/pattern.rs
@@ -268,6 +268,7 @@ impl<'tcx> fmt::Display for Pattern<'tcx> {
 
 pub struct PatternContext<'a, 'tcx: 'a> {
     pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    pub param_env: ty::ParamEnv<'tcx>,
     pub tables: &'a ty::TypeckTables<'tcx>,
     pub substs: &'tcx Substs<'tcx>,
     pub errors: Vec<PatternError<'tcx>>,
@@ -275,10 +276,10 @@ pub struct PatternContext<'a, 'tcx: 'a> {
 
 impl<'a, 'tcx> Pattern<'tcx> {
     pub fn from_hir(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                    param_env_and_substs: ty::ParamEnvAnd<'tcx, &'tcx Substs<'tcx>>,
                     tables: &'a ty::TypeckTables<'tcx>,
-                    substs: &'tcx Substs<'tcx>,
                     pat: &hir::Pat) -> Self {
-        let mut pcx = PatternContext::new(tcx, tables, substs);
+        let mut pcx = PatternContext::new(tcx, param_env_and_substs, tables);
         let result = pcx.lower_pattern(pat);
         if !pcx.errors.is_empty() {
             span_bug!(pat.span, "encountered errors lowering pattern: {:?}", pcx.errors)
@@ -290,9 +291,15 @@ impl<'a, 'tcx> Pattern<'tcx> {
 
 impl<'a, 'tcx> PatternContext<'a, 'tcx> {
     pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-               tables: &'a ty::TypeckTables<'tcx>,
-               substs: &'tcx Substs<'tcx>) -> Self {
-        PatternContext { tcx, tables, substs, errors: vec![] }
+               param_env_and_substs: ty::ParamEnvAnd<'tcx, &'tcx Substs<'tcx>>,
+               tables: &'a ty::TypeckTables<'tcx>) -> Self {
+        PatternContext {
+            tcx,
+            param_env: param_env_and_substs.param_env,
+            tables,
+            substs: param_env_and_substs.value,
+            errors: vec![]
+        }
     }
 
     pub fn lower_pattern(&mut self, pat: &hir::Pat) -> Pattern<'tcx> {
@@ -588,7 +595,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
         let kind = match def {
             Def::Const(def_id) | Def::AssociatedConst(def_id) => {
                 let substs = self.tables.node_substs(id);
-                match eval::lookup_const_by_id(self.tcx, def_id, substs) {
+                match eval::lookup_const_by_id(self.tcx, self.param_env.and((def_id, substs))) {
                     Some((def_id, substs)) => {
                         // Enter the inlined constant's tables&substs temporarily.
                         let old_tables = self.tables;
@@ -622,7 +629,9 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
     }
 
     fn lower_lit(&mut self, expr: &hir::Expr) -> PatternKind<'tcx> {
-        let const_cx = eval::ConstContext::new(self.tcx, self.tables, self.substs);
+        let const_cx = eval::ConstContext::new(self.tcx,
+                                               self.param_env.and(self.substs),
+                                               self.tables);
         match const_cx.eval(expr) {
             Ok(value) => {
                 if let ConstVal::Variant(def_id) = value {
diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index be7976b7a93..aca98df9cc9 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -113,7 +113,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
                             let parent_item = cx.tcx.hir.get_parent(e.id);
                             let parent_def_id = cx.tcx.hir.local_def_id(parent_item);
                             let substs = Substs::identity_for_item(cx.tcx, parent_def_id);
-                            let const_cx = ConstContext::new(cx.tcx, cx.tables, substs);
+                            let const_cx = ConstContext::new(cx.tcx,
+                                                             cx.param_env.and(substs),
+                                                             cx.tables);
                             match const_cx.eval(&r) {
                                 Ok(ConstVal::Integral(i)) => {
                                     i.is_negative() ||
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index 9615dfa5093..5badef3cfa1 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -514,8 +514,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
 
             if let Some(pattern) = pattern {
                 let pattern = Pattern::from_hir(self.hir.tcx().global_tcx(),
+                                                self.hir.param_env.and(self.hir.identity_substs),
                                                 self.hir.tables(),
-                                                self.hir.identity_substs,
                                                 pattern);
                 scope = self.declare_bindings(scope, ast_body.span, &pattern);
                 unpack!(block = self.lvalue_into_pattern(block, pattern, &lvalue));
diff --git a/src/librustc_mir/hair/cx/block.rs b/src/librustc_mir/hair/cx/block.rs
index f39c354fb30..c91326f6d87 100644
--- a/src/librustc_mir/hair/cx/block.rs
+++ b/src/librustc_mir/hair/cx/block.rs
@@ -71,8 +71,8 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
                         });
 
                         let pattern = Pattern::from_hir(cx.tcx.global_tcx(),
+                                                        cx.param_env.and(cx.identity_substs),
                                                         cx.tables(),
-                                                        cx.identity_substs,
                                                         &local.pat);
                         result.push(StmtRef::Mirror(Box::new(Stmt {
                             span: stmt.span,
diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs
index db3b15d44bc..06a0c4ff213 100644
--- a/src/librustc_mir/hair/cx/expr.rs
+++ b/src/librustc_mir/hair/cx/expr.rs
@@ -467,7 +467,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
             let c = &cx.tcx.hir.body(count).value;
             let def_id = cx.tcx.hir.body_owner_def_id(count);
             let substs = Substs::identity_for_item(cx.tcx.global_tcx(), def_id);
-            let count = match cx.tcx.at(c.span).const_eval((def_id, substs)) {
+            let count = match cx.tcx.at(c.span).const_eval(cx.param_env.and((def_id, substs))) {
                 Ok(ConstVal::Integral(ConstInt::Usize(u))) => u,
                 Ok(other) => bug!("constant evaluation of repeat count yielded {:?}", other),
                 Err(s) => cx.fatal_const_eval_err(&s, c.span, "expression")
@@ -605,7 +605,10 @@ fn to_borrow_kind(m: hir::Mutability) -> BorrowKind {
 fn convert_arm<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, arm: &'tcx hir::Arm) -> Arm<'tcx> {
     Arm {
         patterns: arm.pats.iter().map(|p| {
-            Pattern::from_hir(cx.tcx.global_tcx(), cx.tables(), cx.identity_substs, p)
+            Pattern::from_hir(cx.tcx.global_tcx(),
+                              cx.param_env.and(cx.identity_substs),
+                              cx.tables(),
+                              p)
         }).collect(),
         guard: arm.guard.to_ref(),
         body: arm.body.to_ref(),
diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs
index 2d6dce8adf5..2f4ab36d394 100644
--- a/src/librustc_mir/hair/cx/mod.rs
+++ b/src/librustc_mir/hair/cx/mod.rs
@@ -37,7 +37,7 @@ pub struct Cx<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'gcx, 'tcx>,
     infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
 
-    pub param_env: ty::ParamEnv<'tcx>,
+    pub param_env: ty::ParamEnv<'gcx>,
 
     /// Identity `Substs` for use with const-evaluation.
     pub identity_substs: &'gcx Substs<'gcx>,
@@ -135,7 +135,10 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
 
     pub fn const_eval_literal(&mut self, e: &hir::Expr) -> Literal<'tcx> {
         let tcx = self.tcx.global_tcx();
-        match ConstContext::new(tcx, self.tables(), self.identity_substs).eval(e) {
+        let const_cx = ConstContext::new(tcx,
+                                         self.param_env.and(self.identity_substs),
+                                         self.tables());
+        match const_cx.eval(e) {
             Ok(value) => Literal::Value { value: value },
             Err(s) => self.fatal_const_eval_err(&s, e.span, "expression")
         }
diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs
index 76a576cd17b..a881bf9eac7 100644
--- a/src/librustc_passes/consts.rs
+++ b/src/librustc_passes/consts.rs
@@ -65,7 +65,7 @@ struct CheckCrateVisitor<'a, 'tcx: 'a> {
 
 impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> {
     fn const_cx(&self) -> ConstContext<'a, 'gcx> {
-        ConstContext::new(self.tcx, self.tables, self.identity_substs)
+        ConstContext::new(self.tcx, self.param_env.and(self.identity_substs), self.tables)
     }
 
     fn check_const_eval(&self, expr: &'gcx hir::Expr) {
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 45ed6ecffd8..8780131bbcc 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -59,6 +59,7 @@ use constrained_type_params as ctp;
 use middle::lang_items::SizedTraitLangItem;
 use middle::const_val::ConstVal;
 use middle::resolve_lifetime as rl;
+use rustc::traits::Reveal;
 use rustc::ty::subst::Substs;
 use rustc::ty::{ToPredicate, ReprOptions};
 use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt};
@@ -550,6 +551,7 @@ fn convert_variant_ctor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 fn convert_enum_variant_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                         def_id: DefId,
                                         variants: &[hir::Variant]) {
+    let param_env = ty::ParamEnv::empty(Reveal::UserFacing);
     let def = tcx.adt_def(def_id);
     let repr_type = def.repr.discr_type();
     let initial = repr_type.initial_discriminant(tcx);
@@ -561,7 +563,7 @@ fn convert_enum_variant_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         prev_discr = Some(if let Some(e) = variant.node.disr_expr {
             let expr_did = tcx.hir.local_def_id(e.node_id);
             let substs = Substs::identity_for_item(tcx, expr_did);
-            let result = tcx.at(variant.span).const_eval((expr_did, substs));
+            let result = tcx.at(variant.span).const_eval(param_env.and((expr_did, substs)));
 
             // enum variant evaluation happens before the global constant check
             // so we need to report the real error
diff --git a/src/test/run-pass/issue-43357.rs b/src/test/run-pass/issue-43357.rs
new file mode 100644
index 00000000000..9a5f65d67b1
--- /dev/null
+++ b/src/test/run-pass/issue-43357.rs
@@ -0,0 +1,19 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+trait Trait {
+    type Output;
+}
+
+fn f<T: Trait>() {
+    std::mem::size_of::<T::Output>();
+}
+
+fn main() {}