From dc7d1156bef37b2fe38c3b5c83919dd8f0e39414 Mon Sep 17 00:00:00 2001 From: Steven Malis Date: Wed, 22 Jul 2020 22:54:06 -0700 Subject: [PATCH 1/2] Don't ICE on unconstrained anonymous lifetimes inside associated types. --- src/librustc_typeck/astconv.rs | 29 +++++++++++-------- src/test/ui/associated-types/issue-62200.rs | 14 +++++++++ .../ui/associated-types/issue-62200.stderr | 11 +++++++ 3 files changed, 42 insertions(+), 12 deletions(-) create mode 100644 src/test/ui/associated-types/issue-62200.rs create mode 100644 src/test/ui/associated-types/issue-62200.stderr 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..10f06eb26f8 --- /dev/null +++ b/src/test/ui/associated-types/issue-62200.rs @@ -0,0 +1,14 @@ +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 + +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`. From bbaab63f844d64ca726a2a83c18774b3957c7169 Mon Sep 17 00:00:00 2001 From: Steven Malis Date: Wed, 22 Jul 2020 23:19:38 -0700 Subject: [PATCH 2/2] Include the note in the test. --- src/test/ui/associated-types/issue-62200.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/ui/associated-types/issue-62200.rs b/src/test/ui/associated-types/issue-62200.rs index 10f06eb26f8..9d18690e960 100644 --- a/src/test/ui/associated-types/issue-62200.rs +++ b/src/test/ui/associated-types/issue-62200.rs @@ -10,5 +10,6 @@ impl T<'_> for S { 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() {}