@@ -473,12 +473,14 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
473
473
474
474
let abstract_type_generics = self . tcx . generics_of ( def_id) ;
475
475
476
+ let span = self . tcx . def_span ( def_id) ;
477
+
476
478
// Go through all the regions used as arguments to the
477
479
// abstract type. These are the parameters to the abstract
478
480
// type; so in our example above, `substs` would contain
479
481
// `['a]` for the first impl trait and `'b` for the
480
482
// second.
481
- let mut bound_region = None ;
483
+ let mut least_region = None ;
482
484
for region_def in & abstract_type_generics. regions {
483
485
// Find the index of this region in the list of substitutions.
484
486
let index = region_def. index as usize ;
@@ -487,39 +489,48 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
487
489
let subst_arg = anon_defn. substs [ index] . as_region ( ) . unwrap ( ) ;
488
490
489
491
// Compute the least upper bound of it with the other regions.
490
- debug ! ( "constrain_anon_types: bound_region ={:?}" , bound_region ) ;
492
+ debug ! ( "constrain_anon_types: least_region ={:?}" , least_region ) ;
491
493
debug ! ( "constrain_anon_types: subst_arg={:?}" , subst_arg) ;
492
- if let Some ( r) = bound_region {
493
- let lub = self . free_region_map . lub_free_regions ( self . tcx ,
494
- r,
495
- subst_arg) ;
496
- bound_region = Some ( lub) ;
497
-
498
- if let ty:: ReStatic = * lub {
499
- // If LUB results in `'static`, we might as well
500
- // stop iterating here.
501
- //
502
- // FIXME: We might consider issuing an error
503
- // here. `'static` is too strict to be useful,
504
- // most likely, and the resulting errors may
505
- // well be rather confusing.
506
- break ;
494
+ match least_region {
495
+ None => least_region = Some ( subst_arg) ,
496
+ Some ( lr) => {
497
+ if self . free_region_map . sub_free_regions ( lr, subst_arg) {
498
+ // keep the current least region
499
+ } else if self . free_region_map . sub_free_regions ( subst_arg, lr) {
500
+ // switch to `subst_arg`
501
+ least_region = Some ( subst_arg) ;
502
+ } else {
503
+ // There are two regions (`lr` and
504
+ // `subst_arg`) which are not relatable. We can't
505
+ // find a best choice.
506
+
507
+ // FIXME We don't need to issue an error
508
+ // if there is a lifetime bound in the
509
+ // `impl Trait` already (e.g., `impl Foo +
510
+ // 'a`). `required_region_bounds` could be
511
+ // applied during the instantiation phase
512
+ // to find this, I suspect.
513
+ self . tcx
514
+ . sess
515
+ . struct_span_err ( span, "ambiguous lifetime bound in `impl Trait`" )
516
+ . span_label ( span,
517
+ format ! ( "neither `{}` nor `{}` outlives the other" ,
518
+ lr, subst_arg) )
519
+ . emit ( ) ;
520
+
521
+ least_region = Some ( self . tcx . mk_region ( ty:: ReEmpty ) ) ;
522
+ break ;
523
+ }
507
524
}
508
- } else {
509
- bound_region = Some ( subst_arg) ;
510
525
}
511
526
}
512
- debug ! ( "constrain_anon_types: bound_region={:?}" , bound_region) ;
513
527
514
- // If we don't find any arguments in the interface, then
515
- // the only valid region that can appear in the resulting
516
- // type is `'static`.
517
- let bound_region = bound_region. unwrap_or ( self . tcx . types . re_static ) ;
528
+ let least_region = least_region. unwrap_or ( self . tcx . types . re_static ) ;
529
+ debug ! ( "constrain_anon_types: least_region={:?}" , least_region) ;
518
530
519
- // Require that all regions outlive `bound_region`
520
- let span = self . tcx . def_span ( def_id) ;
531
+ // Require that all regions outlive `least_region`
521
532
self . tcx . for_each_free_region ( & concrete_ty, |region| {
522
- self . sub_regions ( infer:: CallReturn ( span) , bound_region , region) ;
533
+ self . sub_regions ( infer:: CallReturn ( span) , least_region , region) ;
523
534
} ) ;
524
535
}
525
536
}
0 commit comments