diff options
| author | bors <bors@rust-lang.org> | 2015-10-27 21:04:59 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-10-27 21:04:59 +0000 |
| commit | 8a72584f977d2d72f752c2a540e160944159e8db (patch) | |
| tree | 78a1d3ba818bb07a64cb6d67b19205ce6e0305ed | |
| parent | a1e2a5538a33577f5845fc8bf56d06c452513245 (diff) | |
| parent | ba9c383790c22dba74026340b01f2dda3e78f88c (diff) | |
| download | rust-8a72584f977d2d72f752c2a540e160944159e8db.tar.gz rust-8a72584f977d2d72f752c2a540e160944159e8db.zip | |
Auto merge of #28833 - jryans:borrowck-linear-errors, r=pnkfelix
Change error reporting of conflicting loans to stop earlier after printing an error for a given borrow, instead of proceeding to error on possibly every issued loan. This keeps us down to O(n) errors (for n problem lines), instead of O(n^2) errors in some cases. Fixes #27485.
| -rw-r--r-- | src/librustc_borrowck/borrowck/check_loans.rs | 18 | ||||
| -rw-r--r-- | src/test/compile-fail/borrowck-mut-borrow-linear-errors.rs | 28 |
2 files changed, 38 insertions, 8 deletions
diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index 43e9cdd73c4..ff5d364b968 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -363,13 +363,14 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { let new_loan_indices = self.loans_generated_by(node); debug!("new_loan_indices = {:?}", new_loan_indices); - self.each_issued_loan(node, |issued_loan| { - for &new_loan_index in &new_loan_indices { + for &new_loan_index in &new_loan_indices { + self.each_issued_loan(node, |issued_loan| { let new_loan = &self.all_loans[new_loan_index]; - self.report_error_if_loans_conflict(issued_loan, new_loan); - } - true - }); + // Only report an error for the first issued loan that conflicts + // to avoid O(n^2) errors. + self.report_error_if_loans_conflict(issued_loan, new_loan) + }); + } for (i, &x) in new_loan_indices.iter().enumerate() { let old_loan = &self.all_loans[x]; @@ -382,7 +383,8 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { pub fn report_error_if_loans_conflict(&self, old_loan: &Loan<'tcx>, - new_loan: &Loan<'tcx>) { + new_loan: &Loan<'tcx>) + -> bool { //! Checks whether `old_loan` and `new_loan` can safely be issued //! simultaneously. @@ -397,7 +399,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { 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); + new_loan, old_loan, old_loan, new_loan) } pub fn report_error_if_loan_conflicts_with_restriction(&self, diff --git a/src/test/compile-fail/borrowck-mut-borrow-linear-errors.rs b/src/test/compile-fail/borrowck-mut-borrow-linear-errors.rs new file mode 100644 index 00000000000..38e0e27a7b9 --- /dev/null +++ b/src/test/compile-fail/borrowck-mut-borrow-linear-errors.rs @@ -0,0 +1,28 @@ +// Copyright 2015 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. + +// Test to ensure we only report an error for the first issued loan that +// conflicts with a new loan, as opposed to every issued loan. This keeps us +// down to O(n) errors (for n problem lines), instead of O(n^2) errors. + +fn main() { + let mut x = 1; + let mut addr; + loop { + match 1 { + 1 => { addr = &mut x; } + //~^ ERROR cannot borrow `x` as mutable more than once at a time + 2 => { addr = &mut x; } + //~^ ERROR cannot borrow `x` as mutable more than once at a time + _ => { addr = &mut x; } + //~^ ERROR cannot borrow `x` as mutable more than once at a time + } + } +} |
