Point to let when modifying field of immutable variable

Point at the immutable local variable when trying to modify one of its
fields.

Given a file:

```rust
struct Foo {
    pub v: Vec<String>
}

fn main() {
    let f = Foo { v: Vec::new() };
    f.v.push("cat".to_string());
}
```

present the following output:

```
error: cannot borrow immutable field `f.v` as mutable
 --> file.rs:7:13
  |
6 |    let f = Foo { v: Vec::new() };
  |        - this should be `mut`
7 |    f.v.push("cat".to_string());
  |    ^^^

error: aborting due to previous error
```
This commit is contained in:
Esteban Küber 2017-03-11 11:11:50 -08:00
parent f573db4f80
commit 6ba494b68b
3 changed files with 29 additions and 0 deletions

View File

@ -195,6 +195,21 @@ pub struct cmt_<'tcx> {
pub type cmt<'tcx> = Rc<cmt_<'tcx>>;
impl<'tcx> cmt_<'tcx> {
pub fn get_def(&self) -> Option<ast::NodeId> {
match self.cat {
Categorization::Deref(ref cmt, ..) |
Categorization::Interior(ref cmt, _) |
Categorization::Downcast(ref cmt, _) => {
if let Categorization::Local(nid) = cmt.cat {
Some(nid)
} else {
None
}
}
_ => None
}
}
pub fn get_field(&self, name: ast::Name) -> Option<DefId> {
match self.cat {
Categorization::Deref(ref cmt, ..) |

View File

@ -659,6 +659,7 @@ pub fn span_err_with_code<S: Into<MultiSpan>>(&self, s: S, msg: &str, code: &str
pub fn bckerr_to_diag(&self, err: &BckError<'tcx>) -> DiagnosticBuilder<'a> {
let span = err.span.clone();
let mut immutable_field = None;
let mut local_def = None;
let msg = &match err.code {
err_mutbl => {
@ -708,6 +709,14 @@ pub fn bckerr_to_diag(&self, err: &BckError<'tcx>) -> DiagnosticBuilder<'a> {
}
None
});
local_def = err.cmt.get_def()
.and_then(|nid| {
if !self.tcx.hir.is_argument(nid) {
Some(self.tcx.hir.span(nid))
} else {
None
}
});
format!("cannot borrow {} as mutable", descr)
}
@ -738,6 +747,9 @@ pub fn bckerr_to_diag(&self, err: &BckError<'tcx>) -> DiagnosticBuilder<'a> {
if let Some((span, msg)) = immutable_field {
db.span_label(span, &msg);
}
if let Some(span) = local_def {
db.span_label(span, &"this should be `mut`");
}
db
}

View File

@ -1,6 +1,8 @@
error: cannot borrow immutable field `z.x` as mutable
--> $DIR/issue-39544.rs:21:18
|
20 | let z = Z { x: X::Y };
| - this should be `mut`
21 | let _ = &mut z.x;
| ^^^