X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Flibrustc%2Fty%2Finhabitedness%2Fmod.rs;h=b9e34e0cabc65bb6abfdba305a1b59b7a21028f6;hb=fff08cb04389497d254fb40948674cbbee402908;hp=197d3325f51cfdb232dd3c8b3815a9788baca0c3;hpb=c7fcbfbf1fff2794de5ec6dcb0a052c345ded3a7;p=rust.git diff --git a/src/librustc/ty/inhabitedness/mod.rs b/src/librustc/ty/inhabitedness/mod.rs index 197d3325f51..b9e34e0cabc 100644 --- a/src/librustc/ty/inhabitedness/mod.rs +++ b/src/librustc/ty/inhabitedness/mod.rs @@ -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),