Skip to content

Commit 8a72584

Browse files
committed
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.
2 parents a1e2a55 + ba9c383 commit 8a72584

File tree

2 files changed

+38
-8
lines changed

2 files changed

+38
-8
lines changed

src/librustc_borrowck/borrowck/check_loans.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -363,13 +363,14 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
363363
let new_loan_indices = self.loans_generated_by(node);
364364
debug!("new_loan_indices = {:?}", new_loan_indices);
365365

366-
self.each_issued_loan(node, |issued_loan| {
367-
for &new_loan_index in &new_loan_indices {
366+
for &new_loan_index in &new_loan_indices {
367+
self.each_issued_loan(node, |issued_loan| {
368368
let new_loan = &self.all_loans[new_loan_index];
369-
self.report_error_if_loans_conflict(issued_loan, new_loan);
370-
}
371-
true
372-
});
369+
// Only report an error for the first issued loan that conflicts
370+
// to avoid O(n^2) errors.
371+
self.report_error_if_loans_conflict(issued_loan, new_loan)
372+
});
373+
}
373374

374375
for (i, &x) in new_loan_indices.iter().enumerate() {
375376
let old_loan = &self.all_loans[x];
@@ -382,7 +383,8 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
382383

383384
pub fn report_error_if_loans_conflict(&self,
384385
old_loan: &Loan<'tcx>,
385-
new_loan: &Loan<'tcx>) {
386+
new_loan: &Loan<'tcx>)
387+
-> bool {
386388
//! Checks whether `old_loan` and `new_loan` can safely be issued
387389
//! simultaneously.
388390
@@ -397,7 +399,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
397399
self.report_error_if_loan_conflicts_with_restriction(
398400
old_loan, new_loan, old_loan, new_loan) &&
399401
self.report_error_if_loan_conflicts_with_restriction(
400-
new_loan, old_loan, old_loan, new_loan);
402+
new_loan, old_loan, old_loan, new_loan)
401403
}
402404

403405
pub fn report_error_if_loan_conflicts_with_restriction(&self,
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright 2015 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+
// Test to ensure we only report an error for the first issued loan that
12+
// conflicts with a new loan, as opposed to every issued loan. This keeps us
13+
// down to O(n) errors (for n problem lines), instead of O(n^2) errors.
14+
15+
fn main() {
16+
let mut x = 1;
17+
let mut addr;
18+
loop {
19+
match 1 {
20+
1 => { addr = &mut x; }
21+
//~^ ERROR cannot borrow `x` as mutable more than once at a time
22+
2 => { addr = &mut x; }
23+
//~^ ERROR cannot borrow `x` as mutable more than once at a time
24+
_ => { addr = &mut x; }
25+
//~^ ERROR cannot borrow `x` as mutable more than once at a time
26+
}
27+
}
28+
}

0 commit comments

Comments
 (0)