@@ -973,7 +973,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
973973 propagated_outlives_requirements : & mut Vec < ClosureOutlivesRequirement < ' tcx > > ,
974974 ) -> bool {
975975 let tcx = infcx. tcx ;
976- let TypeTest { generic_kind, lower_bound, span : blame_span, ref verify_bound } = * type_test;
976+ let TypeTest { generic_kind, lower_bound, span : blame_span, verify_bound : _ } = * type_test;
977977
978978 let generic_ty = generic_kind. to_ty ( tcx) ;
979979 let Some ( subject) = self . try_promote_type_test_subject ( infcx, generic_ty) else {
@@ -1008,50 +1008,31 @@ impl<'tcx> RegionInferenceContext<'tcx> {
10081008 return true ;
10091009 }
10101010
1011- // For each region outlived by lower_bound find a non-local,
1012- // universal region (it may be the same region) and add it to
1013- // `ClosureOutlivesRequirement`.
1011+ // Add all non-local universal regions which are outlived by
1012+ // `lower_bound` to the `ClosureOutlivesRequirement`.
1013+ //
1014+ // This is slightly too conservative. To show T: '1, given `'2: '1`
1015+ // and `'3: '1` we only need to prove that T: '2 *or* T: '3, but to
1016+ // avoid potential non-determinism we approximate this by requiring
1017+ // T: '1 and T: '2.
1018+ let mut found_candidate = false ;
10141019 for ur in self . scc_values . universal_regions_outlived_by ( r_scc) {
1015- debug ! ( "universal_region_outlived_by ur={:?}" , ur) ;
1016- // Check whether we can already prove that the "subject" outlives `ur`.
1017- // If so, we don't have to propagate this requirement to our caller.
1018- //
1019- // To continue the example from the function, if we are trying to promote
1020- // a requirement that `T: 'X`, and we know that `'X = '1 + '2` (i.e., the union
1021- // `'1` and `'2`), then in this loop `ur` will be `'1` (and `'2`). So here
1022- // we check whether `T: '1` is something we *can* prove. If so, no need
1023- // to propagate that requirement.
1024- //
1025- // This is needed because -- particularly in the case
1026- // where `ur` is a local bound -- we are sometimes in a
1027- // position to prove things that our caller cannot. See
1028- // #53570 for an example.
1029- if self . eval_verify_bound ( infcx, generic_ty, ur, & verify_bound) {
1030- continue ;
1031- }
1032-
1033- let non_local_ub = self . universal_region_relations . non_local_upper_bounds ( ur) ;
1034- debug ! ( ?non_local_ub) ;
1035-
1036- // This is slightly too conservative. To show T: '1, given `'2: '1`
1037- // and `'3: '1` we only need to prove that T: '2 *or* T: '3, but to
1038- // avoid potential non-determinism we approximate this by requiring
1039- // T: '1 and T: '2.
1040- for upper_bound in non_local_ub {
1041- debug_assert ! ( self . universal_regions( ) . is_universal_region( upper_bound) ) ;
1042- debug_assert ! ( !self . universal_regions( ) . is_local_free_region( upper_bound) ) ;
1043-
1020+ if !self . universal_regions ( ) . is_local_free_region ( ur) {
1021+ debug_assert ! ( !self . universal_regions( ) . is_local_free_region( ur) ) ;
10441022 let requirement = ClosureOutlivesRequirement {
10451023 subject,
1046- outlived_free_region : upper_bound ,
1024+ outlived_free_region : ur ,
10471025 blame_span,
10481026 category : ConstraintCategory :: Boring ,
10491027 } ;
1050- debug ! ( ?requirement, "adding closure requirement" ) ;
1028+ debug ! ( ?requirement, ?ur , "adding closure requirement" ) ;
10511029 propagated_outlives_requirements. push ( requirement) ;
1030+ found_candidate = true ;
1031+ } else {
1032+ debug ! ( ?ur, "skippiung local universal" ) ;
10521033 }
10531034 }
1054- true
1035+ found_candidate
10551036 }
10561037
10571038 /// When we promote a type test `T: 'r`, we have to replace all region
0 commit comments