Gather loans for static items

We currently gather loans for static items that are defined within
functions. This change enables loan gathering on static items declared
globally.
This commit is contained in:
Flavio Percoco 2014-03-14 17:01:05 +01:00
parent 8767c69339
commit 69ccd807da
2 changed files with 59 additions and 28 deletions

View File

@ -82,10 +82,12 @@ impl<'a> visit::Visitor<()> for GatherLoanCtxt<'a> {
fn visit_block(&mut self, b: &Block, _: ()) {
gather_loans_in_block(self, b);
}
fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block,
s: Span, n: NodeId, _: ()) {
gather_loans_in_fn(self, fk, fd, b, s, n);
}
/// Do not visit closures or fn items here, the outer loop in
/// borrowck/mod will visit them for us in turn.
fn visit_fn(&mut self, _: &FnKind, _: &FnDecl, _: &Block,
_: Span, _: NodeId, _: ()) {}
fn visit_stmt(&mut self, s: &Stmt, _: ()) {
visit::walk_stmt(self, s, ());
}
@ -99,10 +101,20 @@ impl<'a> visit::Visitor<()> for GatherLoanCtxt<'a> {
// #7740: Do not visit items here, not even fn items nor methods
// of impl items; the outer loop in borrowck/mod will visit them
// for us in turn. Thus override visit_item's walk with a no-op.
fn visit_item(&mut self, _: &ast::Item, _: ()) { }
fn visit_item(&mut self, _: &ast::Item, _: ()) {}
}
pub fn gather_loans(bccx: &BorrowckCtxt, decl: &ast::FnDecl, body: &ast::Block)
fn add_pat_to_id_range(this: &mut GatherLoanCtxt,
p: &ast::Pat) {
// NB: This visitor function just adds the pat ids into the id
// range. We gather loans that occur in patterns using the
// `gather_pat()` method below. Eventually these two should be
// brought together.
this.id_range.add(p.id);
visit::walk_pat(this, p, ());
}
pub fn gather_loans_in_fn(bccx: &BorrowckCtxt, decl: &ast::FnDecl, body: &ast::Block)
-> (IdRange, Vec<Loan>, move_data::MoveData) {
let mut glcx = GatherLoanCtxt {
bccx: bccx,
@ -119,27 +131,6 @@ pub fn gather_loans(bccx: &BorrowckCtxt, decl: &ast::FnDecl, body: &ast::Block)
(id_range, all_loans, move_data)
}
fn add_pat_to_id_range(this: &mut GatherLoanCtxt,
p: &ast::Pat) {
// NB: This visitor function just adds the pat ids into the id
// range. We gather loans that occur in patterns using the
// `gather_pat()` method below. Eventually these two should be
// brought together.
this.id_range.add(p.id);
visit::walk_pat(this, p, ());
}
fn gather_loans_in_fn(_v: &mut GatherLoanCtxt,
_fk: &FnKind,
_decl: &ast::FnDecl,
_body: &ast::Block,
_sp: Span,
_id: ast::NodeId) {
// Do not visit closures or fn items here, the outer loop in
// borrowck/mod will visit them for us in turn.
return;
}
fn gather_loans_in_block(this: &mut GatherLoanCtxt,
blk: &ast::Block) {
this.id_range.add(blk.id);
@ -171,6 +162,28 @@ fn gather_loans_in_local(this: &mut GatherLoanCtxt,
visit::walk_local(this, local, ());
}
pub fn gather_loans_in_static_initializer(bccx: &mut BorrowckCtxt, expr: &ast::Expr) {
debug!("gather_loans_in_item(expr={})", expr.repr(bccx.tcx));
let mut glcx = GatherLoanCtxt {
bccx: bccx,
id_range: IdRange::max(),
all_loans: Vec::new(),
item_ub: expr.id,
repeating_ids: vec!(expr.id),
move_data: MoveData::new()
};
match expr.node {
// Just visit the expression if the
// item is taking an address.
ast::ExprAddrOf(..) => {
glcx.visit_expr(expr, ());
}
_ => {}
}
}
fn gather_loans_in_expr(this: &mut GatherLoanCtxt,
ex: &ast::Expr) {

View File

@ -69,6 +69,10 @@ impl<'a> Visitor<()> for BorrowckCtxt<'a> {
b: &Block, s: Span, n: NodeId, _: ()) {
borrowck_fn(self, fk, fd, b, s, n);
}
fn visit_item(&mut self, item: &ast::Item, _: ()) {
borrowck_item(self, item);
}
}
pub fn check_crate(tcx: &ty::ctxt,
@ -117,6 +121,20 @@ pub fn check_crate(tcx: &ty::ctxt,
}
}
fn borrowck_item(this: &mut BorrowckCtxt, item: &ast::Item) {
// Gather loans for items. Note that we don't need
// to check loans for single expressions. The check
// loan step is intended for things that have a data
// flow dependent conditions.
match item.node {
ast::ItemStatic(_, _, ex) => {
gather_loans::gather_loans_in_static_initializer(this, ex);
}
_ => {}
}
visit::walk_item(this, item, ());
}
fn borrowck_fn(this: &mut BorrowckCtxt,
fk: &FnKind,
decl: &ast::FnDecl,
@ -127,7 +145,7 @@ fn borrowck_fn(this: &mut BorrowckCtxt,
// Check the body of fn items.
let (id_range, all_loans, move_data) =
gather_loans::gather_loans(this, decl, body);
gather_loans::gather_loans_in_fn(this, decl, body);
let mut loan_dfcx =
DataFlowContext::new(this.tcx,
this.method_map,