Skip to content

Commit 7894509

Browse files
committed
Fiddle ParamEnv through to a place that used to use ParamEnv::empty in a buggy manner
1 parent 59f4ba9 commit 7894509

File tree

5 files changed

+64
-24
lines changed

5 files changed

+64
-24
lines changed

src/librustc/ty/inhabitedness/mod.rs

+34-15
Original file line numberDiff line numberDiff line change
@@ -90,30 +90,46 @@ impl<'tcx> TyCtxt<'tcx> {
9090
/// ```
9191
/// This code should only compile in modules where the uninhabitedness of Foo is
9292
/// visible.
93-
pub fn is_ty_uninhabited_from(self, module: DefId, ty: Ty<'tcx>) -> bool {
93+
pub fn is_ty_uninhabited_from(
94+
self,
95+
module: DefId,
96+
ty: Ty<'tcx>,
97+
param_env: ty::ParamEnv<'tcx>,
98+
) -> bool {
9499
// To check whether this type is uninhabited at all (not just from the
95100
// given node), you could check whether the forest is empty.
96101
// ```
97102
// forest.is_empty()
98103
// ```
99-
ty.uninhabited_from(self).contains(self, module)
104+
ty.uninhabited_from(self, param_env).contains(self, module)
100105
}
101106

102-
pub fn is_ty_uninhabited_from_any_module(self, ty: Ty<'tcx>) -> bool {
103-
!ty.uninhabited_from(self).is_empty()
107+
pub fn is_ty_uninhabited_from_any_module(
108+
self,
109+
ty: Ty<'tcx>,
110+
param_env: ty::ParamEnv<'tcx>,
111+
) -> bool {
112+
!ty.uninhabited_from(self, param_env).is_empty()
104113
}
105114
}
106115

107116
impl<'tcx> AdtDef {
108117
/// Calculates the forest of `DefId`s from which this ADT is visibly uninhabited.
109-
fn uninhabited_from(&self, tcx: TyCtxt<'tcx>, substs: SubstsRef<'tcx>) -> DefIdForest {
118+
fn uninhabited_from(
119+
&self,
120+
tcx: TyCtxt<'tcx>,
121+
substs: SubstsRef<'tcx>,
122+
param_env: ty::ParamEnv<'tcx>,
123+
) -> DefIdForest {
110124
// Non-exhaustive ADTs from other crates are always considered inhabited.
111125
if self.is_variant_list_non_exhaustive() && !self.did.is_local() {
112126
DefIdForest::empty()
113127
} else {
114128
DefIdForest::intersection(
115129
tcx,
116-
self.variants.iter().map(|v| v.uninhabited_from(tcx, substs, self.adt_kind())),
130+
self.variants
131+
.iter()
132+
.map(|v| v.uninhabited_from(tcx, substs, self.adt_kind(), param_env)),
117133
)
118134
}
119135
}
@@ -126,6 +142,7 @@ impl<'tcx> VariantDef {
126142
tcx: TyCtxt<'tcx>,
127143
substs: SubstsRef<'tcx>,
128144
adt_kind: AdtKind,
145+
param_env: ty::ParamEnv<'tcx>,
129146
) -> DefIdForest {
130147
let is_enum = match adt_kind {
131148
// For now, `union`s are never considered uninhabited.
@@ -140,7 +157,7 @@ impl<'tcx> VariantDef {
140157
} else {
141158
DefIdForest::union(
142159
tcx,
143-
self.fields.iter().map(|f| f.uninhabited_from(tcx, substs, is_enum)),
160+
self.fields.iter().map(|f| f.uninhabited_from(tcx, substs, is_enum, param_env)),
144161
)
145162
}
146163
}
@@ -153,8 +170,9 @@ impl<'tcx> FieldDef {
153170
tcx: TyCtxt<'tcx>,
154171
substs: SubstsRef<'tcx>,
155172
is_enum: bool,
173+
param_env: ty::ParamEnv<'tcx>,
156174
) -> DefIdForest {
157-
let data_uninhabitedness = move || self.ty(tcx, substs).uninhabited_from(tcx);
175+
let data_uninhabitedness = move || self.ty(tcx, substs).uninhabited_from(tcx, param_env);
158176
// FIXME(canndrew): Currently enum fields are (incorrectly) stored with
159177
// `Visibility::Invisible` so we need to override `self.vis` if we're
160178
// dealing with an enum.
@@ -176,20 +194,21 @@ impl<'tcx> FieldDef {
176194

177195
impl<'tcx> TyS<'tcx> {
178196
/// Calculates the forest of `DefId`s from which this type is visibly uninhabited.
179-
fn uninhabited_from(&self, tcx: TyCtxt<'tcx>) -> DefIdForest {
197+
fn uninhabited_from(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> DefIdForest {
180198
match self.kind {
181-
Adt(def, substs) => def.uninhabited_from(tcx, substs),
199+
Adt(def, substs) => def.uninhabited_from(tcx, substs, param_env),
182200

183201
Never => DefIdForest::full(tcx),
184202

185-
Tuple(ref tys) => {
186-
DefIdForest::union(tcx, tys.iter().map(|ty| ty.expect_ty().uninhabited_from(tcx)))
187-
}
203+
Tuple(ref tys) => DefIdForest::union(
204+
tcx,
205+
tys.iter().map(|ty| ty.expect_ty().uninhabited_from(tcx, param_env)),
206+
),
188207

189-
Array(ty, len) => match len.try_eval_usize(tcx, ty::ParamEnv::empty()) {
208+
Array(ty, len) => match len.try_eval_usize(tcx, param_env) {
190209
// If the array is definitely non-empty, it's uninhabited if
191210
// the type of its elements is uninhabited.
192-
Some(n) if n != 0 => ty.uninhabited_from(tcx),
211+
Some(n) if n != 0 => ty.uninhabited_from(tcx, param_env),
193212
_ => DefIdForest::empty(),
194213
},
195214

src/librustc_lint/unused.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
124124
descr_post: &str,
125125
plural_len: usize,
126126
) -> bool {
127-
if ty.is_unit() || cx.tcx.is_ty_uninhabited_from(cx.tcx.parent_module(expr.hir_id), ty)
127+
if ty.is_unit()
128+
|| cx.tcx.is_ty_uninhabited_from(
129+
cx.tcx.parent_module(expr.hir_id),
130+
ty,
131+
cx.param_env,
132+
)
128133
{
129134
return true;
130135
}

src/librustc_mir_build/build/matches/simplify.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
209209
i == variant_index || {
210210
self.hir.tcx().features().exhaustive_patterns
211211
&& !v
212-
.uninhabited_from(self.hir.tcx(), substs, adt_def.adt_kind())
212+
.uninhabited_from(
213+
self.hir.tcx(),
214+
substs,
215+
adt_def.adt_kind(),
216+
self.hir.param_env,
217+
)
213218
.is_empty()
214219
}
215220
}) && (adt_def.did.is_local()

src/librustc_mir_build/hair/pattern/_match.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,7 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
598598

599599
fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool {
600600
if self.tcx.features().exhaustive_patterns {
601-
self.tcx.is_ty_uninhabited_from(self.module, ty)
601+
self.tcx.is_ty_uninhabited_from(self.module, ty, self.param_env)
602602
} else {
603603
false
604604
}
@@ -1267,7 +1267,7 @@ fn all_constructors<'a, 'tcx>(
12671267
def.variants
12681268
.iter()
12691269
.filter(|v| {
1270-
!v.uninhabited_from(cx.tcx, substs, def.adt_kind())
1270+
!v.uninhabited_from(cx.tcx, substs, def.adt_kind(), cx.param_env)
12711271
.contains(cx.tcx, cx.module)
12721272
})
12731273
.map(|v| Variant(v.def_id))

src/librustc_passes/liveness.rs

+16-5
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ fn visit_fn<'tcx>(
398398
intravisit::walk_fn(&mut fn_maps, fk, decl, body_id, sp, id);
399399

400400
// compute liveness
401-
let mut lsets = Liveness::new(&mut fn_maps, body_id);
401+
let mut lsets = Liveness::new(&mut fn_maps, def_id);
402402
let entry_ln = lsets.compute(&body.value);
403403

404404
// check for various error conditions
@@ -658,6 +658,7 @@ const ACC_USE: u32 = 4;
658658
struct Liveness<'a, 'tcx> {
659659
ir: &'a mut IrMaps<'tcx>,
660660
tables: &'a ty::TypeckTables<'tcx>,
661+
param_env: ty::ParamEnv<'tcx>,
661662
s: Specials,
662663
successors: Vec<LiveNode>,
663664
rwu_table: RWUTable,
@@ -670,7 +671,7 @@ struct Liveness<'a, 'tcx> {
670671
}
671672

672673
impl<'a, 'tcx> Liveness<'a, 'tcx> {
673-
fn new(ir: &'a mut IrMaps<'tcx>, body: hir::BodyId) -> Liveness<'a, 'tcx> {
674+
fn new(ir: &'a mut IrMaps<'tcx>, def_id: DefId) -> Liveness<'a, 'tcx> {
674675
// Special nodes and variables:
675676
// - exit_ln represents the end of the fn, either by return or panic
676677
// - implicit_ret_var is a pseudo-variable that represents
@@ -681,14 +682,16 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
681682
clean_exit_var: ir.add_variable(CleanExit),
682683
};
683684

684-
let tables = ir.tcx.body_tables(body);
685+
let tables = ir.tcx.typeck_tables_of(def_id);
686+
let param_env = ir.tcx.param_env(def_id);
685687

686688
let num_live_nodes = ir.num_live_nodes;
687689
let num_vars = ir.num_vars;
688690

689691
Liveness {
690692
ir,
691693
tables,
694+
param_env,
692695
s: specials,
693696
successors: vec![invalid_node(); num_live_nodes],
694697
rwu_table: RWUTable::new(num_live_nodes * num_vars),
@@ -1126,7 +1129,11 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
11261129

11271130
hir::ExprKind::Call(ref f, ref args) => {
11281131
let m = self.ir.tcx.parent_module(expr.hir_id);
1129-
let succ = if self.ir.tcx.is_ty_uninhabited_from(m, self.tables.expr_ty(expr)) {
1132+
let succ = if self.ir.tcx.is_ty_uninhabited_from(
1133+
m,
1134+
self.tables.expr_ty(expr),
1135+
self.param_env,
1136+
) {
11301137
self.s.exit_ln
11311138
} else {
11321139
succ
@@ -1137,7 +1144,11 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
11371144

11381145
hir::ExprKind::MethodCall(.., ref args) => {
11391146
let m = self.ir.tcx.parent_module(expr.hir_id);
1140-
let succ = if self.ir.tcx.is_ty_uninhabited_from(m, self.tables.expr_ty(expr)) {
1147+
let succ = if self.ir.tcx.is_ty_uninhabited_from(
1148+
m,
1149+
self.tables.expr_ty(expr),
1150+
self.param_env,
1151+
) {
11411152
self.s.exit_ln
11421153
} else {
11431154
succ

0 commit comments

Comments
 (0)