about summary refs log tree commit diff
diff options
context:
space:
mode:
authorvarkor <github@varkor.com>2018-11-20 19:20:14 +0000
committervarkor <github@varkor.com>2018-11-29 20:58:37 +0000
commit682f0f8d807b728cb18712fb3315e024f22118bb (patch)
treef782d5873255b47aa37b9d081b47cc085a6d7960
parent3dde9e132207b5a40e12f8d5a1a363ebea60e0b0 (diff)
downloadrust-682f0f8d807b728cb18712fb3315e024f22118bb.tar.gz
rust-682f0f8d807b728cb18712fb3315e024f22118bb.zip
Consider references and unions potentially inhabited during privacy-respecting inhabitedness checks
-rw-r--r--src/librustc/ty/inhabitedness/mod.rs44
1 files changed, 20 insertions, 24 deletions
diff --git a/src/librustc/ty/inhabitedness/mod.rs b/src/librustc/ty/inhabitedness/mod.rs
index 56fe479ffc5..3f9a9c17202 100644
--- a/src/librustc/ty/inhabitedness/mod.rs
+++ b/src/librustc/ty/inhabitedness/mod.rs
@@ -167,23 +167,15 @@ impl<'a, 'gcx, 'tcx> VariantDef {
         substs: &'tcx Substs<'tcx>,
         adt_kind: AdtKind) -> DefIdForest
     {
-        match adt_kind {
-            AdtKind::Union => {
-                DefIdForest::intersection(tcx, self.fields.iter().map(|f| {
-                    f.uninhabited_from(visited, tcx, substs, false)
-                }))
-            },
-            AdtKind::Struct => {
-                DefIdForest::union(tcx, self.fields.iter().map(|f| {
-                    f.uninhabited_from(visited, tcx, substs, false)
-                }))
-            },
-            AdtKind::Enum => {
-                DefIdForest::union(tcx, self.fields.iter().map(|f| {
-                    f.uninhabited_from(visited, tcx, substs, true)
-                }))
-            },
-        }
+        let is_enum = match adt_kind {
+            // For now, `union`s are never considered uninhabited.
+            AdtKind::Union => return DefIdForest::empty(),
+            AdtKind::Enum => true,
+            AdtKind::Struct => false,
+        };
+        DefIdForest::union(tcx, self.fields.iter().map(|f| {
+            f.uninhabited_from(visited, tcx, substs, is_enum)
+        }))
     }
 }
 
@@ -194,8 +186,8 @@ impl<'a, 'gcx, 'tcx> FieldDef {
         visited: &mut FxHashMap<DefId, FxHashSet<&'tcx Substs<'tcx>>>,
         tcx: TyCtxt<'a, 'gcx, 'tcx>,
         substs: &'tcx Substs<'tcx>,
-        is_enum: bool) -> DefIdForest
-    {
+        is_enum: bool,
+    ) -> DefIdForest {
         let mut data_uninhabitedness = move || {
             self.ty(tcx, substs).uninhabited_from(visited, tcx)
         };
@@ -253,14 +245,16 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
                 let substs_set = visited.get_mut(&def.did).unwrap();
                 substs_set.remove(substs);
                 ret
-            },
+            }
 
             Never => DefIdForest::full(tcx),
+
             Tuple(ref tys) => {
                 DefIdForest::union(tcx, tys.iter().map(|ty| {
                     ty.uninhabited_from(visited, tcx)
                 }))
-            },
+            }
+
             Array(ty, len) => {
                 match len.assert_usize(tcx) {
                     // If the array is definitely non-empty, it's uninhabited if
@@ -269,9 +263,11 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
                     _ => DefIdForest::empty()
                 }
             }
-            Ref(_, ty, _) => {
-                ty.uninhabited_from(visited, tcx)
-            }
+
+            // References to uninitialised memory is valid for any type, including
+            // uninhabited types, in unsafe code, so we treat all references as
+            // inhabited.
+            Ref(..) => DefIdForest::empty(),
 
             _ => DefIdForest::empty(),
         }