about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver Scherer <github35764891676564198441@oli-obk.de>2019-03-31 18:35:39 +0200
committerOliver Scherer <github35764891676564198441@oli-obk.de>2019-08-05 17:48:05 +0200
commitf4f957d00b5e8f8de0a2818a39cc9ec6a47bc828 (patch)
tree5a2d01b9d829b284d03227870ea12b3b0eafdbaf
parent7710820d184f36c3ab659dace70f8ee366212169 (diff)
downloadrust-f4f957d00b5e8f8de0a2818a39cc9ec6a47bc828.tar.gz
rust-f4f957d00b5e8f8de0a2818a39cc9ec6a47bc828.zip
Clear the ParamEnv where its information is irrelevant
-rw-r--r--src/librustc/ty/mod.rs4
-rw-r--r--src/librustc/ty/sty.rs26
-rw-r--r--src/librustc_codegen_utils/symbol_names/v0.rs2
-rw-r--r--src/librustc_mir/build/matches/test.rs11
-rw-r--r--src/librustc_mir/hair/pattern/_match.rs16
-rw-r--r--src/librustc_mir/hair/pattern/mod.rs17
-rw-r--r--src/librustc_mir/transform/simplify_branches.rs2
7 files changed, 43 insertions, 35 deletions
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 646fb7e4c36..5fec95e2a3b 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -2357,7 +2357,7 @@ impl<'tcx> AdtDef {
 
     #[inline]
     pub fn eval_explicit_discr(&self, tcx: TyCtxt<'tcx>, expr_did: DefId) -> Option<Discr<'tcx>> {
-        let param_env = ParamEnv::empty();
+        let param_env = tcx.param_env(expr_did);
         let repr_type = self.repr.discr_type();
         let substs = InternalSubsts::identity_for_item(tcx.global_tcx(), expr_did);
         let instance = ty::Instance::new(expr_did, substs);
@@ -2368,7 +2368,7 @@ impl<'tcx> AdtDef {
         match tcx.const_eval(param_env.and(cid)) {
             Ok(val) => {
                 // FIXME: Find the right type and use it instead of `val.ty` here
-                if let Some(b) = val.try_eval_bits(tcx.global_tcx(), param_env.and(val.ty)) {
+                if let Some(b) = val.try_eval_bits(tcx.global_tcx(), param_env, val.ty) {
                     trace!("discriminants: {} ({:?})", b, repr_type);
                     Some(Discr {
                         val: b,
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 497d1d8a917..a37fa130813 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -2294,21 +2294,25 @@ impl<'tcx> Const<'tcx> {
     pub fn try_eval_bits(
         &self,
         tcx: TyCtxt<'tcx>,
-        ty: ParamEnvAnd<'tcx, Ty<'tcx>>,
+        param_env: ParamEnv<'tcx>,
+        ty: Ty<'tcx>,
     ) -> Option<u128> {
-        assert_eq!(self.ty, ty.value);
-        let size = tcx.layout_of(ty).ok()?.size;
+        assert_eq!(self.ty, ty);
+        let size = tcx.layout_of(param_env.with_reveal_all().and(ty)).ok()?.size;
         match self.val {
             // FIXME(const_generics): this doesn't work right now,
             // because it tries to relate an `Infer` to a `Param`.
             ConstValue::Unevaluated(did, substs) => {
-                let substs = tcx.lift_to_global(&substs).unwrap();
-                let instance = ty::Instance::resolve(tcx, ty.param_env, did, substs)?;
+                // if `substs` has no unresolved components, use and empty param_env
+                let pem_and_substs = param_env.with_reveal_all().and(substs);
+                let (param_env, substs) = tcx.lift_to_global(&pem_and_substs).unwrap().into_parts();
+                // try to resolve e.g. associated constants to their definition on an impl
+                let instance = ty::Instance::resolve(tcx, param_env, did, substs)?;
                 let gid = GlobalId {
                     instance,
                     promoted: None,
                 };
-                let evaluated = tcx.const_eval(ty.param_env.and(gid)).ok()?;
+                let evaluated = tcx.const_eval(param_env.and(gid)).ok()?;
                 evaluated.val.try_to_bits(size)
             },
             // FIXME(const_generics): try to evaluate generic consts with a given param env?
@@ -2319,7 +2323,7 @@ impl<'tcx> Const<'tcx> {
 
     #[inline]
     pub fn try_eval_bool(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<bool> {
-        self.try_eval_bits(tcx, param_env.and(tcx.types.bool)).and_then(|v| match v {
+        self.try_eval_bits(tcx, param_env, tcx.types.bool).and_then(|v| match v {
             0 => Some(false),
             1 => Some(true),
             _ => None,
@@ -2328,18 +2332,18 @@ impl<'tcx> Const<'tcx> {
 
     #[inline]
     pub fn try_eval_usize(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<u64> {
-        self.try_eval_bits(tcx, param_env.and(tcx.types.usize)).map(|v| v as u64)
+        self.try_eval_bits(tcx, param_env, tcx.types.usize).map(|v| v as u64)
     }
 
     #[inline]
-    pub fn eval_bits(&self, tcx: TyCtxt<'tcx>, ty: ParamEnvAnd<'tcx, Ty<'tcx>>) -> u128 {
-        self.try_eval_bits(tcx, ty).unwrap_or_else(||
+    pub fn eval_bits(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: Ty<'tcx>) -> u128 {
+        self.try_eval_bits(tcx, param_env, ty).unwrap_or_else(||
             bug!("expected bits of {:#?}, got {:#?}", ty, self))
     }
 
     #[inline]
     pub fn eval_usize(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> u64 {
-        self.eval_bits(tcx, param_env.and(tcx.types.usize)) as u64
+        self.eval_bits(tcx, param_env, tcx.types.usize) as u64
     }
 }
 
diff --git a/src/librustc_codegen_utils/symbol_names/v0.rs b/src/librustc_codegen_utils/symbol_names/v0.rs
index 79ec7e63b21..47601da8b7b 100644
--- a/src/librustc_codegen_utils/symbol_names/v0.rs
+++ b/src/librustc_codegen_utils/symbol_names/v0.rs
@@ -512,7 +512,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> {
         }
         self = ct.ty.print(self)?;
 
-        if let Some(bits) = ct.try_eval_bits(self.tcx, ty::ParamEnv::reveal_all().and(ct.ty)) {
+        if let Some(bits) = ct.try_eval_bits(self.tcx, ty::ParamEnv::reveal_all(), ct.ty) {
             let _ = write!(self.out, "{:x}_", bits);
         } else {
             // NOTE(eddyb) despite having the path, we need to
diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs
index 2165b1a342d..1c93abd40de 100644
--- a/src/librustc_mir/build/matches/test.rs
+++ b/src/librustc_mir/build/matches/test.rs
@@ -112,7 +112,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 indices.entry(value)
                        .or_insert_with(|| {
                            options.push(value.eval_bits(
-                               self.hir.tcx(), self.hir.param_env.and(switch_ty),
+                               self.hir.tcx(), self.hir.param_env, switch_ty,
                            ));
                            options.len() - 1
                        });
@@ -655,10 +655,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     use rustc::hir::RangeEnd::*;
 
                     let tcx = self.hir.tcx();
-                    let test_ty = self.hir.param_env.and(test.ty);
 
-                    let lo = compare_const_vals(tcx, test.lo, pat.hi, test_ty)?;
-                    let hi = compare_const_vals(tcx, test.hi, pat.lo, test_ty)?;
+                    let lo = compare_const_vals(tcx, test.lo, pat.hi, self.hir.param_env, test.ty)?;
+                    let hi = compare_const_vals(tcx, test.hi, pat.lo, self.hir.param_env, test.ty)?;
 
                     match (test.end, pat.end, lo, hi) {
                         // pat < test
@@ -775,8 +774,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
         let tcx = self.hir.tcx();
 
-        let a = compare_const_vals(tcx, range.lo, value, self.hir.param_env.and(range.ty))?;
-        let b = compare_const_vals(tcx, value, range.hi, self.hir.param_env.and(range.ty))?;
+        let a = compare_const_vals(tcx, range.lo, value, self.hir.param_env, range.ty)?;
+        let b = compare_const_vals(tcx, value, range.hi, self.hir.param_env, range.ty)?;
 
         match (b, range.end) {
             (Less, _) |
diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs
index 2a11ea83136..8da4d737cc5 100644
--- a/src/librustc_mir/hair/pattern/_match.rs
+++ b/src/librustc_mir/hair/pattern/_match.rs
@@ -860,7 +860,7 @@ impl<'tcx> IntRange<'tcx> {
             }
             ConstantValue(val) if is_integral(val.ty) => {
                 let ty = val.ty;
-                if let Some(val) = val.try_eval_bits(tcx, param_env.and(ty)) {
+                if let Some(val) = val.try_eval_bits(tcx, param_env, ty) {
                     let bias = IntRange::signed_bias(tcx, ty);
                     let val = val ^ bias;
                     Some(IntRange { range: val..=val, ty })
@@ -881,8 +881,8 @@ impl<'tcx> IntRange<'tcx> {
             match pat.kind {
                 box PatternKind::Constant { value } => break ConstantValue(value),
                 box PatternKind::Range(PatternRange { lo, hi, ty, end }) => break ConstantRange(
-                    lo.eval_bits(tcx, param_env.and(ty)),
-                    hi.eval_bits(tcx, param_env.and(ty)),
+                    lo.eval_bits(tcx, param_env, ty),
+                    hi.eval_bits(tcx, param_env, ty),
                     ty,
                     end,
                 ),
@@ -1341,8 +1341,8 @@ fn pat_constructors<'tcx>(cx: &mut MatchCheckCtxt<'_, 'tcx>,
         PatternKind::Constant { value } => Some(vec![ConstantValue(value)]),
         PatternKind::Range(PatternRange { lo, hi, ty, end }) =>
             Some(vec![ConstantRange(
-                lo.eval_bits(cx.tcx, cx.param_env.and(ty)),
-                hi.eval_bits(cx.tcx, cx.param_env.and(ty)),
+                lo.eval_bits(cx.tcx, cx.param_env, ty),
+                hi.eval_bits(cx.tcx, cx.param_env, ty),
                 ty,
                 end,
             )]),
@@ -1480,7 +1480,7 @@ fn slice_pat_covered_by_const<'tcx>(
     {
         match pat.kind {
             box PatternKind::Constant { value } => {
-                let b = value.eval_bits(tcx, param_env.and(pat.ty));
+                let b = value.eval_bits(tcx, param_env, pat.ty);
                 assert_eq!(b as u8 as u128, b);
                 if b as u8 != *ch {
                     return Ok(false);
@@ -1660,9 +1660,9 @@ fn constructor_covered_by_range<'tcx>(
         _ => bug!("`constructor_covered_by_range` called with {:?}", pat),
     };
     trace!("constructor_covered_by_range {:#?}, {:#?}, {:#?}, {}", ctor, from, to, ty);
-    let cmp_from = |c_from| compare_const_vals(tcx, c_from, from, param_env.and(ty))
+    let cmp_from = |c_from| compare_const_vals(tcx, c_from, from, param_env, ty)
         .map(|res| res != Ordering::Less);
-    let cmp_to = |c_to| compare_const_vals(tcx, c_to, to, param_env.and(ty));
+    let cmp_to = |c_to| compare_const_vals(tcx, c_to, to, param_env, ty);
     macro_rules! some_or_ok {
         ($e:expr) => {
             match $e {
diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs
index af030476706..5ecfb84b632 100644
--- a/src/librustc_mir/hair/pattern/mod.rs
+++ b/src/librustc_mir/hair/pattern/mod.rs
@@ -446,7 +446,8 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
                             self.tcx,
                             lo,
                             hi,
-                            self.param_env.and(ty),
+                            self.param_env,
+                            ty,
                         );
                         match (end, cmp) {
                             (RangeEnd::Excluded, Some(Ordering::Less)) =>
@@ -1452,7 +1453,8 @@ pub fn compare_const_vals<'tcx>(
     tcx: TyCtxt<'tcx>,
     a: &'tcx ty::Const<'tcx>,
     b: &'tcx ty::Const<'tcx>,
-    ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
+    param_env: ty::ParamEnv<'tcx>,
+    ty: Ty<'tcx>,
 ) -> Option<Ordering> {
     trace!("compare_const_vals: {:?}, {:?}", a, b);
 
@@ -1467,13 +1469,16 @@ pub fn compare_const_vals<'tcx>(
     let fallback = || from_bool(a == b);
 
     // Use the fallback if any type differs
-    if a.ty != b.ty || a.ty != ty.value {
+    if a.ty != b.ty || a.ty != ty {
         return fallback();
     }
 
-    if let (Some(a), Some(b)) = (a.try_eval_bits(tcx, ty), b.try_eval_bits(tcx, ty)) {
+    let a_bits = a.try_eval_bits(tcx, param_env, ty);
+    let b_bits = b.try_eval_bits(tcx, param_env, ty);
+
+    if let (Some(a), Some(b)) = (a_bits, b_bits) {
         use ::rustc_apfloat::Float;
-        return match ty.value.sty {
+        return match ty.sty {
             ty::Float(ast::FloatTy::F32) => {
                 let l = ::rustc_apfloat::ieee::Single::from_bits(a);
                 let r = ::rustc_apfloat::ieee::Single::from_bits(b);
@@ -1496,7 +1501,7 @@ pub fn compare_const_vals<'tcx>(
         }
     }
 
-    if let ty::Str = ty.value.sty {
+    if let ty::Str = ty.sty {
         match (a.val, b.val) {
             (
                 ConstValue::Slice { data: alloc_a, start: offset_a, end: end_a },
diff --git a/src/librustc_mir/transform/simplify_branches.rs b/src/librustc_mir/transform/simplify_branches.rs
index 973aa706472..9ffa3db4c2e 100644
--- a/src/librustc_mir/transform/simplify_branches.rs
+++ b/src/librustc_mir/transform/simplify_branches.rs
@@ -27,7 +27,7 @@ impl MirPass for SimplifyBranches {
                 TerminatorKind::SwitchInt {
                     discr: Operand::Constant(ref c), switch_ty, ref values, ref targets, ..
                 } => {
-                    let constant = c.literal.try_eval_bits(tcx, param_env.and(switch_ty));
+                    let constant = c.literal.try_eval_bits(tcx, param_env, switch_ty);
                     if let Some(constant) = constant {
                         let (otherwise, targets) = targets.split_last().unwrap();
                         let mut ret = TerminatorKind::Goto { target: *otherwise };