diff options
| author | Steven Malis <smmalis37@gmail.com> | 2020-07-22 22:54:06 -0700 |
|---|---|---|
| committer | Steven Malis <smmalis37@gmail.com> | 2020-07-22 23:01:15 -0700 |
| commit | dc7d1156bef37b2fe38c3b5c83919dd8f0e39414 (patch) | |
| tree | 6ef18dcdd1b7504852e082c1c7b1ecb8fc4475f8 | |
| parent | 734233d29771869f824d8ddbaddabb90b3b68e03 (diff) | |
Don't ICE on unconstrained anonymous lifetimes inside associated types.
| -rw-r--r-- | src/librustc_typeck/astconv.rs | 29 | ||||
| -rw-r--r-- | src/test/ui/associated-types/issue-62200.rs | 14 | ||||
| -rw-r--r-- | src/test/ui/associated-types/issue-62200.stderr | 11 |
3 files changed, 42 insertions, 12 deletions
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<F: for<'a> 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(<S as T<'_>>::A) -> <S as T<'_>>::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(<S as T<'_>>::A) -> <S as T<'_>>::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`. |
