Consider references and unions potentially inhabited during privacy-respecting inhabitedness checks
This commit is contained in:
parent
3dde9e1322
commit
682f0f8d80
1 changed files with 20 additions and 24 deletions
|
@ -167,23 +167,15 @@ impl<'a, 'gcx, 'tcx> VariantDef {
|
||||||
substs: &'tcx Substs<'tcx>,
|
substs: &'tcx Substs<'tcx>,
|
||||||
adt_kind: AdtKind) -> DefIdForest
|
adt_kind: AdtKind) -> DefIdForest
|
||||||
{
|
{
|
||||||
match adt_kind {
|
let is_enum = match adt_kind {
|
||||||
AdtKind::Union => {
|
// For now, `union`s are never considered uninhabited.
|
||||||
DefIdForest::intersection(tcx, self.fields.iter().map(|f| {
|
AdtKind::Union => return DefIdForest::empty(),
|
||||||
f.uninhabited_from(visited, tcx, substs, false)
|
AdtKind::Enum => true,
|
||||||
}))
|
AdtKind::Struct => false,
|
||||||
},
|
};
|
||||||
AdtKind::Struct => {
|
DefIdForest::union(tcx, self.fields.iter().map(|f| {
|
||||||
DefIdForest::union(tcx, self.fields.iter().map(|f| {
|
f.uninhabited_from(visited, tcx, substs, is_enum)
|
||||||
f.uninhabited_from(visited, tcx, substs, false)
|
}))
|
||||||
}))
|
|
||||||
},
|
|
||||||
AdtKind::Enum => {
|
|
||||||
DefIdForest::union(tcx, self.fields.iter().map(|f| {
|
|
||||||
f.uninhabited_from(visited, tcx, substs, true)
|
|
||||||
}))
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,8 +186,8 @@ impl<'a, 'gcx, 'tcx> FieldDef {
|
||||||
visited: &mut FxHashMap<DefId, FxHashSet<&'tcx Substs<'tcx>>>,
|
visited: &mut FxHashMap<DefId, FxHashSet<&'tcx Substs<'tcx>>>,
|
||||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
substs: &'tcx Substs<'tcx>,
|
substs: &'tcx Substs<'tcx>,
|
||||||
is_enum: bool) -> DefIdForest
|
is_enum: bool,
|
||||||
{
|
) -> DefIdForest {
|
||||||
let mut data_uninhabitedness = move || {
|
let mut data_uninhabitedness = move || {
|
||||||
self.ty(tcx, substs).uninhabited_from(visited, tcx)
|
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();
|
let substs_set = visited.get_mut(&def.did).unwrap();
|
||||||
substs_set.remove(substs);
|
substs_set.remove(substs);
|
||||||
ret
|
ret
|
||||||
},
|
}
|
||||||
|
|
||||||
Never => DefIdForest::full(tcx),
|
Never => DefIdForest::full(tcx),
|
||||||
|
|
||||||
Tuple(ref tys) => {
|
Tuple(ref tys) => {
|
||||||
DefIdForest::union(tcx, tys.iter().map(|ty| {
|
DefIdForest::union(tcx, tys.iter().map(|ty| {
|
||||||
ty.uninhabited_from(visited, tcx)
|
ty.uninhabited_from(visited, tcx)
|
||||||
}))
|
}))
|
||||||
},
|
}
|
||||||
|
|
||||||
Array(ty, len) => {
|
Array(ty, len) => {
|
||||||
match len.assert_usize(tcx) {
|
match len.assert_usize(tcx) {
|
||||||
// If the array is definitely non-empty, it's uninhabited if
|
// If the array is definitely non-empty, it's uninhabited if
|
||||||
|
@ -269,9 +263,11 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
|
||||||
_ => DefIdForest::empty()
|
_ => 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(),
|
_ => DefIdForest::empty(),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue