@@ -1483,36 +1483,25 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
1483
1483
tcx. collect_referenced_late_bound_regions ( & ty:: Binder :: bind ( ty) ) ;
1484
1484
debug ! ( "late_bound_in_trait_ref = {:?}" , late_bound_in_trait_ref) ;
1485
1485
debug ! ( "late_bound_in_ty = {:?}" , late_bound_in_ty) ;
1486
- for br in late_bound_in_ty. difference ( & late_bound_in_trait_ref) {
1487
- let br_name = match * br {
1488
- ty:: BrNamed ( _, name) => format ! ( "lifetime `{}`" , name) ,
1489
- _ => "an anonymous lifetime" . to_string ( ) ,
1490
- } ;
1491
- // FIXME: point at the type params that don't have appropriate lifetimes:
1492
- // struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F);
1493
- // ---- ---- ^^^^^^^
1494
- let mut err = struct_span_err ! (
1495
- tcx. sess,
1496
- binding. span,
1497
- E0582 ,
1498
- "binding for associated type `{}` references {}, \
1499
- which does not appear in the trait input types",
1500
- binding. item_name,
1501
- br_name
1502
- ) ;
1503
-
1504
- if let ty:: BrAnon ( _) = * br {
1505
- // The only way for an anonymous lifetime to wind up
1506
- // in the return type but **also** be unconstrained is
1507
- // if it only appears in "associated types" in the
1508
- // input. See #62200 for an example. In this case,
1509
- // though we can easily give a hint that ought to be
1510
- // relevant.
1511
- err. note ( "lifetimes appearing in an associated type are not considered constrained" ) ;
1512
- }
1513
1486
1514
- err. emit ( ) ;
1515
- }
1487
+ // FIXME: point at the type params that don't have appropriate lifetimes:
1488
+ // struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F);
1489
+ // ---- ---- ^^^^^^^
1490
+ self . validate_late_bound_regions (
1491
+ late_bound_in_trait_ref,
1492
+ late_bound_in_ty,
1493
+ |br_name| {
1494
+ struct_span_err ! (
1495
+ tcx. sess,
1496
+ binding. span,
1497
+ E0582 ,
1498
+ "binding for associated type `{}` references {}, \
1499
+ which does not appear in the trait input types",
1500
+ binding. item_name,
1501
+ br_name
1502
+ )
1503
+ } ,
1504
+ ) ;
1516
1505
}
1517
1506
}
1518
1507
@@ -3085,33 +3074,48 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
3085
3074
tcx. collect_constrained_late_bound_regions ( & inputs. map_bound ( |i| i. to_owned ( ) ) ) ;
3086
3075
let output = bare_fn_ty. output ( ) ;
3087
3076
let late_bound_in_ret = tcx. collect_referenced_late_bound_regions ( & output) ;
3088
- for br in late_bound_in_ret. difference ( & late_bound_in_args) {
3089
- let lifetime_name = match * br {
3090
- ty:: BrNamed ( _, name) => format ! ( "lifetime `{}`," , name) ,
3091
- ty:: BrAnon ( _) | ty:: BrEnv => "an anonymous lifetime" . to_string ( ) ,
3092
- } ;
3093
- let mut err = struct_span_err ! (
3077
+
3078
+ self . validate_late_bound_regions ( late_bound_in_args, late_bound_in_ret, |br_name| {
3079
+ struct_span_err ! (
3094
3080
tcx. sess,
3095
3081
decl. output. span( ) ,
3096
3082
E0581 ,
3097
- "return type references {} which is not constrained by the fn input types" ,
3098
- lifetime_name
3099
- ) ;
3083
+ "return type references {}, which is not constrained by the fn input types" ,
3084
+ br_name
3085
+ )
3086
+ } ) ;
3087
+
3088
+ bare_fn_ty
3089
+ }
3090
+
3091
+ fn validate_late_bound_regions (
3092
+ & self ,
3093
+ constrained_regions : FxHashSet < ty:: BoundRegion > ,
3094
+ referenced_regions : FxHashSet < ty:: BoundRegion > ,
3095
+ generate_err : impl Fn ( & str ) -> rustc_errors:: DiagnosticBuilder < ' tcx > ,
3096
+ ) {
3097
+ for br in referenced_regions. difference ( & constrained_regions) {
3098
+ let br_name = match * br {
3099
+ ty:: BrNamed ( _, name) => format ! ( "lifetime `{}`" , name) ,
3100
+ ty:: BrAnon ( _) | ty:: BrEnv => "an anonymous lifetime" . to_string ( ) ,
3101
+ } ;
3102
+
3103
+ let mut err = generate_err ( & br_name) ;
3104
+
3100
3105
if let ty:: BrAnon ( _) = * br {
3101
3106
// The only way for an anonymous lifetime to wind up
3102
3107
// in the return type but **also** be unconstrained is
3103
3108
// if it only appears in "associated types" in the
3104
- // input. See #47511 for an example . In this case,
3109
+ // input. See #47511 and #62200 for examples . In this case,
3105
3110
// though we can easily give a hint that ought to be
3106
3111
// relevant.
3107
3112
err. note (
3108
3113
"lifetimes appearing in an associated type are not considered constrained" ,
3109
3114
) ;
3110
3115
}
3116
+
3111
3117
err. emit ( ) ;
3112
3118
}
3113
-
3114
- bare_fn_ty
3115
3119
}
3116
3120
3117
3121
/// Given the bounds on an object, determines what single region bound (if any) we can
0 commit comments