Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
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
```
  • Loading branch information
estebank committed Mar 11, 2017
commit 6ba494b68bede3bd8d1288f53137c8895260bec7
15 changes: 15 additions & 0 deletions src/librustc/middle/mem_categorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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, ..) |
Expand Down
12 changes: 12 additions & 0 deletions src/librustc_borrowck/borrowck/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
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 => {
Expand Down Expand Up @@ -708,6 +709,14 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
}
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)
}
Expand Down Expand Up @@ -738,6 +747,9 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
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
}

Expand Down
2 changes: 2 additions & 0 deletions src/test/ui/did_you_mean/issue-39544.stderr
Original file line number Diff line number Diff line change
@@ -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;
| ^^^

Expand Down