Skip to content

Commit 2c18d60

Browse files
committed
Use query for Variant InhabitedPredicate
1 parent eff8269 commit 2c18d60

4 files changed

Lines changed: 53 additions & 45 deletions

File tree

compiler/rustc_lint/src/builtin.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2522,8 +2522,9 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
25222522
// And now, enums.
25232523
let span = cx.tcx.def_span(adt_def.did());
25242524
let mut potential_variants = adt_def.variants().iter().filter_map(|variant| {
2525-
let definitely_inhabited = match variant
2526-
.inhabited_predicate(cx.tcx, *adt_def)
2525+
let definitely_inhabited = match cx
2526+
.tcx
2527+
.inhabited_predicate_adt(variant.def_id)
25272528
.instantiate(cx.tcx, args)
25282529
.apply_any_module(cx.tcx, cx.typing_env())
25292530
{

compiler/rustc_middle/src/ty/inhabitedness/mod.rs

Lines changed: 42 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
use std::assert_matches;
4747

4848
use rustc_data_structures::fx::FxHashSet;
49+
use rustc_hir::def::DefKind;
4950
use rustc_span::def_id::LocalModId;
5051
use rustc_type_ir::TyKind::*;
5152
use tracing::instrument;
@@ -69,47 +70,53 @@ pub(crate) fn provide(providers: &mut Providers) {
6970
/// Returns an `InhabitedPredicate` that is generic over type parameters and
7071
/// requires calling [`InhabitedPredicate::instantiate`]
7172
fn inhabited_predicate_adt(tcx: TyCtxt<'_>, def_id: DefId) -> InhabitedPredicate<'_> {
72-
if let Some(def_id) = def_id.as_local() {
73-
tcx.ensure_ok().check_representability(def_id);
73+
match tcx.def_kind(def_id) {
74+
DefKind::Enum => {
75+
if let Some(def_id) = def_id.as_local() {
76+
tcx.ensure_ok().check_representability(def_id);
77+
}
78+
let adt = tcx.adt_def(def_id);
79+
InhabitedPredicate::any(
80+
tcx,
81+
adt.variants().iter().map(|v| tcx.inhabited_predicate_adt(v.def_id)),
82+
)
83+
}
84+
DefKind::Struct => {
85+
if let Some(def_id) = def_id.as_local() {
86+
tcx.ensure_ok().check_representability(def_id);
87+
}
88+
let adt = tcx.adt_def(def_id);
89+
variant_inhabited_predicate(tcx, adt.non_enum_variant())
90+
}
91+
DefKind::Variant => {
92+
let adt = tcx.adt_def(tcx.parent(def_id));
93+
let variant = adt.variant_with_id(def_id);
94+
variant_inhabited_predicate(tcx, variant)
95+
}
96+
def_kind => bug!("unexpected DefKind: {def_kind:?}"),
7497
}
98+
}
7599

76-
let adt = tcx.adt_def(def_id);
77-
InhabitedPredicate::any(
100+
fn variant_inhabited_predicate<'tcx>(
101+
tcx: TyCtxt<'tcx>,
102+
variant: &VariantDef,
103+
) -> InhabitedPredicate<'tcx> {
104+
InhabitedPredicate::all(
78105
tcx,
79-
adt.variants().iter().map(|variant| variant.inhabited_predicate(tcx, adt)),
106+
variant.fields.iter().map(|field| {
107+
let pred = tcx
108+
.type_of(field.did)
109+
.instantiate_identity()
110+
.skip_norm_wip()
111+
.inhabited_predicate(tcx);
112+
match field.vis {
113+
Visibility::Public => pred,
114+
Visibility::Restricted(from) => InhabitedPredicate::NotInModule(from).or(tcx, pred),
115+
}
116+
}),
80117
)
81118
}
82119

83-
impl<'tcx> VariantDef {
84-
/// Calculates the forest of `DefId`s from which this variant is visibly uninhabited.
85-
pub fn inhabited_predicate(
86-
&self,
87-
tcx: TyCtxt<'tcx>,
88-
adt: ty::AdtDef<'_>,
89-
) -> InhabitedPredicate<'tcx> {
90-
debug_assert!(!adt.is_union());
91-
InhabitedPredicate::all(
92-
tcx,
93-
self.fields.iter().map(|field| {
94-
let pred = tcx
95-
.type_of(field.did)
96-
.instantiate_identity()
97-
.skip_norm_wip()
98-
.inhabited_predicate(tcx);
99-
if adt.is_enum() {
100-
return pred;
101-
}
102-
match field.vis {
103-
Visibility::Public => pred,
104-
Visibility::Restricted(from) => {
105-
InhabitedPredicate::NotInModule(from).or(tcx, pred)
106-
}
107-
}
108-
}),
109-
)
110-
}
111-
}
112-
113120
impl<'tcx> Ty<'tcx> {
114121
#[instrument(level = "debug", skip(tcx), ret)]
115122
pub fn inhabited_predicate(self, tcx: TyCtxt<'tcx>) -> InhabitedPredicate<'tcx> {

compiler/rustc_mir_build/src/thir/pattern/check_match.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -730,12 +730,11 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
730730
let witness_1_is_privately_uninhabited = if let Some(witness_1) = witnesses.get(0)
731731
&& let ty::Adt(adt, args) = witness_1.ty().kind()
732732
&& adt.is_enum()
733-
&& let Constructor::Variant(variant_index) = witness_1.ctor()
733+
&& let Constructor::Variant(variant_index) = *witness_1.ctor()
734734
{
735-
let variant_inhabited = adt
736-
.variant(*variant_index)
737-
.inhabited_predicate(self.tcx, *adt)
738-
.instantiate(self.tcx, args);
735+
let variant_def_id = adt.variant(variant_index).def_id;
736+
let variant_inhabited =
737+
self.tcx.inhabited_predicate_adt(variant_def_id).instantiate(self.tcx, args);
739738
variant_inhabited.apply(self.tcx, cx.typing_env, cx.module)
740739
&& !variant_inhabited.apply_ignore_module(self.tcx, cx.typing_env)
741740
} else {

compiler/rustc_pattern_analysis/src/rustc.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -377,10 +377,11 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
377377
let mut variants =
378378
IndexVec::from_elem(VariantVisibility::Visible, def.variants());
379379
for (idx, v) in def.variants().iter_enumerated() {
380-
let variant_def_id = def.variant(idx).def_id;
380+
let variant_def_id = v.def_id;
381381
// Visibly uninhabited variants.
382-
let is_inhabited = v
383-
.inhabited_predicate(cx.tcx, *def)
382+
let is_inhabited = self
383+
.tcx
384+
.inhabited_predicate_adt(variant_def_id)
384385
.instantiate(cx.tcx, args)
385386
.apply_revealing_opaque(cx.tcx, cx.typing_env, cx.module, &|key| {
386387
cx.reveal_opaque_key(key)

0 commit comments

Comments
 (0)