]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc/ty/inhabitedness/mod.rs
Run `rustfmt --file-lines ...` for changes from previous commits.
[rust.git] / src / librustc / ty / inhabitedness / mod.rs
index 197d3325f51cfdb232dd3c8b3815a9788baca0c3..b9e34e0cabc65bb6abfdba305a1b59b7a21028f6 100644 (file)
@@ -51,7 +51,7 @@
 // This code should only compile in modules where the uninhabitedness of Foo is
 // visible.
 
-impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
+impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
     /// Checks whether a type is visibly uninhabited from a particular module.
     /// # Example
     /// ```rust
@@ -106,27 +106,28 @@ fn ty_inhabitedness_forest(self, ty: Ty<'tcx>) -> DefIdForest {
     }
 }
 
-impl<'a, 'gcx, 'tcx> AdtDef {
+impl<'gcx, 'tcx> AdtDef {
     /// Calculate the forest of DefIds from which this adt is visibly uninhabited.
-    fn uninhabited_from(
-        &self,
-        tcx: TyCtxt<'a, 'gcx, 'tcx>,
-        substs: SubstsRef<'tcx>) -> DefIdForest
-    {
-        DefIdForest::intersection(tcx, self.variants.iter().map(|v| {
-            v.uninhabited_from(tcx, substs, self.adt_kind())
-        }))
+    fn uninhabited_from(&self, tcx: TyCtxt<'gcx, 'tcx>, substs: SubstsRef<'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())
+            }))
+        }
     }
 }
 
-impl<'a, 'gcx, 'tcx> VariantDef {
+impl<'gcx, 'tcx> VariantDef {
     /// Calculate the forest of DefIds from which this variant is visibly uninhabited.
     pub fn uninhabited_from(
         &self,
-        tcx: TyCtxt<'a, 'gcx, 'tcx>,
+        tcx: TyCtxt<'gcx, 'tcx>,
         substs: SubstsRef<'tcx>,
-        adt_kind: AdtKind) -> DefIdForest
-    {
+        adt_kind: AdtKind,
+    ) -> DefIdForest {
         let is_enum = match adt_kind {
             // For now, `union`s are never considered uninhabited.
             // The precise semantics of inhabitedness with respect to unions is currently undecided.
@@ -134,17 +135,22 @@ pub fn uninhabited_from(
             AdtKind::Enum => true,
             AdtKind::Struct => false,
         };
-        DefIdForest::union(tcx, self.fields.iter().map(|f| {
-            f.uninhabited_from(tcx, substs, is_enum)
-        }))
+        // Non-exhaustive variants from other crates are always considered inhabited.
+        if self.is_field_list_non_exhaustive() && !self.def_id.is_local() {
+            DefIdForest::empty()
+        } else {
+            DefIdForest::union(tcx, self.fields.iter().map(|f| {
+                f.uninhabited_from(tcx, substs, is_enum)
+            }))
+        }
     }
 }
 
-impl<'a, 'gcx, 'tcx> FieldDef {
+impl<'gcx, 'tcx> FieldDef {
     /// Calculate the forest of DefIds from which this field is visibly uninhabited.
     fn uninhabited_from(
         &self,
-        tcx: TyCtxt<'a, 'gcx, 'tcx>,
+        tcx: TyCtxt<'gcx, 'tcx>,
         substs: SubstsRef<'tcx>,
         is_enum: bool,
     ) -> DefIdForest {
@@ -170,10 +176,9 @@ fn uninhabited_from(
     }
 }
 
-impl<'a, 'gcx, 'tcx> TyS<'tcx> {
+impl<'gcx, 'tcx> TyS<'tcx> {
     /// Calculate the forest of DefIds from which this type is visibly uninhabited.
-    fn uninhabited_from(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> DefIdForest
-    {
+    fn uninhabited_from(&self, tcx: TyCtxt<'gcx, 'tcx>) -> DefIdForest {
         match self.sty {
             Adt(def, substs) => def.uninhabited_from(tcx, substs),