@@ -388,20 +388,24 @@ where
388
388
// rule might not apply (but another rule might). For now, we err
389
389
// on the side of adding too few edges into the graph.
390
390
391
- // Compute the bounds we can derive from the environment or trait
392
- // definition. We know that the projection outlives all the
393
- // regions in this list.
394
- let mut declared_bounds = self . verify_bound
395
- . projection_declared_bounds_from_env ( projection_ty) ;
396
-
397
- declared_bounds. extend (
398
- self . verify_bound
399
- . projection_declared_bounds_from_trait ( projection_ty) ,
391
+ // Compute the bounds we can derive from the environment. This
392
+ // is an "approximate" match -- in some cases, these bounds
393
+ // may not apply.
394
+ let approx_env_bounds = self . verify_bound
395
+ . projection_approx_declared_bounds_from_env ( projection_ty) ;
396
+ debug ! (
397
+ "projection_must_outlive: approx_env_bounds={:?}" ,
398
+ approx_env_bounds
400
399
) ;
401
400
401
+ // Compute the bounds we can derive from the trait definition.
402
+ // These are guaranteed to apply, no matter the inference
403
+ // results.
404
+ let trait_bounds = self . verify_bound
405
+ . projection_declared_bounds_from_trait ( projection_ty) ;
402
406
debug ! (
403
- "projection_must_outlive: declared_bounds ={:?}" ,
404
- declared_bounds
407
+ "projection_must_outlive: trait_bounds ={:?}" ,
408
+ trait_bounds
405
409
) ;
406
410
407
411
// If declared bounds list is empty, the only applicable rule is
@@ -419,7 +423,7 @@ where
419
423
// inference variables, we use a verify constraint instead of adding
420
424
// edges, which winds up enforcing the same condition.
421
425
let needs_infer = projection_ty. needs_infer ( ) ;
422
- if declared_bounds . is_empty ( ) && needs_infer {
426
+ if approx_env_bounds . is_empty ( ) && trait_bounds . is_empty ( ) && needs_infer {
423
427
debug ! ( "projection_must_outlive: no declared bounds" ) ;
424
428
425
429
for component_ty in projection_ty. substs . types ( ) {
@@ -434,34 +438,31 @@ where
434
438
return ;
435
439
}
436
440
437
- // If we find that there is a unique declared bound `'b`, and this bound
438
- // appears in the trait reference, then the best action is to require that `'b:'r`,
439
- // so do that. This is best no matter what rule we use:
441
+ // If we found a unique bound `'b` from the trait, and we
442
+ // found nothing else from the environment, then the best
443
+ // action is to require that `'b: 'r`, so do that.
444
+ //
445
+ // This is best no matter what rule we use:
440
446
//
441
- // - OutlivesProjectionEnv or OutlivesProjectionTraitDef : these would translate to
442
- // the requirement that `'b:'r`
443
- // - OutlivesProjectionComponent: this would require `'b:'r` in addition to
444
- // other conditions
445
- if !declared_bounds . is_empty ( )
446
- && declared_bounds [ 1 ..]
447
+ // - OutlivesProjectionEnv: these would translate to the requirement that `'b:'r`
448
+ // - OutlivesProjectionTraitDef: these would translate to the requirement that `'b:'r`
449
+ // - OutlivesProjectionComponent: this would require `'b:'r`
450
+ // in addition to other conditions
451
+ if !trait_bounds . is_empty ( )
452
+ && trait_bounds [ 1 ..]
447
453
. iter ( )
448
- . all ( |b| * b == declared_bounds[ 0 ] )
454
+ . chain ( & approx_env_bounds)
455
+ . all ( |b| * b == trait_bounds[ 0 ] )
449
456
{
450
- let unique_bound = declared_bounds [ 0 ] ;
457
+ let unique_bound = trait_bounds [ 0 ] ;
451
458
debug ! (
452
- "projection_must_outlive: unique declared bound = {:?}" ,
459
+ "projection_must_outlive: unique trait bound = {:?}" ,
453
460
unique_bound
454
461
) ;
455
- if projection_ty
456
- . substs
457
- . regions ( )
458
- . any ( |r| declared_bounds. contains ( & r) )
459
- {
460
- debug ! ( "projection_must_outlive: unique declared bound appears in trait ref" ) ;
461
- self . delegate
462
- . push_sub_region_constraint ( origin. clone ( ) , region, unique_bound) ;
463
- return ;
464
- }
462
+ debug ! ( "projection_must_outlive: unique declared bound appears in trait ref" ) ;
463
+ self . delegate
464
+ . push_sub_region_constraint ( origin. clone ( ) , region, unique_bound) ;
465
+ return ;
465
466
}
466
467
467
468
// Fallback to verifying after the fact that there exists a
0 commit comments