@@ -2,7 +2,6 @@ use crate::check::FnCtxt;
2
2
use rustc_data_structures:: {
3
3
fx:: FxHashMap , graph:: vec_graph:: VecGraph , graph:: WithSuccessors , stable_set:: FxHashSet ,
4
4
} ;
5
- use rustc_infer:: infer:: type_variable:: Diverging ;
6
5
use rustc_middle:: ty:: { self , Ty } ;
7
6
8
7
impl < ' tcx > FnCtxt < ' _ , ' tcx > {
@@ -255,8 +254,27 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
255
254
256
255
// Extract the unsolved type inference variable vids; note that some
257
256
// unsolved variables are integer/float variables and are excluded.
258
- let unsolved_vids: Vec < _ > =
259
- unsolved_variables. iter ( ) . filter_map ( |ty| ty. ty_vid ( ) ) . collect ( ) ;
257
+ let unsolved_vids = unsolved_variables. iter ( ) . filter_map ( |ty| ty. ty_vid ( ) ) ;
258
+
259
+ // Compute the diverging root vids D -- that is, the root vid of
260
+ // those type variables that (a) are the target of a coercion from
261
+ // a `!` type and (b) have not yet been solved.
262
+ //
263
+ // These variables are the ones that are targets for fallback to
264
+ // either `!` or `()`.
265
+ let diverging_roots: FxHashSet < ty:: TyVid > = self
266
+ . diverging_type_vars
267
+ . borrow ( )
268
+ . iter ( )
269
+ . map ( |& ty| self . infcx . shallow_resolve ( ty) )
270
+ . filter_map ( |ty| ty. ty_vid ( ) )
271
+ . map ( |vid| self . infcx . root_var ( vid) )
272
+ . collect ( ) ;
273
+ debug ! (
274
+ "calculate_diverging_fallback: diverging_type_vars={:?}" ,
275
+ self . diverging_type_vars. borrow( )
276
+ ) ;
277
+ debug ! ( "calculate_diverging_fallback: diverging_roots={:?}" , diverging_roots) ;
260
278
261
279
// Find all type variables that are reachable from a diverging
262
280
// type variable. These will typically default to `!`, unless
@@ -265,27 +283,24 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
265
283
let mut roots_reachable_from_diverging = FxHashSet :: default ( ) ;
266
284
let mut diverging_vids = vec ! [ ] ;
267
285
let mut non_diverging_vids = vec ! [ ] ;
268
- for & unsolved_vid in & unsolved_vids {
286
+ for unsolved_vid in unsolved_vids {
287
+ let root_vid = self . infcx . root_var ( unsolved_vid) ;
269
288
debug ! (
270
- "calculate_diverging_fallback: unsolved_vid={:?} diverges={:?}" ,
289
+ "calculate_diverging_fallback: unsolved_vid={:?} root_vid={:?} diverges={:?}" ,
271
290
unsolved_vid,
272
- self . infcx. ty_vid_diverges( unsolved_vid)
291
+ root_vid,
292
+ diverging_roots. contains( & root_vid) ,
273
293
) ;
274
- match self . infcx . ty_vid_diverges ( unsolved_vid) {
275
- Diverging :: Diverges => {
276
- diverging_vids. push ( unsolved_vid) ;
277
- let root_vid = self . infcx . root_var ( unsolved_vid) ;
278
- debug ! (
279
- "calculate_diverging_fallback: root_vid={:?} reaches {:?}" ,
280
- root_vid,
281
- coercion_graph. depth_first_search( root_vid) . collect:: <Vec <_>>( )
282
- ) ;
283
- roots_reachable_from_diverging
284
- . extend ( coercion_graph. depth_first_search ( root_vid) ) ;
285
- }
286
- Diverging :: NotDiverging => {
287
- non_diverging_vids. push ( unsolved_vid) ;
288
- }
294
+ if diverging_roots. contains ( & root_vid) {
295
+ diverging_vids. push ( unsolved_vid) ;
296
+ debug ! (
297
+ "calculate_diverging_fallback: root_vid={:?} reaches {:?}" ,
298
+ root_vid,
299
+ coercion_graph. depth_first_search( root_vid) . collect:: <Vec <_>>( )
300
+ ) ;
301
+ roots_reachable_from_diverging. extend ( coercion_graph. depth_first_search ( root_vid) ) ;
302
+ } else {
303
+ non_diverging_vids. push ( unsolved_vid) ;
289
304
}
290
305
}
291
306
debug ! (
0 commit comments