diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2017-10-11 14:38:52 -0700 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2017-10-11 15:56:22 -0700 |
| commit | fab6a10c00ffda25ed9ec3195b28a9f6a58150a4 (patch) | |
| tree | e00a0047ca0393c577cbca27bfcca14bd5bbcd87 | |
| parent | ec016f80cf725a9c8a613cdcd2ac97588d5f9af2 (diff) | |
| download | rust-fab6a10c00ffda25ed9ec3195b28a9f6a58150a4.tar.gz rust-fab6a10c00ffda25ed9ec3195b28a9f6a58150a4.zip | |
Point at immutable outer variable
When attempting to mutate an immutable outer variable from a closure, point at the outer variable and suggest making it mutable.
| -rw-r--r-- | src/librustc_borrowck/borrowck/mod.rs | 16 | ||||
| -rw-r--r-- | src/test/ui/suggestions/closure-immutable-outer-variable.rs | 20 | ||||
| -rw-r--r-- | src/test/ui/suggestions/closure-immutable-outer-variable.stderr | 10 |
3 files changed, 45 insertions, 1 deletions
diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index a3f1340d429..d6f7c2aa887 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -759,7 +759,21 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { let mut db = match err.cause { MutabilityViolation => { - self.cannot_assign(error_span, &descr, Origin::Ast) + let mut db = self.cannot_assign(error_span, &descr, Origin::Ast); + if let mc::NoteClosureEnv(upvar_id) = err.cmt.note { + let node_id = self.tcx.hir.hir_to_node_id(upvar_id.var_id); + let sp = self.tcx.hir.span(node_id); + match self.tcx.sess.codemap().span_to_snippet(sp) { + Ok(snippet) => { + let msg = &format!("consider making `{}` mutable", snippet); + db.span_suggestion(sp, msg, format!("mut {}", snippet)); + } + _ => { + db.span_help(sp, "consider making this binding mutable"); + } + } + } + db } BorrowViolation(euv::ClosureCapture(_)) => { struct_span_err!(self.tcx.sess, error_span, E0595, diff --git a/src/test/ui/suggestions/closure-immutable-outer-variable.rs b/src/test/ui/suggestions/closure-immutable-outer-variable.rs new file mode 100644 index 00000000000..fe8e2bc6c8e --- /dev/null +++ b/src/test/ui/suggestions/closure-immutable-outer-variable.rs @@ -0,0 +1,20 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Point at the captured immutable outer variable + +fn foo(mut f: Box<FnMut()>) { + f(); +} + +fn main() { + let y = true; + foo(Box::new(move || y = false) as Box<_>); +} diff --git a/src/test/ui/suggestions/closure-immutable-outer-variable.stderr b/src/test/ui/suggestions/closure-immutable-outer-variable.stderr new file mode 100644 index 00000000000..19f1cd07171 --- /dev/null +++ b/src/test/ui/suggestions/closure-immutable-outer-variable.stderr @@ -0,0 +1,10 @@ +error[E0594]: cannot assign to captured outer variable in an `FnMut` closure + --> $DIR/closure-immutable-outer-variable.rs:19:26 + | +18 | let y = true; + | - help: consider making `y` mutable: `mut y` +19 | foo(Box::new(move || y = false) as Box<_>); + | ^^^^^^^^^ + +error: aborting due to previous error + |
