diff options
| author | Santiago Pastorino <spastorino@gmail.com> | 2017-10-25 15:10:48 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2017-10-31 12:41:39 -0400 |
| commit | b8615f3bea67f12db7a84687923d62d5aabc22c1 (patch) | |
| tree | d1120935ea8b3865e4909fd13084cc894fda3e92 /src/librustc_mir/transform | |
| parent | f700728a3bcb1f82b5457c4ac3051c672460ed7e (diff) | |
| download | rust-b8615f3bea67f12db7a84687923d62d5aabc22c1.tar.gz rust-b8615f3bea67f12db7a84687923d62d5aabc22c1.zip | |
add reborrow constraints
Diffstat (limited to 'src/librustc_mir/transform')
| -rw-r--r-- | src/librustc_mir/transform/nll/constraint_generation.rs | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/src/librustc_mir/transform/nll/constraint_generation.rs b/src/librustc_mir/transform/nll/constraint_generation.rs index 1acbd72a47d..1fc7dbd5bd0 100644 --- a/src/librustc_mir/transform/nll/constraint_generation.rs +++ b/src/librustc_mir/transform/nll/constraint_generation.rs @@ -8,9 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use rustc::hir; use rustc::mir::{BasicBlock, BorrowKind, Location, Lvalue, Mir, Rvalue, Statement, StatementKind}; use rustc::mir::transform::MirSource; use rustc::mir::visit::Visitor; +use rustc::mir::Lvalue::Projection; +use rustc::mir::{LvalueProjection, ProjectionElem}; use rustc::infer::InferCtxt; use rustc::traits::{self, ObligationCause}; use rustc::ty::{self, Ty}; @@ -198,6 +201,37 @@ impl<'cx, 'gcx, 'tcx> ConstraintGeneration<'cx, 'gcx, 'tcx> { destination_region.to_region_index(), location.successor_within_block()); } + + fn add_reborrow_constraint( + &mut self, + location: Location, + borrow_region: ty::Region<'tcx>, + borrowed_lv: &Lvalue<'tcx>, + ) { + if let Projection(ref proj) = *borrowed_lv { + let LvalueProjection { ref base, ref elem } = **proj; + + if let ProjectionElem::Deref = *elem { + let tcx = self.infcx.tcx; + let base_ty = base.ty(self.mir, tcx).to_ty(tcx); + let base_sty = &base_ty.sty; + + if let ty::TyRef(base_region, ty::TypeAndMut{ ty: _, mutbl }) = *base_sty { + match mutbl { + hir::Mutability::MutImmutable => { }, + + hir::Mutability::MutMutable => { + self.add_reborrow_constraint(location, borrow_region, base); + }, + } + + self.regioncx.add_outlives(base_region.to_region_index(), + borrow_region.to_region_index(), + location.successor_within_block()); + } + } + } + } } impl<'cx, 'gcx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cx, 'gcx, 'tcx> { @@ -214,6 +248,7 @@ impl<'cx, 'gcx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cx, 'gcx, 'tcx> { if let StatementKind::Assign(ref destination_lv, ref rv) = statement.kind { if let Rvalue::Ref(region, bk, ref borrowed_lv) = *rv { self.add_borrow_constraint(location, destination_lv, region, bk, borrowed_lv); + self.add_reborrow_constraint(location, region, borrowed_lv); } } |
