From aa58439f87f58aa9c7b1ccfb5d52ae5d3d0f1106 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 14 Feb 2025 18:42:06 -0300 Subject: [PATCH] Fail gracefully if mutating on a use closure and the closure it not declared mut --- .../src/diagnostics/mutability_errors.rs | 2 +- tests/ui/ergonomic-clones/closure/mutation2.rs | 10 ++++++++++ .../ergonomic-clones/closure/mutation2.stderr | 17 +++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 tests/ui/ergonomic-clones/closure/mutation2.rs create mode 100644 tests/ui/ergonomic-clones/closure/mutation2.stderr diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index be4a7736b1c2..145137f92369 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -823,7 +823,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { ) => { capture_reason = format!("mutable borrow of `{upvar}`"); } - ty::UpvarCapture::ByValue => { + ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse => { capture_reason = format!("possible mutation of `{upvar}`"); } _ => bug!("upvar `{upvar}` borrowed, but not mutably"), diff --git a/tests/ui/ergonomic-clones/closure/mutation2.rs b/tests/ui/ergonomic-clones/closure/mutation2.rs new file mode 100644 index 000000000000..8a43f9232bf4 --- /dev/null +++ b/tests/ui/ergonomic-clones/closure/mutation2.rs @@ -0,0 +1,10 @@ +#![feature(ergonomic_clones)] + +fn main() { + let mut my_var = false; + let callback = use || { + my_var = true; + }; + callback(); + //~^ ERROR cannot borrow `callback` as mutable, as it is not declared as mutable [E0596] +} diff --git a/tests/ui/ergonomic-clones/closure/mutation2.stderr b/tests/ui/ergonomic-clones/closure/mutation2.stderr new file mode 100644 index 000000000000..3ee8f80ce223 --- /dev/null +++ b/tests/ui/ergonomic-clones/closure/mutation2.stderr @@ -0,0 +1,17 @@ +error[E0596]: cannot borrow `callback` as mutable, as it is not declared as mutable + --> $DIR/mutation2.rs:8:5 + | +LL | my_var = true; + | ------ calling `callback` requires mutable binding due to possible mutation of `my_var` +LL | }; +LL | callback(); + | ^^^^^^^^ cannot borrow as mutable + | +help: consider changing this to be mutable + | +LL | let mut callback = use || { + | +++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0596`.