@@ -2,7 +2,6 @@ use crate::check::FnCtxt;
22use rustc_data_structures:: {
33 fx:: FxHashMap , graph:: vec_graph:: VecGraph , graph:: WithSuccessors , stable_set:: FxHashSet ,
44} ;
5- use rustc_infer:: infer:: type_variable:: Diverging ;
65use rustc_middle:: ty:: { self , Ty } ;
76
87impl < ' tcx > FnCtxt < ' _ , ' tcx > {
@@ -255,8 +254,27 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
255254
256255 // Extract the unsolved type inference variable vids; note that some
257256 // 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) ;
260278
261279 // Find all type variables that are reachable from a diverging
262280 // type variable. These will typically default to `!`, unless
@@ -265,27 +283,24 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
265283 let mut roots_reachable_from_diverging = FxHashSet :: default ( ) ;
266284 let mut diverging_vids = vec ! [ ] ;
267285 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) ;
269288 debug ! (
270- "calculate_diverging_fallback: unsolved_vid={:?} diverges={:?}" ,
289+ "calculate_diverging_fallback: unsolved_vid={:?} root_vid={:?} diverges={:?}" ,
271290 unsolved_vid,
272- self . infcx. ty_vid_diverges( unsolved_vid)
291+ root_vid,
292+ diverging_roots. contains( & root_vid) ,
273293 ) ;
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) ;
289304 }
290305 }
291306 debug ! (
0 commit comments