Skip to content

Commit 289772f

Browse files
committed
Point to definition when modifying field of immutable variable
Given a file ```rust struct S { x: i32, } fn foo() { let s = S { x: 42 }; s.x += 1; } fn bar(s: S) { s.x += 1; } ``` Provide the following output: ```rust error: cannot assign to immutable field `s.x` --> $DIR/issue-35937.rs:16:5 | 5 | let s = S { x: 42 }; | - consider changing this to `mut s` 6 | s.x += 1; | ^^^^^^^^ cannot mutably borrow immutable field error: cannot assign to immutable field `s.x` --> $DIR/issue-35937.rs:20:5 | 8 | fn bar(s: S) { | - consider changing this to `mut s` 9 | s.x += 1; | ^^^^^^^^ cannot mutably borrow immutable field ``` Follow up to rust-lang#40445. Fix rust-lang#35937.
1 parent c62e532 commit 289772f

File tree

3 files changed

+59
-0
lines changed

3 files changed

+59
-0
lines changed

src/librustc_borrowck/borrowck/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
688688

689689
match err.cause {
690690
MutabilityViolation => {
691+
local_def = err.cmt.get_def().map(|nid| self.tcx.hir.span(nid));
691692
format!("cannot assign to {}", descr)
692693
}
693694
BorrowViolation(euv::ClosureCapture(_)) => {
@@ -1132,6 +1133,7 @@ before rustc 1.16, this temporary lived longer - see issue #39283 \
11321133
}
11331134
}
11341135
}
1136+
11351137
pub fn append_loan_path_to_string(&self,
11361138
loan_path: &LoanPath<'tcx>,
11371139
out: &mut String) {
+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
struct Foo {
12+
pub v: Vec<String>
13+
}
14+
15+
fn main() {
16+
let f = Foo { v: Vec::new() };
17+
f.v.push("cat".to_string());
18+
}
19+
20+
21+
struct S {
22+
x: i32,
23+
}
24+
fn foo() {
25+
let s = S { x: 42 };
26+
s.x += 1;
27+
}
28+
29+
fn bar(s: S) {
30+
s.x += 1;
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
error: cannot borrow immutable field `f.v` as mutable
2+
--> $DIR/issue-35937.rs:17:5
3+
|
4+
16 | let f = Foo { v: Vec::new() };
5+
| - consider changing this to `mut f`
6+
17 | f.v.push("cat".to_string());
7+
| ^^^ cannot mutably borrow immutable field
8+
9+
error: cannot assign to immutable field `s.x`
10+
--> $DIR/issue-35937.rs:26:5
11+
|
12+
25 | let s = S { x: 42 };
13+
| - consider changing this to `mut s`
14+
26 | s.x += 1;
15+
| ^^^^^^^^ cannot mutably borrow immutable field
16+
17+
error: cannot assign to immutable field `s.x`
18+
--> $DIR/issue-35937.rs:30:5
19+
|
20+
29 | fn bar(s: S) {
21+
| - consider changing this to `mut s`
22+
30 | s.x += 1;
23+
| ^^^^^^^^ cannot mutably borrow immutable field
24+
25+
error: aborting due to 3 previous errors
26+

0 commit comments

Comments
 (0)