From bc84e211075e4c53e6fd122353f3132939e45ff9 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 3 Feb 2021 12:33:27 -0500 Subject: [PATCH] Fix panic when emitting diagnostic for closure mutable binding error Fixes #81700 The upvar borrow kind may be `ty::BorrowKind::UniqueImmBorrow`, which is still a mutable borrow for the purposes of this diagnostic code. --- .../borrow_check/diagnostics/mutability_errors.rs | 4 ++-- src/test/ui/closures/issue-81700-mut-borrow.rs | 5 +++++ src/test/ui/closures/issue-81700-mut-borrow.stderr | 13 +++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/closures/issue-81700-mut-borrow.rs create mode 100644 src/test/ui/closures/issue-81700-mut-borrow.stderr diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs index 74abe2d35ee74..333ac0738d45b 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs @@ -514,7 +514,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let upvar = ty::place_to_string_for_capture(tcx, place); match tables.upvar_capture(upvar_id) { ty::UpvarCapture::ByRef(ty::UpvarBorrow { - kind: ty::BorrowKind::MutBorrow, + kind: ty::BorrowKind::MutBorrow | ty::BorrowKind::UniqueImmBorrow, .. }) => { format!("mutable borrow of `{}`", upvar) @@ -522,7 +522,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ty::UpvarCapture::ByValue(_) => { format!("possible mutation of `{}`", upvar) } - _ => bug!("upvar `{}` borrowed, but not mutably", upvar), + val => bug!("upvar `{}` borrowed, but not mutably: {:?}", upvar, val), } } else { bug!("not an upvar") diff --git a/src/test/ui/closures/issue-81700-mut-borrow.rs b/src/test/ui/closures/issue-81700-mut-borrow.rs new file mode 100644 index 0000000000000..a27a6160142ad --- /dev/null +++ b/src/test/ui/closures/issue-81700-mut-borrow.rs @@ -0,0 +1,5 @@ +fn foo(x: &mut u32) { + let bar = || { foo(x); }; + bar(); //~ ERROR cannot borrow +} +fn main() {} diff --git a/src/test/ui/closures/issue-81700-mut-borrow.stderr b/src/test/ui/closures/issue-81700-mut-borrow.stderr new file mode 100644 index 0000000000000..3f564afff58e2 --- /dev/null +++ b/src/test/ui/closures/issue-81700-mut-borrow.stderr @@ -0,0 +1,13 @@ +error[E0596]: cannot borrow `bar` as mutable, as it is not declared as mutable + --> $DIR/issue-81700-mut-borrow.rs:3:5 + | +LL | let bar = || { foo(x); }; + | --- - calling `bar` requires mutable binding due to mutable borrow of `x` + | | + | help: consider changing this to be mutable: `mut bar` +LL | bar(); + | ^^^ cannot borrow as mutable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0596`.