From 34ff35298938f0d0ae477618b17a41d5afc00a7a Mon Sep 17 00:00:00 2001 From: SNCPlay42 Date: Tue, 21 Jul 2020 19:56:21 +0100 Subject: [PATCH] don't refer to async as 'generators' and give return of async fn a better span --- .../borrow_check/diagnostics/region_name.rs | 30 +++++++++++--- .../issue-74072-lifetime-name-annotations.rs | 29 ++++++++++++++ ...sue-74072-lifetime-name-annotations.stderr | 39 +++++++++++++++++++ 3 files changed, 92 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/async-await/issue-74072-lifetime-name-annotations.rs create mode 100644 src/test/ui/async-await/issue-74072-lifetime-name-annotations.stderr diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs index 2e5a231fef0..bf512451568 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs @@ -657,15 +657,33 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { let (return_span, mir_description) = match tcx.hir().get(self.mir_hir_id()) { hir::Node::Expr(hir::Expr { - kind: hir::ExprKind::Closure(_, return_ty, _, span, gen_move), + kind: hir::ExprKind::Closure(_, return_ty, body_id, span, _), .. - }) => ( - match return_ty.output { + }) => { + let mut span = match return_ty.output { hir::FnRetTy::DefaultReturn(_) => tcx.sess.source_map().end_point(*span), hir::FnRetTy::Return(_) => return_ty.output.span(), - }, - if gen_move.is_some() { " of generator" } else { " of closure" }, - ), + }; + let mir_description = match tcx.hir().body(*body_id).generator_kind { + Some(hir::GeneratorKind::Async(gen)) => match gen { + hir::AsyncGeneratorKind::Block => " of async block", + hir::AsyncGeneratorKind::Closure => " of async closure", + hir::AsyncGeneratorKind::Fn => { + span = tcx + .hir() + .get(tcx.hir().get_parent_item(mir_hir_id)) + .fn_decl() + .expect("generator lowered from async fn should be in fn") + .output + .span(); + " of async function" + } + }, + Some(hir::GeneratorKind::Gen) => " of generator", + None => " of closure", + }; + (span, mir_description) + } hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(method_sig, _), .. diff --git a/src/test/ui/async-await/issue-74072-lifetime-name-annotations.rs b/src/test/ui/async-await/issue-74072-lifetime-name-annotations.rs new file mode 100644 index 00000000000..f8e11633359 --- /dev/null +++ b/src/test/ui/async-await/issue-74072-lifetime-name-annotations.rs @@ -0,0 +1,29 @@ +// edition:2018 +#![feature(async_closure)] +use std::future::Future; + +// test the quality of annotations giving lifetimes names (`'1`) when async constructs are involved + +pub async fn async_fn(x: &mut i32) -> &i32 { + let y = &*x; + *x += 1; //~ ERROR cannot assign to `*x` because it is borrowed + y +} + +pub fn async_closure(x: &mut i32) -> impl Future { + (async move || { + let y = &*x; + *x += 1; //~ ERROR cannot assign to `*x` because it is borrowed + y + })() +} + +pub fn async_block(x: &mut i32) -> impl Future { + async move { + let y = &*x; + *x += 1; //~ ERROR cannot assign to `*x` because it is borrowed + y + } +} + +fn main() {} 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 new file mode 100644 index 00000000000..997e36fe22c --- /dev/null +++ b/src/test/ui/async-await/issue-74072-lifetime-name-annotations.stderr @@ -0,0 +1,39 @@ +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 { + | ---- return type of async function is &'1 i32 +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 + | +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` +LL | })() + | - return type of async closure is &'1 i32 + +error[E0506]: cannot assign to `*x` because it is borrowed + --> $DIR/issue-74072-lifetime-name-annotations.rs:24:9 + | +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` +LL | } + | - return type of async block is &'1 i32 + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0506`.