diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 37f48f82ea6..e6d59d30e2f 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1485,28 +1485,33 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { debug!("late_bound_in_ty = {:?}", late_bound_in_ty); for br in late_bound_in_ty.difference(&late_bound_in_trait_ref) { let br_name = match *br { - ty::BrNamed(_, name) => name, - _ => { - span_bug!( - binding.span, - "anonymous bound region {:?} in binding but not trait ref", - br - ); - } + ty::BrNamed(_, name) => format!("lifetime `{}`", name), + _ => "an anonymous lifetime".to_string(), }; // FIXME: point at the type params that don't have appropriate lifetimes: // struct S1 Fn(&i32, &i32) -> &'a i32>(F); // ---- ---- ^^^^^^^ - struct_span_err!( + let mut err = struct_span_err!( tcx.sess, binding.span, E0582, - "binding for associated type `{}` references lifetime `{}`, \ + "binding for associated type `{}` references {}, \ which does not appear in the trait input types", binding.item_name, br_name - ) - .emit(); + ); + + if let ty::BrAnon(_) = *br { + // The only way for an anonymous lifetime to wind up + // in the return type but **also** be unconstrained is + // if it only appears in "associated types" in the + // input. See #62200 for an example. In this case, + // though we can easily give a hint that ought to be + // relevant. + err.note("lifetimes appearing in an associated type are not considered constrained"); + } + + err.emit(); } } } diff --git a/src/test/ui/associated-types/issue-62200.rs b/src/test/ui/associated-types/issue-62200.rs new file mode 100644 index 00000000000..9d18690e960 --- /dev/null +++ b/src/test/ui/associated-types/issue-62200.rs @@ -0,0 +1,15 @@ +struct S {} + +trait T<'a> { + type A; +} + +impl T<'_> for S { + type A = u32; +} + +fn foo(x: impl Fn(>::A) -> >::A) {} +//~^ ERROR binding for associated type `Output` references an anonymous lifetime +//~^^ NOTE lifetimes appearing in an associated type are not considered constrained + +fn main() {} diff --git a/src/test/ui/associated-types/issue-62200.stderr b/src/test/ui/associated-types/issue-62200.stderr new file mode 100644 index 00000000000..f14cd81fdfe --- /dev/null +++ b/src/test/ui/associated-types/issue-62200.stderr @@ -0,0 +1,11 @@ +error[E0582]: binding for associated type `Output` references an anonymous lifetime, which does not appear in the trait input types + --> $DIR/issue-62200.rs:11:39 + | +LL | fn foo(x: impl Fn(>::A) -> >::A) {} + | ^^^^^^^^^^^^^^^ + | + = note: lifetimes appearing in an associated type are not considered constrained + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0582`.