Auto merge of #82159 - BoxyUwU:uwu, r=varkor

Use correct param_env in conservative_is_privately_uninhabited

cc `@lcnr`
r? `@varkor` since this is your FIXME that was removed ^^
This commit is contained in:
bors
2021-02-24 21:54:52 +00:00
9 changed files with 131 additions and 57 deletions

View File

@@ -1697,53 +1697,6 @@ impl<'tcx> TyS<'tcx> {
matches!(self.kind(), Never)
}
/// Checks whether a type is definitely uninhabited. This is
/// conservative: for some types that are uninhabited we return `false`,
/// but we only return `true` for types that are definitely uninhabited.
/// `ty.conservative_is_privately_uninhabited` implies that any value of type `ty`
/// will be `Abi::Uninhabited`. (Note that uninhabited types may have nonzero
/// size, to account for partial initialisation. See #49298 for details.)
pub fn conservative_is_privately_uninhabited(&self, tcx: TyCtxt<'tcx>) -> bool {
// FIXME(varkor): we can make this less conversative by substituting concrete
// type arguments.
match self.kind() {
ty::Never => true,
ty::Adt(def, _) if def.is_union() => {
// For now, `union`s are never considered uninhabited.
false
}
ty::Adt(def, _) => {
// Any ADT is uninhabited if either:
// (a) It has no variants (i.e. an empty `enum`);
// (b) Each of its variants (a single one in the case of a `struct`) has at least
// one uninhabited field.
def.variants.iter().all(|var| {
var.fields.iter().any(|field| {
tcx.type_of(field.did).conservative_is_privately_uninhabited(tcx)
})
})
}
ty::Tuple(..) => {
self.tuple_fields().any(|ty| ty.conservative_is_privately_uninhabited(tcx))
}
ty::Array(ty, len) => {
match len.try_eval_usize(tcx, ParamEnv::empty()) {
Some(0) | None => false,
// If the array is definitely non-empty, it's uninhabited if
// the type of its elements is uninhabited.
Some(1..) => ty.conservative_is_privately_uninhabited(tcx),
}
}
ty::Ref(..) => {
// References to uninitialised memory is valid for any type, including
// uninhabited types, in unsafe code, so we treat all references as
// inhabited.
false
}
_ => false,
}
}
#[inline]
pub fn is_primitive(&self) -> bool {
self.kind().is_primitive()