@@ -1290,17 +1290,44 @@ impl<'tcx> RegionInferenceContext<'tcx> {
12901290 // Grow `shorter_fr` until we find some non-local regions. (We
12911291 // always will.) We'll call them `shorter_fr+` -- they're ever
12921292 // so slightly larger than `shorter_fr`.
1293- let shorter_fr_plus =
1293+ let shorter_fr_plusses =
12941294 self . universal_region_relations . non_local_upper_bounds ( shorter_fr) ;
1295- debug ! ( "try_propagate_universal_region_error: shorter_fr_plus={:?}" , shorter_fr_plus) ;
1296- for fr in shorter_fr_plus {
1297- // Push the constraint `fr-: shorter_fr+`
1298- propagated_outlives_requirements. push ( ClosureOutlivesRequirement {
1299- subject : ClosureOutlivesSubject :: Region ( fr_minus) ,
1300- outlived_free_region : fr,
1301- blame_span : blame_constraint. cause . span ,
1302- category : blame_constraint. category ,
1303- } ) ;
1295+ debug ! (
1296+ "try_propagate_universal_region_error: shorter_fr_plus={:?}" ,
1297+ shorter_fr_plusses
1298+ ) ;
1299+
1300+ let fr_static = self . universal_regions ( ) . fr_static ;
1301+ let single_region = shorter_fr_plusses. len ( ) == 1 ;
1302+
1303+ for shorter_fr_plus in shorter_fr_plusses {
1304+ // Don't propagate every `fr-: shorter_fr+`.
1305+ // A smaller "optimal subset" exists, since full propagation is overly conservative
1306+ // and can reject valid code. Consider this small example (`'b: 'a` == `a -> b`)
1307+ // were we try to propagate region error `'d: 'a`:
1308+ // a --> b --> d
1309+ // \
1310+ // \-> c
1311+ // Here `shorter_fr_plusses` == `['b, 'c]`.
1312+ // Propagating `'d: 'b` is correct and should happen; `'d: 'c` is redundant and can reject valid code.
1313+ // We can come closer to this "optimal subset" by checking if the `shorter_fr+` should be outlived by `fr-`.
1314+ // NOTE: [] is *not* a valid subset, so we check for that as well.
1315+ if single_region
1316+ || shorter_fr_plus == fr_static // `fr-: 'static` should be propagated
1317+ || self . eval_outlives ( fr_minus, shorter_fr_plus)
1318+ {
1319+ debug ! (
1320+ "try_propagate_universal_region_error: propagating {:?}: {:?}" ,
1321+ fr_minus, shorter_fr_plus,
1322+ ) ;
1323+ // If that's the case, push the constraint `fr-: shorter_fr+`
1324+ propagated_outlives_requirements. push ( ClosureOutlivesRequirement {
1325+ subject : ClosureOutlivesSubject :: Region ( fr_minus) ,
1326+ outlived_free_region : shorter_fr_plus,
1327+ blame_span : blame_constraint. cause . span ,
1328+ category : blame_constraint. category ,
1329+ } ) ;
1330+ }
13041331 }
13051332 return RegionRelationCheckResult :: Propagated ;
13061333 }
0 commit comments