add reborrow constraints

This commit is contained in:
Santiago Pastorino 2017-10-25 15:10:48 -04:00 committed by Niko Matsakis
parent f700728a3b
commit b8615f3bea
2 changed files with 74 additions and 0 deletions

View File

@ -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 @@ fn add_borrow_constraint(
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 @@ fn visit_statement(&mut self,
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);
}
}

View File

@ -0,0 +1,39 @@
// Copyright 2012-2016 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Basic test for reborrow constraints: the region (`R5`) that appears
// in the type of `r_a` must outlive the region (`R7`) that appears in
// the type of `r_b`
// compile-flags:-Znll -Zverbose
// ^^^^^^^^^ force compiler to dump more region information
#![allow(warnings)]
fn use_x(_: &mut i32) -> bool { true }
fn main() {
let mut foo: i32 = 22;
let r_a: &mut i32 = &mut foo;
let r_b: &mut i32 = &mut *r_a;
use_x(r_b);
}
// END RUST SOURCE
// START rustc.node13.nll.0.mir
// | R5: {bb0[6], bb0[7], bb0[8], bb0[9], bb0[10], bb0[11], bb0[12], bb0[13], bb0[14]}
// ...
// | R7: {bb0[11], bb0[12], bb0[13], bb0[14]}
// END rustc.node13.nll.0.mir
// START rustc.node13.nll.0.mir
// let _2: &'_#5r mut i32;
// ...
// let _4: &'_#7r mut i32;
// END rustc.node13.nll.0.mir