From 5e1b366fb6c7bb11f08a085a07f7c11666fdf80a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 28 Dec 2019 13:51:29 -0800 Subject: [PATCH] Do not ICE on lifetime error involving closures --- .../diagnostics/conflict_errors.rs | 22 +++++++++++++++++-- ...ure-doesnt-life-long-enough-issue-67634.rs | 3 +++ ...doesnt-life-long-enough-issue-67634.stderr | 15 +++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.rs create mode 100644 src/test/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.stderr diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs index 79221329ead48..af6fcb6922a8b 100644 --- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs @@ -882,9 +882,27 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { err.span_label( drop_span, format!( - "...but `{}` will be dropped here, when the function `{}` returns", + "...but `{}` will be dropped here, when the {} returns", name, - self.infcx.tcx.hir().name(fn_hir_id), + self.infcx + .tcx + .hir() + .opt_name(fn_hir_id) + .map(|name| format!("function `{}`", name)) + .unwrap_or_else(|| { + match &self + .infcx + .tcx + .typeck_tables_of(self.mir_def_id) + .node_type(fn_hir_id) + .kind + { + ty::Closure(..) => "enclosing closure", + ty::Generator(..) => "enclosing generator", + kind => bug!("expected closure or generator, found {:?}", kind), + } + .to_string() + }) ), ); diff --git a/src/test/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.rs b/src/test/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.rs new file mode 100644 index 0000000000000..19d7f0190479e --- /dev/null +++ b/src/test/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.rs @@ -0,0 +1,3 @@ +fn main() { + [0].iter().flat_map(|a| [0].iter().map(|_| &a)); //~ ERROR `a` does not live long enough +} diff --git a/src/test/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.stderr b/src/test/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.stderr new file mode 100644 index 0000000000000..cb0b481e74876 --- /dev/null +++ b/src/test/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.stderr @@ -0,0 +1,15 @@ +error[E0597]: `a` does not live long enough + --> $DIR/unnamed-closure-doesnt-life-long-enough-issue-67634.rs:2:49 + | +LL | [0].iter().flat_map(|a| [0].iter().map(|_| &a)); + | - ^- ...but `a` will be dropped here, when the enclosing closure returns + | | | + | | `a` would have to be valid for `'_`... + | has type `&i32` + | + = note: functions cannot return a borrow to data owned within the function's scope, functions can only return borrows to data passed as arguments + = note: to learn more, visit + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0597`.