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, ());
}
// #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,
(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);
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) {
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,
}
}
+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,
// 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,