about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/ty/inhabitedness/mod.rs49
-rw-r--r--src/librustc_lint/unused.rs7
-rw-r--r--src/librustc_mir_build/build/matches/simplify.rs7
-rw-r--r--src/librustc_mir_build/hair/pattern/_match.rs4
-rw-r--r--src/librustc_passes/liveness.rs21
5 files changed, 64 insertions, 24 deletions
diff --git a/src/librustc/ty/inhabitedness/mod.rs b/src/librustc/ty/inhabitedness/mod.rs
index 144e3bc9c8b..b166c4dea0c 100644
--- a/src/librustc/ty/inhabitedness/mod.rs
+++ b/src/librustc/ty/inhabitedness/mod.rs
@@ -90,30 +90,46 @@ impl<'tcx> TyCtxt<'tcx> {
     /// ```
     /// This code should only compile in modules where the uninhabitedness of Foo is
     /// visible.
-    pub fn is_ty_uninhabited_from(self, module: DefId, ty: Ty<'tcx>) -> bool {
+    pub fn is_ty_uninhabited_from(
+        self,
+        module: DefId,
+        ty: Ty<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
+    ) -> bool {
         // To check whether this type is uninhabited at all (not just from the
         // given node), you could check whether the forest is empty.
         // ```
         // forest.is_empty()
         // ```
-        ty.uninhabited_from(self).contains(self, module)
+        ty.uninhabited_from(self, param_env).contains(self, module)
     }
 
-    pub fn is_ty_uninhabited_from_any_module(self, ty: Ty<'tcx>) -> bool {
-        !ty.uninhabited_from(self).is_empty()
+    pub fn is_ty_uninhabited_from_any_module(
+        self,
+        ty: Ty<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
+    ) -> bool {
+        !ty.uninhabited_from(self, param_env).is_empty()
     }
 }
 
 impl<'tcx> AdtDef {
     /// Calculates the forest of `DefId`s from which this ADT is visibly uninhabited.
-    fn uninhabited_from(&self, tcx: TyCtxt<'tcx>, substs: SubstsRef<'tcx>) -> DefIdForest {
+    fn uninhabited_from(
+        &self,
+        tcx: TyCtxt<'tcx>,
+        substs: SubstsRef<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
+    ) -> DefIdForest {
         // Non-exhaustive ADTs from other crates are always considered inhabited.
         if self.is_variant_list_non_exhaustive() && !self.did.is_local() {
             DefIdForest::empty()
         } else {
             DefIdForest::intersection(
                 tcx,
-                self.variants.iter().map(|v| v.uninhabited_from(tcx, substs, self.adt_kind())),
+                self.variants
+                    .iter()
+                    .map(|v| v.uninhabited_from(tcx, substs, self.adt_kind(), param_env)),
             )
         }
     }
@@ -126,6 +142,7 @@ impl<'tcx> VariantDef {
         tcx: TyCtxt<'tcx>,
         substs: SubstsRef<'tcx>,
         adt_kind: AdtKind,
+        param_env: ty::ParamEnv<'tcx>,
     ) -> DefIdForest {
         let is_enum = match adt_kind {
             // For now, `union`s are never considered uninhabited.
@@ -140,7 +157,7 @@ impl<'tcx> VariantDef {
         } else {
             DefIdForest::union(
                 tcx,
-                self.fields.iter().map(|f| f.uninhabited_from(tcx, substs, is_enum)),
+                self.fields.iter().map(|f| f.uninhabited_from(tcx, substs, is_enum, param_env)),
             )
         }
     }
@@ -153,8 +170,9 @@ impl<'tcx> FieldDef {
         tcx: TyCtxt<'tcx>,
         substs: SubstsRef<'tcx>,
         is_enum: bool,
+        param_env: ty::ParamEnv<'tcx>,
     ) -> DefIdForest {
-        let data_uninhabitedness = move || self.ty(tcx, substs).uninhabited_from(tcx);
+        let data_uninhabitedness = move || self.ty(tcx, substs).uninhabited_from(tcx, param_env);
         // FIXME(canndrew): Currently enum fields are (incorrectly) stored with
         // `Visibility::Invisible` so we need to override `self.vis` if we're
         // dealing with an enum.
@@ -176,20 +194,21 @@ impl<'tcx> FieldDef {
 
 impl<'tcx> TyS<'tcx> {
     /// Calculates the forest of `DefId`s from which this type is visibly uninhabited.
-    fn uninhabited_from(&self, tcx: TyCtxt<'tcx>) -> DefIdForest {
+    fn uninhabited_from(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> DefIdForest {
         match self.kind {
-            Adt(def, substs) => def.uninhabited_from(tcx, substs),
+            Adt(def, substs) => def.uninhabited_from(tcx, substs, param_env),
 
             Never => DefIdForest::full(tcx),
 
-            Tuple(ref tys) => {
-                DefIdForest::union(tcx, tys.iter().map(|ty| ty.expect_ty().uninhabited_from(tcx)))
-            }
+            Tuple(ref tys) => DefIdForest::union(
+                tcx,
+                tys.iter().map(|ty| ty.expect_ty().uninhabited_from(tcx, param_env)),
+            ),
 
-            Array(ty, len) => match len.try_eval_usize(tcx, ty::ParamEnv::empty()) {
+            Array(ty, len) => match len.try_eval_usize(tcx, param_env) {
                 // If the array is definitely non-empty, it's uninhabited if
                 // the type of its elements is uninhabited.
-                Some(n) if n != 0 => ty.uninhabited_from(tcx),
+                Some(n) if n != 0 => ty.uninhabited_from(tcx, param_env),
                 _ => DefIdForest::empty(),
             },
 
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index d0bbc5ac26d..2ac461a0eb2 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -124,7 +124,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
             descr_post: &str,
             plural_len: usize,
         ) -> bool {
-            if ty.is_unit() || cx.tcx.is_ty_uninhabited_from(cx.tcx.parent_module(expr.hir_id), ty)
+            if ty.is_unit()
+                || cx.tcx.is_ty_uninhabited_from(
+                    cx.tcx.parent_module(expr.hir_id),
+                    ty,
+                    cx.param_env,
+                )
             {
                 return true;
             }
diff --git a/src/librustc_mir_build/build/matches/simplify.rs b/src/librustc_mir_build/build/matches/simplify.rs
index 80fa0c44860..aea4f5f1b3a 100644
--- a/src/librustc_mir_build/build/matches/simplify.rs
+++ b/src/librustc_mir_build/build/matches/simplify.rs
@@ -209,7 +209,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     i == variant_index || {
                         self.hir.tcx().features().exhaustive_patterns
                             && !v
-                                .uninhabited_from(self.hir.tcx(), substs, adt_def.adt_kind())
+                                .uninhabited_from(
+                                    self.hir.tcx(),
+                                    substs,
+                                    adt_def.adt_kind(),
+                                    self.hir.param_env,
+                                )
                                 .is_empty()
                     }
                 }) && (adt_def.did.is_local()
diff --git a/src/librustc_mir_build/hair/pattern/_match.rs b/src/librustc_mir_build/hair/pattern/_match.rs
index 37ad5f5ea4e..486dd3579d2 100644
--- a/src/librustc_mir_build/hair/pattern/_match.rs
+++ b/src/librustc_mir_build/hair/pattern/_match.rs
@@ -598,7 +598,7 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
 
     fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool {
         if self.tcx.features().exhaustive_patterns {
-            self.tcx.is_ty_uninhabited_from(self.module, ty)
+            self.tcx.is_ty_uninhabited_from(self.module, ty, self.param_env)
         } else {
             false
         }
@@ -1267,7 +1267,7 @@ fn all_constructors<'a, 'tcx>(
                 def.variants
                     .iter()
                     .filter(|v| {
-                        !v.uninhabited_from(cx.tcx, substs, def.adt_kind())
+                        !v.uninhabited_from(cx.tcx, substs, def.adt_kind(), cx.param_env)
                             .contains(cx.tcx, cx.module)
                     })
                     .map(|v| Variant(v.def_id))
diff --git a/src/librustc_passes/liveness.rs b/src/librustc_passes/liveness.rs
index 030d0893b02..d7208a00e09 100644
--- a/src/librustc_passes/liveness.rs
+++ b/src/librustc_passes/liveness.rs
@@ -398,7 +398,7 @@ fn visit_fn<'tcx>(
     intravisit::walk_fn(&mut fn_maps, fk, decl, body_id, sp, id);
 
     // compute liveness
-    let mut lsets = Liveness::new(&mut fn_maps, body_id);
+    let mut lsets = Liveness::new(&mut fn_maps, def_id);
     let entry_ln = lsets.compute(&body.value);
 
     // check for various error conditions
@@ -658,6 +658,7 @@ const ACC_USE: u32 = 4;
 struct Liveness<'a, 'tcx> {
     ir: &'a mut IrMaps<'tcx>,
     tables: &'a ty::TypeckTables<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
     s: Specials,
     successors: Vec<LiveNode>,
     rwu_table: RWUTable,
@@ -670,7 +671,7 @@ struct Liveness<'a, 'tcx> {
 }
 
 impl<'a, 'tcx> Liveness<'a, 'tcx> {
-    fn new(ir: &'a mut IrMaps<'tcx>, body: hir::BodyId) -> Liveness<'a, 'tcx> {
+    fn new(ir: &'a mut IrMaps<'tcx>, def_id: DefId) -> Liveness<'a, 'tcx> {
         // Special nodes and variables:
         // - exit_ln represents the end of the fn, either by return or panic
         // - implicit_ret_var is a pseudo-variable that represents
@@ -681,7 +682,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
             clean_exit_var: ir.add_variable(CleanExit),
         };
 
-        let tables = ir.tcx.body_tables(body);
+        let tables = ir.tcx.typeck_tables_of(def_id);
+        let param_env = ir.tcx.param_env(def_id);
 
         let num_live_nodes = ir.num_live_nodes;
         let num_vars = ir.num_vars;
@@ -689,6 +691,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         Liveness {
             ir,
             tables,
+            param_env,
             s: specials,
             successors: vec![invalid_node(); num_live_nodes],
             rwu_table: RWUTable::new(num_live_nodes * num_vars),
@@ -1126,7 +1129,11 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
 
             hir::ExprKind::Call(ref f, ref args) => {
                 let m = self.ir.tcx.parent_module(expr.hir_id);
-                let succ = if self.ir.tcx.is_ty_uninhabited_from(m, self.tables.expr_ty(expr)) {
+                let succ = if self.ir.tcx.is_ty_uninhabited_from(
+                    m,
+                    self.tables.expr_ty(expr),
+                    self.param_env,
+                ) {
                     self.s.exit_ln
                 } else {
                     succ
@@ -1137,7 +1144,11 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
 
             hir::ExprKind::MethodCall(.., ref args) => {
                 let m = self.ir.tcx.parent_module(expr.hir_id);
-                let succ = if self.ir.tcx.is_ty_uninhabited_from(m, self.tables.expr_ty(expr)) {
+                let succ = if self.ir.tcx.is_ty_uninhabited_from(
+                    m,
+                    self.tables.expr_ty(expr),
+                    self.param_env,
+                ) {
                     self.s.exit_ln
                 } else {
                     succ