@@ -1405,18 +1405,39 @@ impl<'tcx> RegionInferenceContext<'tcx> {
14051405 }
14061406
14071407 /// Walks the graph of constraints (where `'a: 'b` is considered
1408- /// an edge `'a -> 'b`) to find all paths from `from_region` to
1409- /// `to_region`. The paths are accumulated into the vector
1410- /// `results`. The paths are stored as a series of
1411- /// `ConstraintIndex` values -- in other words, a list of *edges*.
1408+ /// an edge `'a -> 'b`) to find a path from `from_region` to
1409+ /// `to_region`.
14121410 ///
14131411 /// Returns: a series of constraints as well as the region `R`
14141412 /// that passed the target test.
14151413 #[ instrument( skip( self , target_test) , ret) ]
1416- pub ( crate ) fn find_constraint_paths_between_regions (
1414+ pub ( crate ) fn find_constraint_path_between_regions (
14171415 & self ,
14181416 from_region : RegionVid ,
14191417 target_test : impl Fn ( RegionVid ) -> bool ,
1418+ ) -> Option < ( Vec < OutlivesConstraint < ' tcx > > , RegionVid ) > {
1419+ self . find_constraint_path_between_regions_inner ( true , from_region, & target_test) . or_else (
1420+ || self . find_constraint_path_between_regions_inner ( false , from_region, & target_test) ,
1421+ )
1422+ }
1423+
1424+ /// The constraints we get from equating the hidden type of each use of an opaque
1425+ /// with its final concrete type may end up getting preferred over other, potentially
1426+ /// longer constraint paths.
1427+ ///
1428+ /// Given that we compute the final concrete type by relying on this existing constraint
1429+ /// path, this can easily end up hiding the actual reason for why we require these regions
1430+ /// to be equal.
1431+ ///
1432+ /// To handle this, we first look at the path while ignoring these constraints and then
1433+ /// retry while considering them. This is not perfect, as the `from_region` may have already
1434+ /// been partially related to its argument region, so while we rely on a member constraint
1435+ /// to get a complete path, the most relevant step of that path already existed before then.
1436+ fn find_constraint_path_between_regions_inner (
1437+ & self ,
1438+ ignore_opaque_type_constraints : bool ,
1439+ from_region : RegionVid ,
1440+ target_test : impl Fn ( RegionVid ) -> bool ,
14201441 ) -> Option < ( Vec < OutlivesConstraint < ' tcx > > , RegionVid ) > {
14211442 let mut context = IndexVec :: from_elem ( Trace :: NotVisited , & self . definitions ) ;
14221443 context[ from_region] = Trace :: StartRegion ;
@@ -1431,7 +1452,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
14311452
14321453 while let Some ( r) = deque. pop_front ( ) {
14331454 debug ! (
1434- "find_constraint_paths_between_regions : from_region={:?} r={:?} value={}" ,
1455+ "find_constraint_path_between_regions : from_region={:?} r={:?} value={}" ,
14351456 from_region,
14361457 r,
14371458 self . region_value_str( r) ,
@@ -1503,9 +1524,16 @@ impl<'tcx> RegionInferenceContext<'tcx> {
15031524 let edges = self . constraint_graph . outgoing_edges_from_graph ( r, & self . constraints ) ;
15041525 // This loop can be hot.
15051526 for constraint in edges {
1506- if matches ! ( constraint. category, ConstraintCategory :: IllegalUniverse ) {
1507- debug ! ( "Ignoring illegal universe constraint: {constraint:?}" ) ;
1508- continue ;
1527+ match constraint. category {
1528+ ConstraintCategory :: IllegalUniverse => {
1529+ debug ! ( "Ignoring illegal universe constraint: {constraint:?}" ) ;
1530+ continue ;
1531+ }
1532+ ConstraintCategory :: OpaqueType if ignore_opaque_type_constraints => {
1533+ debug ! ( "Ignoring member constraint: {constraint:?}" ) ;
1534+ continue ;
1535+ }
1536+ _ => { }
15091537 }
15101538 debug_assert_eq ! ( constraint. sup, r) ;
15111539 handle_trace ( constraint. sub , Trace :: FromGraph ( constraint) ) ;
@@ -1521,7 +1549,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
15211549 pub ( crate ) fn find_sub_region_live_at ( & self , fr1 : RegionVid , location : Location ) -> RegionVid {
15221550 trace ! ( scc = ?self . constraint_sccs. scc( fr1) ) ;
15231551 trace ! ( universe = ?self . max_nameable_universe( self . constraint_sccs. scc( fr1) ) ) ;
1524- self . find_constraint_paths_between_regions ( fr1, |r| {
1552+ self . find_constraint_path_between_regions ( fr1, |r| {
15251553 // First look for some `r` such that `fr1: r` and `r` is live at `location`
15261554 trace ! ( ?r, liveness_constraints=?self . liveness_constraints. pretty_print_live_points( r) ) ;
15271555 self . liveness_constraints . is_live_at ( r, location)
@@ -1531,9 +1559,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
15311559 // `fr1: r` and `r` is a placeholder from some universe
15321560 // `fr1` cannot name. This would force `fr1` to be
15331561 // `'static`.
1534- self . find_constraint_paths_between_regions ( fr1, |r| {
1535- self . cannot_name_placeholder ( fr1, r)
1536- } )
1562+ self . find_constraint_path_between_regions ( fr1, |r| self . cannot_name_placeholder ( fr1, r) )
15371563 } )
15381564 . or_else ( || {
15391565 // If we fail to find THAT, it may be that `fr1` is a
@@ -1546,9 +1572,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
15461572 // must be able to name the universe of R2, because R2 will
15471573 // be at least `'empty(Universe(R2))`, and `R1` must be at
15481574 // larger than that.
1549- self . find_constraint_paths_between_regions ( fr1, |r| {
1550- self . cannot_name_placeholder ( r, fr1)
1551- } )
1575+ self . find_constraint_path_between_regions ( fr1, |r| self . cannot_name_placeholder ( r, fr1) )
15521576 } )
15531577 . map ( |( _path, r) | r)
15541578 . unwrap ( )
@@ -1604,9 +1628,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
16041628 ) -> ( BlameConstraint < ' tcx > , Vec < OutlivesConstraint < ' tcx > > ) {
16051629 // Find all paths
16061630 let ( path, target_region) = self
1607- . find_constraint_paths_between_regions ( from_region, target_test)
1631+ . find_constraint_path_between_regions ( from_region, target_test)
16081632 . or_else ( || {
1609- self . find_constraint_paths_between_regions ( from_region, |r| {
1633+ self . find_constraint_path_between_regions ( from_region, |r| {
16101634 self . cannot_name_placeholder ( from_region, r)
16111635 } )
16121636 } )
0 commit comments