summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix S. Klock II <pnkfelix@pnkfx.org>2018-05-07 15:58:09 +0200
committerFelix S. Klock II <pnkfelix@pnkfx.org>2018-05-29 23:02:40 +0200
commit638acd300fa42a2d0128378a37bffae2c11315ad (patch)
treeaf503410b4ee14f41216c9bbee3b299a7e4fdd91
parentrust-lang/rust#41962 has a new error with my new code. Incorporate that into ... (diff)
downloadgrust-638acd300fa42a2d0128378a37bffae2c11315ad.tar.gz
grust-638acd300fa42a2d0128378a37bffae2c11315ad.tar.bz2
grust-638acd300fa42a2d0128378a37bffae2c11315ad.tar.xz
Fallout from allowing some mutation in guards.
For some reason, allowing restricted mutation in match arms exposed an obvious case where a unique borrow can indeed fail, namely something like: ```rust match b { ... ref mut r if { (|| { let bar = &mut *r; **bar = false; })(); false } => { &mut *r } // ~~~~~~~ // | // This ends up holding a `&unique` borrow of `r`, but there ends up being an // implicit shared borrow in the guard thanks to rust-lang/rust#49870 ... } ```
-rw-r--r--src/librustc_mir/borrow_check/mod.rs18
1 files changed, 10 insertions, 8 deletions
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 233974435f..ec26710451 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -1697,14 +1697,16 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
1697 ); 1697 );
1698 let mut error_reported = false; 1698 let mut error_reported = false;
1699 match kind { 1699 match kind {
1700 Reservation(WriteKind::MutableBorrow(BorrowKind::Unique)) 1700 Reservation(WriteKind::MutableBorrow(borrow_kind @ BorrowKind::Unique))
1701 | Write(WriteKind::MutableBorrow(BorrowKind::Unique)) => { 1701 | Reservation(WriteKind::MutableBorrow(borrow_kind @ BorrowKind::Mut { .. }))
1702 if let Err(_place_err) = self.is_mutable(place, LocalMutationIsAllowed::Yes) { 1702 | Write(WriteKind::MutableBorrow(borrow_kind @ BorrowKind::Unique))
1703 span_bug!(span, "&unique borrow for {:?} should not fail", place); 1703 | Write(WriteKind::MutableBorrow(borrow_kind @ BorrowKind::Mut { .. })) =>
1704 } 1704 {
1705 } 1705 let is_local_mutation_allowed = match borrow_kind {
1706 Reservation(WriteKind::MutableBorrow(BorrowKind::Mut { .. })) 1706 BorrowKind::Unique => LocalMutationIsAllowed::Yes,
1707 | Write(WriteKind::MutableBorrow(BorrowKind::Mut { .. })) => { 1707 BorrowKind::Mut { .. } => is_local_mutation_allowed,
1708 BorrowKind::Shared => unreachable!(),
1709 };
1708 match self.is_mutable(place, is_local_mutation_allowed) { 1710 match self.is_mutable(place, is_local_mutation_allowed) {
1709 Ok(root_place) => self.add_used_mut(root_place, flow_state), 1711 Ok(root_place) => self.add_used_mut(root_place, flow_state),
1710 Err(place_err) => { 1712 Err(place_err) => {