8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
- use util:: nodemap:: { FxHashMap , FxHashSet } ;
12
11
use ty:: context:: TyCtxt ;
13
12
use ty:: { AdtDef , VariantDef , FieldDef , Ty , TyS } ;
14
13
use ty:: { DefId , Substs } ;
@@ -113,7 +112,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
113
112
}
114
113
115
114
fn ty_inhabitedness_forest ( self , ty : Ty < ' tcx > ) -> DefIdForest {
116
- ty. uninhabited_from ( & mut FxHashMap :: default ( ) , self )
115
+ ty. uninhabited_from ( self )
117
116
}
118
117
119
118
pub fn is_enum_variant_uninhabited_from ( self ,
@@ -140,20 +139,19 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
140
139
let adt_kind = self . adt_def ( adt_def_id) . adt_kind ( ) ;
141
140
142
141
// Compute inhabitedness forest:
143
- variant. uninhabited_from ( & mut FxHashMap :: default ( ) , self , substs, adt_kind)
142
+ variant. uninhabited_from ( self , substs, adt_kind)
144
143
}
145
144
}
146
145
147
146
impl < ' a , ' gcx , ' tcx > AdtDef {
148
147
/// Calculate the forest of DefIds from which this adt is visibly uninhabited.
149
148
fn uninhabited_from (
150
149
& self ,
151
- visited : & mut FxHashMap < DefId , FxHashSet < & ' tcx Substs < ' tcx > > > ,
152
150
tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
153
151
substs : & ' tcx Substs < ' tcx > ) -> DefIdForest
154
152
{
155
153
DefIdForest :: intersection ( tcx, self . variants . iter ( ) . map ( |v| {
156
- v. uninhabited_from ( visited , tcx, substs, self . adt_kind ( ) )
154
+ v. uninhabited_from ( tcx, substs, self . adt_kind ( ) )
157
155
} ) )
158
156
}
159
157
}
@@ -162,7 +160,6 @@ impl<'a, 'gcx, 'tcx> VariantDef {
162
160
/// Calculate the forest of DefIds from which this variant is visibly uninhabited.
163
161
fn uninhabited_from (
164
162
& self ,
165
- visited : & mut FxHashMap < DefId , FxHashSet < & ' tcx Substs < ' tcx > > > ,
166
163
tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
167
164
substs : & ' tcx Substs < ' tcx > ,
168
165
adt_kind : AdtKind ) -> DefIdForest
@@ -175,7 +172,7 @@ impl<'a, 'gcx, 'tcx> VariantDef {
175
172
AdtKind :: Struct => false ,
176
173
} ;
177
174
DefIdForest :: union ( tcx, self . fields . iter ( ) . map ( |f| {
178
- f. uninhabited_from ( visited , tcx, substs, is_enum)
175
+ f. uninhabited_from ( tcx, substs, is_enum)
179
176
} ) )
180
177
}
181
178
}
@@ -184,13 +181,12 @@ impl<'a, 'gcx, 'tcx> FieldDef {
184
181
/// Calculate the forest of DefIds from which this field is visibly uninhabited.
185
182
fn uninhabited_from (
186
183
& self ,
187
- visited : & mut FxHashMap < DefId , FxHashSet < & ' tcx Substs < ' tcx > > > ,
188
184
tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
189
185
substs : & ' tcx Substs < ' tcx > ,
190
186
is_enum : bool ,
191
187
) -> DefIdForest {
192
- let mut data_uninhabitedness = move || {
193
- self . ty ( tcx, substs) . uninhabited_from ( visited , tcx)
188
+ let data_uninhabitedness = move || {
189
+ self . ty ( tcx, substs) . uninhabited_from ( tcx)
194
190
} ;
195
191
// FIXME(canndrew): Currently enum fields are (incorrectly) stored with
196
192
// Visibility::Invisible so we need to override self.vis if we're
@@ -213,54 +209,24 @@ impl<'a, 'gcx, 'tcx> FieldDef {
213
209
214
210
impl < ' a , ' gcx , ' tcx > TyS < ' tcx > {
215
211
/// Calculate the forest of DefIds from which this type is visibly uninhabited.
216
- fn uninhabited_from (
217
- & self ,
218
- visited : & mut FxHashMap < DefId , FxHashSet < & ' tcx Substs < ' tcx > > > ,
219
- tcx : TyCtxt < ' a , ' gcx , ' tcx > ) -> DefIdForest
212
+ fn uninhabited_from ( & self , tcx : TyCtxt < ' a , ' gcx , ' tcx > ) -> DefIdForest
220
213
{
221
214
match self . sty {
222
- Adt ( def, substs) => {
223
- {
224
- let substs_set = visited. entry ( def. did ) . or_default ( ) ;
225
- if !substs_set. insert ( substs) {
226
- // We are already calculating the inhabitedness of this type.
227
- // The type must contain a reference to itself. Break the
228
- // infinite loop.
229
- return DefIdForest :: empty ( ) ;
230
- }
231
- if substs_set. len ( ) >= tcx. sess . recursion_limit . get ( ) / 4 {
232
- // We have gone very deep, reinstantiating this ADT inside
233
- // itself with different type arguments. We are probably
234
- // hitting an infinite loop. For example, it's possible to write:
235
- // a type Foo<T>
236
- // which contains a Foo<(T, T)>
237
- // which contains a Foo<((T, T), (T, T))>
238
- // which contains a Foo<(((T, T), (T, T)), ((T, T), (T, T)))>
239
- // etc.
240
- let error = format ! ( "reached recursion limit while checking \
241
- inhabitedness of `{}`", self ) ;
242
- tcx. sess . fatal ( & error) ;
243
- }
244
- }
245
- let ret = def. uninhabited_from ( visited, tcx, substs) ;
246
- let substs_set = visited. get_mut ( & def. did ) . unwrap ( ) ;
247
- substs_set. remove ( substs) ;
248
- ret
249
- }
215
+ Adt ( def, substs) => def. uninhabited_from ( tcx, substs) ,
250
216
251
217
Never => DefIdForest :: full ( tcx) ,
252
218
253
219
Tuple ( ref tys) => {
254
220
DefIdForest :: union ( tcx, tys. iter ( ) . map ( |ty| {
255
- ty. uninhabited_from ( visited , tcx)
221
+ ty. uninhabited_from ( tcx)
256
222
} ) )
257
223
}
258
224
259
225
Array ( ty, len) => {
260
226
match len. assert_usize ( tcx) {
261
227
// If the array is definitely non-empty, it's uninhabited if
262
228
// the type of its elements is uninhabited.
263
- Some ( n) if n != 0 => ty. uninhabited_from ( visited , tcx) ,
229
+ Some ( n) if n != 0 => ty. uninhabited_from ( tcx) ,
264
230
_ => DefIdForest :: empty ( )
265
231
}
266
232
}
0 commit comments