diff options
| author | Ariel Ben-Yehuda <ariel.byd@gmail.com> | 2017-12-04 13:21:28 +0200 |
|---|---|---|
| committer | Ariel Ben-Yehuda <ariel.byd@gmail.com> | 2017-12-06 00:34:02 +0200 |
| commit | 6b9fbb2ab85914820da703182a5c51acf59088cf (patch) | |
| tree | 639e973658bc7dd681d2b048946005d713fe8994 | |
| parent | 82f3fc5dbca4d2d696ce66b902cb339f4507ae9f (diff) | |
| download | rust-6b9fbb2ab85914820da703182a5c51acf59088cf.tar.gz rust-6b9fbb2ab85914820da703182a5c51acf59088cf.zip | |
fix borrows across loops, libcore *almost* compiles
| -rw-r--r-- | src/librustc_mir/dataflow/impls/borrows.rs | 31 | ||||
| -rw-r--r-- | src/test/compile-fail/borrowck/borrowck-mut-borrow-linear-errors.rs | 10 | ||||
| -rw-r--r-- | src/test/compile-fail/issue-25579.rs | 6 |
3 files changed, 32 insertions, 15 deletions
diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index b3b06f7f6cd..c27cb43eff7 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -43,6 +43,7 @@ pub struct Borrows<'a, 'gcx: 'tcx, 'tcx: 'a> { borrows: IndexVec<BorrowIndex, BorrowData<'tcx>>, location_map: FxHashMap<Location, BorrowIndex>, region_map: FxHashMap<Region<'tcx>, FxHashSet<BorrowIndex>>, + local_map: FxHashMap<mir::Local, FxHashSet<BorrowIndex>>, region_span_map: FxHashMap<RegionKind, Span>, nonlexical_regioncx: Option<RegionInferenceContext<'tcx>>, } @@ -89,6 +90,7 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { idx_vec: IndexVec::new(), location_map: FxHashMap(), region_map: FxHashMap(), + local_map: FxHashMap(), region_span_map: FxHashMap() }; visitor.visit_mir(mir); @@ -99,6 +101,7 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { root_scope, location_map: visitor.location_map, region_map: visitor.region_map, + local_map: visitor.local_map, region_span_map: visitor.region_span_map, nonlexical_regioncx }; @@ -108,6 +111,7 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { idx_vec: IndexVec<BorrowIndex, BorrowData<'tcx>>, location_map: FxHashMap<Location, BorrowIndex>, region_map: FxHashMap<Region<'tcx>, FxHashSet<BorrowIndex>>, + local_map: FxHashMap<mir::Local, FxHashSet<BorrowIndex>>, region_span_map: FxHashMap<RegionKind, Span>, } @@ -115,6 +119,14 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>, location: mir::Location) { + fn root_local(mut p: &mir::Place<'_>) -> Option<mir::Local> { + loop { match p { + mir::Place::Projection(pi) => p = &pi.base, + mir::Place::Static(_) => return None, + mir::Place::Local(l) => return Some(*l) + }} + } + if let mir::Rvalue::Ref(region, kind, ref place) = *rvalue { if is_unsafe_place(self.tcx, self.mir, place) { return; } @@ -123,8 +135,14 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { }; let idx = self.idx_vec.push(borrow); self.location_map.insert(location, idx); + let borrows = self.region_map.entry(region).or_insert(FxHashSet()); borrows.insert(idx); + + if let Some(local) = root_local(place) { + let borrows = self.local_map.entry(local).or_insert(FxHashSet()); + borrows.insert(idx); + } } } @@ -213,7 +231,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> { mir::StatementKind::EndRegion(region_scope) => { if let Some(borrow_indexes) = self.region_map.get(&ReScope(region_scope)) { assert!(self.nonlexical_regioncx.is_none()); - for idx in borrow_indexes { sets.kill(&idx); } + sets.kill_all(borrow_indexes); } else { // (if there is no entry, then there are no borrows to be tracked) } @@ -238,10 +256,19 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> { } } + mir::StatementKind::StorageDead(local) => { + // Make sure there are no remaining borrows for locals that + // are gone out of scope. + // + // FIXME: expand this to variables that are assigned over. + if let Some(borrow_indexes) = self.local_map.get(&local) { + sets.kill_all(borrow_indexes); + } + } + mir::StatementKind::InlineAsm { .. } | mir::StatementKind::SetDiscriminant { .. } | mir::StatementKind::StorageLive(..) | - mir::StatementKind::StorageDead(..) | mir::StatementKind::Validate(..) | mir::StatementKind::Nop => {} diff --git a/src/test/compile-fail/borrowck/borrowck-mut-borrow-linear-errors.rs b/src/test/compile-fail/borrowck/borrowck-mut-borrow-linear-errors.rs index 6896d166e7a..63bb04a0e4c 100644 --- a/src/test/compile-fail/borrowck/borrowck-mut-borrow-linear-errors.rs +++ b/src/test/compile-fail/borrowck/borrowck-mut-borrow-linear-errors.rs @@ -23,15 +23,9 @@ fn main() { 1 => { addr = &mut x; } //[ast]~ ERROR [E0499] //[mir]~^ ERROR [E0499] 2 => { addr = &mut x; } //[ast]~ ERROR [E0499] - //[mir]~^ ERROR [E0506] - //[mir]~| ERROR [E0499] - //[mir]~| ERROR [E0499] + //[mir]~^ ERROR [E0499] _ => { addr = &mut x; } //[ast]~ ERROR [E0499] - //[mir]~^ ERROR [E0506] - //[mir]~| ERROR [E0499] - //[mir]~| ERROR [E0499] + //[mir]~^ ERROR [E0499] } } } - - diff --git a/src/test/compile-fail/issue-25579.rs b/src/test/compile-fail/issue-25579.rs index b4a5cd72d86..5f5a58ed759 100644 --- a/src/test/compile-fail/issue-25579.rs +++ b/src/test/compile-fail/issue-25579.rs @@ -20,13 +20,9 @@ fn causes_ice(mut l: &mut Sexpression) { loop { match l { &mut Sexpression::Num(ref mut n) => {}, &mut Sexpression::Cons(ref mut expr) => { //[ast]~ ERROR [E0499] - //[mir]~^ ERROR [E0506] - //[mir]~| ERROR [E0499] + //[mir]~^ ERROR [E0499] l = &mut **expr; //[ast]~ ERROR [E0506] //[mir]~^ ERROR [E0506] - //[mir]~| ERROR [E0499] - //[mir]~| ERROR [E0506] - //[mir]~| ERROR [E0499] } }} } |
