@@ -12,11 +12,12 @@ use rustc_data_structures::fx::FxHashSet;
1212use rustc_data_structures:: graph:: scc:: { self , Sccs } ;
1313use rustc_index:: IndexVec ;
1414use rustc_infer:: infer:: NllRegionVariableOrigin ;
15- use rustc_infer:: infer:: outlives:: test_type_match;
15+ use rustc_infer:: infer:: outlives:: test_type_match:: MatchAgainstHigherRankedOutlives ;
1616use rustc_infer:: infer:: region_constraints:: { GenericKind , VarInfos , VerifyBound } ;
17- use rustc_middle:: ty:: { Region , RegionVid , TyCtxt , UniverseIndex } ;
17+ use rustc_infer:: infer:: relate:: TypeRelation ;
18+ use rustc_middle:: ty:: { self , Region , RegionVid , TyCtxt , UniverseIndex } ;
1819use rustc_span:: Span ;
19- use tracing:: { debug, info , instrument, trace} ;
20+ use tracing:: { debug, instrument, trace} ;
2021
2122use crate :: constraints:: graph:: { ConstraintGraph , Normal } ;
2223use crate :: constraints:: { ConstraintSccIndex , OutlivesConstraintSet } ;
@@ -617,31 +618,39 @@ fn rewrite_verify_bound<'t>(
617618 // equality, and it does -- except that we do not track placeholders,
618619 // and so in the event that you have two empty regions, one of which is
619620 // in an unnameable universe, they would compare equal since they
620- // are both empty. This bit checks if we
621- VerifyBound :: IfEq ( binder) => {
622- match test_type_match:: extract_verify_if_eq ( tcx, & binder, generic_kind. to_ty ( tcx) ) {
623- Some ( r) => {
624- let r_vid = universal_regions. to_region_vid ( r) ;
625- let r_scc = scc_annotations[ sccs. scc ( r_vid) ] ;
626- let l_scc = scc_annotations[ lower_scc] ;
627- let in_same_universe = r_scc. universe_compatible_with ( l_scc)
628- && l_scc. universe_compatible_with ( r_scc) ;
629- let reaches_same_placeholders =
630- r_scc. reachable_placeholders == l_scc. reachable_placeholders ;
631-
632- if in_same_universe && reaches_same_placeholders {
633- Either :: Left ( bound)
634- } else {
635- Either :: Right ( RewrittenVerifyBound :: Unsatisfied )
636- }
637- }
638- None => {
639- info ! (
640- "Failed to extract type from {:#?}; assuming we are fine!" ,
641- generic_kind. to_ty( tcx)
642- ) ;
643- Either :: Left ( bound)
621+ // are both empty. This bit ensures that whatever comes out of the
622+ // bound also matches the placeholder reachability of the lower bound.
623+ VerifyBound :: IfEq ( verify_if_eq_b) => {
624+ let mut m = MatchAgainstHigherRankedOutlives :: new ( tcx) ;
625+ let verify_if_eq = verify_if_eq_b. skip_binder ( ) ;
626+ // We ignore the error here because we are not concerned with if the
627+ // match actually held -- we can't tell that yet -- we just want to
628+ // see if the resulting region can't match for universe-related
629+ // reasons.
630+ let _what_error = m. relate ( verify_if_eq. ty , generic_kind. to_ty ( tcx) ) ;
631+
632+ let r = if let ty:: RegionKind :: ReBound ( depth, br) = verify_if_eq. bound . kind ( ) {
633+ assert ! ( depth == ty:: INNERMOST ) ;
634+ match m. map . get ( & br) {
635+ Some ( & r) => r,
636+ None => tcx. lifetimes . re_static ,
644637 }
638+ } else {
639+ verify_if_eq. bound
640+ } ;
641+
642+ let r_vid = universal_regions. to_region_vid ( r) ;
643+ let r_scc = scc_annotations[ sccs. scc ( r_vid) ] ;
644+ let l_scc = scc_annotations[ lower_scc] ;
645+ let in_same_universe =
646+ r_scc. universe_compatible_with ( l_scc) && l_scc. universe_compatible_with ( r_scc) ;
647+ let reaches_same_placeholders =
648+ r_scc. reachable_placeholders == l_scc. reachable_placeholders ;
649+
650+ if in_same_universe && reaches_same_placeholders {
651+ Either :: Left ( bound)
652+ } else {
653+ Either :: Right ( RewrittenVerifyBound :: Unsatisfied )
645654 }
646655 }
647656 // Rewrite an outlives bound to an outlives-static bound upon referencing
0 commit comments