Auto merge of #45603 - joshleeb:iss42106, r=estebank

Fix duplicate display of error E0502

Ref. Repeated "mutable/immutable borrow" error messages #42106.

This PR modifies the return type of [`report_error_if_loan_conflicts_with_restriction`](0f0f5db465/src/librustc_borrowck/borrowck/check_loans.rs (L398-L403)) so the result can be checked in [`report_error_if_loans_conflict`](0f0f5db465/src/librustc_borrowck/borrowck/check_loans.rs (L377-L396)). This is done to prevent displaying a duplicate of the error message E0502 which is referenced in #42106.

The output of compiling:

```rust
fn do_something<T>(collection: &mut Vec<T>) {
    let _a = &collection;
    collection.swap(1, 2);
}

fn main() {}
```

is now

```bash
$ rustc src/test/compile-fail/issue-42106.rs
error[E0502]: cannot borrow `*collection` as mutable because `collection` is also borrowed as immutable
  --> src/test/compile-fail/issue-42106.rs:13:5
   |
12 |     let _a = &collection;
   |               ---------- immutable borrow occurs here
13 |     collection.swap(1, 2);
   |     ^^^^^^^^^^ mutable borrow occurs here
14 | }
   | - immutable borrow ends here

error: aborting due to 2 previous errors
```

r? @estebank
This commit is contained in:
bors 2017-10-30 06:17:39 +00:00
commit 86d1178320
3 changed files with 47 additions and 9 deletions

View File

@ -395,10 +395,21 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
assert!(self.bccx.region_scope_tree.scopes_intersect(old_loan.kill_scope,
new_loan.kill_scope));
self.report_error_if_loan_conflicts_with_restriction(
old_loan, new_loan, old_loan, new_loan) &&
self.report_error_if_loan_conflicts_with_restriction(
new_loan, old_loan, old_loan, new_loan)
let err_old_new = self.report_error_if_loan_conflicts_with_restriction(
old_loan, new_loan, old_loan, new_loan).err();
let err_new_old = self.report_error_if_loan_conflicts_with_restriction(
new_loan, old_loan, old_loan, new_loan).err();
match (err_old_new, err_new_old) {
(Some(mut err), None) | (None, Some(mut err)) => err.emit(),
(Some(mut err_old), Some(mut err_new)) => {
err_old.emit();
err_new.cancel();
}
(None, None) => return true,
}
false
}
pub fn report_error_if_loan_conflicts_with_restriction(&self,
@ -406,7 +417,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
loan2: &Loan<'tcx>,
old_loan: &Loan<'tcx>,
new_loan: &Loan<'tcx>)
-> bool {
-> Result<(), DiagnosticBuilder<'a>> {
//! Checks whether the restrictions introduced by `loan1` would
//! prohibit `loan2`. Returns false if an error is reported.
@ -416,7 +427,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
loan2);
if compatible_borrow_kinds(loan1.kind, loan2.kind) {
return true;
return Ok(());
}
let loan2_base_path = owned_ptr_base_path_rc(&loan2.loan_path);
@ -520,11 +531,10 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
_ => { }
}
err.emit();
return false;
return Err(err);
}
true
Ok(())
}
fn consume_common(&self,

View File

@ -0,0 +1,16 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn do_something<T>(collection: &mut Vec<T>) {
let _a = &collection;
collection.swap(1, 2);
}
fn main() {}

View File

@ -0,0 +1,12 @@
error[E0502]: cannot borrow `*collection` as mutable because `collection` is also borrowed as immutable
--> $DIR/issue-42106.rs:13:5
|
12 | let _a = &collection;
| ---------- immutable borrow occurs here
13 | collection.swap(1, 2);
| ^^^^^^^^^^ mutable borrow occurs here
14 | }
| - immutable borrow ends here
error: aborting due to 2 previous errors