@@ -1483,36 +1483,25 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
14831483 tcx. collect_referenced_late_bound_regions ( & ty:: Binder :: bind ( ty) ) ;
14841484 debug ! ( "late_bound_in_trait_ref = {:?}" , late_bound_in_trait_ref) ;
14851485 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- }
15131486
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+ ) ;
15161505 }
15171506 }
15181507
@@ -3085,33 +3074,48 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
30853074 tcx. collect_constrained_late_bound_regions ( & inputs. map_bound ( |i| i. to_owned ( ) ) ) ;
30863075 let output = bare_fn_ty. output ( ) ;
30873076 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 ! (
30943080 tcx. sess,
30953081 decl. output. span( ) ,
30963082 E0581 ,
30973083 "return type references {} which is not constrained by the fn input types" ,
3098- lifetime_name
3099- ) ;
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+
31003105 if let ty:: BrAnon ( _) = * br {
31013106 // The only way for an anonymous lifetime to wind up
31023107 // in the return type but **also** be unconstrained is
31033108 // 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,
31053110 // though we can easily give a hint that ought to be
31063111 // relevant.
31073112 err. note (
31083113 "lifetimes appearing in an associated type are not considered constrained" ,
31093114 ) ;
31103115 }
3116+
31113117 err. emit ( ) ;
31123118 }
3113-
3114- bare_fn_ty
31153119 }
31163120
31173121 /// Given the bounds on an object, determines what single region bound (if any) we can
0 commit comments