@@ -90,30 +90,46 @@ impl<'tcx> TyCtxt<'tcx> {
90
90
/// ```
91
91
/// This code should only compile in modules where the uninhabitedness of Foo is
92
92
/// 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 {
94
99
// To check whether this type is uninhabited at all (not just from the
95
100
// given node), you could check whether the forest is empty.
96
101
// ```
97
102
// forest.is_empty()
98
103
// ```
99
- ty. uninhabited_from ( self ) . contains ( self , module)
104
+ ty. uninhabited_from ( self , param_env ) . contains ( self , module)
100
105
}
101
106
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 ( )
104
113
}
105
114
}
106
115
107
116
impl < ' tcx > AdtDef {
108
117
/// 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 {
110
124
// Non-exhaustive ADTs from other crates are always considered inhabited.
111
125
if self . is_variant_list_non_exhaustive ( ) && !self . did . is_local ( ) {
112
126
DefIdForest :: empty ( )
113
127
} else {
114
128
DefIdForest :: intersection (
115
129
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) ) ,
117
133
)
118
134
}
119
135
}
@@ -126,6 +142,7 @@ impl<'tcx> VariantDef {
126
142
tcx : TyCtxt < ' tcx > ,
127
143
substs : SubstsRef < ' tcx > ,
128
144
adt_kind : AdtKind ,
145
+ param_env : ty:: ParamEnv < ' tcx > ,
129
146
) -> DefIdForest {
130
147
let is_enum = match adt_kind {
131
148
// For now, `union`s are never considered uninhabited.
@@ -140,7 +157,7 @@ impl<'tcx> VariantDef {
140
157
} else {
141
158
DefIdForest :: union (
142
159
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 ) ) ,
144
161
)
145
162
}
146
163
}
@@ -153,8 +170,9 @@ impl<'tcx> FieldDef {
153
170
tcx : TyCtxt < ' tcx > ,
154
171
substs : SubstsRef < ' tcx > ,
155
172
is_enum : bool ,
173
+ param_env : ty:: ParamEnv < ' tcx > ,
156
174
) -> 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 ) ;
158
176
// FIXME(canndrew): Currently enum fields are (incorrectly) stored with
159
177
// `Visibility::Invisible` so we need to override `self.vis` if we're
160
178
// dealing with an enum.
@@ -176,20 +194,21 @@ impl<'tcx> FieldDef {
176
194
177
195
impl < ' tcx > TyS < ' tcx > {
178
196
/// 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 {
180
198
match self . kind {
181
- Adt ( def, substs) => def. uninhabited_from ( tcx, substs) ,
199
+ Adt ( def, substs) => def. uninhabited_from ( tcx, substs, param_env ) ,
182
200
183
201
Never => DefIdForest :: full ( tcx) ,
184
202
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
+ ) ,
188
207
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 ) {
190
209
// If the array is definitely non-empty, it's uninhabited if
191
210
// 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 ) ,
193
212
_ => DefIdForest :: empty ( ) ,
194
213
} ,
195
214
0 commit comments