diff options
| author | varkor <github@varkor.com> | 2018-11-20 19:20:14 +0000 |
|---|---|---|
| committer | varkor <github@varkor.com> | 2018-11-29 20:58:37 +0000 |
| commit | 682f0f8d807b728cb18712fb3315e024f22118bb (patch) | |
| tree | f782d5873255b47aa37b9d081b47cc085a6d7960 | |
| parent | 3dde9e132207b5a40e12f8d5a1a363ebea60e0b0 (diff) | |
| download | rust-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.rs | 44 |
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(), } |
