Skip to content

Commit da4d490

Browse files
committed
Auto merge of #43479 - ivanbakel:loop_borrow_msg, r=estebank
Extended error message for mut borrow conflicts in loops RFC issue: rust-lang/rfcs#2080 The error message for multiple mutable borrows on the same value over loop iterations now makes it clear that the conflict comes from the borrow outlasting the loop. The wording of the error is based on the special case of the moved-value error for a value moved in a loop. Following the example of that error, the code remains the same for the special case. This is mainly because I felt the current message is confusing in the loop case : #43437. It's not clear that the two conflicting borrows are in different iterations of the loop, and instead it just looks like the compiler has an issue with a single line.
2 parents e574ba4 + 6888520 commit da4d490

File tree

5 files changed

+145
-13
lines changed

5 files changed

+145
-13
lines changed

src/librustc_borrowck/borrowck/check_loans.rs

+27-13
Original file line numberDiff line numberDiff line change
@@ -466,19 +466,33 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
466466
let mut err = match (new_loan.kind, old_loan.kind) {
467467
(ty::MutBorrow, ty::MutBorrow) => {
468468
let mut err = struct_span_err!(self.bccx, new_loan.span, E0499,
469-
"cannot borrow `{}`{} as mutable \
470-
more than once at a time",
471-
nl, new_loan_msg);
472-
err.span_label(
473-
old_loan.span,
474-
format!("first mutable borrow occurs here{}", old_loan_msg));
475-
err.span_label(
476-
new_loan.span,
477-
format!("second mutable borrow occurs here{}", new_loan_msg));
478-
err.span_label(
479-
previous_end_span,
480-
"first borrow ends here");
481-
err
469+
"cannot borrow `{}`{} as mutable \
470+
more than once at a time",
471+
nl, new_loan_msg);
472+
473+
if new_loan.span == old_loan.span {
474+
// Both borrows are happening in the same place
475+
// Meaning the borrow is occuring in a loop
476+
err.span_label(
477+
new_loan.span,
478+
format!("mutable borrow starts here in previous \
479+
iteration of loop{}", new_loan_msg));
480+
err.span_label(
481+
previous_end_span,
482+
"mutable borrow ends here");
483+
err
484+
} else {
485+
err.span_label(
486+
old_loan.span,
487+
format!("first mutable borrow occurs here{}", old_loan_msg));
488+
err.span_label(
489+
new_loan.span,
490+
format!("second mutable borrow occurs here{}", new_loan_msg));
491+
err.span_label(
492+
previous_end_span,
493+
"first borrow ends here");
494+
err
495+
}
482496
}
483497

484498
(ty::UniqueImmBorrow, ty::UniqueImmBorrow) => {
+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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+
// produce special borrowck message inside all kinds of loops
12+
13+
struct FuncWrapper<'a, T : 'a> {
14+
func : fn(&'a mut T) -> ()
15+
}
16+
17+
impl<'a, T : 'a> FuncWrapper<'a, T> {
18+
fn in_loop(self, arg : &'a mut T) {
19+
loop {
20+
(self.func)(arg)
21+
}
22+
}
23+
24+
fn in_while(self, arg : &'a mut T) {
25+
while true {
26+
(self.func)(arg)
27+
}
28+
}
29+
30+
fn in_for(self, arg : &'a mut T) {
31+
let v : Vec<()> = vec![];
32+
for _ in v.iter() {
33+
(self.func)(arg)
34+
}
35+
}
36+
}
37+
38+
fn main() {
39+
}
40+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
error[E0499]: cannot borrow `*arg` as mutable more than once at a time
2+
--> $DIR/mut-borrow-in-loop.rs:20:25
3+
|
4+
20 | (self.func)(arg)
5+
| ^^^ mutable borrow starts here in previous iteration of loop
6+
21 | }
7+
22 | }
8+
| - mutable borrow ends here
9+
10+
error[E0499]: cannot borrow `*arg` as mutable more than once at a time
11+
--> $DIR/mut-borrow-in-loop.rs:26:25
12+
|
13+
26 | (self.func)(arg)
14+
| ^^^ mutable borrow starts here in previous iteration of loop
15+
27 | }
16+
28 | }
17+
| - mutable borrow ends here
18+
19+
error[E0499]: cannot borrow `*arg` as mutable more than once at a time
20+
--> $DIR/mut-borrow-in-loop.rs:33:25
21+
|
22+
33 | (self.func)(arg)
23+
| ^^^ mutable borrow starts here in previous iteration of loop
24+
34 | }
25+
35 | }
26+
| - mutable borrow ends here
27+
28+
error: aborting due to 3 previous errors
29+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
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+
// ensure borrowck messages are correct outside special case
12+
13+
fn main() {
14+
let mut void = ();
15+
16+
let first = &mut void;
17+
let second = &mut void;
18+
19+
loop {
20+
let mut inner_void = ();
21+
22+
let inner_first = &mut inner_void;
23+
let inner_second = &mut inner_void;
24+
}
25+
}
26+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
error[E0499]: cannot borrow `void` as mutable more than once at a time
2+
--> $DIR/mut-borrow-outside-loop.rs:17:23
3+
|
4+
16 | let first = &mut void;
5+
| ---- first mutable borrow occurs here
6+
17 | let second = &mut void;
7+
| ^^^^ second mutable borrow occurs here
8+
...
9+
25 | }
10+
| - first borrow ends here
11+
12+
error[E0499]: cannot borrow `inner_void` as mutable more than once at a time
13+
--> $DIR/mut-borrow-outside-loop.rs:23:33
14+
|
15+
22 | let inner_first = &mut inner_void;
16+
| ---------- first mutable borrow occurs here
17+
23 | let inner_second = &mut inner_void;
18+
| ^^^^^^^^^^ second mutable borrow occurs here
19+
24 | }
20+
| - first borrow ends here
21+
22+
error: aborting due to 2 previous errors
23+

0 commit comments

Comments
 (0)