diff --git a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs index 563ff1112c3a6..d91f6edc9800c 100644 --- a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs @@ -10,7 +10,7 @@ use rustc_span::Span; use crate::borrow_check::diagnostics::BorrowedContentSource; use crate::borrow_check::MirBorrowckCtxt; use crate::util::collect_writes::FindAssignments; -use rustc_errors::Applicability; +use rustc_errors::{Applicability, DiagnosticBuilder}; #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub(crate) enum AccessKind { @@ -412,11 +412,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { projection: [ProjectionElem::Deref], // FIXME document what is this 1 magic number about } if local == Local::new(1) && !self.upvars.is_empty() => { - err.span_label(span, format!("cannot {ACT}", ACT = act)); - err.span_help( - self.body.span, - "consider changing this to accept closures that implement `FnMut`", - ); + self.expected_fn_found_fn_mut_call(&mut err, span, act); } PlaceRef { local: _, projection: [.., ProjectionElem::Deref] } => { @@ -448,6 +444,101 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { err.buffer(&mut self.errors_buffer); } + + /// Targetted error when encountering an `FnMut` closure where an `Fn` closure was expected. + fn expected_fn_found_fn_mut_call(&self, err: &mut DiagnosticBuilder<'_>, sp: Span, act: &str) { + err.span_label(sp, format!("cannot {}", act)); + + let hir = self.infcx.tcx.hir(); + let closure_id = hir.as_local_hir_id(self.mir_def_id).unwrap(); + let fn_call_id = hir.get_parent_node(closure_id); + let node = hir.get(fn_call_id); + let item_id = hir.get_parent_item(fn_call_id); + let mut look_at_return = true; + // If we can detect the expression to be an `fn` call where the closure was an argument, + // we point at the `fn` definition argument... + match node { + hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Call(func, args), .. }) => { + let arg_pos = args + .iter() + .enumerate() + .filter(|(_, arg)| arg.span == self.body.span) + .map(|(pos, _)| pos) + .next(); + let def_id = hir.local_def_id(item_id); + let tables = self.infcx.tcx.typeck_tables_of(def_id); + if let Some(ty::FnDef(def_id, _)) = + tables.node_type_opt(func.hir_id).as_ref().map(|ty| &ty.kind) + { + let arg = match hir.get_if_local(*def_id) { + Some(hir::Node::Item(hir::Item { + ident, + kind: hir::ItemKind::Fn(sig, ..), + .. + })) + | Some(hir::Node::TraitItem(hir::TraitItem { + ident, + kind: hir::TraitItemKind::Method(sig, _), + .. + })) + | Some(hir::Node::ImplItem(hir::ImplItem { + ident, + kind: hir::ImplItemKind::Method(sig, _), + .. + })) => Some( + arg_pos + .and_then(|pos| { + sig.decl.inputs.get( + pos + if sig.decl.implicit_self.has_implicit_self() { + 1 + } else { + 0 + }, + ) + }) + .map(|arg| arg.span) + .unwrap_or(ident.span), + ), + _ => None, + }; + if let Some(span) = arg { + err.span_label(span, "change this to accept `FnMut` instead of `Fn`"); + err.span_label(func.span, "expects `Fn` instead of `FnMut`"); + if self.infcx.tcx.sess.source_map().is_multiline(self.body.span) { + err.span_label(self.body.span, "in this closure"); + } + look_at_return = false; + } + } + } + _ => {} + } + if look_at_return && hir.get_return_block(closure_id).is_some() { + // ...otherwise we are probably in the tail expression of the function, point at the + // return type. + match hir.get(hir.get_parent_item(fn_call_id)) { + hir::Node::Item(hir::Item { ident, kind: hir::ItemKind::Fn(sig, ..), .. }) + | hir::Node::TraitItem(hir::TraitItem { + ident, + kind: hir::TraitItemKind::Method(sig, _), + .. + }) + | hir::Node::ImplItem(hir::ImplItem { + ident, + kind: hir::ImplItemKind::Method(sig, _), + .. + }) => { + err.span_label(ident.span, ""); + err.span_label( + sig.decl.output.span(), + "change this to return `FnMut` instead of `Fn`", + ); + err.span_label(self.body.span, "in this closure"); + } + _ => {} + } + } + } } fn suggest_ampmut_self<'tcx>( diff --git a/src/test/ui/borrowck/borrow-immutable-upvar-mutation.rs b/src/test/ui/borrowck/borrow-immutable-upvar-mutation.rs index fed8bc95b6b86..62e27bcf1643f 100644 --- a/src/test/ui/borrowck/borrow-immutable-upvar-mutation.rs +++ b/src/test/ui/borrowck/borrow-immutable-upvar-mutation.rs @@ -18,7 +18,10 @@ fn main() { let _g = to_fn(|| set(&mut y)); //~ ERROR cannot borrow let mut z = 0; - let _h = to_fn_mut(|| { set(&mut z); to_fn(|| z = 42); }); //~ ERROR cannot assign + let _h = to_fn_mut(|| { + set(&mut z); + to_fn(|| z = 42); //~ ERROR cannot assign + }); } // By-value captures @@ -33,3 +36,19 @@ fn main() { let _h = to_fn_mut(move || { set(&mut z); to_fn(move || z = 42); }); //~ ERROR cannot assign } } + +fn foo() -> Box usize> { + let mut x = 0; + Box::new(move || { + x += 1; //~ ERROR cannot assign + x + }) +} + +fn bar() -> impl Fn() -> usize { + let mut x = 0; + move || { + x += 1; //~ ERROR cannot assign + x + } +} diff --git a/src/test/ui/borrowck/borrow-immutable-upvar-mutation.stderr b/src/test/ui/borrowck/borrow-immutable-upvar-mutation.stderr index 097e4c75065c9..3046b047d00f6 100644 --- a/src/test/ui/borrowck/borrow-immutable-upvar-mutation.stderr +++ b/src/test/ui/borrowck/borrow-immutable-upvar-mutation.stderr @@ -1,76 +1,97 @@ error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure --> $DIR/borrow-immutable-upvar-mutation.rs:15:27 | +LL | fn to_fn>(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | let _f = to_fn(|| x = 42); - | ^^^^^^ cannot assign - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/borrow-immutable-upvar-mutation.rs:15:24 - | -LL | let _f = to_fn(|| x = 42); - | ^^^^^^^^^ + | ----- ^^^^^^ cannot assign + | | + | expects `Fn` instead of `FnMut` error[E0596]: cannot borrow `y` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/borrow-immutable-upvar-mutation.rs:18:31 | +LL | fn to_fn>(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | let _g = to_fn(|| set(&mut y)); - | ^^^^^^ cannot borrow as mutable - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/borrow-immutable-upvar-mutation.rs:18:24 - | -LL | let _g = to_fn(|| set(&mut y)); - | ^^^^^^^^^^^^^^ + | ----- ^^^^^^ cannot borrow as mutable + | | + | expects `Fn` instead of `FnMut` error[E0594]: cannot assign to `z`, as it is a captured variable in a `Fn` closure - --> $DIR/borrow-immutable-upvar-mutation.rs:21:55 - | -LL | let _h = to_fn_mut(|| { set(&mut z); to_fn(|| z = 42); }); - | ^^^^^^ cannot assign - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/borrow-immutable-upvar-mutation.rs:21:52 - | -LL | let _h = to_fn_mut(|| { set(&mut z); to_fn(|| z = 42); }); - | ^^^^^^^^^ + --> $DIR/borrow-immutable-upvar-mutation.rs:23:22 + | +LL | fn to_fn>(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... +LL | to_fn(|| z = 42); + | ----- ^^^^^^ cannot assign + | | + | expects `Fn` instead of `FnMut` error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure - --> $DIR/borrow-immutable-upvar-mutation.rs:27:32 - | -LL | let _f = to_fn(move || x = 42); - | ^^^^^^ cannot assign - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/borrow-immutable-upvar-mutation.rs:27:24 + --> $DIR/borrow-immutable-upvar-mutation.rs:30:32 | +LL | fn to_fn>(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | let _f = to_fn(move || x = 42); - | ^^^^^^^^^^^^^^ + | ----- ^^^^^^ cannot assign + | | + | expects `Fn` instead of `FnMut` error[E0596]: cannot borrow `y` as mutable, as it is a captured variable in a `Fn` closure - --> $DIR/borrow-immutable-upvar-mutation.rs:30:36 - | -LL | let _g = to_fn(move || set(&mut y)); - | ^^^^^^ cannot borrow as mutable - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/borrow-immutable-upvar-mutation.rs:30:24 + --> $DIR/borrow-immutable-upvar-mutation.rs:33:36 | +LL | fn to_fn>(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | let _g = to_fn(move || set(&mut y)); - | ^^^^^^^^^^^^^^^^^^^ + | ----- ^^^^^^ cannot borrow as mutable + | | + | expects `Fn` instead of `FnMut` error[E0594]: cannot assign to `z`, as it is a captured variable in a `Fn` closure - --> $DIR/borrow-immutable-upvar-mutation.rs:33:65 + --> $DIR/borrow-immutable-upvar-mutation.rs:36:65 | +LL | fn to_fn>(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | let _h = to_fn_mut(move || { set(&mut z); to_fn(move || z = 42); }); - | ^^^^^^ cannot assign - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/borrow-immutable-upvar-mutation.rs:33:57 - | -LL | let _h = to_fn_mut(move || { set(&mut z); to_fn(move || z = 42); }); - | ^^^^^^^^^^^^^^ + | ----- ^^^^^^ cannot assign + | | + | expects `Fn` instead of `FnMut` + +error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure + --> $DIR/borrow-immutable-upvar-mutation.rs:43:9 + | +LL | fn foo() -> Box usize> { + | --- ---------------------- change this to return `FnMut` instead of `Fn` +LL | let mut x = 0; +LL | Box::new(move || { + | ______________- +LL | | x += 1; + | | ^^^^^^ cannot assign +LL | | x +LL | | }) + | |_____- in this closure + +error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure + --> $DIR/borrow-immutable-upvar-mutation.rs:51:9 + | +LL | fn bar() -> impl Fn() -> usize { + | --- ------------------ change this to return `FnMut` instead of `Fn` +LL | let mut x = 0; +LL | / move || { +LL | | x += 1; + | | ^^^^^^ cannot assign +LL | | x +LL | | } + | |_____- in this closure -error: aborting due to 6 previous errors +error: aborting due to 8 previous errors Some errors have detailed explanations: E0594, E0596. For more information about an error, try `rustc --explain E0594`. diff --git a/src/test/ui/borrowck/borrow-raw-address-of-mutability.stderr b/src/test/ui/borrowck/borrow-raw-address-of-mutability.stderr index cf01c362d50bc..44dde0fd80b0d 100644 --- a/src/test/ui/borrowck/borrow-raw-address-of-mutability.stderr +++ b/src/test/ui/borrowck/borrow-raw-address-of-mutability.stderr @@ -27,32 +27,32 @@ LL | f(); error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/borrow-raw-address-of-mutability.rs:29:17 | -LL | let y = &raw mut x; - | ^^^^^^^^^^ cannot borrow as mutable - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/borrow-raw-address-of-mutability.rs:28:21 - | +LL | fn make_fn(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | let f = make_fn(|| { - | _____________________^ + | _____________-------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | let y = &raw mut x; + | | ^^^^^^^^^^ cannot borrow as mutable LL | | }); - | |_____^ + | |_____- in this closure error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/borrow-raw-address-of-mutability.rs:37:17 | -LL | let y = &raw mut x; - | ^^^^^^^^^^ cannot borrow as mutable - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/borrow-raw-address-of-mutability.rs:36:21 - | +LL | fn make_fn(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | let f = make_fn(move || { - | _____________________^ + | _____________-------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | let y = &raw mut x; + | | ^^^^^^^^^^ cannot borrow as mutable LL | | }); - | |_____^ + | |_____- in this closure error: aborting due to 5 previous errors diff --git a/src/test/ui/borrowck/mutability-errors.stderr b/src/test/ui/borrowck/mutability-errors.stderr index 72547a40352c9..5361ebe3916d7 100644 --- a/src/test/ui/borrowck/mutability-errors.stderr +++ b/src/test/ui/borrowck/mutability-errors.stderr @@ -119,146 +119,146 @@ LL | &mut (*f()).0; error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure --> $DIR/mutability-errors.rs:40:9 | -LL | x = (1,); - | ^^^^^^^^ cannot assign - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/mutability-errors.rs:39:12 - | +LL | fn fn_ref(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | fn_ref(|| { - | ____________^ + | _____------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | x = (1,); + | | ^^^^^^^^ cannot assign LL | | x.0 = 1; LL | | &mut x; LL | | &mut x.0; LL | | }); - | |_____^ + | |_____- in this closure error[E0594]: cannot assign to `x.0`, as `Fn` closures cannot mutate their captured variables --> $DIR/mutability-errors.rs:41:9 | -LL | x.0 = 1; - | ^^^^^^^ cannot assign - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/mutability-errors.rs:39:12 - | +LL | fn fn_ref(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | fn_ref(|| { - | ____________^ + | _____------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | x = (1,); LL | | x.0 = 1; + | | ^^^^^^^ cannot assign LL | | &mut x; LL | | &mut x.0; LL | | }); - | |_____^ + | |_____- in this closure error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/mutability-errors.rs:42:9 | -LL | &mut x; - | ^^^^^^ cannot borrow as mutable - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/mutability-errors.rs:39:12 - | +LL | fn fn_ref(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | fn_ref(|| { - | ____________^ + | _____------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | x = (1,); LL | | x.0 = 1; LL | | &mut x; + | | ^^^^^^ cannot borrow as mutable LL | | &mut x.0; LL | | }); - | |_____^ + | |_____- in this closure error[E0596]: cannot borrow `x.0` as mutable, as `Fn` closures cannot mutate their captured variables --> $DIR/mutability-errors.rs:43:9 | -LL | &mut x.0; - | ^^^^^^^^ cannot borrow as mutable - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/mutability-errors.rs:39:12 - | +LL | fn fn_ref(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | fn_ref(|| { - | ____________^ + | _____------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | x = (1,); LL | | x.0 = 1; LL | | &mut x; LL | | &mut x.0; + | | ^^^^^^^^ cannot borrow as mutable LL | | }); - | |_____^ + | |_____- in this closure error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure --> $DIR/mutability-errors.rs:46:9 | -LL | x = (1,); - | ^^^^^^^^ cannot assign - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/mutability-errors.rs:45:12 - | +LL | fn fn_ref(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | fn_ref(move || { - | ____________^ + | _____------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | x = (1,); + | | ^^^^^^^^ cannot assign LL | | x.0 = 1; LL | | &mut x; LL | | &mut x.0; LL | | }); - | |_____^ + | |_____- in this closure error[E0594]: cannot assign to `x.0`, as `Fn` closures cannot mutate their captured variables --> $DIR/mutability-errors.rs:47:9 | -LL | x.0 = 1; - | ^^^^^^^ cannot assign - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/mutability-errors.rs:45:12 - | +LL | fn fn_ref(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | fn_ref(move || { - | ____________^ + | _____------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | x = (1,); LL | | x.0 = 1; + | | ^^^^^^^ cannot assign LL | | &mut x; LL | | &mut x.0; LL | | }); - | |_____^ + | |_____- in this closure error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/mutability-errors.rs:48:9 | -LL | &mut x; - | ^^^^^^ cannot borrow as mutable - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/mutability-errors.rs:45:12 - | +LL | fn fn_ref(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | fn_ref(move || { - | ____________^ + | _____------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | x = (1,); LL | | x.0 = 1; LL | | &mut x; + | | ^^^^^^ cannot borrow as mutable LL | | &mut x.0; LL | | }); - | |_____^ + | |_____- in this closure error[E0596]: cannot borrow `x.0` as mutable, as `Fn` closures cannot mutate their captured variables --> $DIR/mutability-errors.rs:49:9 | -LL | &mut x.0; - | ^^^^^^^^ cannot borrow as mutable - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/mutability-errors.rs:45:12 - | +LL | fn fn_ref(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | fn_ref(move || { - | ____________^ + | _____------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | x = (1,); LL | | x.0 = 1; LL | | &mut x; LL | | &mut x.0; + | | ^^^^^^^^ cannot borrow as mutable LL | | }); - | |_____^ + | |_____- in this closure error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable --> $DIR/mutability-errors.rs:54:5 diff --git a/src/test/ui/fn/fn-closure-mutable-capture.rs b/src/test/ui/fn/fn-closure-mutable-capture.rs index 81376af091b45..0e427b9cf318f 100644 --- a/src/test/ui/fn/fn-closure-mutable-capture.rs +++ b/src/test/ui/fn/fn-closure-mutable-capture.rs @@ -1,11 +1,11 @@ -pub fn bar(_f: F) {} +pub fn bar(_f: F) {} //~ NOTE change this to accept `FnMut` instead of `Fn` pub fn foo() { let mut x = 0; bar(move || x = 1); //~^ ERROR cannot assign to `x`, as it is a captured variable in a `Fn` closure //~| NOTE cannot assign - //~| HELP consider changing this to accept closures that implement `FnMut` + //~| NOTE expects `Fn` instead of `FnMut` } fn main() {} diff --git a/src/test/ui/fn/fn-closure-mutable-capture.stderr b/src/test/ui/fn/fn-closure-mutable-capture.stderr index f7ab56da8de97..d23c363ae1582 100644 --- a/src/test/ui/fn/fn-closure-mutable-capture.stderr +++ b/src/test/ui/fn/fn-closure-mutable-capture.stderr @@ -1,14 +1,13 @@ error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure --> $DIR/fn-closure-mutable-capture.rs:5:17 | +LL | pub fn bar(_f: F) {} + | - change this to accept `FnMut` instead of `Fn` +... LL | bar(move || x = 1); - | ^^^^^ cannot assign - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/fn-closure-mutable-capture.rs:5:9 - | -LL | bar(move || x = 1); - | ^^^^^^^^^^^^^ + | --- ^^^^^ cannot assign + | | + | expects `Fn` instead of `FnMut` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-21600.stderr b/src/test/ui/issues/issue-21600.stderr index 9c534809dbee3..84c7106e89016 100644 --- a/src/test/ui/issues/issue-21600.stderr +++ b/src/test/ui/issues/issue-21600.stderr @@ -1,34 +1,33 @@ error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/issue-21600.rs:14:20 | +LL | fn call_it(f: F) where F: Fn() { f(); } + | - change this to accept `FnMut` instead of `Fn` +... LL | call_it(|| x.gen_mut()); - | ^ cannot borrow as mutable - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/issue-21600.rs:14:17 - | -LL | call_it(|| x.gen_mut()); - | ^^^^^^^^^^^^^^ + | ------- ^ cannot borrow as mutable + | | + | expects `Fn` instead of `FnMut` error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/issue-21600.rs:14:17 | -LL | call_it(|| x.gen_mut()); - | ^^ - mutable borrow occurs due to use of `x` in closure - | | - | cannot borrow as mutable - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/issue-21600.rs:12:13 - | +LL | fn call_it(f: F) where F: Fn() { f(); } + | - change this to accept `FnMut` instead of `Fn` +... LL | call_it(|| { - | _____________^ + | _____-------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | call_it(|| x.gen()); LL | | call_it(|| x.gen_mut()); + | | ^^ - mutable borrow occurs due to use of `x` in closure + | | | + | | cannot borrow as mutable LL | | LL | | LL | | }); - | |_____^ + | |_____- in this closure error: aborting due to 2 previous errors diff --git a/src/test/ui/nll/closure-captures.stderr b/src/test/ui/nll/closure-captures.stderr index b8f5cc86500c5..dd5f32ef4f581 100644 --- a/src/test/ui/nll/closure-captures.stderr +++ b/src/test/ui/nll/closure-captures.stderr @@ -37,36 +37,36 @@ LL | x = 1; error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/closure-captures.rs:27:9 | -LL | || - | ^^ cannot borrow as mutable -LL | x = 1;} - | - mutable borrow occurs due to use of `x` in closure - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/closure-captures.rs:26:12 - | +LL | fn fn_ref(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | fn_ref(|| { - | ____________^ + | _____------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | || + | | ^^ cannot borrow as mutable LL | | x = 1;} - | |________________^ + | |__________-_____- in this closure + | | + | mutable borrow occurs due to use of `x` in closure error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/closure-captures.rs:31:9 | -LL | || - | ^^ cannot borrow as mutable -LL | x = 1;}); - | - mutable borrow occurs due to use of `x` in closure - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/closure-captures.rs:30:12 - | +LL | fn fn_ref(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | fn_ref(move || { - | ____________^ + | _____------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | || + | | ^^ cannot borrow as mutable LL | | x = 1;}); - | |___________^ + | |_____-_____- in this closure + | | + | mutable borrow occurs due to use of `x` in closure error[E0594]: cannot assign to `x`, as it is not declared as mutable --> $DIR/closure-captures.rs:39:10 @@ -80,19 +80,19 @@ LL | x = 1;} error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/closure-captures.rs:38:9 | -LL | || - | ^^ cannot borrow as mutable -LL | x = 1;} - | - mutable borrow occurs due to use of `x` in closure - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/closure-captures.rs:37:12 - | +LL | fn fn_ref(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | fn_ref(|| { - | ____________^ + | _____------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | || + | | ^^ cannot borrow as mutable LL | | x = 1;} - | |________________^ + | |__________-_____- in this closure + | | + | mutable borrow occurs due to use of `x` in closure error[E0594]: cannot assign to `x`, as it is not declared as mutable --> $DIR/closure-captures.rs:43:5 @@ -106,53 +106,53 @@ LL | x = 1;}); error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/closure-captures.rs:42:9 | -LL | || - | ^^ cannot borrow as mutable -LL | x = 1;}); - | - mutable borrow occurs due to use of `x` in closure - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/closure-captures.rs:41:12 - | +LL | fn fn_ref(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | fn_ref(move || { - | ____________^ + | _____------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | || + | | ^^ cannot borrow as mutable LL | | x = 1;}); - | |___________^ + | |_____-_____- in this closure + | | + | mutable borrow occurs due to use of `x` in closure error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/closure-captures.rs:48:9 | -LL | || - | ^^ cannot borrow as mutable -LL | *x = 1;}); - | - mutable borrow occurs due to use of `x` in closure - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/closure-captures.rs:47:12 - | +LL | fn fn_ref(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | fn_ref(|| { - | ____________^ + | _____------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | || + | | ^^ cannot borrow as mutable LL | | *x = 1;}); - | |________________^ + | |__________-_____- in this closure + | | + | mutable borrow occurs due to use of `x` in closure error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/closure-captures.rs:51:9 | -LL | || - | ^^ cannot borrow as mutable -LL | *x = 1;}); - | - mutable borrow occurs due to use of `x` in closure - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/closure-captures.rs:50:12 - | +LL | fn fn_ref(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | fn_ref(move || { - | ____________^ + | _____------_- + | | | + | | expects `Fn` instead of `FnMut` LL | | || + | | ^^ cannot borrow as mutable LL | | *x = 1;}); - | |________________^ + | |__________-_____- in this closure + | | + | mutable borrow occurs due to use of `x` in closure error: aborting due to 12 previous errors diff --git a/src/test/ui/unboxed-closures/unboxed-closures-mutate-upvar.stderr b/src/test/ui/unboxed-closures/unboxed-closures-mutate-upvar.stderr index 6bba38510b676..48ec620d92ea7 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-mutate-upvar.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-mutate-upvar.stderr @@ -28,17 +28,17 @@ LL | n += 1; error[E0594]: cannot assign to `n`, as it is a captured variable in a `Fn` closure --> $DIR/unboxed-closures-mutate-upvar.rs:53:9 | -LL | n += 1; - | ^^^^^^ cannot assign - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/unboxed-closures-mutate-upvar.rs:52:23 - | +LL | fn to_fn>(f: F) -> F { f } + | - change this to accept `FnMut` instead of `Fn` +... LL | let mut f = to_fn(move || { - | _______________________^ + | _________________-----_- + | | | + | | expects `Fn` instead of `FnMut` LL | | n += 1; + | | ^^^^^^ cannot assign LL | | }); - | |_____^ + | |_____- in this closure error: aborting due to 4 previous errors diff --git a/src/test/ui/unboxed-closures/unboxed-closures-mutated-upvar-from-fn-closure.stderr b/src/test/ui/unboxed-closures/unboxed-closures-mutated-upvar-from-fn-closure.stderr index a38c612e1dea9..80e84fb7cad3f 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-mutated-upvar-from-fn-closure.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-mutated-upvar-from-fn-closure.stderr @@ -1,18 +1,18 @@ error[E0594]: cannot assign to `counter`, as it is a captured variable in a `Fn` closure --> $DIR/unboxed-closures-mutated-upvar-from-fn-closure.rs:11:9 | -LL | counter += 1; - | ^^^^^^^^^^^^ cannot assign - | -help: consider changing this to accept closures that implement `FnMut` - --> $DIR/unboxed-closures-mutated-upvar-from-fn-closure.rs:10:10 - | +LL | fn call(f: F) where F : Fn() { + | - change this to accept `FnMut` instead of `Fn` +... LL | call(|| { - | __________^ + | _____----_- + | | | + | | expects `Fn` instead of `FnMut` LL | | counter += 1; + | | ^^^^^^^^^^^^ cannot assign LL | | LL | | }); - | |_____^ + | |_____- in this closure error: aborting due to previous error