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