From 4d7a21d530a33a9ed33569764f0b3013a1a43094 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Sat, 14 May 2022 01:58:47 -0400 Subject: [PATCH 1/2] A revised, beta-targeted, approach to PR 96970. This carries on with some of the ideas from PR 96970, but generalizes them slightly to try to narrow the cases where the error fires. (It also sidesteps the whole question of trying to deal with lifetime resolution during ast lowering by just looking at names.) More specifically: This tracks the depth of Return Position Opaque Ty (aka Return Position Impl Trait aka RPIT). As it descends the AST, each time it does lower_poly_trait_ref, it tracks what lifetimes are introduced there, and what depth they were introduced at. (As I write this, I realize that I probably didn't handle shadowed lifetimes quite right; see below.) Anyway, when it hits a use of a lifetime, it checks the depth. If the depths don't match and we're in a nested RPIT, then it errors. (Compare this to PR 96970, which just errors unconditionally in the nested RPIT, without checking if the depths match and thus it's a `for<'a>` that was introduced at the current level as well, and thus should not be a problem.) Regarding shadowing mistake: my code probably generates an error in a situation like `impl for<'a> Trait1 Trait2<'a>>`, or something along those lines. But that should be easy to fix.) A follow-up commit will include the blessed test output, so you can see the effect of this and compare it against PR 96970. (I did not put in any new unit tests, but obviously we should make those too.) --- compiler/rustc_ast_lowering/src/item.rs | 7 +- compiler/rustc_ast_lowering/src/lib.rs | 130 +++++++++++++++++++----- 2 files changed, 113 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index c8fd96309a6c..c84a9b155d94 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -88,6 +88,8 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> { lifetimes_to_define: Vec::new(), is_collecting_anonymous_lifetimes: None, in_scope_lifetimes: Vec::new(), + hkt_bound_lifetimes: Vec::new(), + allow_try_trait: Some([sym::try_trait_v2][..].into()), allow_gen_future: Some([sym::gen_future][..].into()), allow_into_future: Some([sym::into_future][..].into()), @@ -1537,7 +1539,10 @@ impl<'hir> LoweringContext<'_, 'hir> { span, }) => hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate { span: self.lower_span(span), - lifetime: self.lower_lifetime(lifetime), + lifetime: self.lower_lifetime( + lifetime, + ImplTraitContext::Disallowed(ImplTraitPosition::Bound), + ), bounds: self.lower_param_bounds( bounds, ImplTraitContext::Disallowed(ImplTraitPosition::Bound), diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index e4ed48d4b530..6b5393c70ea7 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -85,6 +85,9 @@ mod path; rustc_hir::arena_types!(rustc_arena::declare_arena); +#[allow(non_camel_case_types)] +type usize_nesting = u32; + struct LoweringContext<'a, 'hir: 'a> { /// Used to assign IDs to HIR nodes that do not directly correspond to AST nodes. sess: &'a Session, @@ -144,6 +147,10 @@ struct LoweringContext<'a, 'hir: 'a> { /// vector. in_scope_lifetimes: Vec, + /// `for<'a>` bound lifetimes currently in scope, and the + /// ReturnPositionOpaqueTy-depth they were bound at. + hkt_bound_lifetimes: Vec<(hir::LifetimeName, Span, usize_nesting)>, + current_hir_id_owner: LocalDefId, item_local_id_counter: hir::ItemLocalId, local_id_to_def_id: SortedMap, @@ -222,6 +229,9 @@ enum ImplTraitContext<'b, 'a> { fn_def_id: LocalDefId, /// Origin: Either OpaqueTyOrigin::FnReturn or OpaqueTyOrigin::AsyncFn, origin: hir::OpaqueTyOrigin, + /// The depth to which we have nested return position opaque types. + /// 0 if the context *is* is the outermost return position opaque type. + nested: usize_nesting, }, /// Impl trait in type aliases. TypeAliasesOpaqueTy { @@ -273,8 +283,8 @@ impl<'a> ImplTraitContext<'_, 'a> { use self::ImplTraitContext::*; match self { Universal(params, parent) => Universal(params, *parent), - ReturnPositionOpaqueTy { fn_def_id, origin } => { - ReturnPositionOpaqueTy { fn_def_id: *fn_def_id, origin: *origin } + ReturnPositionOpaqueTy { fn_def_id, origin, nested } => { + ReturnPositionOpaqueTy { fn_def_id: *fn_def_id, origin: *origin, nested: *nested } } TypeAliasesOpaqueTy { capturable_lifetimes } => { TypeAliasesOpaqueTy { capturable_lifetimes } @@ -1162,7 +1172,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { itctx: ImplTraitContext<'_, 'hir>, ) -> hir::GenericArg<'hir> { match arg { - ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(<)), + ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(<, itctx)), ast::GenericArg::Type(ty) => { match ty.kind { TyKind::Infer if self.sess.features_untracked().generic_arg_infer => { @@ -1260,10 +1270,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { TyKind::Rptr(ref region, ref mt) => { let span = self.sess.source_map().next_point(t.span.shrink_to_lo()); let lifetime = match *region { - Some(ref lt) => self.lower_lifetime(lt), + Some(ref lt) => self.lower_lifetime(lt, itctx.reborrow()), None => self.elided_ref_lifetime(span), }; - hir::TyKind::Rptr(lifetime, self.lower_mt(mt, itctx)) + hir::TyKind::Rptr(lifetime, self.lower_mt(mt, itctx.reborrow())) } TyKind::BareFn(ref f) => self.with_in_scope_lifetime_defs(&f.generic_params, |this| { this.with_anonymous_lifetime_mode(AnonymousLifetimeMode::PassThrough, |this| { @@ -1327,7 +1337,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) => None, GenericBound::Outlives(ref lifetime) => { if lifetime_bound.is_none() { - lifetime_bound = Some(this.lower_lifetime(lifetime)); + lifetime_bound = + Some(this.lower_lifetime(lifetime, itctx.reborrow())); } None } @@ -1342,15 +1353,23 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { TyKind::ImplTrait(def_node_id, ref bounds) => { let span = t.span; match itctx { - ImplTraitContext::ReturnPositionOpaqueTy { fn_def_id, origin } => self - .lower_opaque_impl_trait( + ImplTraitContext::ReturnPositionOpaqueTy { fn_def_id, origin, nested } => { + self.lower_opaque_impl_trait( span, Some(fn_def_id), origin, def_node_id, None, - |this| this.lower_param_bounds(bounds, itctx), - ), + |this, itctx| this.lower_param_bounds(bounds, itctx), + ImplTraitContext::ReturnPositionOpaqueTy { + fn_def_id, + origin, + nested: nested.checked_add(1).unwrap_or_else(|| { + panic!("return position opaque ty nesting depth exceeded max"); + }) + }, + ) + } ImplTraitContext::TypeAliasesOpaqueTy { ref capturable_lifetimes } => { // Reset capturable lifetimes, any nested impl trait // types will inherit lifetimes from this opaque type, @@ -1364,7 +1383,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::OpaqueTyOrigin::TyAlias, def_node_id, Some(capturable_lifetimes), - |this| this.lower_param_bounds(bounds, nested_itctx), + |this, itctx| this.lower_param_bounds(bounds, itctx), + nested_itctx, ) } ImplTraitContext::Universal(in_band_ty_params, parent_def_id) => { @@ -1428,7 +1448,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { origin: hir::OpaqueTyOrigin, opaque_ty_node_id: NodeId, capturable_lifetimes: Option<&FxHashSet>, - lower_bounds: impl FnOnce(&mut Self) -> hir::GenericBounds<'hir>, + lower_bounds: impl FnOnce(&mut Self, ImplTraitContext<'_, 'hir>) -> hir::GenericBounds<'hir>, + mut itctx: ImplTraitContext<'_, 'hir>, ) -> hir::TyKind<'hir> { debug!( "lower_opaque_impl_trait(fn_def_id={:?}, opaque_ty_node_id={:?}, span={:?})", @@ -1446,7 +1467,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let mut collected_lifetimes = Vec::new(); self.with_hir_id_owner(opaque_ty_node_id, |lctx| { - let hir_bounds = lower_bounds(lctx); + let hir_bounds = lower_bounds(lctx, itctx.reborrow()); collected_lifetimes = lifetimes_from_impl_trait_bounds( opaque_ty_node_id, @@ -1636,6 +1657,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ImplTraitContext::ReturnPositionOpaqueTy { fn_def_id: def_id, origin: hir::OpaqueTyOrigin::FnReturn(def_id), + nested: 0, } } _ => ImplTraitContext::Disallowed(match kind { @@ -1907,6 +1929,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let context = ImplTraitContext::ReturnPositionOpaqueTy { fn_def_id, origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id), + nested: 0, }; self.lower_ty(ty, context) } @@ -1933,7 +1956,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_param_bound( &mut self, tpb: &GenericBound, - itctx: ImplTraitContext<'_, 'hir>, + mut itctx: ImplTraitContext<'_, 'hir>, ) -> hir::GenericBound<'hir> { match tpb { GenericBound::Trait(p, modifier) => hir::GenericBound::Trait( @@ -1941,32 +1964,32 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.lower_trait_bound_modifier(*modifier), ), GenericBound::Outlives(lifetime) => { - hir::GenericBound::Outlives(self.lower_lifetime(lifetime)) + hir::GenericBound::Outlives(self.lower_lifetime(lifetime, itctx.reborrow())) } } } - fn lower_lifetime(&mut self, l: &Lifetime) -> hir::Lifetime { + fn lower_lifetime(&mut self, l: &Lifetime, mut itctx: ImplTraitContext<'_, 'hir>) -> hir::Lifetime { let span = self.lower_span(l.ident.span); match l.ident { ident if ident.name == kw::StaticLifetime => { - self.new_named_lifetime(l.id, span, hir::LifetimeName::Static) + self.new_named_lifetime(l.id, span, hir::LifetimeName::Static, itctx.reborrow()) } ident if ident.name == kw::UnderscoreLifetime => match self.anonymous_lifetime_mode { AnonymousLifetimeMode::CreateParameter => { let fresh_name = self.collect_fresh_anonymous_lifetime(span); - self.new_named_lifetime(l.id, span, hir::LifetimeName::Param(fresh_name)) + self.new_named_lifetime(l.id, span, hir::LifetimeName::Param(fresh_name), itctx.reborrow()) } AnonymousLifetimeMode::PassThrough => { - self.new_named_lifetime(l.id, span, hir::LifetimeName::Underscore) + self.new_named_lifetime(l.id, span, hir::LifetimeName::Underscore, itctx.reborrow()) } AnonymousLifetimeMode::ReportError => self.new_error_lifetime(Some(l.id), span), }, ident => { let param_name = ParamName::Plain(self.lower_ident(ident)); - self.new_named_lifetime(l.id, span, hir::LifetimeName::Param(param_name)) + self.new_named_lifetime(l.id, span, hir::LifetimeName::Param(param_name), itctx.reborrow()) } } } @@ -1976,7 +1999,57 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { id: NodeId, span: Span, name: hir::LifetimeName, + mut itctx: ImplTraitContext<'_, 'hir>, ) -> hir::Lifetime { + fn check_impl_trait_lifetimes( + sess: &Session, + itctx: ImplTraitContext<'_, '_>, + span: Span, + note_span: Option, + def_site_nesting: usize_nesting, + ) { + match itctx { + ImplTraitContext::ReturnPositionOpaqueTy { nested, .. } + if nested > 0 && nested > def_site_nesting => + { + debug!("check_impl_trait_lifetimes badness \ + nested: {} def_site_nesting: {}, span: {:?}, note_span: {:?}", + nested, def_site_nesting, span, note_span); + // fall through to error reporting code + } + ImplTraitContext::TypeAliasesOpaqueTy { .. } => { + // fall through to error reporting code + } + _ => { + // otherwise, accept this lifetime + return + } + } + let mut err = sess.struct_span_err( + span, + "higher kinded lifetime bounds on nested opaque types are not supported yet", + ); + if let Some(span) = note_span { + err.span_note(span, "lifetime declared here"); + } + err.help( + "See https://github.com/rust-lang/rust/issues/96194 for further details", + ); + err.emit(); + } + + for (lt, def_site_span, def_site_nesting) in &self.hkt_bound_lifetimes { + if lt == &name { + check_impl_trait_lifetimes( + self.sess, + itctx.reborrow(), + span, + Some(*def_site_span), + *def_site_nesting, + ); + } + } + hir::Lifetime { hir_id: self.lower_node_id(id), span: self.lower_span(span), name } } @@ -2013,7 +2086,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let lt = self .with_anonymous_lifetime_mode(AnonymousLifetimeMode::ReportError, |this| { - this.lower_lifetime(&Lifetime { id: param.id, ident: param.ident }) + this.lower_lifetime(&Lifetime { id: param.id, ident: param.ident }, itctx.reborrow()) }); let param_name = match lt.name { hir::LifetimeName::Param(param_name) => param_name, @@ -2108,8 +2181,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { capturable_lifetimes.extend(lt_def_names.clone()); } + let hkt_len = this.hkt_bound_lifetimes.len(); + if let ImplTraitContext::ReturnPositionOpaqueTy { nested: rp_nesting, .. } = itctx { + this.hkt_bound_lifetimes.extend(lt_def_names.clone().map(|lt| (lt, p.span, rp_nesting))); + } + let res = this.lower_trait_ref(&p.trait_ref, itctx.reborrow()); + this.hkt_bound_lifetimes.truncate(hkt_len); if let ImplTraitContext::TypeAliasesOpaqueTy { ref mut capturable_lifetimes } = itctx { for param in lt_def_names { capturable_lifetimes.remove(¶m); @@ -2418,7 +2497,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { err.span_label(span, label); err.emit(); - self.new_named_lifetime(id, span, hir::LifetimeName::Error) + self.new_silent_error_lifetime(id, span) + } + + fn new_silent_error_lifetime(&mut self, id: NodeId, span: Span) -> hir::Lifetime + { + hir::Lifetime { hir_id: self.lower_node_id(id), span: self.lower_span(span), name: hir::LifetimeName::Error } } /// Invoked to create the lifetime argument(s) for a path like @@ -2441,7 +2525,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.sess .delay_span_bug(span, "expected 'implicit elided lifetime not allowed' error"); let id = self.resolver.next_node_id(); - self.new_named_lifetime(id, span, hir::LifetimeName::Error) + self.new_silent_error_lifetime(id, span) } // `PassThrough` is the normal case. // `new_error_lifetime`, which would usually be used in the case of `ReportError`, From 28c24cc4ebd4445be39c4079d819c12d48af9b8b Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Sat, 14 May 2022 02:08:22 -0400 Subject: [PATCH 2/2] result of blessing the ui tests. I skimmed these results and compared them against PR 96970 and it seems consistent but I have not inspected them carefully. --- src/test/ui/error-codes/E0657.rs | 6 ++- src/test/ui/error-codes/E0657.stderr | 30 ++++++++++++- src/test/ui/impl-trait/issues/issue-54895.rs | 3 +- .../ui/impl-trait/issues/issue-54895.stderr | 15 +++++++ src/test/ui/impl-trait/issues/issue-67830.rs | 1 + .../ui/impl-trait/issues/issue-67830.stderr | 15 ++++++- .../ui/impl-trait/issues/issue-88236-2.rs | 9 +++- .../ui/impl-trait/issues/issue-88236-2.stderr | 45 +++++++++++++++++-- src/test/ui/impl-trait/issues/issue-88236.rs | 3 +- .../ui/impl-trait/issues/issue-88236.stderr | 15 +++++++ .../missing-lifetimes-in-signature.nll.stderr | 11 ----- 11 files changed, 128 insertions(+), 25 deletions(-) create mode 100644 src/test/ui/impl-trait/issues/issue-54895.stderr create mode 100644 src/test/ui/impl-trait/issues/issue-88236.stderr delete mode 100644 src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.nll.stderr diff --git a/src/test/ui/error-codes/E0657.rs b/src/test/ui/error-codes/E0657.rs index cb11de13f73c..63d46866e832 100644 --- a/src/test/ui/error-codes/E0657.rs +++ b/src/test/ui/error-codes/E0657.rs @@ -8,7 +8,8 @@ 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` can only capture lifetimes bound at the fn or impl level [E0657] +//~| ERROR lifetime bounds on nested opaque types are not supported yet { Box::new(()) } @@ -17,7 +18,8 @@ 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` can only capture lifetimes bound at the fn or impl level + //~| ERROR lifetime bounds on nested opaque types are not supported yet { Box::new(()) } diff --git a/src/test/ui/error-codes/E0657.stderr b/src/test/ui/error-codes/E0657.stderr index df76b45a5891..9abd309c1afb 100644 --- a/src/test/ui/error-codes/E0657.stderr +++ b/src/test/ui/error-codes/E0657.stderr @@ -1,3 +1,29 @@ +error: higher kinded lifetime bounds on nested opaque types are not supported yet + --> $DIR/E0657.rs:10:31 + | +LL | -> Box Id>> + | ^^ + | +note: lifetime declared here + --> $DIR/E0657.rs:10:12 + | +LL | -> Box Id>> + | ^^^^^^^^^^^^^^^^^^^^^^^ + = help: See https://github.com/rust-lang/rust/issues/96194 for further details + +error: higher kinded lifetime bounds on nested opaque types are not supported yet + --> $DIR/E0657.rs:20:35 + | +LL | -> Box Id>> + | ^^ + | +note: lifetime declared here + --> $DIR/E0657.rs:20:16 + | +LL | -> Box Id>> + | ^^^^^^^^^^^^^^^^^^^^^^^ + = help: See https://github.com/rust-lang/rust/issues/96194 for further details + error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl level --> $DIR/E0657.rs:10:31 | @@ -5,11 +31,11 @@ LL | -> Box Id>> | ^^ error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl level - --> $DIR/E0657.rs:19:35 + --> $DIR/E0657.rs:20:35 | LL | -> Box Id>> | ^^ -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0657`. diff --git a/src/test/ui/impl-trait/issues/issue-54895.rs b/src/test/ui/impl-trait/issues/issue-54895.rs index a70166e03a7b..0eba8c7f5740 100644 --- a/src/test/ui/impl-trait/issues/issue-54895.rs +++ b/src/test/ui/impl-trait/issues/issue-54895.rs @@ -1,5 +1,3 @@ -// check-pass - trait Trait<'a> { type Out; fn call(&'a self) -> Self::Out; @@ -15,6 +13,7 @@ impl<'a> Trait<'a> for X { } fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> { + //~^ ERROR lifetime bounds on nested opaque types are not supported yet X(()) } diff --git a/src/test/ui/impl-trait/issues/issue-54895.stderr b/src/test/ui/impl-trait/issues/issue-54895.stderr new file mode 100644 index 000000000000..9bfe9412689c --- /dev/null +++ b/src/test/ui/impl-trait/issues/issue-54895.stderr @@ -0,0 +1,15 @@ +error: higher kinded lifetime bounds on nested opaque types are not supported yet + --> $DIR/issue-54895.rs:15:53 + | +LL | fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> { + | ^^ + | +note: lifetime declared here + --> $DIR/issue-54895.rs:15:16 + | +LL | fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: See https://github.com/rust-lang/rust/issues/96194 for further details + +error: aborting due to previous error + diff --git a/src/test/ui/impl-trait/issues/issue-67830.rs b/src/test/ui/impl-trait/issues/issue-67830.rs index a308d975b439..570be81d844d 100644 --- a/src/test/ui/impl-trait/issues/issue-67830.rs +++ b/src/test/ui/impl-trait/issues/issue-67830.rs @@ -20,6 +20,7 @@ where struct A; fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> { //~^ ERROR implementation of `FnOnce` is not general enough + //~| ERROR lifetime bounds on nested opaque types are not supported yet Wrap(|a| Some(a).into_iter()) } diff --git a/src/test/ui/impl-trait/issues/issue-67830.stderr b/src/test/ui/impl-trait/issues/issue-67830.stderr index 4c0490c721bc..622f0eccecad 100644 --- a/src/test/ui/impl-trait/issues/issue-67830.stderr +++ b/src/test/ui/impl-trait/issues/issue-67830.stderr @@ -1,3 +1,16 @@ +error: higher kinded lifetime bounds on nested opaque types are not supported yet + --> $DIR/issue-67830.rs:21:62 + | +LL | fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> { + | ^^ + | +note: lifetime declared here + --> $DIR/issue-67830.rs:21:19 + | +LL | fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: See https://github.com/rust-lang/rust/issues/96194 for further details + error: implementation of `FnOnce` is not general enough --> $DIR/issue-67830.rs:21:14 | @@ -7,5 +20,5 @@ LL | fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> { = note: closure with signature `fn(&'2 A) -> std::option::IntoIter<&A>` must implement `FnOnce<(&'1 A,)>`, for any lifetime `'1`... = note: ...but it actually implements `FnOnce<(&'2 A,)>`, for some specific lifetime `'2` -error: aborting due to previous error +error: aborting due to 2 previous errors diff --git a/src/test/ui/impl-trait/issues/issue-88236-2.rs b/src/test/ui/impl-trait/issues/issue-88236-2.rs index af26a1f54c46..6d66f7d67527 100644 --- a/src/test/ui/impl-trait/issues/issue-88236-2.rs +++ b/src/test/ui/impl-trait/issues/issue-88236-2.rs @@ -13,11 +13,16 @@ impl<'a> Hrtb<'a> for &'a () { } fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {} +//~^ ERROR lifetime bounds on nested opaque types are not supported yet fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { - &() //~^ ERROR implementation of `Hrtb` is not general enough + //~^ ERROR implementation of `Hrtb` is not general enough + //~| ERROR lifetime bounds on nested opaque types are not supported yet + &() } fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { - x //~^ ERROR implementation of `Hrtb` is not general enough + //~^ ERROR implementation of `Hrtb` is not general enough + //~| ERROR lifetime bounds on nested opaque types are not supported yet + x } fn main() {} diff --git a/src/test/ui/impl-trait/issues/issue-88236-2.stderr b/src/test/ui/impl-trait/issues/issue-88236-2.stderr index 9574b880f7d1..23cab4d79fe3 100644 --- a/src/test/ui/impl-trait/issues/issue-88236-2.stderr +++ b/src/test/ui/impl-trait/issues/issue-88236-2.stderr @@ -1,5 +1,44 @@ +error: higher kinded lifetime bounds on nested opaque types are not supported yet + --> $DIR/issue-88236-2.rs:15:61 + | +LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {} + | ^^ + | +note: lifetime declared here + --> $DIR/issue-88236-2.rs:15:24 + | +LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: See https://github.com/rust-lang/rust/issues/96194 for further details + +error: higher kinded lifetime bounds on nested opaque types are not supported yet + --> $DIR/issue-88236-2.rs:17:80 + | +LL | fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { + | ^^ + | +note: lifetime declared here + --> $DIR/issue-88236-2.rs:17:43 + | +LL | fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: See https://github.com/rust-lang/rust/issues/96194 for further details + +error: higher kinded lifetime bounds on nested opaque types are not supported yet + --> $DIR/issue-88236-2.rs:22:78 + | +LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { + | ^^ + | +note: lifetime declared here + --> $DIR/issue-88236-2.rs:22:41 + | +LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: See https://github.com/rust-lang/rust/issues/96194 for further details + error: implementation of `Hrtb` is not general enough - --> $DIR/issue-88236-2.rs:16:38 + --> $DIR/issue-88236-2.rs:17:38 | LL | fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Hrtb` is not general enough @@ -8,7 +47,7 @@ LL | fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Sen = note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1` error: implementation of `Hrtb` is not general enough - --> $DIR/issue-88236-2.rs:19:36 + --> $DIR/issue-88236-2.rs:22:36 | LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Hrtb` is not general enough @@ -16,5 +55,5 @@ LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send = note: `Hrtb<'1>` would have to be implemented for the type `&()`, for any lifetime `'1`... = note: ...but `Hrtb<'_>` is actually implemented for the type `&()` -error: aborting due to 2 previous errors +error: aborting due to 5 previous errors diff --git a/src/test/ui/impl-trait/issues/issue-88236.rs b/src/test/ui/impl-trait/issues/issue-88236.rs index 2ea35270a7e3..27d58714184f 100644 --- a/src/test/ui/impl-trait/issues/issue-88236.rs +++ b/src/test/ui/impl-trait/issues/issue-88236.rs @@ -1,5 +1,3 @@ -// check-pass - // this used to cause stack overflows trait Hrtb<'a> { @@ -15,5 +13,6 @@ impl<'a> Hrtb<'a> for &'a () { } fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {} +//~^ ERROR lifetime bounds on nested opaque types are not supported yet fn main() {} diff --git a/src/test/ui/impl-trait/issues/issue-88236.stderr b/src/test/ui/impl-trait/issues/issue-88236.stderr new file mode 100644 index 000000000000..8a403864c673 --- /dev/null +++ b/src/test/ui/impl-trait/issues/issue-88236.stderr @@ -0,0 +1,15 @@ +error: higher kinded lifetime bounds on nested opaque types are not supported yet + --> $DIR/issue-88236.rs:15:61 + | +LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {} + | ^^ + | +note: lifetime declared here + --> $DIR/issue-88236.rs:15:24 + | +LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: See https://github.com/rust-lang/rust/issues/96194 for further details + +error: aborting due to previous error + diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.nll.stderr b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.nll.stderr deleted file mode 100644 index 916a6c2bf12a..000000000000 --- a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.nll.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0261]: use of undeclared lifetime name `'a` - --> $DIR/missing-lifetimes-in-signature.rs:36:11 - | -LL | fn baz(g: G, dest: &mut T) -> impl FnOnce() + '_ - | - ^^ undeclared lifetime - | | - | help: consider introducing lifetime `'a` here: `'a,` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0261`.