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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn do_something(collection: &mut Vec) { + 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 +