about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_borrowck/borrowck/check_loans.rs28
-rw-r--r--src/test/ui/issue-42106.rs16
-rw-r--r--src/test/ui/issue-42106.stderr12
3 files changed, 47 insertions, 9 deletions
diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs
index 6fd9ff4012e..c1d0d849dfb 100644
--- a/src/librustc_borrowck/borrowck/check_loans.rs
+++ b/src/librustc_borrowck/borrowck/check_loans.rs
@@ -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,
diff --git a/src/test/ui/issue-42106.rs b/src/test/ui/issue-42106.rs
new file mode 100644
index 00000000000..f13f1dd1145
--- /dev/null
+++ b/src/test/ui/issue-42106.rs
@@ -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() {}
diff --git a/src/test/ui/issue-42106.stderr b/src/test/ui/issue-42106.stderr
new file mode 100644
index 00000000000..481cdb5f5b2
--- /dev/null
+++ b/src/test/ui/issue-42106.stderr
@@ -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
+