From 682f0f8d807b728cb18712fb3315e024f22118bb Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 20 Nov 2018 19:20:14 +0000 Subject: [PATCH] Consider references and unions potentially inhabited during privacy-respecting inhabitedness checks --- src/librustc/ty/inhabitedness/mod.rs | 44 +++++++++++++--------------- 1 file 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>>, 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(), }