From ffd30e0a6939d7d25c4ac28bfac4b4e367adcd59 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 7 Mar 2024 15:44:07 +0000 Subject: [PATCH] Improve error message for opaque captures --- .../src/error_codes/E0657.md | 59 ++++------------ compiler/rustc_hir_analysis/messages.ftl | 4 ++ .../src/collect/resolve_bound_vars.rs | 68 +++++++++++-------- compiler/rustc_hir_analysis/src/errors.rs | 12 ++++ tests/ui/error-codes/E0657.rs | 4 +- tests/ui/error-codes/E0657.stderr | 16 ++++- tests/ui/impl-trait/impl-fn-hrtb-bounds.rs | 6 +- .../ui/impl-trait/impl-fn-hrtb-bounds.stderr | 9 +-- .../impl-trait/impl-fn-parsing-ambiguities.rs | 2 +- .../impl-fn-parsing-ambiguities.stderr | 3 +- .../impl-trait/implicit-capture-late.stderr | 8 ++- tests/ui/impl-trait/issues/issue-54895.rs | 2 +- tests/ui/impl-trait/issues/issue-54895.stderr | 3 +- tests/ui/impl-trait/issues/issue-67830.rs | 2 +- tests/ui/impl-trait/issues/issue-67830.stderr | 3 +- tests/ui/impl-trait/issues/issue-88236-2.rs | 6 +- .../ui/impl-trait/issues/issue-88236-2.stderr | 7 +- tests/ui/impl-trait/issues/issue-88236.rs | 2 +- tests/ui/impl-trait/issues/issue-88236.stderr | 3 +- tests/ui/impl-trait/nested-rpit-hrtb.rs | 8 +-- tests/ui/impl-trait/nested-rpit-hrtb.stderr | 10 +-- .../escaping-bound-var.rs | 2 +- .../escaping-bound-var.stderr | 7 +- tests/ui/type-alias-impl-trait/variance.rs | 4 +- .../ui/type-alias-impl-trait/variance.stderr | 16 ++++- 25 files changed, 150 insertions(+), 116 deletions(-) diff --git a/compiler/rustc_error_codes/src/error_codes/E0657.md b/compiler/rustc_error_codes/src/error_codes/E0657.md index 7fe48c5114790..477d8e8bb6dad 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0657.md +++ b/compiler/rustc_error_codes/src/error_codes/E0657.md @@ -1,57 +1,26 @@ -A lifetime bound on a trait implementation was captured at an incorrect place. +An `impl Trait` captured a higher-ranked lifetime, which is not supported. + +Currently, `impl Trait` types are only allowed to capture lifetimes from +their parent items, and not from any `for<'a>` binders in scope. Erroneous code example: ```compile_fail,E0657 -trait Id {} -trait Lt<'a> {} - -impl<'a> Lt<'a> for () {} -impl Id for T {} - -fn free_fn_capture_hrtb_in_impl_trait() - -> Box Id>> // error! -{ - Box::new(()) -} +trait BorrowInto<'a> { + type Target; -struct Foo; -impl Foo { - fn impl_fn_capture_hrtb_in_impl_trait() - -> Box Id>> // error! - { - Box::new(()) - } + fn borrow_into(&'a self) -> Self::Target; } -``` -Here, you have used the inappropriate lifetime in the `impl Trait`, -The `impl Trait` can only capture lifetimes bound at the fn or impl -level. +impl<'a> BorrowInto<'a> for () { + type Target = &'a (); -To fix this we have to define the lifetime at the function or impl -level and use that lifetime in the `impl Trait`. For example you can -define the lifetime at the function: - -``` -trait Id {} -trait Lt<'a> {} - -impl<'a> Lt<'a> for () {} -impl Id for T {} - -fn free_fn_capture_hrtb_in_impl_trait<'b>() - -> Box Id>> // ok! -{ - Box::new(()) + fn borrow_into(&'a self) -> Self::Target { + self + } } -struct Foo; -impl Foo { - fn impl_fn_capture_hrtb_in_impl_trait<'b>() - -> Box Id>> // ok! - { - Box::new(()) - } +fn opaque() -> impl for<'a> BorrowInto<'a, Target = impl Sized + 'a> { + () } ``` diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index e376411cd95c1..bad472dcb5c06 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -312,6 +312,10 @@ hir_analysis_only_current_traits_primitive = only traits defined in the current hir_analysis_only_current_traits_ty = `{$ty}` is not defined in the current crate +hir_analysis_opaque_captures_higher_ranked_lifetime = `impl Trait` cannot capture {$bad_place} + .label = `impl Trait` implicitly captures all lifetimes in scope + .note = lifetime declared here + hir_analysis_paren_sugar_attribute = the `#[rustc_paren_sugar]` attribute is a temporary means of controlling which traits can use parenthetical notation .help = add `#![feature(unboxed_closures)]` to the crate attributes to use it diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 607ada8b5edaa..6531cec765083 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -8,7 +8,6 @@ use rustc_ast::visit::walk_list; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; -use rustc_errors::{codes::*, struct_span_code_err}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::LocalDefId; @@ -673,34 +672,47 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { // and ban them. Type variables instantiated inside binders aren't // well-supported at the moment, so this doesn't work. // In the future, this should be fixed and this error should be removed. - let def = self.map.defs.get(&lifetime.hir_id).cloned(); - let Some(ResolvedArg::LateBound(_, _, def_id)) = def else { continue }; - let Some(def_id) = def_id.as_local() else { continue }; - let hir_id = self.tcx.local_def_id_to_hir_id(def_id); - // Ensure that the parent of the def is an item, not HRTB - let parent_id = self.tcx.parent_hir_id(hir_id); - if !parent_id.is_owner() { - struct_span_code_err!( - self.tcx.dcx(), - lifetime.ident.span, - E0657, - "`impl Trait` can only capture lifetimes bound at the fn or impl level" - ) - .emit(); - self.uninsert_lifetime_on_error(lifetime, def.unwrap()); - } - if let hir::Node::Item(hir::Item { - kind: hir::ItemKind::OpaqueTy { .. }, .. - }) = self.tcx.hir_node(parent_id) + let def = self.map.defs.get(&lifetime.hir_id).copied(); + let Some(ResolvedArg::LateBound(_, _, lifetime_def_id)) = def else { continue }; + let Some(lifetime_def_id) = lifetime_def_id.as_local() else { continue }; + let lifetime_hir_id = self.tcx.local_def_id_to_hir_id(lifetime_def_id); + + let bad_place = match self.tcx.hir_node(self.tcx.parent_hir_id(lifetime_hir_id)) { - self.tcx.dcx().struct_span_err( - lifetime.ident.span, - "higher kinded lifetime bounds on nested opaque types are not supported yet", - ) - .with_span_note(self.tcx.def_span(def_id), "lifetime declared here") - .emit(); - self.uninsert_lifetime_on_error(lifetime, def.unwrap()); - } + // Opaques do not declare their own lifetimes, so if a lifetime comes from an opaque + // it must be a reified late-bound lifetime from a trait goal. + hir::Node::Item(hir::Item { + kind: hir::ItemKind::OpaqueTy { .. }, .. + }) => "higher-ranked lifetime from outer `impl Trait`", + // Other items are fine. + hir::Node::Item(_) | hir::Node::TraitItem(_) | hir::Node::ImplItem(_) => { + continue; + } + hir::Node::Ty(hir::Ty { kind: hir::TyKind::BareFn(_), .. }) => { + "higher-ranked lifetime from function pointer" + } + hir::Node::Ty(hir::Ty { kind: hir::TyKind::TraitObject(..), .. }) => { + "higher-ranked lifetime from `dyn` type" + } + _ => "higher-ranked lifetime", + }; + + let (span, label) = if lifetime.ident.span == self.tcx.def_span(lifetime_def_id) + { + let opaque_span = self.tcx.def_span(item_id.owner_id); + (opaque_span, Some(opaque_span)) + } else { + (lifetime.ident.span, None) + }; + + // Ensure that the parent of the def is an item, not HRTB + self.tcx.dcx().emit_err(errors::OpaqueCapturesHigherRankedLifetime { + span, + label, + decl_span: self.tcx.def_span(lifetime_def_id), + bad_place, + }); + self.uninsert_lifetime_on_error(lifetime, def.unwrap()); } } _ => intravisit::walk_ty(self, ty), diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 5330260fbf513..26349cd1c6551 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1607,3 +1607,15 @@ pub struct UnnamedFieldsReprFieldDefined { #[primary_span] pub span: Span, } + +#[derive(Diagnostic)] +#[diag(hir_analysis_opaque_captures_higher_ranked_lifetime, code = E0657)] +pub struct OpaqueCapturesHigherRankedLifetime { + #[primary_span] + pub span: Span, + #[label] + pub label: Option, + #[note] + pub decl_span: Span, + pub bad_place: &'static str, +} diff --git a/tests/ui/error-codes/E0657.rs b/tests/ui/error-codes/E0657.rs index cb11de13f73c6..212c1d9e581a2 100644 --- a/tests/ui/error-codes/E0657.rs +++ b/tests/ui/error-codes/E0657.rs @@ -8,7 +8,7 @@ impl Id for T {} fn free_fn_capture_hrtb_in_impl_trait() -> Box Id>> - //~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level [E0657] + //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from `dyn` type { Box::new(()) } @@ -17,7 +17,7 @@ struct Foo; impl Foo { fn impl_fn_capture_hrtb_in_impl_trait() -> Box Id>> - //~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level + //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from `dyn` type { Box::new(()) } diff --git a/tests/ui/error-codes/E0657.stderr b/tests/ui/error-codes/E0657.stderr index df76b45a5891f..c539007cdcf19 100644 --- a/tests/ui/error-codes/E0657.stderr +++ b/tests/ui/error-codes/E0657.stderr @@ -1,14 +1,26 @@ -error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl level +error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from `dyn` type --> $DIR/E0657.rs:10:31 | LL | -> Box Id>> | ^^ + | +note: lifetime declared here + --> $DIR/E0657.rs:10:16 + | +LL | -> Box Id>> + | ^^ -error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl level +error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from `dyn` type --> $DIR/E0657.rs:19:35 | LL | -> Box Id>> | ^^ + | +note: lifetime declared here + --> $DIR/E0657.rs:19:20 + | +LL | -> Box Id>> + | ^^ error: aborting due to 2 previous errors diff --git a/tests/ui/impl-trait/impl-fn-hrtb-bounds.rs b/tests/ui/impl-trait/impl-fn-hrtb-bounds.rs index 06c3d9ad434e4..a9ea657f10e2c 100644 --- a/tests/ui/impl-trait/impl-fn-hrtb-bounds.rs +++ b/tests/ui/impl-trait/impl-fn-hrtb-bounds.rs @@ -2,19 +2,19 @@ use std::fmt::Debug; fn a() -> impl Fn(&u8) -> (impl Debug + '_) { - //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet + //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` |x| x //~^ ERROR lifetime may not live long enough } fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) { - //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet + //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` |x| x //~^ ERROR lifetime may not live long enough } fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) { - //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet + //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` |x| x //~^ ERROR lifetime may not live long enough } diff --git a/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr b/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr index 959d6577d9a60..bdb099619b76f 100644 --- a/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr +++ b/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr @@ -10,7 +10,7 @@ help: consider using the `'static` lifetime, but this is uncommon unless you're LL | fn d() -> impl Fn() -> (impl Debug + 'static) { | ~~~~~~~ -error: higher kinded lifetime bounds on nested opaque types are not supported yet +error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` --> $DIR/impl-fn-hrtb-bounds.rs:4:41 | LL | fn a() -> impl Fn(&u8) -> (impl Debug + '_) { @@ -31,7 +31,7 @@ LL | |x| x | |return type of closure is impl Debug + '2 | has type `&'1 u8` -error: higher kinded lifetime bounds on nested opaque types are not supported yet +error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` --> $DIR/impl-fn-hrtb-bounds.rs:10:52 | LL | fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) { @@ -52,7 +52,7 @@ LL | |x| x | |return type of closure is impl Debug + '2 | has type `&'1 u8` -error: higher kinded lifetime bounds on nested opaque types are not supported yet +error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` --> $DIR/impl-fn-hrtb-bounds.rs:16:52 | LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) { @@ -75,4 +75,5 @@ LL | |x| x error: aborting due to 7 previous errors -For more information about this error, try `rustc --explain E0106`. +Some errors have detailed explanations: E0106, E0657. +For more information about an error, try `rustc --explain E0106`. diff --git a/tests/ui/impl-trait/impl-fn-parsing-ambiguities.rs b/tests/ui/impl-trait/impl-fn-parsing-ambiguities.rs index a4a1f1dcee120..ef9d87335097f 100644 --- a/tests/ui/impl-trait/impl-fn-parsing-ambiguities.rs +++ b/tests/ui/impl-trait/impl-fn-parsing-ambiguities.rs @@ -3,7 +3,7 @@ use std::fmt::Debug; fn a() -> impl Fn(&u8) -> impl Debug + '_ { //~^ ERROR ambiguous `+` in a type - //~| ERROR higher kinded lifetime bounds on nested opaque types are not supported yet + //~| ERROR cannot capture higher-ranked lifetime from outer `impl Trait` |x| x //~^ ERROR lifetime may not live long enough } diff --git a/tests/ui/impl-trait/impl-fn-parsing-ambiguities.stderr b/tests/ui/impl-trait/impl-fn-parsing-ambiguities.stderr index e18e89700b4e9..3881b37a0cbf4 100644 --- a/tests/ui/impl-trait/impl-fn-parsing-ambiguities.stderr +++ b/tests/ui/impl-trait/impl-fn-parsing-ambiguities.stderr @@ -10,7 +10,7 @@ error: ambiguous `+` in a type LL | fn b() -> impl Fn() -> impl Debug + Send { | ^^^^^^^^^^^^^^^^^ help: use parentheses to disambiguate: `(impl Debug + Send)` -error: higher kinded lifetime bounds on nested opaque types are not supported yet +error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` --> $DIR/impl-fn-parsing-ambiguities.rs:4:40 | LL | fn a() -> impl Fn(&u8) -> impl Debug + '_ { @@ -33,3 +33,4 @@ LL | |x| x error: aborting due to 4 previous errors +For more information about this error, try `rustc --explain E0657`. diff --git a/tests/ui/impl-trait/implicit-capture-late.stderr b/tests/ui/impl-trait/implicit-capture-late.stderr index 2fb5ebb65418c..080750f849767 100644 --- a/tests/ui/impl-trait/implicit-capture-late.stderr +++ b/tests/ui/impl-trait/implicit-capture-late.stderr @@ -1,4 +1,10 @@ -error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl level +error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from `dyn` type + --> $DIR/implicit-capture-late.rs:10:55 + | +LL | fn foo(x: Vec) -> Box Deref> { + | ^^^^^^^^^^^ `impl Trait` implicitly captures all lifetimes in scope + | +note: lifetime declared here --> $DIR/implicit-capture-late.rs:10:36 | LL | fn foo(x: Vec) -> Box Deref> { diff --git a/tests/ui/impl-trait/issues/issue-54895.rs b/tests/ui/impl-trait/issues/issue-54895.rs index 8d7a1d56f8320..13c0038ce4340 100644 --- a/tests/ui/impl-trait/issues/issue-54895.rs +++ b/tests/ui/impl-trait/issues/issue-54895.rs @@ -13,7 +13,7 @@ impl<'a> Trait<'a> for X { } fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> { - //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet + //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` X(()) } diff --git a/tests/ui/impl-trait/issues/issue-54895.stderr b/tests/ui/impl-trait/issues/issue-54895.stderr index 999ffd5214154..64b425328e3ab 100644 --- a/tests/ui/impl-trait/issues/issue-54895.stderr +++ b/tests/ui/impl-trait/issues/issue-54895.stderr @@ -1,4 +1,4 @@ -error: higher kinded lifetime bounds on nested opaque types are not supported yet +error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` --> $DIR/issue-54895.rs:15:53 | LL | fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> { @@ -12,3 +12,4 @@ LL | fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> { error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0657`. diff --git a/tests/ui/impl-trait/issues/issue-67830.rs b/tests/ui/impl-trait/issues/issue-67830.rs index 6dc8935c77708..939eca82a8f6d 100644 --- a/tests/ui/impl-trait/issues/issue-67830.rs +++ b/tests/ui/impl-trait/issues/issue-67830.rs @@ -19,7 +19,7 @@ where struct A; fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> { - //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet + //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` Wrap(|a| Some(a).into_iter()) //~^ ERROR implementation of `FnOnce` is not general enough //~| ERROR implementation of `FnOnce` is not general enough diff --git a/tests/ui/impl-trait/issues/issue-67830.stderr b/tests/ui/impl-trait/issues/issue-67830.stderr index 546198b8a1037..ef513a40cf39f 100644 --- a/tests/ui/impl-trait/issues/issue-67830.stderr +++ b/tests/ui/impl-trait/issues/issue-67830.stderr @@ -1,4 +1,4 @@ -error: higher kinded lifetime bounds on nested opaque types are not supported yet +error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` --> $DIR/issue-67830.rs:21:62 | LL | fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> { @@ -31,3 +31,4 @@ LL | Wrap(|a| Some(a).into_iter()) error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0657`. diff --git a/tests/ui/impl-trait/issues/issue-88236-2.rs b/tests/ui/impl-trait/issues/issue-88236-2.rs index f4354d1b2aef0..7ff08d8174f8e 100644 --- a/tests/ui/impl-trait/issues/issue-88236-2.rs +++ b/tests/ui/impl-trait/issues/issue-88236-2.rs @@ -13,17 +13,17 @@ impl<'a> Hrtb<'a> for &'a () { } fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {} -//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet +//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { - //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet + //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` &() //~^ ERROR implementation of `Hrtb` is not general enough //~| ERROR implementation of `Hrtb` is not general enough } fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { - //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet + //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` x //~^ ERROR implementation of `Hrtb` is not general enough //~| ERROR implementation of `Hrtb` is not general enough diff --git a/tests/ui/impl-trait/issues/issue-88236-2.stderr b/tests/ui/impl-trait/issues/issue-88236-2.stderr index 1f5029f9d9fa7..09fd58056a561 100644 --- a/tests/ui/impl-trait/issues/issue-88236-2.stderr +++ b/tests/ui/impl-trait/issues/issue-88236-2.stderr @@ -1,4 +1,4 @@ -error: higher kinded lifetime bounds on nested opaque types are not supported yet +error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` --> $DIR/issue-88236-2.rs:15:61 | LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {} @@ -10,7 +10,7 @@ note: lifetime declared here LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {} | ^^ -error: higher kinded lifetime bounds on nested opaque types are not supported yet +error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` --> $DIR/issue-88236-2.rs:18:80 | LL | fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { @@ -40,7 +40,7 @@ LL | &() = note: `Hrtb<'a>` would have to be implemented for the type `&()` = note: ...but `Hrtb<'0>` is actually implemented for the type `&'0 ()`, for some specific lifetime `'0` -error: higher kinded lifetime bounds on nested opaque types are not supported yet +error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` --> $DIR/issue-88236-2.rs:25:78 | LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { @@ -90,3 +90,4 @@ LL | x error: aborting due to 8 previous errors +For more information about this error, try `rustc --explain E0657`. diff --git a/tests/ui/impl-trait/issues/issue-88236.rs b/tests/ui/impl-trait/issues/issue-88236.rs index 36d12417354a2..e782a87657346 100644 --- a/tests/ui/impl-trait/issues/issue-88236.rs +++ b/tests/ui/impl-trait/issues/issue-88236.rs @@ -13,6 +13,6 @@ impl<'a> Hrtb<'a> for &'a () { } fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {} -//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet +//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` fn main() {} diff --git a/tests/ui/impl-trait/issues/issue-88236.stderr b/tests/ui/impl-trait/issues/issue-88236.stderr index 6cf1a42d6a997..5dee5f88c89f2 100644 --- a/tests/ui/impl-trait/issues/issue-88236.stderr +++ b/tests/ui/impl-trait/issues/issue-88236.stderr @@ -1,4 +1,4 @@ -error: higher kinded lifetime bounds on nested opaque types are not supported yet +error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` --> $DIR/issue-88236.rs:15:61 | LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {} @@ -12,3 +12,4 @@ LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {} error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0657`. diff --git a/tests/ui/impl-trait/nested-rpit-hrtb.rs b/tests/ui/impl-trait/nested-rpit-hrtb.rs index a3eca741daad9..c10bfbfe4dc1a 100644 --- a/tests/ui/impl-trait/nested-rpit-hrtb.rs +++ b/tests/ui/impl-trait/nested-rpit-hrtb.rs @@ -23,18 +23,18 @@ impl Qux<'_> for () {} // This is not supported. fn one_hrtb_outlives() -> impl for<'a> Foo<'a, Assoc = impl Sized + 'a> {} -//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet +//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` // This is not supported. fn one_hrtb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl Qux<'a>> {} -//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet +//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {} -//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet +//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` //~| ERROR implementation of `Bar` is not general enough fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {} -//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet +//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` //~| ERROR: the trait bound `for<'a> &'a (): Qux<'_>` is not satisfied // This should resolve. diff --git a/tests/ui/impl-trait/nested-rpit-hrtb.stderr b/tests/ui/impl-trait/nested-rpit-hrtb.stderr index 4fc22712de616..2779694a51711 100644 --- a/tests/ui/impl-trait/nested-rpit-hrtb.stderr +++ b/tests/ui/impl-trait/nested-rpit-hrtb.stderr @@ -29,7 +29,7 @@ help: consider introducing lifetime `'b` here LL | fn two_htrb_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {} | ++++ -error: higher kinded lifetime bounds on nested opaque types are not supported yet +error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` --> $DIR/nested-rpit-hrtb.rs:25:69 | LL | fn one_hrtb_outlives() -> impl for<'a> Foo<'a, Assoc = impl Sized + 'a> {} @@ -41,7 +41,7 @@ note: lifetime declared here LL | fn one_hrtb_outlives() -> impl for<'a> Foo<'a, Assoc = impl Sized + 'a> {} | ^^ -error: higher kinded lifetime bounds on nested opaque types are not supported yet +error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` --> $DIR/nested-rpit-hrtb.rs:29:68 | LL | fn one_hrtb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl Qux<'a>> {} @@ -53,7 +53,7 @@ note: lifetime declared here LL | fn one_hrtb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl Qux<'a>> {} | ^^ -error: higher kinded lifetime bounds on nested opaque types are not supported yet +error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` --> $DIR/nested-rpit-hrtb.rs:32:74 | LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {} @@ -74,7 +74,7 @@ LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a = note: `()` must implement `Bar<'a>` = note: ...but it actually implements `Bar<'0>`, for some specific lifetime `'0` -error: higher kinded lifetime bounds on nested opaque types are not supported yet +error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` --> $DIR/nested-rpit-hrtb.rs:36:73 | LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {} @@ -133,5 +133,5 @@ LL | fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Si error: aborting due to 12 previous errors -Some errors have detailed explanations: E0261, E0277. +Some errors have detailed explanations: E0261, E0277, E0657. For more information about an error, try `rustc --explain E0261`. diff --git a/tests/ui/type-alias-impl-trait/escaping-bound-var.rs b/tests/ui/type-alias-impl-trait/escaping-bound-var.rs index b030ce39d1dfc..1ff200680be5e 100644 --- a/tests/ui/type-alias-impl-trait/escaping-bound-var.rs +++ b/tests/ui/type-alias-impl-trait/escaping-bound-var.rs @@ -7,7 +7,7 @@ pub trait Trait<'a> { trait Test<'a> {} pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>; -//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet +//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` impl Trait<'_> for () { type Assoc = (); diff --git a/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr b/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr index 706de37e9f3c7..09f6fba79cfdf 100644 --- a/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr +++ b/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr @@ -1,8 +1,8 @@ -error: higher kinded lifetime bounds on nested opaque types are not supported yet - --> $DIR/escaping-bound-var.rs:9:25 +error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` + --> $DIR/escaping-bound-var.rs:9:47 | LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>; - | ^^ + | ^^^^^^^^^^^^^ `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/escaping-bound-var.rs:9:25 @@ -12,3 +12,4 @@ LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>; error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0657`. diff --git a/tests/ui/type-alias-impl-trait/variance.rs b/tests/ui/type-alias-impl-trait/variance.rs index 457c4affb9d22..4b9fa67fd64c7 100644 --- a/tests/ui/type-alias-impl-trait/variance.rs +++ b/tests/ui/type-alias-impl-trait/variance.rs @@ -12,11 +12,11 @@ type CapturedEarly<'a> = impl Sized + Captures<'a>; //~ [*, o] //~^ ERROR: unconstrained opaque type type NotCapturedLate<'a> = dyn for<'b> Iterator; //~ [*, o, o] -//~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level +//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from `dyn` type //~| ERROR: unconstrained opaque type type Captured<'a> = dyn for<'b> Iterator>; //~ [*, o, o] -//~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level +//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from `dyn` type //~| ERROR: unconstrained opaque type type Bar<'a, 'b: 'b, T> = impl Sized; //~ ERROR [*, *, o, o, o] diff --git a/tests/ui/type-alias-impl-trait/variance.stderr b/tests/ui/type-alias-impl-trait/variance.stderr index eafe583e89c26..1aaf36223b7f5 100644 --- a/tests/ui/type-alias-impl-trait/variance.stderr +++ b/tests/ui/type-alias-impl-trait/variance.stderr @@ -1,10 +1,22 @@ -error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl level +error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from `dyn` type + --> $DIR/variance.rs:14:56 + | +LL | type NotCapturedLate<'a> = dyn for<'b> Iterator; + | ^^^^^^^^^^ `impl Trait` implicitly captures all lifetimes in scope + | +note: lifetime declared here --> $DIR/variance.rs:14:36 | LL | type NotCapturedLate<'a> = dyn for<'b> Iterator; | ^^ -error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl level +error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from `dyn` type + --> $DIR/variance.rs:18:49 + | +LL | type Captured<'a> = dyn for<'b> Iterator>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ `impl Trait` implicitly captures all lifetimes in scope + | +note: lifetime declared here --> $DIR/variance.rs:18:29 | LL | type Captured<'a> = dyn for<'b> Iterator>;