@@ -349,9 +349,22 @@ impl<'tcx> RegionInferenceContext<'tcx> {
349
349
350
350
self . propagate_constraints ( mir) ;
351
351
352
+ // If this is a closure, we can propagate unsatisfied
353
+ // `outlives_requirements` to our creator, so create a vector
354
+ // to store those. Otherwise, we'll pass in `None` to the
355
+ // functions below, which will trigger them to report errors
356
+ // eagerly.
357
+ let mut outlives_requirements = if infcx. tcx . is_closure ( mir_def_id) {
358
+ Some ( vec ! [ ] )
359
+ } else {
360
+ None
361
+ } ;
362
+
352
363
self . check_type_tests ( infcx, mir) ;
353
364
354
- let outlives_requirements = self . check_universal_regions ( infcx, mir_def_id) ;
365
+ self . check_universal_regions ( infcx, outlives_requirements. as_mut ( ) ) ;
366
+
367
+ let outlives_requirements = outlives_requirements. unwrap_or ( vec ! [ ] ) ;
355
368
356
369
if outlives_requirements. is_empty ( ) {
357
370
None
@@ -429,18 +442,20 @@ impl<'tcx> RegionInferenceContext<'tcx> {
429
442
for type_test in & self . type_tests {
430
443
debug ! ( "check_type_test: {:?}" , type_test) ;
431
444
432
- if ! self . eval_region_test (
445
+ if self . eval_region_test (
433
446
mir,
434
447
type_test. point ,
435
448
type_test. lower_bound ,
436
449
& type_test. test ,
437
450
) {
438
- // Oh the humanity. Obviously we will do better than this error eventually.
439
- infcx. tcx . sess . span_err (
440
- type_test. span ,
441
- & format ! ( "failed type test: {:?}" , type_test) ,
442
- ) ;
451
+ continue ;
443
452
}
453
+
454
+ // Oh the humanity. Obviously we will do better than this error eventually.
455
+ infcx. tcx . sess . span_err (
456
+ type_test. span ,
457
+ & format ! ( "failed type test: {:?}" , type_test) ,
458
+ ) ;
444
459
}
445
460
}
446
461
@@ -538,11 +553,15 @@ impl<'tcx> RegionInferenceContext<'tcx> {
538
553
/// therefore add `end('a)` into the region for `'b` -- but we
539
554
/// have no evidence that `'b` outlives `'a`, so we want to report
540
555
/// an error.
556
+ ///
557
+ /// If `propagated_outlives_requirements` is `Some`, then we will
558
+ /// push unsatisfied obligations into there. Otherwise, we'll
559
+ /// report them as errors.
541
560
fn check_universal_regions (
542
561
& self ,
543
562
infcx : & InferCtxt < ' _ , ' _ , ' tcx > ,
544
- mir_def_id : DefId ,
545
- ) -> Vec < ClosureOutlivesRequirement > {
563
+ mut propagated_outlives_requirements : Option < & mut Vec < ClosureOutlivesRequirement > > ,
564
+ ) {
546
565
// The universal regions are always found in a prefix of the
547
566
// full list.
548
567
let universal_definitions = self . definitions
@@ -555,25 +574,22 @@ impl<'tcx> RegionInferenceContext<'tcx> {
555
574
let mut outlives_requirements = vec ! [ ] ;
556
575
for ( fr, _) in universal_definitions {
557
576
self . check_universal_region ( infcx, fr, & mut outlives_requirements) ;
558
- }
559
-
560
- // If this is a closure, we can propagate unsatisfied
561
- // `outlives_requirements` to our creator. Otherwise, we have
562
- // to report a hard error here.
563
- if infcx. tcx . is_closure ( mir_def_id) {
564
- return outlives_requirements;
565
- }
566
577
567
- for outlives_requirement in outlives_requirements {
568
- self . report_error (
569
- infcx,
570
- outlives_requirement. free_region ,
571
- outlives_requirement. outlived_free_region ,
572
- outlives_requirement. blame_span ,
573
- ) ;
578
+ // Propagate unsatisfied requirements if possible, else
579
+ // report them.
580
+ if let Some ( propagated_outlives_requirements) = & mut propagated_outlives_requirements {
581
+ propagated_outlives_requirements. extend ( outlives_requirements. drain ( ..) ) ;
582
+ } else {
583
+ for outlives_requirement in outlives_requirements. drain ( ..) {
584
+ self . report_error (
585
+ infcx,
586
+ outlives_requirement. free_region ,
587
+ outlives_requirement. outlived_free_region ,
588
+ outlives_requirement. blame_span ,
589
+ ) ;
590
+ }
591
+ }
574
592
}
575
-
576
- vec ! [ ]
577
593
}
578
594
579
595
/// Check the final value for the free region `fr` to see if it
@@ -588,7 +604,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
588
604
& self ,
589
605
infcx : & InferCtxt < ' _ , ' _ , ' tcx > ,
590
606
longer_fr : RegionVid ,
591
- outlives_requirements : & mut Vec < ClosureOutlivesRequirement > ,
607
+ propagated_outlives_requirements : & mut Vec < ClosureOutlivesRequirement > ,
592
608
) {
593
609
let inferred_values = self . inferred_values . as_ref ( ) . unwrap ( ) ;
594
610
@@ -626,7 +642,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
626
642
) ;
627
643
628
644
// Push the constraint `fr-: shorter_fr+`
629
- outlives_requirements . push ( ClosureOutlivesRequirement {
645
+ propagated_outlives_requirements . push ( ClosureOutlivesRequirement {
630
646
free_region : fr_minus,
631
647
outlived_free_region : shorter_fr_plus,
632
648
blame_span : blame_span,
0 commit comments