diff options
| author | Yuki Okushi <huyuumi.dev@gmail.com> | 2020-07-24 18:56:32 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-07-24 18:56:32 +0900 |
| commit | 1f6d5ce4ab620d2b843cd0171d0e20ee24ae8c15 (patch) | |
| tree | 753430a21e794025b53275a410ac74798f78cb82 | |
| parent | a02aecba211ba82e79350db9e4dcd2675fd79423 (diff) | |
| parent | bbaab63f844d64ca726a2a83c18774b3957c7169 (diff) | |
| download | rust-1f6d5ce4ab620d2b843cd0171d0e20ee24ae8c15.tar.gz rust-1f6d5ce4ab620d2b843cd0171d0e20ee24ae8c15.zip | |
Rollup merge of #74665 - smmalis37:issue-62200, r=davidtwco
Don't ICE on unconstrained anonymous lifetimes inside associated types. Fixes #62200. The change here is inspired (copied) by how this case is handled on bare fns at https://github.com/rust-lang/rust/blob/e8b55a4ad230ebec762fdfc4f241ba98a98560af/src/librustc_typeck/astconv.rs#L3083-L3106.
| -rw-r--r-- | src/librustc_typeck/astconv.rs | 29 | ||||
| -rw-r--r-- | src/test/ui/associated-types/issue-62200.rs | 15 | ||||
| -rw-r--r-- | src/test/ui/associated-types/issue-62200.stderr | 11 |
3 files changed, 43 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..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(<S as T<'_>>::A) -> <S as T<'_>>::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(<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`. |
