Reword trying to operate in immutable fields

The previous message ("cannot assign/mutably borrow immutable field")
when trying to modify a field of an immutable binding gave the
(incorrect) impression that fields can be mutable independently of their
ADT's binding. Slightly reword the message to read "cannot
assign/mutably borrow field of immutable binding".
This commit is contained in:
Esteban Küber 2017-12-31 15:32:41 -08:00
parent 885011ef1f
commit 6384568fdb
11 changed files with 85 additions and 64 deletions

View File

@ -484,54 +484,60 @@ impl<'a, 'tcx> LoanPath<'tcx> {
}
}
pub fn opt_loan_path<'tcx>(cmt: &mc::cmt<'tcx>) -> Option<Rc<LoanPath<'tcx>>> {
//! Computes the `LoanPath` (if any) for a `cmt`.
//! Note that this logic is somewhat duplicated in
//! the method `compute()` found in `gather_loans::restrictions`,
//! which allows it to share common loan path pieces as it
//! traverses the CMT.
// Avoid "cannot borrow immutable field `self.x` as mutable" as that implies that a field *can* be
// mutable independently of the struct it belongs to. (#35937)
pub fn opt_loan_path_is_field<'tcx>(cmt: &mc::cmt<'tcx>) -> (Option<Rc<LoanPath<'tcx>>>, bool) {
let new_lp = |v: LoanPathKind<'tcx>| Rc::new(LoanPath::new(v, cmt.ty));
match cmt.cat {
Categorization::Rvalue(..) |
Categorization::StaticItem => {
None
(None, false)
}
Categorization::Local(id) => {
Some(new_lp(LpVar(id)))
(Some(new_lp(LpVar(id))), false)
}
Categorization::Upvar(mc::Upvar { id, .. }) => {
Some(new_lp(LpUpvar(id)))
(Some(new_lp(LpUpvar(id))), false)
}
Categorization::Deref(ref cmt_base, pk) => {
opt_loan_path(cmt_base).map(|lp| {
let lp = opt_loan_path_is_field(cmt_base);
(lp.0.map(|lp| {
new_lp(LpExtend(lp, cmt.mutbl, LpDeref(pk)))
})
}), lp.1)
}
Categorization::Interior(ref cmt_base, ik) => {
opt_loan_path(cmt_base).map(|lp| {
(opt_loan_path(cmt_base).map(|lp| {
let opt_variant_id = match cmt_base.cat {
Categorization::Downcast(_, did) => Some(did),
_ => None
};
new_lp(LpExtend(lp, cmt.mutbl, LpInterior(opt_variant_id, ik.cleaned())))
})
}), true)
}
Categorization::Downcast(ref cmt_base, variant_def_id) =>
opt_loan_path(cmt_base)
.map(|lp| {
Categorization::Downcast(ref cmt_base, variant_def_id) => {
let lp = opt_loan_path_is_field(cmt_base);
(lp.0.map(|lp| {
new_lp(LpDowncast(lp, variant_def_id))
}),
}), lp.1)
}
}
}
/// Computes the `LoanPath` (if any) for a `cmt`.
/// Note that this logic is somewhat duplicated in
/// the method `compute()` found in `gather_loans::restrictions`,
/// which allows it to share common loan path pieces as it
/// traverses the CMT.
pub fn opt_loan_path<'tcx>(cmt: &mc::cmt<'tcx>) -> Option<Rc<LoanPath<'tcx>>> {
opt_loan_path_is_field(cmt).0
}
///////////////////////////////////////////////////////////////////////////
// Errors
@ -787,14 +793,26 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
mc::NoteClosureEnv(_) | mc::NoteUpvarRef(_) => {
self.cmt_to_string(&err.cmt)
}
_ => match opt_loan_path(&err.cmt) {
None => {
_ => match opt_loan_path_is_field(&err.cmt) {
(None, true) => {
format!("{} of {} binding",
self.cmt_to_string(&err.cmt),
err.cmt.mutbl.to_user_str())
}
(None, false) => {
format!("{} {}",
err.cmt.mutbl.to_user_str(),
self.cmt_to_string(&err.cmt))
}
Some(lp) => {
(Some(lp), true) => {
format!("{} `{}` of {} binding",
self.cmt_to_string(&err.cmt),
self.loan_path_to_string(&lp),
err.cmt.mutbl.to_user_str())
}
(Some(lp), false) => {
format!("{} {} `{}`",
err.cmt.mutbl.to_user_str(),
self.cmt_to_string(&err.cmt),
@ -1326,7 +1344,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
} else if let Categorization::Interior(ref cmt, _) = err.cmt.cat {
if let mc::MutabilityCategory::McImmutable = cmt.mutbl {
db.span_label(*error_span,
"cannot mutably borrow immutable field");
"cannot mutably borrow field of immutable binding");
}
}
}

View File

@ -18,8 +18,8 @@ struct TrieMapIterator<'a> {
fn main() {
let a = 5;
let _iter = TrieMapIterator{node: &a};
_iter.node = & //[ast]~ ERROR cannot assign to immutable field `_iter.node`
//[mir]~^ ERROR cannot assign to immutable field `_iter.node` (Ast)
_iter.node = & //[ast]~ ERROR cannot assign to field `_iter.node` of immutable binding
//[mir]~^ ERROR cannot assign to field `_iter.node` of immutable binding (Ast)
// MIR doesn't generate an error because the code isn't reachable. This is OK
// because the test is here to check that the compiler doesn't ICE (cf. #5500).
panic!()

View File

@ -1,26 +1,26 @@
error[E0596]: cannot borrow immutable field `f.v` as mutable
error[E0596]: cannot borrow field `f.v` of immutable binding as mutable
--> $DIR/issue-35937.rs:17:5
|
16 | let f = Foo { v: Vec::new() };
| - consider changing this to `mut f`
17 | f.v.push("cat".to_string()); //~ ERROR cannot borrow
| ^^^ cannot mutably borrow immutable field
| ^^^ cannot mutably borrow field of immutable binding
error[E0594]: cannot assign to immutable field `s.x`
error[E0594]: cannot assign to field `s.x` of immutable binding
--> $DIR/issue-35937.rs:26:5
|
25 | let s = S { x: 42 };
| - consider changing this to `mut s`
26 | s.x += 1; //~ ERROR cannot assign
| ^^^^^^^^ cannot mutably borrow immutable field
| ^^^^^^^^ cannot mutably borrow field of immutable binding
error[E0594]: cannot assign to immutable field `s.x`
error[E0594]: cannot assign to field `s.x` of immutable binding
--> $DIR/issue-35937.rs:30:5
|
29 | fn bar(s: S) {
| - consider changing this to `mut s`
30 | s.x += 1; //~ ERROR cannot assign
| ^^^^^^^^ cannot mutably borrow immutable field
| ^^^^^^^^ cannot mutably borrow field of immutable binding
error: aborting due to 3 previous errors

View File

@ -14,7 +14,8 @@ struct Bar<'a> {
impl<'a> Bar<'a> {
fn f(&mut self) {
self.s.push('x'); //~ ERROR cannot borrow immutable borrowed
self.s.push('x');
//~^ ERROR cannot borrow borrowed content `*self.s` of immutable binding as mutable
}
}

View File

@ -1,10 +1,10 @@
error[E0596]: cannot borrow immutable borrowed content `*self.s` as mutable
error[E0596]: cannot borrow borrowed content `*self.s` of immutable binding as mutable
--> $DIR/issue-38147-2.rs:17:9
|
12 | s: &'a String
| ---------- use `&'a mut String` here to make mutable
...
17 | self.s.push('x'); //~ ERROR cannot borrow immutable borrowed
17 | self.s.push('x');
| ^^^^^^ cannot borrow as mutable
error: aborting due to previous error

View File

@ -14,7 +14,8 @@ struct Qux<'a> {
impl<'a> Qux<'a> {
fn f(&self) {
self.s.push('x'); //~ ERROR cannot borrow immutable borrowed
self.s.push('x');
//~^ ERROR cannot borrow borrowed content `*self.s` of immutable binding as mutable
}
}

View File

@ -1,10 +1,10 @@
error[E0596]: cannot borrow immutable borrowed content `*self.s` as mutable
error[E0596]: cannot borrow borrowed content `*self.s` of immutable binding as mutable
--> $DIR/issue-38147-3.rs:17:9
|
12 | s: &'a String
| ---------- use `&'a mut String` here to make mutable
...
17 | self.s.push('x'); //~ ERROR cannot borrow immutable borrowed
17 | self.s.push('x');
| ^^^^^^ cannot borrow as mutable
error: aborting due to previous error

View File

@ -55,5 +55,6 @@ pub fn with_arg(z: Z, w: &Z) {
pub fn with_tuple() {
let mut y = 0;
let x = (&y,);
*x.0 = 1; //~ ERROR cannot assign to immutable borrowed content
*x.0 = 1;
//~^ ERROR cannot assign to borrowed content `*x.0` of immutable binding
}

View File

@ -1,99 +1,99 @@
error[E0596]: cannot borrow immutable field `z.x` as mutable
error[E0596]: cannot borrow field `z.x` of immutable binding as mutable
--> $DIR/issue-39544.rs:21:18
|
20 | let z = Z { x: X::Y };
| - consider changing this to `mut z`
21 | let _ = &mut z.x; //~ ERROR cannot borrow
| ^^^ cannot mutably borrow immutable field
| ^^^ cannot mutably borrow field of immutable binding
error[E0596]: cannot borrow immutable field `self.x` as mutable
error[E0596]: cannot borrow field `self.x` of immutable binding as mutable
--> $DIR/issue-39544.rs:26:22
|
25 | fn foo<'z>(&'z self) {
| -------- use `&'z mut self` here to make mutable
26 | let _ = &mut self.x; //~ ERROR cannot borrow
| ^^^^^^ cannot mutably borrow immutable field
| ^^^^^^ cannot mutably borrow field of immutable binding
error[E0596]: cannot borrow immutable field `self.x` as mutable
error[E0596]: cannot borrow field `self.x` of immutable binding as mutable
--> $DIR/issue-39544.rs:30:22
|
29 | fn foo1(&self, other: &Z) {
| ----- use `&mut self` here to make mutable
30 | let _ = &mut self.x; //~ ERROR cannot borrow
| ^^^^^^ cannot mutably borrow immutable field
| ^^^^^^ cannot mutably borrow field of immutable binding
error[E0596]: cannot borrow immutable field `other.x` as mutable
error[E0596]: cannot borrow field `other.x` of immutable binding as mutable
--> $DIR/issue-39544.rs:31:22
|
29 | fn foo1(&self, other: &Z) {
| -- use `&mut Z` here to make mutable
30 | let _ = &mut self.x; //~ ERROR cannot borrow
31 | let _ = &mut other.x; //~ ERROR cannot borrow
| ^^^^^^^ cannot mutably borrow immutable field
| ^^^^^^^ cannot mutably borrow field of immutable binding
error[E0596]: cannot borrow immutable field `self.x` as mutable
error[E0596]: cannot borrow field `self.x` of immutable binding as mutable
--> $DIR/issue-39544.rs:35:22
|
34 | fn foo2<'a>(&'a self, other: &Z) {
| -------- use `&'a mut self` here to make mutable
35 | let _ = &mut self.x; //~ ERROR cannot borrow
| ^^^^^^ cannot mutably borrow immutable field
| ^^^^^^ cannot mutably borrow field of immutable binding
error[E0596]: cannot borrow immutable field `other.x` as mutable
error[E0596]: cannot borrow field `other.x` of immutable binding as mutable
--> $DIR/issue-39544.rs:36:22
|
34 | fn foo2<'a>(&'a self, other: &Z) {
| -- use `&mut Z` here to make mutable
35 | let _ = &mut self.x; //~ ERROR cannot borrow
36 | let _ = &mut other.x; //~ ERROR cannot borrow
| ^^^^^^^ cannot mutably borrow immutable field
| ^^^^^^^ cannot mutably borrow field of immutable binding
error[E0596]: cannot borrow immutable field `self.x` as mutable
error[E0596]: cannot borrow field `self.x` of immutable binding as mutable
--> $DIR/issue-39544.rs:40:22
|
39 | fn foo3<'a>(self: &'a Self, other: &Z) {
| -------- use `&'a mut Self` here to make mutable
40 | let _ = &mut self.x; //~ ERROR cannot borrow
| ^^^^^^ cannot mutably borrow immutable field
| ^^^^^^ cannot mutably borrow field of immutable binding
error[E0596]: cannot borrow immutable field `other.x` as mutable
error[E0596]: cannot borrow field `other.x` of immutable binding as mutable
--> $DIR/issue-39544.rs:41:22
|
39 | fn foo3<'a>(self: &'a Self, other: &Z) {
| -- use `&mut Z` here to make mutable
40 | let _ = &mut self.x; //~ ERROR cannot borrow
41 | let _ = &mut other.x; //~ ERROR cannot borrow
| ^^^^^^^ cannot mutably borrow immutable field
| ^^^^^^^ cannot mutably borrow field of immutable binding
error[E0596]: cannot borrow immutable field `other.x` as mutable
error[E0596]: cannot borrow field `other.x` of immutable binding as mutable
--> $DIR/issue-39544.rs:45:22
|
44 | fn foo4(other: &Z) {
| -- use `&mut Z` here to make mutable
45 | let _ = &mut other.x; //~ ERROR cannot borrow
| ^^^^^^^ cannot mutably borrow immutable field
| ^^^^^^^ cannot mutably borrow field of immutable binding
error[E0596]: cannot borrow immutable field `z.x` as mutable
error[E0596]: cannot borrow field `z.x` of immutable binding as mutable
--> $DIR/issue-39544.rs:51:18
|
50 | pub fn with_arg(z: Z, w: &Z) {
| - consider changing this to `mut z`
51 | let _ = &mut z.x; //~ ERROR cannot borrow
| ^^^ cannot mutably borrow immutable field
| ^^^ cannot mutably borrow field of immutable binding
error[E0596]: cannot borrow immutable field `w.x` as mutable
error[E0596]: cannot borrow field `w.x` of immutable binding as mutable
--> $DIR/issue-39544.rs:52:18
|
50 | pub fn with_arg(z: Z, w: &Z) {
| -- use `&mut Z` here to make mutable
51 | let _ = &mut z.x; //~ ERROR cannot borrow
52 | let _ = &mut w.x; //~ ERROR cannot borrow
| ^^^ cannot mutably borrow immutable field
| ^^^ cannot mutably borrow field of immutable binding
error[E0594]: cannot assign to immutable borrowed content `*x.0`
error[E0594]: cannot assign to borrowed content `*x.0` of immutable binding
--> $DIR/issue-39544.rs:58:5
|
58 | *x.0 = 1; //~ ERROR cannot assign to immutable borrowed content
58 | *x.0 = 1;
| ^^^^^^^^ cannot borrow as mutable
error: aborting due to 12 previous errors

View File

@ -42,7 +42,7 @@ fn test3<F>(f: &mut F) where F: FnMut() {
fn test4(f: &Test) {
f.f.call_mut(())
//~^ ERROR: cannot borrow immutable `Box` content `*f.f` as mutable
//~^ ERROR: cannot borrow `Box` content `*f.f` of immutable binding as mutable
}
fn test5(f: &mut Test) {

View File

@ -19,7 +19,7 @@ error[E0596]: cannot borrow immutable borrowed content `*f` as mutable
35 | (*f)();
| ^^^^ cannot borrow as mutable
error[E0596]: cannot borrow immutable `Box` content `*f.f` as mutable
error[E0596]: cannot borrow `Box` content `*f.f` of immutable binding as mutable
--> $DIR/borrowck-call-is-borrow-issue-12224.rs:44:5
|
43 | fn test4(f: &Test) {