diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 00fdf331ca60c..082dd86902354 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -902,7 +902,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { hir::ExprKind::MethodCall(.., args, _) => { // only the first closre parameter of the method. args[0] is MethodCall PathSegment for i in 1..args.len() { - if let hir::ExprKind::Closure(..) = args[i].kind { + if let hir::ExprKind::Closure(hir::Closure { + capture_clause: hir::CaptureBy::Ref, + .. + }) = args[i].kind + { closure_span = Some(args[i].span.shrink_to_lo()); break; } @@ -911,7 +915,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { hir::ExprKind::Block(blk, _) => { if let Some(ref expr) = blk.expr { // only when the block is a closure - if let hir::ExprKind::Closure(..) = expr.kind { + if let hir::ExprKind::Closure(hir::Closure { + capture_clause: hir::CaptureBy::Ref, + .. + }) = expr.kind + { closure_span = Some(expr.span.shrink_to_lo()); } } @@ -921,7 +929,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { if let Some(closure_span) = closure_span { diag.span_suggestion_verbose( closure_span, - format!("consider adding 'move' keyword before the nested closure"), + "consider adding 'move' keyword before the nested closure", "move ", Applicability::MaybeIncorrect, ); diff --git a/src/test/ui/borrowck/do-not-suggest-adding-move-when-closure-is-already-marked-as-move.rs b/src/test/ui/borrowck/do-not-suggest-adding-move-when-closure-is-already-marked-as-move.rs new file mode 100644 index 0000000000000..524459291f853 --- /dev/null +++ b/src/test/ui/borrowck/do-not-suggest-adding-move-when-closure-is-already-marked-as-move.rs @@ -0,0 +1,8 @@ +fn main() { + let mut vec: Vec = Vec::new(); + let closure = move || { + vec.clear(); + let mut iter = vec.iter(); + move || { iter.next() } //~ ERROR captured variable cannot escape `FnMut` closure bod + }; +} diff --git a/src/test/ui/borrowck/do-not-suggest-adding-move-when-closure-is-already-marked-as-move.stderr b/src/test/ui/borrowck/do-not-suggest-adding-move-when-closure-is-already-marked-as-move.stderr new file mode 100644 index 0000000000000..78ca090feb722 --- /dev/null +++ b/src/test/ui/borrowck/do-not-suggest-adding-move-when-closure-is-already-marked-as-move.stderr @@ -0,0 +1,18 @@ +error: captured variable cannot escape `FnMut` closure body + --> $DIR/do-not-suggest-adding-move-when-closure-is-already-marked-as-move.rs:6:9 + | +LL | let mut vec: Vec = Vec::new(); + | ------- variable defined here +LL | let closure = move || { + | - inferred to be a `FnMut` closure +LL | vec.clear(); + | --- variable captured here +LL | let mut iter = vec.iter(); +LL | move || { iter.next() } + | ^^^^^^^^^^^^^^^^^^^^^^^ returns a closure that contains a reference to a captured variable, which then escapes the closure body + | + = note: `FnMut` closures only have access to their captured variables while they are executing... + = note: ...therefore, they cannot allow references to captured variables to escape + +error: aborting due to previous error +