From 5086657b42624f0c28b0df01f1c31563ac6b2f4a Mon Sep 17 00:00:00 2001 From: Josh Leeb-du Toit Date: Sun, 29 Oct 2017 10:37:59 +1100 Subject: [PATCH 1/5] Fix duplicate display of error E0502 --- src/librustc_borrowck/borrowck/check_loans.rs | 39 ++++++++++++++----- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index 6fd9ff4012e..a2d6fd536bc 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -395,10 +395,32 @@ 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 = match self.report_error_if_loan_conflicts_with_restriction( + old_loan, new_loan, old_loan, new_loan + ) { + Err(err) => Some(err), + Ok(_) => None + }; + + let err_new_old = match self.report_error_if_loan_conflicts_with_restriction( + new_loan, old_loan, old_loan, new_loan + ) { + Err(err) => Some(err), + Ok(_) => None + }; + + if let Some(mut err_old) = err_old_new { + err_old.emit(); + if let Some(mut err_new) = err_new_old { + err_new.cancel(); + } + } else if let Some(mut err_new) = err_new_old { + err_new.emit(); + } else { + return true; + } + + false } pub fn report_error_if_loan_conflicts_with_restriction(&self, @@ -406,7 +428,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 +438,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 +542,10 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { _ => { } } - err.emit(); - return false; + return Err(err); } - true + Ok(()) } fn consume_common(&self, From 975ff7b7a053f99fa24e7a79b22aec63d054409a Mon Sep 17 00:00:00 2001 From: Josh Leeb-du Toit Date: Sun, 29 Oct 2017 12:10:59 +1100 Subject: [PATCH 2/5] Add test for fix duplicate display of E0502 --- src/test/compile-fail/issue-42106.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/test/compile-fail/issue-42106.rs diff --git a/src/test/compile-fail/issue-42106.rs b/src/test/compile-fail/issue-42106.rs new file mode 100644 index 00000000000..a9aa94b5b08 --- /dev/null +++ b/src/test/compile-fail/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); //~ ERROR E0502 +} + +fn main() {} From 014e61094a6547cf1aee521c41e86eba22c8ac8f Mon Sep 17 00:00:00 2001 From: Josh Leeb-du Toit Date: Mon, 30 Oct 2017 08:20:52 +1100 Subject: [PATCH 3/5] Refactor matches to use Result::err --- src/librustc_borrowck/borrowck/check_loans.rs | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index a2d6fd536bc..01a6aedc0b0 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -395,19 +395,12 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { assert!(self.bccx.region_scope_tree.scopes_intersect(old_loan.kill_scope, new_loan.kill_scope)); - let err_old_new = match self.report_error_if_loan_conflicts_with_restriction( + let err_old_new = Result::err(self.report_error_if_loan_conflicts_with_restriction( old_loan, new_loan, old_loan, new_loan - ) { - Err(err) => Some(err), - Ok(_) => None - }; - - let err_new_old = match self.report_error_if_loan_conflicts_with_restriction( + )); + let err_new_old = Result::err(self.report_error_if_loan_conflicts_with_restriction( new_loan, old_loan, old_loan, new_loan - ) { - Err(err) => Some(err), - Ok(_) => None - }; + )); if let Some(mut err_old) = err_old_new { err_old.emit(); From 37f2382435816b0ddfc3e46a856463810f66862c Mon Sep 17 00:00:00 2001 From: Josh Leeb-du Toit Date: Mon, 30 Oct 2017 09:58:09 +1100 Subject: [PATCH 4/5] Refactor if block to use idiomatic matches --- src/librustc_borrowck/borrowck/check_loans.rs | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index 01a6aedc0b0..c1d0d849dfb 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -395,22 +395,18 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { assert!(self.bccx.region_scope_tree.scopes_intersect(old_loan.kill_scope, new_loan.kill_scope)); - let err_old_new = Result::err(self.report_error_if_loan_conflicts_with_restriction( - old_loan, new_loan, old_loan, new_loan - )); - let err_new_old = Result::err(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(); - if let Some(mut err_old) = err_old_new { - err_old.emit(); - if let Some(mut err_new) = err_new_old { + 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(); } - } else if let Some(mut err_new) = err_new_old { - err_new.emit(); - } else { - return true; + (None, None) => return true, } false From cf10bcfe4861ce01fe932300fa64dbb4484f3ef7 Mon Sep 17 00:00:00 2001 From: Josh Leeb-du Toit Date: Mon, 30 Oct 2017 09:58:45 +1100 Subject: [PATCH 5/5] Move issue-42106 test from compile-fail to ui --- src/test/{compile-fail => ui}/issue-42106.rs | 2 +- src/test/ui/issue-42106.stderr | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) rename src/test/{compile-fail => ui}/issue-42106.rs (92%) create mode 100644 src/test/ui/issue-42106.stderr diff --git a/src/test/compile-fail/issue-42106.rs b/src/test/ui/issue-42106.rs similarity index 92% rename from src/test/compile-fail/issue-42106.rs rename to src/test/ui/issue-42106.rs index a9aa94b5b08..f13f1dd1145 100644 --- a/src/test/compile-fail/issue-42106.rs +++ b/src/test/ui/issue-42106.rs @@ -10,7 +10,7 @@ fn do_something(collection: &mut Vec) { let _a = &collection; - collection.swap(1, 2); //~ ERROR E0502 + 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 +