Tweak borrow error on FnMut when Fn is expected

This commit is contained in:
Esteban Küber 2020-02-03 16:08:45 -08:00
parent 994e5e7465
commit 109d5c189f
11 changed files with 369 additions and 237 deletions

View File

@ -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,100 @@ 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}", ACT = 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, "you might have to change this...");
err.span_label(sig.decl.output.span(), "...to return `FnMut` instead of `Fn`");
err.span_label(self.body.span, "in this closure");
}
parent => {
err.note(&format!("parent {:?}", parent));
}
}
}
}
}
fn suggest_ampmut_self<'tcx>(

View File

@ -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<dyn Fn() -> 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
}
}

View File

@ -1,76 +1,101 @@
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<A,F:Fn<A>>(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<A,F:Fn<A>>(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
--> $DIR/borrow-immutable-upvar-mutation.rs:23:22
|
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); });
| ^^^^^^^^^
LL | fn to_fn<A,F:Fn<A>>(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
--> $DIR/borrow-immutable-upvar-mutation.rs:30:32
|
LL | fn to_fn<A,F:Fn<A>>(f: F) -> F { f }
| - change this to accept `FnMut` instead of `Fn`
...
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
|
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
--> $DIR/borrow-immutable-upvar-mutation.rs:33:36
|
LL | fn to_fn<A,F:Fn<A>>(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
|
help: consider changing this to accept closures that implement `FnMut`
--> $DIR/borrow-immutable-upvar-mutation.rs:30:24
|
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<A,F:Fn<A>>(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: aborting due to 6 previous errors
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<dyn Fn() -> usize> {
| --- ---------------------- ...to return `FnMut` instead of `Fn`
| |
| you might have to change this...
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 {
| --- ------------------ ...to return `FnMut` instead of `Fn`
| |
| you might have to change this...
LL | let mut x = 0;
LL | / move || {
LL | | x += 1;
| | ^^^^^^ cannot assign
LL | | x
LL | | }
| |_____- in this closure
error: aborting due to 8 previous errors
Some errors have detailed explanations: E0594, E0596.
For more information about an error, try `rustc --explain E0594`.

View File

@ -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: 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: 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

View File

@ -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: Fn()>(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: Fn()>(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: Fn()>(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: Fn()>(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: Fn()>(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: Fn()>(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: Fn()>(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: Fn()>(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

View File

@ -1,11 +1,11 @@
pub fn bar<F: Fn()>(_f: F) {}
pub fn bar<F: Fn()>(_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() {}

View File

@ -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: Fn()>(_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

View File

@ -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: 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: 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

View File

@ -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: Fn()>(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: Fn()>(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: Fn()>(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: Fn()>(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: Fn()>(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: Fn()>(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

View File

@ -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<A,F:Fn<A>>(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

View File

@ -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: 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