From a4da6308b7b2cb14649a3e3e6f0d72ed43855970 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 30 Nov 2021 21:55:52 +0100 Subject: [PATCH 1/5] Inherit lifetimes for async fn instead of duplicating them. --- compiler/rustc_ast_lowering/src/lib.rs | 69 +++++-------------- .../rustc_infer/src/infer/opaque_types.rs | 4 +- compiler/rustc_resolve/src/late/lifetimes.rs | 34 ++++++--- compiler/rustc_typeck/src/astconv/mod.rs | 15 ++-- compiler/rustc_typeck/src/check/check.rs | 15 +--- compiler/rustc_typeck/src/collect.rs | 5 +- .../issue-61949-self-return-type.rs | 2 +- .../issue-61949-self-return-type.stderr | 16 +++-- ...sue-74072-lifetime-name-annotations.stderr | 4 -- .../issue-75785-confusing-named-region.stderr | 4 -- .../async-await/issues/issue-63388-1.stderr | 8 +-- src/test/ui/async-await/issues/issue-78600.rs | 2 +- .../ui/async-await/issues/issue-78600.stderr | 11 --- .../ret-impl-trait-one.stderr | 7 +- src/test/ui/async-await/unused-lifetime.rs | 3 + .../ui/async-await/unused-lifetime.stderr | 34 +++++++-- ...f_types_pin_lifetime_mismatch-async.stderr | 12 ++-- .../ui/self/elision/lt-ref-self-async.stderr | 36 ++++------ .../ui/self/elision/ref-mut-self-async.stderr | 36 ++++------ .../self/elision/ref-mut-struct-async.stderr | 30 +++----- .../ui/self/elision/ref-self-async.stderr | 42 ++++------- .../ui/self/elision/ref-struct-async.stderr | 30 +++----- 22 files changed, 171 insertions(+), 248 deletions(-) delete mode 100644 src/test/ui/async-await/issues/issue-78600.stderr diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index b1e601516ab97..60b5aeb52b18f 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1659,11 +1659,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // When we create the opaque type for this async fn, it is going to have // to capture all the lifetimes involved in the signature (including in the - // return type). This is done by introducing lifetime parameters for: + // return type). This is done by: // - // - all the explicitly declared lifetimes from the impl and function itself; - // - all the elided lifetimes in the fn arguments; - // - all the elided lifetimes in the return type. + // - making the opaque type inherit all lifetime parameters from its parent; + // - make all the elided lifetimes in the fn arguments into parameters; + // - manually introducing parameters on the opaque type for elided + // lifetimes in the return type. // // So for example in this snippet: // @@ -1679,14 +1680,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // we would create an opaque type like: // // ``` - // type Bar<'a, 'b, '0, '1, '2> = impl Future; + // type Foo<'a>::bar<'b, '0, '1>::Bar<'2> = impl Future; // ``` // // and we would then desugar `bar` to the equivalent of: // // ```rust // impl<'a> Foo<'a> { - // fn bar<'b, '0, '1>(&'0 self, x: &'b Vec, y: &'1 str) -> Bar<'a, 'b, '0, '1, '_> + // fn bar<'b, '0, '1>(&'0 self, x: &'b Vec, y: &'1 str) -> Bar<'_> // } // ``` // @@ -1694,29 +1695,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // this is because the elided lifetimes from the return type // should be figured out using the ordinary elision rules, and // this desugaring achieves that. - - debug!("lower_async_fn_ret_ty: in_scope_lifetimes={:#?}", self.in_scope_lifetimes); - debug!("lower_async_fn_ret_ty: lifetimes_to_define={:#?}", self.lifetimes_to_define); - - // Calculate all the lifetimes that should be captured - // by the opaque type. This should include all in-scope - // lifetime parameters, including those defined in-band. - // - // `lifetime_params` is a vector of tuple (span, parameter name, lifetime name). - - // Input lifetime like `'a` or `'1`: - let mut lifetime_params: Vec<_> = self - .in_scope_lifetimes - .iter() - .cloned() - .map(|name| (name.ident().span, name, hir::LifetimeName::Param(name))) - .chain( - self.lifetimes_to_define - .iter() - .map(|&(span, name)| (span, name, hir::LifetimeName::Param(name))), - ) - .collect(); - + let mut lifetime_params = Vec::new(); self.with_hir_id_owner(opaque_ty_node_id, |this| { // We have to be careful to get elision right here. The // idea is that we create a lifetime parameter for each @@ -1735,16 +1714,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { debug!("lower_async_fn_ret_ty: future_bound={:#?}", future_bound); debug!("lower_async_fn_ret_ty: lifetimes_to_define={:#?}", lifetimes_to_define); - lifetime_params.extend( - // Output lifetime like `'_`: - lifetimes_to_define - .into_iter() - .map(|(span, name)| (span, name, hir::LifetimeName::Implicit(false))), - ); + // Output lifetime like `'_`: + lifetime_params = lifetimes_to_define; debug!("lower_async_fn_ret_ty: lifetime_params={:#?}", lifetime_params); let generic_params = - this.arena.alloc_from_iter(lifetime_params.iter().map(|&(span, hir_name, _)| { + this.arena.alloc_from_iter(lifetime_params.iter().map(|&(span, hir_name)| { this.lifetime_to_generic_param(span, hir_name, opaque_ty_def_id) })); @@ -1762,28 +1737,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { this.generate_opaque_type(opaque_ty_def_id, opaque_ty_item, span, opaque_ty_span) }); - // As documented above on the variable - // `input_lifetimes_count`, we need to create the lifetime - // arguments to our opaque type. Continuing with our example, - // we're creating the type arguments for the return type: + // We need to create the lifetime arguments to our opaque type. + // Continuing with our example, we're creating the type arguments + // for the return type: // // ``` - // Bar<'a, 'b, '0, '1, '_> + // For<'a>::bar<'b, '0, '1>::Bar<'_> // ``` // - // For the "input" lifetime parameters, we wish to create - // references to the parameters themselves, including the - // "implicit" ones created from parameter types (`'a`, `'b`, - // '`0`, `'1`). - // - // For the "output" lifetime parameters, we just want to - // generate `'_`. + // For the "input" lifetime parameters are inherited automatically. + // For the "output" lifetime parameters, we just want to generate `'_`. let generic_args = - self.arena.alloc_from_iter(lifetime_params.into_iter().map(|(span, _, name)| { + self.arena.alloc_from_iter(lifetime_params.into_iter().map(|(span, _)| { GenericArg::Lifetime(hir::Lifetime { hir_id: self.next_id(), span: self.lower_span(span), - name, + name: hir::LifetimeName::Implicit(false), }) })); diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index e7dca94806cb7..e79ece9a4a4d5 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -276,7 +276,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { debug!(?concrete_ty); let first_own_region = match opaque_defn.origin { - hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => { + hir::OpaqueTyOrigin::FnReturn(..) => { // We lower // // fn foo<'l0..'ln>() -> impl Trait<'l0..'lm> @@ -291,7 +291,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } // These opaque type inherit all lifetime parameters from their // parent, so we have to check them all. - hir::OpaqueTyOrigin::TyAlias => 0, + hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::TyAlias => 0, }; // For a case like `impl Foo<'a, 'b>`, we would generate a constraint diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 5a1378a3686b3..d25bee67d4ee0 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -729,9 +729,16 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { match item.kind { hir::ItemKind::Fn(ref sig, ref generics, _) => { self.missing_named_lifetime_spots.push(generics.into()); - self.visit_early_late(None, item.hir_id(), &sig.decl, generics, |this| { - intravisit::walk_item(this, item); - }); + self.visit_early_late( + None, + item.hir_id(), + &sig.decl, + generics, + sig.header.asyncness, + |this| { + intravisit::walk_item(this, item); + }, + ); self.missing_named_lifetime_spots.pop(); } @@ -849,11 +856,16 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) { match item.kind { - hir::ForeignItemKind::Fn(ref decl, _, ref generics) => { - self.visit_early_late(None, item.hir_id(), decl, generics, |this| { + hir::ForeignItemKind::Fn(ref decl, _, ref generics) => self.visit_early_late( + None, + item.hir_id(), + decl, + generics, + hir::IsAsync::NotAsync, + |this| { intravisit::walk_foreign_item(this, item); - }) - } + }, + ), hir::ForeignItemKind::Static(..) => { intravisit::walk_foreign_item(self, item); } @@ -1130,6 +1142,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { trait_item.hir_id(), &sig.decl, &trait_item.generics, + sig.header.asyncness, |this| intravisit::walk_trait_item(this, trait_item), ); self.missing_named_lifetime_spots.pop(); @@ -1199,6 +1212,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { impl_item.hir_id(), &sig.decl, &impl_item.generics, + sig.header.asyncness, |this| intravisit::walk_impl_item(this, impl_item), ); self.missing_named_lifetime_spots.pop(); @@ -2159,11 +2173,15 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { hir_id: hir::HirId, decl: &'tcx hir::FnDecl<'tcx>, generics: &'tcx hir::Generics<'tcx>, + asyncness: hir::IsAsync, walk: F, ) where F: for<'b, 'c> FnOnce(&'b mut LifetimeContext<'c, 'tcx>), { - insert_late_bound_lifetimes(self.map, decl, generics); + // Async fns need all their lifetime parameters to be early bound. + if asyncness != hir::IsAsync::Async { + insert_late_bound_lifetimes(self.map, decl, generics); + } // Find the start of nested early scopes, e.g., in methods. let mut next_early_index = 0; diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index aa054043c4e88..366d20dbbc21a 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -2408,16 +2408,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let def_id = item_id.def_id.to_def_id(); match opaque_ty.kind { - hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => self - .impl_trait_ty_to_ty( - def_id, - lifetimes, - matches!( - origin, - hir::OpaqueTyOrigin::FnReturn(..) - | hir::OpaqueTyOrigin::AsyncFn(..) - ), - ), + hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => { + let replace_parent_lifetimes = + matches!(origin, hir::OpaqueTyOrigin::FnReturn(..)); + self.impl_trait_ty_to_ty(def_id, lifetimes, replace_parent_lifetimes) + } ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i), } } diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index 18a0a8767d45b..536a848e5bb2f 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -535,10 +535,8 @@ pub(super) fn check_opaque_for_inheriting_lifetimes<'tcx>( } } - if let ItemKind::OpaqueTy(hir::OpaqueTy { - origin: hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::FnReturn(..), - .. - }) = item.kind + if let ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn(..), .. }) = + item.kind { let mut visitor = ProhibitOpaqueVisitor { opaque_identity_ty: tcx.mk_opaque( @@ -560,20 +558,13 @@ pub(super) fn check_opaque_for_inheriting_lifetimes<'tcx>( if let Some(ty) = prohibit_opaque.break_value() { visitor.visit_item(&item); - let is_async = match item.kind { - ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => { - matches!(origin, hir::OpaqueTyOrigin::AsyncFn(..)) - } - _ => unreachable!(), - }; let mut err = struct_span_err!( tcx.sess, span, E0760, - "`{}` return type cannot contain a projection or `Self` that references lifetimes from \ + "`impl Trait` return type cannot contain a projection or `Self` that references lifetimes from \ a parent scope", - if is_async { "async fn" } else { "impl Trait" }, ); for (span, name) in visitor.selftys { diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 3f0c3edfe0926..727ca19d6ffd6 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -2162,8 +2162,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP generics } ItemKind::OpaqueTy(OpaqueTy { - origin: hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::FnReturn(..), - .. + origin: hir::OpaqueTyOrigin::FnReturn(..), .. }) => { // return-position impl trait // @@ -2183,7 +2182,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP } ItemKind::OpaqueTy(OpaqueTy { ref generics, - origin: hir::OpaqueTyOrigin::TyAlias, + origin: hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::TyAlias, .. }) => { // type-alias impl trait diff --git a/src/test/ui/async-await/issue-61949-self-return-type.rs b/src/test/ui/async-await/issue-61949-self-return-type.rs index 43429ba2329f9..42133d5104146 100644 --- a/src/test/ui/async-await/issue-61949-self-return-type.rs +++ b/src/test/ui/async-await/issue-61949-self-return-type.rs @@ -8,7 +8,6 @@ pub struct Foo<'a> { impl<'a> Foo<'a> { pub async fn new(_bar: &'a i32) -> Self { - //~^ ERROR `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope Foo { bar: &22 } @@ -19,6 +18,7 @@ async fn foo() { let x = { let bar = 22; Foo::new(&bar).await + //~^ ERROR `bar` does not live long enough [E0597] }; drop(x); } diff --git a/src/test/ui/async-await/issue-61949-self-return-type.stderr b/src/test/ui/async-await/issue-61949-self-return-type.stderr index 52b726e186e3a..f86844e1a9cac 100644 --- a/src/test/ui/async-await/issue-61949-self-return-type.stderr +++ b/src/test/ui/async-await/issue-61949-self-return-type.stderr @@ -1,9 +1,15 @@ -error[E0760]: `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope - --> $DIR/issue-61949-self-return-type.rs:10:40 +error[E0597]: `bar` does not live long enough + --> $DIR/issue-61949-self-return-type.rs:20:18 | -LL | pub async fn new(_bar: &'a i32) -> Self { - | ^^^^ help: consider spelling out the type instead: `Foo<'a>` +LL | let x = { + | - borrow later stored here +LL | let bar = 22; +LL | Foo::new(&bar).await + | ^^^^ borrowed value does not live long enough +LL | +LL | }; + | - `bar` dropped here while still borrowed error: aborting due to previous error -For more information about this error, try `rustc --explain E0760`. +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/async-await/issue-74072-lifetime-name-annotations.stderr b/src/test/ui/async-await/issue-74072-lifetime-name-annotations.stderr index b96cab9f0f51a..80504613eb4e3 100644 --- a/src/test/ui/async-await/issue-74072-lifetime-name-annotations.stderr +++ b/src/test/ui/async-await/issue-74072-lifetime-name-annotations.stderr @@ -1,14 +1,10 @@ error[E0506]: cannot assign to `*x` because it is borrowed --> $DIR/issue-74072-lifetime-name-annotations.rs:9:5 | -LL | pub async fn async_fn(x: &mut i32) -> &i32 { - | - let's call the lifetime of this reference `'1` LL | let y = &*x; | --- borrow of `*x` occurs here LL | *x += 1; | ^^^^^^^ assignment to borrowed `*x` occurs here -LL | y - | - returning this value requires that `*x` is borrowed for `'1` error[E0506]: cannot assign to `*x` because it is borrowed --> $DIR/issue-74072-lifetime-name-annotations.rs:16:9 diff --git a/src/test/ui/async-await/issue-75785-confusing-named-region.stderr b/src/test/ui/async-await/issue-75785-confusing-named-region.stderr index 3b731d9c60a6a..06660b7c182b3 100644 --- a/src/test/ui/async-await/issue-75785-confusing-named-region.stderr +++ b/src/test/ui/async-await/issue-75785-confusing-named-region.stderr @@ -1,14 +1,10 @@ error[E0506]: cannot assign to `*x` because it is borrowed --> $DIR/issue-75785-confusing-named-region.rs:9:5 | -LL | pub async fn async_fn(x: &mut i32) -> (&i32, &i32) { - | - let's call the lifetime of this reference `'1` LL | let y = &*x; | --- borrow of `*x` occurs here LL | *x += 1; | ^^^^^^^ assignment to borrowed `*x` occurs here -LL | (&32, y) - | -------- returning this value requires that `*x` is borrowed for `'1` error: aborting due to previous error diff --git a/src/test/ui/async-await/issues/issue-63388-1.stderr b/src/test/ui/async-await/issues/issue-63388-1.stderr index 8f602a1492ad2..ee270d3697965 100644 --- a/src/test/ui/async-await/issues/issue-63388-1.stderr +++ b/src/test/ui/async-await/issues/issue-63388-1.stderr @@ -2,12 +2,10 @@ error[E0623]: lifetime mismatch --> $DIR/issue-63388-1.rs:14:9 | LL | &'a self, foo: &dyn Foo - | -------- this parameter and the return type are declared with different lifetimes... -LL | ) -> &dyn Foo - | -------- -LL | { + | -------- -------- these two types are declared with different lifetimes... +... LL | foo - | ^^^ ...but data from `foo` is returned here + | ^^^ ...but data from `foo` flows into `self` here error: aborting due to previous error diff --git a/src/test/ui/async-await/issues/issue-78600.rs b/src/test/ui/async-await/issues/issue-78600.rs index 8aaeaecf3e1da..4303fc7952f2b 100644 --- a/src/test/ui/async-await/issues/issue-78600.rs +++ b/src/test/ui/async-await/issues/issue-78600.rs @@ -1,10 +1,10 @@ +// check-pass // edition:2018 struct S<'a>(&'a i32); impl<'a> S<'a> { async fn new(i: &'a i32) -> Result { - //~^ ERROR: `async fn` Ok(S(&22)) } } diff --git a/src/test/ui/async-await/issues/issue-78600.stderr b/src/test/ui/async-await/issues/issue-78600.stderr deleted file mode 100644 index 92b66147106e1..0000000000000 --- a/src/test/ui/async-await/issues/issue-78600.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0760]: `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope - --> $DIR/issue-78600.rs:6:33 - | -LL | async fn new(i: &'a i32) -> Result { - | ^^^^^^^----^^^^^ - | | - | help: consider spelling out the type instead: `S<'a>` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0760`. diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr index 149692a2c6998..6f79d9e9b5f57 100644 --- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr +++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr @@ -2,10 +2,9 @@ error[E0623]: lifetime mismatch --> $DIR/ret-impl-trait-one.rs:10:65 | LL | async fn async_ret_impl_trait3<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> + 'b { - | ------ ^^^^^^^^^^^^^^^^^^^ - | | | - | | ...but data from `a` is returned here - | this parameter and the return type are declared with different lifetimes... + | ------ ------ ^^^^^^^^^^^^^^^^^^^ ...but data from `a` flows into `b` here + | | + | these two types are declared with different lifetimes... error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds --> $DIR/ret-impl-trait-one.rs:16:65 diff --git a/src/test/ui/async-await/unused-lifetime.rs b/src/test/ui/async-await/unused-lifetime.rs index 5bd6ae8d3a42d..a0504927254b6 100644 --- a/src/test/ui/async-await/unused-lifetime.rs +++ b/src/test/ui/async-await/unused-lifetime.rs @@ -10,10 +10,13 @@ // Even wrong cases don't cause errors because async functions are desugared with all lifetimes // involved in the signature. So, we cannot predict what lifetimes are unused in async function. async fn async_wrong_without_args<'a>() {} +//~^ ERROR lifetime parameter `'a` never used [unused_lifetimes] async fn async_wrong_1_lifetime<'a>(_: &i32) {} +//~^ ERROR lifetime parameter `'a` never used [unused_lifetimes] async fn async_wrong_2_lifetimes<'a, 'b>(_: &'a i32, _: &i32) {} +//~^ ERROR lifetime parameter `'b` never used [unused_lifetimes] async fn async_right_1_lifetime<'a>(_: &'a i32) {} diff --git a/src/test/ui/async-await/unused-lifetime.stderr b/src/test/ui/async-await/unused-lifetime.stderr index 4e90f43fdd07b..85304b9cb9ef7 100644 --- a/src/test/ui/async-await/unused-lifetime.stderr +++ b/src/test/ui/async-await/unused-lifetime.stderr @@ -1,8 +1,8 @@ error: lifetime parameter `'a` never used - --> $DIR/unused-lifetime.rs:31:23 + --> $DIR/unused-lifetime.rs:12:35 | -LL | fn wrong_without_args<'a>() {} - | -^^- help: elide the unused lifetime +LL | async fn async_wrong_without_args<'a>() {} + | -^^- help: elide the unused lifetime | note: the lint level is defined here --> $DIR/unused-lifetime.rs:5:9 @@ -11,18 +11,40 @@ LL | #![deny(unused_lifetimes)] | ^^^^^^^^^^^^^^^^ error: lifetime parameter `'a` never used - --> $DIR/unused-lifetime.rs:33:21 + --> $DIR/unused-lifetime.rs:15:33 + | +LL | async fn async_wrong_1_lifetime<'a>(_: &i32) {} + | ^^----- + | | + | help: elide the unused lifetime + +error: lifetime parameter `'b` never used + --> $DIR/unused-lifetime.rs:18:38 + | +LL | async fn async_wrong_2_lifetimes<'a, 'b>(_: &'a i32, _: &i32) {} + | ^^----------------- + | | + | help: elide the unused lifetime + +error: lifetime parameter `'a` never used + --> $DIR/unused-lifetime.rs:34:23 + | +LL | fn wrong_without_args<'a>() {} + | -^^- help: elide the unused lifetime + +error: lifetime parameter `'a` never used + --> $DIR/unused-lifetime.rs:36:21 | LL | fn wrong_1_lifetime<'a>(_: &i32) {} | -^^- help: elide the unused lifetime error: lifetime parameter `'b` never used - --> $DIR/unused-lifetime.rs:35:26 + --> $DIR/unused-lifetime.rs:38:26 | LL | fn wrong_2_lifetimes<'a, 'b>(_: &'a i32, _: &i32) {} | --^^ | | | help: elide the unused lifetime -error: aborting due to 3 previous errors +error: aborting due to 6 previous errors diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr index 299a2d2f2d3de..042ae53dba13f 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr @@ -2,25 +2,25 @@ error[E0623]: lifetime mismatch --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:8:52 | LL | async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } - | ---- ---- ^ ...but data from `f` is returned here + | ---- ---- ^ ...but data from `f` flows into `self` here | | - | this parameter and the return type are declared with different lifetimes... + | these two types are declared with different lifetimes... error[E0623]: lifetime mismatch --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:11:82 | LL | async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } - | ---- ----------------- ^ ...but data from `f` is returned here + | ----- ---- ^ ...but data from `f` flows into `self` here | | - | this parameter and the return type are declared with different lifetimes... + | these two types are declared with different lifetimes... error[E0623]: lifetime mismatch --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:64 | LL | async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg } - | ------ --- ^^^ ...but data from `arg` is returned here + | ----- ------ ^^^ ...but data from `arg` flows into `self` here | | - | this parameter and the return type are declared with different lifetimes... + | these two types are declared with different lifetimes... error: aborting due to 3 previous errors diff --git a/src/test/ui/self/elision/lt-ref-self-async.stderr b/src/test/ui/self/elision/lt-ref-self-async.stderr index 7448e8484b47a..ae48467021306 100644 --- a/src/test/ui/self/elision/lt-ref-self-async.stderr +++ b/src/test/ui/self/elision/lt-ref-self-async.stderr @@ -2,61 +2,49 @@ error[E0623]: lifetime mismatch --> $DIR/lt-ref-self-async.rs:13:9 | LL | async fn ref_self(&self, f: &u32) -> &u32 { - | ---- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | ----- ---- these two types are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` flows into `self` here error[E0623]: lifetime mismatch --> $DIR/lt-ref-self-async.rs:19:9 | LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { - | ---- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | ----- ---- these two types are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` flows into `self` here error[E0623]: lifetime mismatch --> $DIR/lt-ref-self-async.rs:23:9 | LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { - | ---- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | ----- ---- these two types are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` flows into `self` here error[E0623]: lifetime mismatch --> $DIR/lt-ref-self-async.rs:27:9 | LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { - | ---- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | ----- ---- these two types are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` flows into `self` here error[E0623]: lifetime mismatch --> $DIR/lt-ref-self-async.rs:31:9 | LL | async fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { - | ---- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | ----- ---- these two types are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` flows into `self` here error[E0623]: lifetime mismatch --> $DIR/lt-ref-self-async.rs:35:9 | LL | async fn box_pin_Self(self: Box>, f: &u32) -> &u32 { - | ---- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | ----- ---- these two types are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` flows into `self` here error: aborting due to 6 previous errors diff --git a/src/test/ui/self/elision/ref-mut-self-async.stderr b/src/test/ui/self/elision/ref-mut-self-async.stderr index 6056cc46d3d8a..7b984b343d639 100644 --- a/src/test/ui/self/elision/ref-mut-self-async.stderr +++ b/src/test/ui/self/elision/ref-mut-self-async.stderr @@ -2,61 +2,49 @@ error[E0623]: lifetime mismatch --> $DIR/ref-mut-self-async.rs:13:9 | LL | async fn ref_self(&mut self, f: &u32) -> &u32 { - | ---- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | --------- ---- these two types are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` flows into `self` here error[E0623]: lifetime mismatch --> $DIR/ref-mut-self-async.rs:19:9 | LL | async fn ref_Self(self: &mut Self, f: &u32) -> &u32 { - | ---- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | --------- ---- these two types are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` flows into `self` here error[E0623]: lifetime mismatch --> $DIR/ref-mut-self-async.rs:23:9 | LL | async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 { - | ---- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | --------- ---- these two types are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` flows into `self` here error[E0623]: lifetime mismatch --> $DIR/ref-mut-self-async.rs:27:9 | LL | async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 { - | ---- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | --------- ---- these two types are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` flows into `self` here error[E0623]: lifetime mismatch --> $DIR/ref-mut-self-async.rs:31:9 | LL | async fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { - | ---- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | --------- ---- these two types are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` flows into `self` here error[E0623]: lifetime mismatch --> $DIR/ref-mut-self-async.rs:35:9 | LL | async fn box_pin_ref_Self(self: Box>, f: &u32) -> &u32 { - | ---- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | --------- ---- these two types are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` flows into `self` here error: aborting due to 6 previous errors diff --git a/src/test/ui/self/elision/ref-mut-struct-async.stderr b/src/test/ui/self/elision/ref-mut-struct-async.stderr index 61034ae4d47b6..87a144f62f643 100644 --- a/src/test/ui/self/elision/ref-mut-struct-async.stderr +++ b/src/test/ui/self/elision/ref-mut-struct-async.stderr @@ -2,51 +2,41 @@ error[E0623]: lifetime mismatch --> $DIR/ref-mut-struct-async.rs:13:9 | LL | async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 { - | ---- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | ----------- ---- these two types are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` flows into `self` here error[E0623]: lifetime mismatch --> $DIR/ref-mut-struct-async.rs:17:9 | LL | async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 { - | ---- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | ----------- ---- these two types are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` flows into `self` here error[E0623]: lifetime mismatch --> $DIR/ref-mut-struct-async.rs:21:9 | LL | async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 { - | ---- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | ----------- ---- these two types are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` flows into `self` here error[E0623]: lifetime mismatch --> $DIR/ref-mut-struct-async.rs:25:9 | LL | async fn box_box_ref_Struct(self: Box>, f: &u32) -> &u32 { - | ---- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | ----------- ---- these two types are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` flows into `self` here error[E0623]: lifetime mismatch --> $DIR/ref-mut-struct-async.rs:29:9 | LL | async fn box_pin_ref_Struct(self: Box>, f: &u32) -> &u32 { - | ---- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | ----------- ---- these two types are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` flows into `self` here error: aborting due to 5 previous errors diff --git a/src/test/ui/self/elision/ref-self-async.stderr b/src/test/ui/self/elision/ref-self-async.stderr index 0eab16e685d4c..15c20c1bc4d94 100644 --- a/src/test/ui/self/elision/ref-self-async.stderr +++ b/src/test/ui/self/elision/ref-self-async.stderr @@ -2,71 +2,57 @@ error[E0623]: lifetime mismatch --> $DIR/ref-self-async.rs:23:9 | LL | async fn ref_self(&self, f: &u32) -> &u32 { - | ---- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | ----- ---- these two types are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` flows into `self` here error[E0623]: lifetime mismatch --> $DIR/ref-self-async.rs:29:9 | LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { - | ---- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | ----- ---- these two types are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` flows into `self` here error[E0623]: lifetime mismatch --> $DIR/ref-self-async.rs:33:9 | LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { - | ---- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | ----- ---- these two types are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` flows into `self` here error[E0623]: lifetime mismatch --> $DIR/ref-self-async.rs:37:9 | LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { - | ---- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | ----- ---- these two types are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` flows into `self` here error[E0623]: lifetime mismatch --> $DIR/ref-self-async.rs:41:9 | LL | async fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { - | ---- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | ----- ---- these two types are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` flows into `self` here error[E0623]: lifetime mismatch --> $DIR/ref-self-async.rs:45:9 | LL | async fn box_pin_ref_Self(self: Box>, f: &u32) -> &u32 { - | ---- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | ----- ---- these two types are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` flows into `self` here error[E0623]: lifetime mismatch --> $DIR/ref-self-async.rs:49:9 | LL | async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 { - | --- --- - | | - | this parameter and the return type are declared with different lifetimes... + | ----- --- these two types are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` flows into `self` here error: aborting due to 7 previous errors diff --git a/src/test/ui/self/elision/ref-struct-async.stderr b/src/test/ui/self/elision/ref-struct-async.stderr index aa1d7453e83e1..f24be3b58a771 100644 --- a/src/test/ui/self/elision/ref-struct-async.stderr +++ b/src/test/ui/self/elision/ref-struct-async.stderr @@ -2,51 +2,41 @@ error[E0623]: lifetime mismatch --> $DIR/ref-struct-async.rs:13:9 | LL | async fn ref_Struct(self: &Struct, f: &u32) -> &u32 { - | ---- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | ------- ---- these two types are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` flows into `self` here error[E0623]: lifetime mismatch --> $DIR/ref-struct-async.rs:17:9 | LL | async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 { - | ---- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | ------- ---- these two types are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` flows into `self` here error[E0623]: lifetime mismatch --> $DIR/ref-struct-async.rs:21:9 | LL | async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 { - | ---- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | ------- ---- these two types are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` flows into `self` here error[E0623]: lifetime mismatch --> $DIR/ref-struct-async.rs:25:9 | LL | async fn box_box_ref_Struct(self: Box>, f: &u32) -> &u32 { - | ---- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | ------- ---- these two types are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` flows into `self` here error[E0623]: lifetime mismatch --> $DIR/ref-struct-async.rs:29:9 | LL | async fn box_pin_Struct(self: Box>, f: &u32) -> &u32 { - | ---- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | ------- ---- these two types are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` flows into `self` here error: aborting due to 5 previous errors From a3f2a326f5fe840856720b18f7764702684550f6 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 5 Dec 2021 21:33:41 +0100 Subject: [PATCH 2/5] Filter out anonymous generics in rustdoc. --- src/librustdoc/clean/mod.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index f54fb4af26133..e34faef9d6dbd 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -585,7 +585,12 @@ fn clean_ty_generics( .params .iter() .filter_map(|param| match param.kind { - ty::GenericParamDefKind::Lifetime => Some(param.clean(cx)), + ty::GenericParamDefKind::Lifetime => { + if param.name == kw::UnderscoreLifetime { + return None; + } + Some(param.clean(cx)) + } ty::GenericParamDefKind::Type { synthetic, .. } => { if param.name == kw::SelfUpper { assert_eq!(param.index, 0); From 289216f281b136e905aef7f3e825b35ff05fb422 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 28 Jan 2022 18:14:18 +0100 Subject: [PATCH 3/5] Bless clippy test. --- src/tools/clippy/tests/ui/manual_async_fn.fixed | 1 + src/tools/clippy/tests/ui/manual_async_fn.rs | 1 + src/tools/clippy/tests/ui/manual_async_fn.stderr | 2 +- src/tools/clippy/tests/ui/needless_lifetimes.stderr | 8 +++++++- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/tools/clippy/tests/ui/manual_async_fn.fixed b/src/tools/clippy/tests/ui/manual_async_fn.fixed index 136cc96be70ca..e9ca66f125d8f 100644 --- a/src/tools/clippy/tests/ui/manual_async_fn.fixed +++ b/src/tools/clippy/tests/ui/manual_async_fn.fixed @@ -80,6 +80,7 @@ fn elided_not_bound(_: &i32) -> impl Future { async { 42 } } +#[allow(clippy::needless_lifetimes)] async fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> i32 { 42 } // should be ignored diff --git a/src/tools/clippy/tests/ui/manual_async_fn.rs b/src/tools/clippy/tests/ui/manual_async_fn.rs index ddc453ffdb750..c3fa846485ba3 100644 --- a/src/tools/clippy/tests/ui/manual_async_fn.rs +++ b/src/tools/clippy/tests/ui/manual_async_fn.rs @@ -98,6 +98,7 @@ fn elided_not_bound(_: &i32) -> impl Future { async { 42 } } +#[allow(clippy::needless_lifetimes)] fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future + 'a + 'b { async { 42 } } diff --git a/src/tools/clippy/tests/ui/manual_async_fn.stderr b/src/tools/clippy/tests/ui/manual_async_fn.stderr index 7435f46074c81..b83abfccd4e12 100644 --- a/src/tools/clippy/tests/ui/manual_async_fn.stderr +++ b/src/tools/clippy/tests/ui/manual_async_fn.stderr @@ -140,7 +140,7 @@ LL | fn elided(_: &i32) -> impl Future + '_ { 42 } | ~~~~~~ error: this function can be simplified using the `async fn` syntax - --> $DIR/manual_async_fn.rs:101:1 + --> $DIR/manual_async_fn.rs:102:1 | LL | fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future + 'a + 'b { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.stderr b/src/tools/clippy/tests/ui/needless_lifetimes.stderr index ffa152427a977..8df50d79ca573 100644 --- a/src/tools/clippy/tests/ui/needless_lifetimes.stderr +++ b/src/tools/clippy/tests/ui/needless_lifetimes.stderr @@ -18,6 +18,12 @@ error: explicit lifetimes given in parameter types where they could be elided (o LL | fn in_and_out<'a>(x: &'a u8, _y: u8) -> &'a u8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration) + --> $DIR/needless_lifetimes.rs:37:1 + | +LL | async fn func<'a>(args: &[&'a str]) -> Option<&'a str> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration) --> $DIR/needless_lifetimes.rs:56:1 | @@ -192,5 +198,5 @@ error: explicit lifetimes given in parameter types where they could be elided (o LL | fn lifetime_elsewhere_provided<'a>(self: Box, here: &'a ()) -> &'a () { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 32 previous errors +error: aborting due to 33 previous errors From c6a3f5d6062f55779e52de24a6465cf87ffbdd19 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 27 Dec 2021 18:14:27 +0100 Subject: [PATCH 4/5] Update error code documentation. --- compiler/rustc_error_codes/src/error_codes/E0760.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_error_codes/src/error_codes/E0760.md b/compiler/rustc_error_codes/src/error_codes/E0760.md index e1dcfefebcd76..65acd4fabdf72 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0760.md +++ b/compiler/rustc_error_codes/src/error_codes/E0760.md @@ -1,4 +1,4 @@ -`async fn`/`impl trait` return type cannot contain a projection +`impl trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope. Erroneous code example: @@ -7,7 +7,7 @@ Erroneous code example: struct S<'a>(&'a i32); impl<'a> S<'a> { - async fn new(i: &'a i32) -> Self { + fn new(i: &'a i32) -> impl Into { S(&22) } } @@ -19,7 +19,7 @@ To fix this error we need to spell out `Self` to `S<'a>`: struct S<'a>(&'a i32); impl<'a> S<'a> { - async fn new(i: &'a i32) -> S<'a> { + fn new(i: &'a i32) -> impl Into> { S(&22) } } From 10cf626d0ea7be3eb971691772b5eb30013d4f02 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 29 Dec 2021 09:19:57 +0100 Subject: [PATCH 5/5] Bless nll tests. --- .../rustc_borrowck/src/region_infer/mod.rs | 18 ++++++++++++++++++ .../ret-impl-trait-one.nll.stderr | 18 ++++++++---------- .../dropck/drop-with-active-borrows-2.stderr | 5 ++--- src/test/ui/issues/issue-13497-2.rs | 4 ++-- src/test/ui/issues/issue-13497-2.stderr | 14 +++++--------- ...ypes_pin_lifetime_mismatch-async.nll.stderr | 5 ++--- 6 files changed, 37 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index d9120ff245735..0f0d3eaa2938b 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -2156,6 +2156,24 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } + // When in async fn, prefer errors that come from inside the closure. + if !categorized_path[i].from_closure { + let span = categorized_path.iter().find_map(|p| { + if p.from_closure + && p.category == categorized_path[i].category + && categorized_path[i].cause.span.contains(p.cause.span) + { + Some(p.cause.span) + } else { + None + } + }); + + if let Some(span) = span { + categorized_path[i].cause.span = span; + } + } + return categorized_path[i].clone(); } diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr index 2722c72c20a33..b0ea6af005004 100644 --- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr +++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr @@ -1,15 +1,13 @@ error: lifetime may not live long enough - --> $DIR/ret-impl-trait-one.rs:10:85 + --> $DIR/ret-impl-trait-one.rs:12:5 | -LL | async fn async_ret_impl_trait3<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> + 'b { - | ________________________________--__--_______________________________________________^ - | | | | - | | | lifetime `'b` defined here - | | lifetime `'a` defined here -LL | | -LL | | (a, b) -LL | | } - | |_^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` +LL | async fn async_ret_impl_trait3<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> + 'b { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | +LL | (a, b) + | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'b` diff --git a/src/test/ui/dropck/drop-with-active-borrows-2.stderr b/src/test/ui/dropck/drop-with-active-borrows-2.stderr index 24650dfac02d9..d5b747d42fb18 100644 --- a/src/test/ui/dropck/drop-with-active-borrows-2.stderr +++ b/src/test/ui/dropck/drop-with-active-borrows-2.stderr @@ -1,10 +1,9 @@ error[E0515]: cannot return value referencing local variable `raw_lines` - --> $DIR/drop-with-active-borrows-2.rs:3:5 + --> $DIR/drop-with-active-borrows-2.rs:3:30 | LL | raw_lines.iter().map(|l| l.trim()).collect() - | ----------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ---------------- ^^^^^^^^ returns a value referencing data owned by the current function | | - | returns a value referencing data owned by the current function | `raw_lines` is borrowed here error: aborting due to previous error diff --git a/src/test/ui/issues/issue-13497-2.rs b/src/test/ui/issues/issue-13497-2.rs index c82da0f0096ad..32abe2b854312 100644 --- a/src/test/ui/issues/issue-13497-2.rs +++ b/src/test/ui/issues/issue-13497-2.rs @@ -1,7 +1,7 @@ fn read_lines_borrowed<'a>() -> Vec<&'a str> { let rawLines: Vec = vec!["foo ".to_string(), " bar".to_string()]; - rawLines //~ ERROR cannot return value referencing local variable `rawLines` - .iter().map(|l| l.trim()).collect() + rawLines.iter().map(|l| l.trim()).collect() + //~^ ERROR cannot return value referencing local variable `rawLines` } fn main() {} diff --git a/src/test/ui/issues/issue-13497-2.stderr b/src/test/ui/issues/issue-13497-2.stderr index 6f72b79f2a5e0..1b78e7ec1c64d 100644 --- a/src/test/ui/issues/issue-13497-2.stderr +++ b/src/test/ui/issues/issue-13497-2.stderr @@ -1,14 +1,10 @@ error[E0515]: cannot return value referencing local variable `rawLines` - --> $DIR/issue-13497-2.rs:3:5 + --> $DIR/issue-13497-2.rs:3:29 | -LL | rawLines - | _____^ - | |_____| - | || -LL | || .iter().map(|l| l.trim()).collect() - | ||_______________-___________________________^ returns a value referencing data owned by the current function - | |________________| - | `rawLines` is borrowed here +LL | rawLines.iter().map(|l| l.trim()).collect() + | --------------- ^^^^^^^^ returns a value referencing data owned by the current function + | | + | `rawLines` is borrowed here error: aborting due to previous error diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr index 57374b7e3bb27..aaed3665149a2 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr @@ -20,9 +20,8 @@ error: lifetime may not live long enough --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:64 | LL | async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg } - | -- - ^^^ associated function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a` - | | | - | | let's call the lifetime of this reference `'1` + | -- ---- has type `Pin<&'1 Foo>` ^^^ associated function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a` + | | | lifetime `'a` defined here error: aborting due to 3 previous errors