From 64878458841d00882d1673a0b4579b4babaab91f Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Tue, 21 Dec 2021 22:08:47 +0000 Subject: [PATCH 1/3] Properly account for binders in get_impl_future_output_ty --- .../src/infer/error_reporting/mod.rs | 29 ++++++++++++------- compiler/rustc_typeck/src/check/expr.rs | 2 +- .../src/check/fn_ctxt/suggestions.rs | 18 +++++++----- .../rustc_typeck/src/check/method/suggest.rs | 2 +- 4 files changed, 31 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index e98b9c3b03c5a..75472faeebafa 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -69,7 +69,7 @@ use rustc_middle::ty::error::TypeError; use rustc_middle::ty::{ self, subst::{GenericArgKind, Subst, SubstsRef}, - Region, Ty, TyCtxt, TypeFoldable, + Binder, Region, Ty, TyCtxt, TypeFoldable, }; use rustc_span::{sym, BytePos, DesugaringKind, MultiSpan, Pos, Span}; use rustc_target::spec::abi; @@ -1765,7 +1765,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { self.note_error_origin(diag, cause, exp_found, terr); } - pub fn get_impl_future_output_ty(&self, ty: Ty<'tcx>) -> Option> { + pub fn get_impl_future_output_ty(&self, ty: Ty<'tcx>) -> Option>> { if let ty::Opaque(def_id, substs) = ty.kind() { let future_trait = self.tcx.require_lang_item(LangItem::Future, None); // Future::Output @@ -1775,13 +1775,20 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { for (predicate, _) in bounds { let predicate = predicate.subst(self.tcx, substs); - if let ty::PredicateKind::Projection(projection_predicate) = - predicate.kind().skip_binder() - { - if projection_predicate.projection_ty.item_def_id == item_def_id { - // We don't account for multiple `Future::Output = Ty` contraints. - return projection_predicate.term.ty(); - } + let output = predicate + .kind() + .map_bound(|kind| match kind { + ty::PredicateKind::Projection(projection_predicate) + if projection_predicate.projection_ty.item_def_id == item_def_id => + { + projection_predicate.term.ty() + } + _ => None, + }) + .transpose(); + if output.is_some() { + // We don't account for multiple `Future::Output = Ty` contraints. + return output; } } } @@ -1823,8 +1830,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } match ( - self.get_impl_future_output_ty(exp_found.expected), - self.get_impl_future_output_ty(exp_found.found), + self.get_impl_future_output_ty(exp_found.expected).map(Binder::skip_binder), + self.get_impl_future_output_ty(exp_found.found).map(Binder::skip_binder), ) { (Some(exp), Some(found)) if same_type_modulo_infer(exp, found) => match cause.code() { ObligationCauseCode::IfExpression(box IfExpressionCause { then, .. }) => { diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 3e73cc659ec46..f6abeff60cd94 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -1909,7 +1909,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => return, }; let mut add_label = true; - if let ty::Adt(def, _) = output_ty.kind() { + if let ty::Adt(def, _) = output_ty.skip_binder().kind() { // no field access on enum type if !def.is_enum() { if def diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs index 473c848ad8f13..be4c9ec99b9c6 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs @@ -609,14 +609,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = self.tcx.erase_late_bound_regions(Binder::bind_with_vars(ty, bound_vars)); let ty = self.normalize_associated_types_in(expr.span, ty); let ty = match self.tcx.asyncness(fn_id.owner) { - hir::IsAsync::Async => self.tcx.infer_ctxt().enter(|infcx| { - infcx.get_impl_future_output_ty(ty).unwrap_or_else(|| { - span_bug!( - fn_decl.output.span(), - "failed to get output type of async function" - ) + hir::IsAsync::Async => self + .tcx + .infer_ctxt() + .enter(|infcx| { + infcx.get_impl_future_output_ty(ty).unwrap_or_else(|| { + span_bug!( + fn_decl.output.span(), + "failed to get output type of async function" + ) + }) }) - }), + .skip_binder(), hir::IsAsync::NotAsync => ty, }; if self.can_coerce(found, ty) { diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 56f4d5afe400d..96ab800afaffe 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -1274,7 +1274,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: Span, ) { let output_ty = match self.infcx.get_impl_future_output_ty(ty) { - Some(output_ty) => self.resolve_vars_if_possible(output_ty), + Some(output_ty) => self.resolve_vars_if_possible(output_ty).skip_binder(), _ => return, }; let method_exists = self.method_exists(item_name, output_ty, call.hir_id, true); From 5c15ad7fca5140362fe459d7c72661ea59a66b10 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Sat, 20 Nov 2021 02:48:29 +0000 Subject: [PATCH 2/3] NiceRegionError: Use written return type for async fn --- compiler/rustc_hir/src/hir.rs | 15 ++++- .../src/infer/error_reporting/mod.rs | 2 +- .../nice_region_error/different_lifetimes.rs | 1 + .../nice_region_error/find_anon_type.rs | 19 ++----- .../error_reporting/nice_region_error/util.rs | 37 ++++++++---- src/test/ui/async-await/issue-76547.stderr | 14 ++--- .../async-await/issues/issue-63388-1.stderr | 2 +- ...f_types_pin_lifetime_mismatch-async.stderr | 24 ++++---- .../ui/self/elision/lt-ref-self-async.stderr | 48 ++++++++-------- .../ui/self/elision/ref-mut-self-async.stderr | 48 ++++++++-------- .../self/elision/ref-mut-struct-async.stderr | 40 ++++++------- .../ui/self/elision/ref-self-async.stderr | 56 +++++++++---------- .../ui/self/elision/ref-struct-async.stderr | 40 ++++++------- 13 files changed, 181 insertions(+), 165 deletions(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 43aa0ae265a09..a9dbdd483fe6f 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2726,6 +2726,10 @@ pub struct FnHeader { } impl FnHeader { + pub fn is_async(&self) -> bool { + matches!(&self.asyncness, IsAsync::Async) + } + pub fn is_const(&self) -> bool { matches!(&self.constness, Constness::Const) } @@ -3169,7 +3173,7 @@ impl<'hir> Node<'hir> { } } - pub fn fn_decl(&self) -> Option<&FnDecl<'hir>> { + pub fn fn_decl(&self) -> Option<&'hir FnDecl<'hir>> { match self { Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. }) | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. }) @@ -3181,6 +3185,15 @@ impl<'hir> Node<'hir> { } } + pub fn fn_sig(&self) -> Option<&'hir FnSig<'hir>> { + match self { + Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. }) + | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. }) + | Node::Item(Item { kind: ItemKind::Fn(fn_sig, _, _), .. }) => Some(fn_sig), + _ => None, + } + } + pub fn body_id(&self) -> Option { match self { Node::TraitItem(TraitItem { diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 75472faeebafa..14ab635a2ae2b 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -65,9 +65,9 @@ use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; use rustc_hir::{Item, ItemKind, Node}; use rustc_middle::dep_graph::DepContext; -use rustc_middle::ty::error::TypeError; use rustc_middle::ty::{ self, + error::TypeError, subst::{GenericArgKind, Subst, SubstsRef}, Binder, Region, Ty, TyCtxt, TypeFoldable, }; diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs index ac57796763fb3..5d33d2b4f9b06 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs @@ -171,6 +171,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { self.suggest_adding_lifetime_params(sub, ty_sup, ty_sub, &mut err); + // TODO: This is only helpful if the lifetime more visible in the impl Future type than in the signature. if let Some(t) = future_return_type { let snip = self .tcx() diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs index 07bba00056630..b1535701bb399 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs @@ -1,6 +1,5 @@ use rustc_hir as hir; use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir::Node; use rustc_middle::hir::map::Map; use rustc_middle::hir::nested_filter; use rustc_middle::middle::resolve_lifetime as rl; @@ -25,25 +24,19 @@ pub(crate) fn find_anon_type<'tcx>( tcx: TyCtxt<'tcx>, region: Region<'tcx>, br: &ty::BoundRegionKind, -) -> Option<(&'tcx hir::Ty<'tcx>, &'tcx hir::FnDecl<'tcx>)> { +) -> Option<(&'tcx hir::Ty<'tcx>, &'tcx hir::FnSig<'tcx>)> { if let Some(anon_reg) = tcx.is_suitable_region(region) { let hir_id = tcx.hir().local_def_id_to_hir_id(anon_reg.def_id); - let fndecl = match tcx.hir().get(hir_id) { - Node::Item(&hir::Item { kind: hir::ItemKind::Fn(ref m, ..), .. }) - | Node::TraitItem(&hir::TraitItem { - kind: hir::TraitItemKind::Fn(ref m, ..), .. - }) - | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(ref m, ..), .. }) => { - &m.decl - } - _ => return None, + let Some(fn_sig) = tcx.hir().get(hir_id).fn_sig() else { + return None }; - fndecl + fn_sig + .decl .inputs .iter() .find_map(|arg| find_component_for_bound_region(tcx, arg, br)) - .map(|ty| (ty, &**fndecl)) + .map(|ty| (ty, fn_sig)) } else { None } diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs index 3fa71d1a3d817..3e87f97f496b8 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs @@ -4,7 +4,7 @@ use crate::infer::error_reporting::nice_region_error::NiceRegionError; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; -use rustc_middle::ty::{self, DefIdTree, Region, Ty}; +use rustc_middle::ty::{self, Binder, DefIdTree, Region, Ty, TypeFoldable}; use rustc_span::Span; /// Information about the anonymous region we are searching for. @@ -149,26 +149,41 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { } // Here, we check for the case where the anonymous region - // is in the return type. + // is in the return type as written by the user. // FIXME(#42703) - Need to handle certain cases here. pub(super) fn is_return_type_anon( &self, scope_def_id: LocalDefId, br: ty::BoundRegionKind, - decl: &hir::FnDecl<'_>, + hir_sig: &hir::FnSig<'_>, ) -> Option { - let ret_ty = self.tcx().type_of(scope_def_id); - if let ty::FnDef(_, _) = ret_ty.kind() { - let sig = ret_ty.fn_sig(self.tcx()); - let late_bound_regions = - self.tcx().collect_referenced_late_bound_regions(&sig.output()); - if late_bound_regions.iter().any(|r| *r == br) { - return Some(decl.output.span()); - } + let fn_ty = self.tcx().type_of(scope_def_id); + if let ty::FnDef(_, _) = fn_ty.kind() { + let ret_ty = fn_ty.fn_sig(self.tcx()).output(); + let span = hir_sig.decl.output.span(); + let future_output = if hir_sig.header.is_async() { + ret_ty.map_bound(|ty| self.infcx.get_impl_future_output_ty(ty)).transpose() + } else { + None + }; + return match future_output { + Some(output) if self.includes_region(output, br) => Some(span), + None if self.includes_region(ret_ty, br) => Some(span), + _ => None, + }; } None } + fn includes_region( + &self, + ty: Binder<'tcx, impl TypeFoldable<'tcx>>, + region: ty::BoundRegionKind, + ) -> bool { + let late_bound_regions = self.tcx().collect_referenced_late_bound_regions(&ty); + late_bound_regions.iter().any(|r| *r == region) + } + // Here we check for the case where anonymous region // corresponds to self and if yes, we display E0312. // FIXME(#42700) - Need to format self properly to diff --git a/src/test/ui/async-await/issue-76547.stderr b/src/test/ui/async-await/issue-76547.stderr index 9bfb0f28028cb..ac5f99970c814 100644 --- a/src/test/ui/async-await/issue-76547.stderr +++ b/src/test/ui/async-await/issue-76547.stderr @@ -2,23 +2,17 @@ error[E0623]: lifetime mismatch --> $DIR/issue-76547.rs:20:13 | LL | async fn fut(bufs: &mut [&mut [u8]]) { - | --------- - - | | | - | | this `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ---------------- these two types are declared with different lifetimes... LL | ListFut(bufs).await - | ^^^^ ...but data from `bufs` is held across an await point here + | ^^^^ ...but data from `bufs` flows into `bufs` here error[E0623]: lifetime mismatch --> $DIR/issue-76547.rs:34:14 | LL | async fn fut2(bufs: &mut [&mut [u8]]) -> i32 { - | --------- --- - | | | - | | this `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ---------------- these two types are declared with different lifetimes... LL | ListFut2(bufs).await - | ^^^^ ...but data from `bufs` is held across an await point here + | ^^^^ ...but data from `bufs` flows into `bufs` here error: aborting due to 2 previous errors 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 ac29cca9d3f60..32ca7afd82d8b 100644 --- a/src/test/ui/async-await/issues/issue-63388-1.stderr +++ b/src/test/ui/async-await/issues/issue-63388-1.stderr @@ -2,7 +2,7 @@ error[E0623]: lifetime mismatch --> $DIR/issue-63388-1.rs:14:9 | LL | &'a self, foo: &dyn Foo - | -------- this parameter and the returned future are declared with different lifetimes... + | -------- this parameter and the returned future are declared with different lifetimes... LL | ) -> &dyn Foo | -------- | | 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 e6846fb40494f..6986cd1a5fdac 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,28 +2,28 @@ 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 held across an await point here - | | | - | | this `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ---- ---- ^ ...but data from `f` is held across an await point here + | | | + | | this `async fn` implicitly returns an `impl Future` + | this parameter and the returned future 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 held across an await point here - | | | - | | this `async fn` implicitly returns an `impl Future, &Foo)>` - | this parameter and the returned future are declared with different lifetimes... + | ---- ----------------- ^ ...but data from `f` is held across an await point here + | | | + | | this `async fn` implicitly returns an `impl Future, &Foo)>` + | this parameter and the returned future 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 held across an await point here - | | | - | | this `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ------ --- ^^^ ...but data from `arg` is held across an await point here + | | | + | | this `async fn` implicitly returns an `impl Future` + | this parameter and the returned future 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 3221d27085096..d65a6ade03733 100644 --- a/src/test/ui/self/elision/lt-ref-self-async.stderr +++ b/src/test/ui/self/elision/lt-ref-self-async.stderr @@ -2,10 +2,10 @@ error[E0623]: lifetime mismatch --> $DIR/lt-ref-self-async.rs:13:9 | LL | async fn ref_self(&self, f: &u32) -> &u32 { - | ----- ---- - | | | - | | this `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ---- ---- + | | | + | | this `async fn` implicitly returns an `impl Future` + | this parameter and the returned future are declared with different lifetimes... LL | f | ^ ...but data from `f` is held across an await point here @@ -13,10 +13,10 @@ error[E0623]: lifetime mismatch --> $DIR/lt-ref-self-async.rs:19:9 | LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { - | ----- ---- - | | | - | | this `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ---- ---- + | | | + | | this `async fn` implicitly returns an `impl Future` + | this parameter and the returned future are declared with different lifetimes... LL | f | ^ ...but data from `f` is held across an await point here @@ -24,10 +24,10 @@ 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ---- ---- + | | | + | | this `async fn` implicitly returns an `impl Future` + | this parameter and the returned future are declared with different lifetimes... LL | f | ^ ...but data from `f` is held across an await point here @@ -35,10 +35,10 @@ 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ---- ---- + | | | + | | this `async fn` implicitly returns an `impl Future` + | this parameter and the returned future are declared with different lifetimes... LL | f | ^ ...but data from `f` is held across an await point here @@ -46,10 +46,10 @@ 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ---- ---- + | | | + | | this `async fn` implicitly returns an `impl Future` + | this parameter and the returned future are declared with different lifetimes... LL | f | ^ ...but data from `f` is held across an await point here @@ -57,10 +57,10 @@ error[E0623]: lifetime mismatch --> $DIR/lt-ref-self-async.rs:35:9 | LL | async fn box_pin_Self(self: Box>, f: &u32) -> &u32 { - | ----- ---- - | | | - | | this `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ---- ---- + | | | + | | this `async fn` implicitly returns an `impl Future` + | this parameter and the returned future are declared with different lifetimes... LL | f | ^ ...but data from `f` is held across an await point here 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 b6ca986923d2e..c4f7b7eb625ea 100644 --- a/src/test/ui/self/elision/ref-mut-self-async.stderr +++ b/src/test/ui/self/elision/ref-mut-self-async.stderr @@ -2,10 +2,10 @@ error[E0623]: lifetime mismatch --> $DIR/ref-mut-self-async.rs:13:9 | LL | async fn ref_self(&mut self, f: &u32) -> &u32 { - | --------- ---- - | | | - | | this `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ---- ---- + | | | + | | this `async fn` implicitly returns an `impl Future` + | this parameter and the returned future are declared with different lifetimes... LL | f | ^ ...but data from `f` is held across an await point here @@ -13,10 +13,10 @@ error[E0623]: lifetime mismatch --> $DIR/ref-mut-self-async.rs:19:9 | LL | async fn ref_Self(self: &mut Self, f: &u32) -> &u32 { - | --------- ---- - | | | - | | this `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ---- ---- + | | | + | | this `async fn` implicitly returns an `impl Future` + | this parameter and the returned future are declared with different lifetimes... LL | f | ^ ...but data from `f` is held across an await point here @@ -24,10 +24,10 @@ 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ---- ---- + | | | + | | this `async fn` implicitly returns an `impl Future` + | this parameter and the returned future are declared with different lifetimes... LL | f | ^ ...but data from `f` is held across an await point here @@ -35,10 +35,10 @@ 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ---- ---- + | | | + | | this `async fn` implicitly returns an `impl Future` + | this parameter and the returned future are declared with different lifetimes... LL | f | ^ ...but data from `f` is held across an await point here @@ -46,10 +46,10 @@ 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ---- ---- + | | | + | | this `async fn` implicitly returns an `impl Future` + | this parameter and the returned future are declared with different lifetimes... LL | f | ^ ...but data from `f` is held across an await point here @@ -57,10 +57,10 @@ 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ---- ---- + | | | + | | this `async fn` implicitly returns an `impl Future` + | this parameter and the returned future are declared with different lifetimes... LL | f | ^ ...but data from `f` is held across an await point here 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 eda15d76390b6..6c5edcb2b366e 100644 --- a/src/test/ui/self/elision/ref-mut-struct-async.stderr +++ b/src/test/ui/self/elision/ref-mut-struct-async.stderr @@ -2,10 +2,10 @@ error[E0623]: lifetime mismatch --> $DIR/ref-mut-struct-async.rs:13:9 | LL | async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 { - | ----------- ---- - | | | - | | this `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ---- ---- + | | | + | | this `async fn` implicitly returns an `impl Future` + | this parameter and the returned future are declared with different lifetimes... LL | f | ^ ...but data from `f` is held across an await point here @@ -13,10 +13,10 @@ 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ---- ---- + | | | + | | this `async fn` implicitly returns an `impl Future` + | this parameter and the returned future are declared with different lifetimes... LL | f | ^ ...but data from `f` is held across an await point here @@ -24,10 +24,10 @@ 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ---- ---- + | | | + | | this `async fn` implicitly returns an `impl Future` + | this parameter and the returned future are declared with different lifetimes... LL | f | ^ ...but data from `f` is held across an await point here @@ -35,10 +35,10 @@ 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ---- ---- + | | | + | | this `async fn` implicitly returns an `impl Future` + | this parameter and the returned future are declared with different lifetimes... LL | f | ^ ...but data from `f` is held across an await point here @@ -46,10 +46,10 @@ 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ---- ---- + | | | + | | this `async fn` implicitly returns an `impl Future` + | this parameter and the returned future are declared with different lifetimes... LL | f | ^ ...but data from `f` is held across an await point here diff --git a/src/test/ui/self/elision/ref-self-async.stderr b/src/test/ui/self/elision/ref-self-async.stderr index b42caa88c6fef..fef346b4d2a6e 100644 --- a/src/test/ui/self/elision/ref-self-async.stderr +++ b/src/test/ui/self/elision/ref-self-async.stderr @@ -2,10 +2,10 @@ error[E0623]: lifetime mismatch --> $DIR/ref-self-async.rs:23:9 | LL | async fn ref_self(&self, f: &u32) -> &u32 { - | ----- ---- - | | | - | | this `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ---- ---- + | | | + | | this `async fn` implicitly returns an `impl Future` + | this parameter and the returned future are declared with different lifetimes... LL | f | ^ ...but data from `f` is held across an await point here @@ -13,10 +13,10 @@ error[E0623]: lifetime mismatch --> $DIR/ref-self-async.rs:29:9 | LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { - | ----- ---- - | | | - | | this `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ---- ---- + | | | + | | this `async fn` implicitly returns an `impl Future` + | this parameter and the returned future are declared with different lifetimes... LL | f | ^ ...but data from `f` is held across an await point here @@ -24,10 +24,10 @@ error[E0623]: lifetime mismatch --> $DIR/ref-self-async.rs:33:9 | LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { - | ----- ---- - | | | - | | this `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ---- ---- + | | | + | | this `async fn` implicitly returns an `impl Future` + | this parameter and the returned future are declared with different lifetimes... LL | f | ^ ...but data from `f` is held across an await point here @@ -35,10 +35,10 @@ error[E0623]: lifetime mismatch --> $DIR/ref-self-async.rs:37:9 | LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { - | ----- ---- - | | | - | | this `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ---- ---- + | | | + | | this `async fn` implicitly returns an `impl Future` + | this parameter and the returned future are declared with different lifetimes... LL | f | ^ ...but data from `f` is held across an await point here @@ -46,10 +46,10 @@ error[E0623]: lifetime mismatch --> $DIR/ref-self-async.rs:41:9 | LL | async fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { - | ----- ---- - | | | - | | this `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ---- ---- + | | | + | | this `async fn` implicitly returns an `impl Future` + | this parameter and the returned future are declared with different lifetimes... LL | f | ^ ...but data from `f` is held across an await point here @@ -57,10 +57,10 @@ error[E0623]: lifetime mismatch --> $DIR/ref-self-async.rs:45:9 | LL | async fn box_pin_ref_Self(self: Box>, f: &u32) -> &u32 { - | ----- ---- - | | | - | | this `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ---- ---- + | | | + | | this `async fn` implicitly returns an `impl Future` + | this parameter and the returned future are declared with different lifetimes... LL | f | ^ ...but data from `f` is held across an await point here @@ -68,10 +68,10 @@ 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | --- --- + | | | + | | this `async fn` implicitly returns an `impl Future` + | this parameter and the returned future are declared with different lifetimes... LL | f | ^ ...but data from `f` is held across an await point here diff --git a/src/test/ui/self/elision/ref-struct-async.stderr b/src/test/ui/self/elision/ref-struct-async.stderr index 599becd308062..cc269c0e7aad5 100644 --- a/src/test/ui/self/elision/ref-struct-async.stderr +++ b/src/test/ui/self/elision/ref-struct-async.stderr @@ -2,10 +2,10 @@ error[E0623]: lifetime mismatch --> $DIR/ref-struct-async.rs:13:9 | LL | async fn ref_Struct(self: &Struct, f: &u32) -> &u32 { - | ------- ---- - | | | - | | this `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ---- ---- + | | | + | | this `async fn` implicitly returns an `impl Future` + | this parameter and the returned future are declared with different lifetimes... LL | f | ^ ...but data from `f` is held across an await point here @@ -13,10 +13,10 @@ error[E0623]: lifetime mismatch --> $DIR/ref-struct-async.rs:17:9 | LL | async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 { - | ------- ---- - | | | - | | this `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ---- ---- + | | | + | | this `async fn` implicitly returns an `impl Future` + | this parameter and the returned future are declared with different lifetimes... LL | f | ^ ...but data from `f` is held across an await point here @@ -24,10 +24,10 @@ error[E0623]: lifetime mismatch --> $DIR/ref-struct-async.rs:21:9 | LL | async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 { - | ------- ---- - | | | - | | this `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ---- ---- + | | | + | | this `async fn` implicitly returns an `impl Future` + | this parameter and the returned future are declared with different lifetimes... LL | f | ^ ...but data from `f` is held across an await point here @@ -35,10 +35,10 @@ error[E0623]: lifetime mismatch --> $DIR/ref-struct-async.rs:25:9 | LL | async fn box_box_ref_Struct(self: Box>, f: &u32) -> &u32 { - | ------- ---- - | | | - | | this `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ---- ---- + | | | + | | this `async fn` implicitly returns an `impl Future` + | this parameter and the returned future are declared with different lifetimes... LL | f | ^ ...but data from `f` is held across an await point here @@ -46,10 +46,10 @@ error[E0623]: lifetime mismatch --> $DIR/ref-struct-async.rs:29:9 | LL | async fn box_pin_Struct(self: Box>, f: &u32) -> &u32 { - | ------- ---- - | | | - | | this `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ---- ---- + | | | + | | this `async fn` implicitly returns an `impl Future` + | this parameter and the returned future are declared with different lifetimes... LL | f | ^ ...but data from `f` is held across an await point here From 698631e16c390c29bacc778e35aba1dc27bed57f Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Fri, 10 Dec 2021 00:01:05 +0000 Subject: [PATCH 3/3] Simplify error reporting code, remove await point wording --- .../nice_region_error/different_lifetimes.rs | 110 ++++++------------ .../error_reporting/nice_region_error/util.rs | 54 --------- .../async-await/issues/issue-63388-1.stderr | 6 +- .../ret-impl-trait-one.stderr | 5 +- ...f_types_pin_lifetime_mismatch-async.stderr | 21 ++-- .../ui/self/elision/lt-ref-self-async.stderr | 42 +++---- .../ui/self/elision/ref-mut-self-async.stderr | 42 +++---- .../self/elision/ref-mut-struct-async.stderr | 35 +++--- .../ui/self/elision/ref-self-async.stderr | 49 ++++---- .../ui/self/elision/ref-struct-async.stderr | 35 +++--- 10 files changed, 133 insertions(+), 266 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs index 5d33d2b4f9b06..4eec492b3aeb9 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs @@ -106,91 +106,47 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { None => String::new(), }; - let (span_1, span_2, main_label, span_label, future_return_type) = - match (sup_is_ret_type, sub_is_ret_type) { - (None, None) => { - let (main_label_1, span_label_1) = if ty_sup.hir_id == ty_sub.hir_id { - ( - "this type is declared with multiple lifetimes...".to_owned(), - "...but data with one lifetime flows into the other here".to_owned(), - ) - } else { - ( - "these two types are declared with different lifetimes...".to_owned(), - format!("...but data{} flows{} here", span_label_var1, span_label_var2), - ) - }; - (ty_sup.span, ty_sub.span, main_label_1, span_label_1, None) - } + debug!( + "try_report_anon_anon_conflict: sub_is_ret_type={:?} sup_is_ret_type={:?}", + sub_is_ret_type, sup_is_ret_type + ); - (Some(ret_span), _) => { - let sup_future = self.future_return_type(scope_def_id_sup); - let (return_type, action) = if sup_future.is_some() { - ("returned future", "held across an await point") - } else { - ("return type", "returned") - }; + let mut err = struct_span_err!(self.tcx().sess, span, E0623, "lifetime mismatch"); - ( - ty_sub.span, - ret_span, - format!( - "this parameter and the {} are declared with different lifetimes...", - return_type - ), - format!("...but data{} is {} here", span_label_var1, action), - sup_future, - ) - } - (_, Some(ret_span)) => { - let sub_future = self.future_return_type(scope_def_id_sub); - let (return_type, action) = if sub_future.is_some() { - ("returned future", "held across an await point") - } else { - ("return type", "returned") - }; + match (sup_is_ret_type, sub_is_ret_type) { + (ret_capture @ Some(ret_span), _) | (_, ret_capture @ Some(ret_span)) => { + let param_span = + if sup_is_ret_type == ret_capture { ty_sub.span } else { ty_sup.span }; + + err.span_label( + param_span, + "this parameter and the return type are declared with different lifetimes...", + ); + err.span_label(ret_span, ""); + err.span_label(span, format!("...but data{} is returned here", span_label_var1)); + } - ( + (None, None) => { + if ty_sup.hir_id == ty_sub.hir_id { + err.span_label(ty_sup.span, "this type is declared with multiple lifetimes..."); + err.span_label(ty_sub.span, ""); + err.span_label(span, "...but data with one lifetime flows into the other here"); + } else { + err.span_label( ty_sup.span, - ret_span, - format!( - "this parameter and the {} are declared with different lifetimes...", - return_type - ), - format!("...but data{} is {} here", span_label_var1, action), - sub_future, - ) + "these two types are declared with different lifetimes...", + ); + err.span_label(ty_sub.span, ""); + err.span_label( + span, + format!("...but data{} flows{} here", span_label_var1, span_label_var2), + ); } - }; - - let mut err = struct_span_err!(self.tcx().sess, span, E0623, "lifetime mismatch"); - - err.span_label(span_1, main_label); - err.span_label(span_2, String::new()); - err.span_label(span, span_label); + } + } self.suggest_adding_lifetime_params(sub, ty_sup, ty_sub, &mut err); - // TODO: This is only helpful if the lifetime more visible in the impl Future type than in the signature. - if let Some(t) = future_return_type { - let snip = self - .tcx() - .sess - .source_map() - .span_to_snippet(t.span) - .ok() - .and_then(|s| match (&t.kind, s.as_str()) { - (rustc_hir::TyKind::Tup(&[]), "") => Some("()".to_string()), - (_, "") => None, - _ => Some(s), - }) - .unwrap_or_else(|| "{unnamed_type}".to_string()); - - err.span_label( - t.span, - &format!("this `async fn` implicitly returns an `impl Future`", snip), - ); - } err.emit(); Some(ErrorReported) } diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs index 3e87f97f496b8..6d71d702cc89b 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs @@ -94,60 +94,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { }) } - pub(super) fn future_return_type( - &self, - local_def_id: LocalDefId, - ) -> Option<&rustc_hir::Ty<'_>> { - if let Some(hir::IsAsync::Async) = self.asyncness(local_def_id) { - if let rustc_middle::ty::Opaque(def_id, _) = - self.tcx().type_of(local_def_id).fn_sig(self.tcx()).output().skip_binder().kind() - { - match self.tcx().hir().get_if_local(*def_id) { - Some(hir::Node::Item(hir::Item { - kind: - hir::ItemKind::OpaqueTy(hir::OpaqueTy { - bounds, - origin: hir::OpaqueTyOrigin::AsyncFn(..), - .. - }), - .. - })) => { - for b in bounds.iter() { - if let hir::GenericBound::LangItemTrait( - hir::LangItem::Future, - _span, - _hir_id, - generic_args, - ) = b - { - for type_binding in generic_args.bindings.iter() { - if type_binding.ident.name == rustc_span::sym::Output { - if let hir::TypeBindingKind::Equality { - term: hir::Term::Ty(ty), - } = type_binding.kind - { - return Some(ty); - } - } - } - } - } - } - _ => {} - } - } - } - None - } - - pub(super) fn asyncness(&self, local_def_id: LocalDefId) -> Option { - // similar to the asyncness fn in rustc_ty_utils::ty - let hir_id = self.tcx().hir().local_def_id_to_hir_id(local_def_id); - let node = self.tcx().hir().get(hir_id); - let fn_kind = node.fn_kind()?; - Some(fn_kind.asyncness()) - } - // Here, we check for the case where the anonymous region // is in the return type as written by the user. // FIXME(#42703) - Need to handle certain cases here. 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 32ca7afd82d8b..8f602a1492ad2 100644 --- a/src/test/ui/async-await/issues/issue-63388-1.stderr +++ b/src/test/ui/async-await/issues/issue-63388-1.stderr @@ -2,14 +2,12 @@ error[E0623]: lifetime mismatch --> $DIR/issue-63388-1.rs:14:9 | LL | &'a self, foo: &dyn Foo - | -------- this parameter and the returned future are declared with different lifetimes... + | -------- this parameter and the return type are declared with different lifetimes... LL | ) -> &dyn Foo | -------- - | | - | this `async fn` implicitly returns an `impl Future` LL | { LL | foo - | ^^^ ...but data from `foo` is held across an await point here + | ^^^ ...but data from `foo` is returned here error: aborting due to previous error 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 464f283095dad..149692a2c6998 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 @@ -4,9 +4,8 @@ error[E0623]: lifetime mismatch LL | async fn async_ret_impl_trait3<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> + 'b { | ------ ^^^^^^^^^^^^^^^^^^^ | | | - | | ...but data from `a` is held across an await point here - | | this `async fn` implicitly returns an `impl Future + 'b>` - | this parameter and the returned future are declared with different lifetimes... + | | ...but data from `a` is returned here + | this parameter and the return type 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/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr index 6986cd1a5fdac..299a2d2f2d3de 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,28 +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 held across an await point here - | | | - | | this `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ---- ---- ^ ...but data from `f` is returned here + | | + | this parameter and the return type 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 held across an await point here - | | | - | | this `async fn` implicitly returns an `impl Future, &Foo)>` - | this parameter and the returned future are declared with different lifetimes... + | ---- ----------------- ^ ...but data from `f` is returned here + | | + | this parameter and the return type 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 held across an await point here - | | | - | | this `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | ------ --- ^^^ ...but data from `arg` is returned here + | | + | this parameter and the return type 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 d65a6ade03733..7448e8484b47a 100644 --- a/src/test/ui/self/elision/lt-ref-self-async.stderr +++ b/src/test/ui/self/elision/lt-ref-self-async.stderr @@ -3,66 +3,60 @@ error[E0623]: lifetime mismatch | LL | async fn ref_self(&self, f: &u32) -> &u32 { | ---- ---- - | | | - | | this `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | | + | this parameter and the return type are declared with different lifetimes... LL | f - | ^ ...but data from `f` is held across an await point here + | ^ ...but data from `f` is returned here error[E0623]: lifetime mismatch --> $DIR/lt-ref-self-async.rs:19:9 | LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { | ---- ---- - | | | - | | this `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | | + | this parameter and the return type are declared with different lifetimes... LL | f - | ^ ...but data from `f` is held across an await point here + | ^ ...but data from `f` is returned 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | | + | this parameter and the return type are declared with different lifetimes... LL | f - | ^ ...but data from `f` is held across an await point here + | ^ ...but data from `f` is returned 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | | + | this parameter and the return type are declared with different lifetimes... LL | f - | ^ ...but data from `f` is held across an await point here + | ^ ...but data from `f` is returned 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | | + | this parameter and the return type are declared with different lifetimes... LL | f - | ^ ...but data from `f` is held across an await point here + | ^ ...but data from `f` is returned 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | | + | this parameter and the return type are declared with different lifetimes... LL | f - | ^ ...but data from `f` is held across an await point here + | ^ ...but data from `f` is returned 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 c4f7b7eb625ea..6056cc46d3d8a 100644 --- a/src/test/ui/self/elision/ref-mut-self-async.stderr +++ b/src/test/ui/self/elision/ref-mut-self-async.stderr @@ -3,66 +3,60 @@ error[E0623]: lifetime mismatch | LL | async fn ref_self(&mut self, f: &u32) -> &u32 { | ---- ---- - | | | - | | this `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | | + | this parameter and the return type are declared with different lifetimes... LL | f - | ^ ...but data from `f` is held across an await point here + | ^ ...but data from `f` is returned 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | | + | this parameter and the return type are declared with different lifetimes... LL | f - | ^ ...but data from `f` is held across an await point here + | ^ ...but data from `f` is returned 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | | + | this parameter and the return type are declared with different lifetimes... LL | f - | ^ ...but data from `f` is held across an await point here + | ^ ...but data from `f` is returned 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | | + | this parameter and the return type are declared with different lifetimes... LL | f - | ^ ...but data from `f` is held across an await point here + | ^ ...but data from `f` is returned 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | | + | this parameter and the return type are declared with different lifetimes... LL | f - | ^ ...but data from `f` is held across an await point here + | ^ ...but data from `f` is returned 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | | + | this parameter and the return type are declared with different lifetimes... LL | f - | ^ ...but data from `f` is held across an await point here + | ^ ...but data from `f` is returned 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 6c5edcb2b366e..61034ae4d47b6 100644 --- a/src/test/ui/self/elision/ref-mut-struct-async.stderr +++ b/src/test/ui/self/elision/ref-mut-struct-async.stderr @@ -3,55 +3,50 @@ error[E0623]: lifetime mismatch | LL | async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 { | ---- ---- - | | | - | | this `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | | + | this parameter and the return type are declared with different lifetimes... LL | f - | ^ ...but data from `f` is held across an await point here + | ^ ...but data from `f` is returned 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | | + | this parameter and the return type are declared with different lifetimes... LL | f - | ^ ...but data from `f` is held across an await point here + | ^ ...but data from `f` is returned 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | | + | this parameter and the return type are declared with different lifetimes... LL | f - | ^ ...but data from `f` is held across an await point here + | ^ ...but data from `f` is returned 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | | + | this parameter and the return type are declared with different lifetimes... LL | f - | ^ ...but data from `f` is held across an await point here + | ^ ...but data from `f` is returned 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | | + | this parameter and the return type are declared with different lifetimes... LL | f - | ^ ...but data from `f` is held across an await point here + | ^ ...but data from `f` is returned 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 fef346b4d2a6e..0eab16e685d4c 100644 --- a/src/test/ui/self/elision/ref-self-async.stderr +++ b/src/test/ui/self/elision/ref-self-async.stderr @@ -3,77 +3,70 @@ error[E0623]: lifetime mismatch | LL | async fn ref_self(&self, f: &u32) -> &u32 { | ---- ---- - | | | - | | this `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | | + | this parameter and the return type are declared with different lifetimes... LL | f - | ^ ...but data from `f` is held across an await point here + | ^ ...but data from `f` is returned here error[E0623]: lifetime mismatch --> $DIR/ref-self-async.rs:29:9 | LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { | ---- ---- - | | | - | | this `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | | + | this parameter and the return type are declared with different lifetimes... LL | f - | ^ ...but data from `f` is held across an await point here + | ^ ...but data from `f` is returned 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | | + | this parameter and the return type are declared with different lifetimes... LL | f - | ^ ...but data from `f` is held across an await point here + | ^ ...but data from `f` is returned 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | | + | this parameter and the return type are declared with different lifetimes... LL | f - | ^ ...but data from `f` is held across an await point here + | ^ ...but data from `f` is returned 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | | + | this parameter and the return type are declared with different lifetimes... LL | f - | ^ ...but data from `f` is held across an await point here + | ^ ...but data from `f` is returned 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | | + | this parameter and the return type are declared with different lifetimes... LL | f - | ^ ...but data from `f` is held across an await point here + | ^ ...but data from `f` is returned 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | | + | this parameter and the return type are declared with different lifetimes... LL | f - | ^ ...but data from `f` is held across an await point here + | ^ ...but data from `f` is returned 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 cc269c0e7aad5..aa1d7453e83e1 100644 --- a/src/test/ui/self/elision/ref-struct-async.stderr +++ b/src/test/ui/self/elision/ref-struct-async.stderr @@ -3,55 +3,50 @@ error[E0623]: lifetime mismatch | LL | async fn ref_Struct(self: &Struct, f: &u32) -> &u32 { | ---- ---- - | | | - | | this `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | | + | this parameter and the return type are declared with different lifetimes... LL | f - | ^ ...but data from `f` is held across an await point here + | ^ ...but data from `f` is returned 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | | + | this parameter and the return type are declared with different lifetimes... LL | f - | ^ ...but data from `f` is held across an await point here + | ^ ...but data from `f` is returned 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | | + | this parameter and the return type are declared with different lifetimes... LL | f - | ^ ...but data from `f` is held across an await point here + | ^ ...but data from `f` is returned 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 `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | | + | this parameter and the return type are declared with different lifetimes... LL | f - | ^ ...but data from `f` is held across an await point here + | ^ ...but data from `f` is returned here error[E0623]: lifetime mismatch --> $DIR/ref-struct-async.rs:29:9 | LL | async fn box_pin_Struct(self: Box>, f: &u32) -> &u32 { | ---- ---- - | | | - | | this `async fn` implicitly returns an `impl Future` - | this parameter and the returned future are declared with different lifetimes... + | | + | this parameter and the return type are declared with different lifetimes... LL | f - | ^ ...but data from `f` is held across an await point here + | ^ ...but data from `f` is returned here error: aborting due to 5 previous errors