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:
commit
1fdadbf13a
9 changed files with 131 additions and 57 deletions
|
@ -1603,4 +1603,14 @@ rustc_queries! {
|
|||
query normalize_opaque_types(key: &'tcx ty::List<ty::Predicate<'tcx>>) -> &'tcx ty::List<ty::Predicate<'tcx>> {
|
||||
desc { "normalizing opaque types in {:?}", key }
|
||||
}
|
||||
|
||||
/// 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.)
|
||||
query conservative_is_privately_uninhabited(key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
|
||||
desc { "conservatively checking if {:?} is privately uninhabited", key }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -232,7 +232,7 @@ fn layout_raw<'tcx>(
|
|||
let layout = cx.layout_raw_uncached(ty);
|
||||
// Type-level uninhabitedness should always imply ABI uninhabitedness.
|
||||
if let Ok(layout) = layout {
|
||||
if ty.conservative_is_privately_uninhabited(tcx) {
|
||||
if tcx.conservative_is_privately_uninhabited(param_env.and(ty)) {
|
||||
assert!(layout.abi.is_uninhabited());
|
||||
}
|
||||
}
|
||||
|
@ -584,11 +584,12 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
|
|||
let size =
|
||||
element.size.checked_mul(count, dl).ok_or(LayoutError::SizeOverflow(ty))?;
|
||||
|
||||
let abi = if count != 0 && ty.conservative_is_privately_uninhabited(tcx) {
|
||||
Abi::Uninhabited
|
||||
} else {
|
||||
Abi::Aggregate { sized: true }
|
||||
};
|
||||
let abi =
|
||||
if count != 0 && tcx.conservative_is_privately_uninhabited(param_env.and(ty)) {
|
||||
Abi::Uninhabited
|
||||
} else {
|
||||
Abi::Aggregate { sized: true }
|
||||
};
|
||||
|
||||
let largest_niche = if count != 0 { element.largest_niche.clone() } else { None };
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue