Skip to content

Commit 2928e9e

Browse files
committed
Introduce InhabitedPredicate
1 parent 0940040 commit 2928e9e

File tree

8 files changed

+338
-354
lines changed

8 files changed

+338
-354
lines changed

Diff for: compiler/rustc_lint/src/builtin.rs

+5-41
Original file line numberDiff line numberDiff line change
@@ -2467,42 +2467,6 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
24672467
None
24682468
}
24692469

2470-
/// Determines whether the given type is inhabited. `None` means that we don't know.
2471-
fn ty_inhabited<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<bool> {
2472-
use rustc_type_ir::sty::TyKind::*;
2473-
if !cx.tcx.type_uninhabited_from(cx.param_env.and(ty)).is_empty() {
2474-
// This is definitely uninhabited from some module.
2475-
return Some(false);
2476-
}
2477-
match ty.kind() {
2478-
Never => Some(false),
2479-
Int(_) | Uint(_) | Float(_) | Bool | Char | RawPtr(_) => Some(true),
2480-
// Fallback for more complicated types. (Note that `&!` might be considered
2481-
// uninhabited so references are "complicated", too.)
2482-
_ => None,
2483-
}
2484-
}
2485-
/// Determines whether a product type formed from a list of types is inhabited.
2486-
fn tys_inhabited<'tcx>(
2487-
cx: &LateContext<'tcx>,
2488-
tys: impl Iterator<Item = Ty<'tcx>>,
2489-
) -> Option<bool> {
2490-
let mut definitely_inhabited = true; // with no fields, we are definitely inhabited.
2491-
for ty in tys {
2492-
match ty_inhabited(cx, ty) {
2493-
// If any type is uninhabited, the product is uninhabited.
2494-
Some(false) => return Some(false),
2495-
// Otherwise go searching for a `None`.
2496-
None => {
2497-
// We don't know.
2498-
definitely_inhabited = false;
2499-
}
2500-
Some(true) => {}
2501-
}
2502-
}
2503-
if definitely_inhabited { Some(true) } else { None }
2504-
}
2505-
25062470
fn variant_find_init_error<'tcx>(
25072471
cx: &LateContext<'tcx>,
25082472
variant: &VariantDef,
@@ -2599,11 +2563,11 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
25992563
// And now, enums.
26002564
let span = cx.tcx.def_span(adt_def.did());
26012565
let mut potential_variants = adt_def.variants().iter().filter_map(|variant| {
2602-
let inhabited = tys_inhabited(
2603-
cx,
2604-
variant.fields.iter().map(|field| field.ty(cx.tcx, substs)),
2605-
);
2606-
let definitely_inhabited = match inhabited {
2566+
let definitely_inhabited = match variant
2567+
.inhabited_predicate(cx.tcx, *adt_def)
2568+
.subst(cx.tcx, substs)
2569+
.apply_any_module(cx.tcx, cx.param_env)
2570+
{
26072571
// Entirely skip uninhbaited variants.
26082572
Some(false) => return None,
26092573
// Forward the others, but remember which ones are definitely inhabited.

Diff for: compiler/rustc_middle/src/query/mod.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -1653,14 +1653,13 @@ rustc_queries! {
16531653
separate_provide_extern
16541654
}
16551655

1656-
/// Computes the set of modules from which this type is visibly uninhabited.
1657-
/// To check whether a type is uninhabited at all (not just from a given module), you could
1658-
/// check whether the forest is empty.
1659-
query type_uninhabited_from(
1660-
key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>
1661-
) -> ty::inhabitedness::DefIdForest<'tcx> {
1662-
desc { "computing the inhabitedness of `{}`", key.value }
1663-
remap_env_constness
1656+
query inhabited_predicate_adt(key: DefId) -> ty::inhabitedness::InhabitedPredicate<'tcx> {
1657+
desc { "computing the uninhabited predicate of `{:?}`", key }
1658+
}
1659+
1660+
/// Do not call this query directly: invoke `Ty::inhabited_predicate` instead.
1661+
query inhabited_predicate_type(key: Ty<'tcx>) -> ty::inhabitedness::InhabitedPredicate<'tcx> {
1662+
desc { "computing the uninhabited predicate of `{}`", key }
16641663
}
16651664

16661665
query dep_kind(_: CrateNum) -> CrateDepKind {

Diff for: compiler/rustc_middle/src/ty/inhabitedness/def_id_forest.rs

-145
This file was deleted.

0 commit comments

Comments
 (0)