Skip to content

Commit 69ccd80

Browse files
committed
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.
1 parent 8767c69 commit 69ccd80

File tree

2 files changed

+59
-28
lines changed

2 files changed

+59
-28
lines changed

src/librustc/middle/borrowck/gather_loans/mod.rs

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,12 @@ impl<'a> visit::Visitor<()> for GatherLoanCtxt<'a> {
8282
fn visit_block(&mut self, b: &Block, _: ()) {
8383
gather_loans_in_block(self, b);
8484
}
85-
fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block,
86-
s: Span, n: NodeId, _: ()) {
87-
gather_loans_in_fn(self, fk, fd, b, s, n);
88-
}
85+
86+
/// Do not visit closures or fn items here, the outer loop in
87+
/// borrowck/mod will visit them for us in turn.
88+
fn visit_fn(&mut self, _: &FnKind, _: &FnDecl, _: &Block,
89+
_: Span, _: NodeId, _: ()) {}
90+
8991
fn visit_stmt(&mut self, s: &Stmt, _: ()) {
9092
visit::walk_stmt(self, s, ());
9193
}
@@ -99,10 +101,20 @@ impl<'a> visit::Visitor<()> for GatherLoanCtxt<'a> {
99101
// #7740: Do not visit items here, not even fn items nor methods
100102
// of impl items; the outer loop in borrowck/mod will visit them
101103
// for us in turn. Thus override visit_item's walk with a no-op.
102-
fn visit_item(&mut self, _: &ast::Item, _: ()) { }
104+
fn visit_item(&mut self, _: &ast::Item, _: ()) {}
103105
}
104106

105-
pub fn gather_loans(bccx: &BorrowckCtxt, decl: &ast::FnDecl, body: &ast::Block)
107+
fn add_pat_to_id_range(this: &mut GatherLoanCtxt,
108+
p: &ast::Pat) {
109+
// NB: This visitor function just adds the pat ids into the id
110+
// range. We gather loans that occur in patterns using the
111+
// `gather_pat()` method below. Eventually these two should be
112+
// brought together.
113+
this.id_range.add(p.id);
114+
visit::walk_pat(this, p, ());
115+
}
116+
117+
pub fn gather_loans_in_fn(bccx: &BorrowckCtxt, decl: &ast::FnDecl, body: &ast::Block)
106118
-> (IdRange, Vec<Loan>, move_data::MoveData) {
107119
let mut glcx = GatherLoanCtxt {
108120
bccx: bccx,
@@ -119,27 +131,6 @@ pub fn gather_loans(bccx: &BorrowckCtxt, decl: &ast::FnDecl, body: &ast::Block)
119131
(id_range, all_loans, move_data)
120132
}
121133

122-
fn add_pat_to_id_range(this: &mut GatherLoanCtxt,
123-
p: &ast::Pat) {
124-
// NB: This visitor function just adds the pat ids into the id
125-
// range. We gather loans that occur in patterns using the
126-
// `gather_pat()` method below. Eventually these two should be
127-
// brought together.
128-
this.id_range.add(p.id);
129-
visit::walk_pat(this, p, ());
130-
}
131-
132-
fn gather_loans_in_fn(_v: &mut GatherLoanCtxt,
133-
_fk: &FnKind,
134-
_decl: &ast::FnDecl,
135-
_body: &ast::Block,
136-
_sp: Span,
137-
_id: ast::NodeId) {
138-
// Do not visit closures or fn items here, the outer loop in
139-
// borrowck/mod will visit them for us in turn.
140-
return;
141-
}
142-
143134
fn gather_loans_in_block(this: &mut GatherLoanCtxt,
144135
blk: &ast::Block) {
145136
this.id_range.add(blk.id);
@@ -171,6 +162,28 @@ fn gather_loans_in_local(this: &mut GatherLoanCtxt,
171162
visit::walk_local(this, local, ());
172163
}
173164

165+
pub fn gather_loans_in_static_initializer(bccx: &mut BorrowckCtxt, expr: &ast::Expr) {
166+
167+
debug!("gather_loans_in_item(expr={})", expr.repr(bccx.tcx));
168+
169+
let mut glcx = GatherLoanCtxt {
170+
bccx: bccx,
171+
id_range: IdRange::max(),
172+
all_loans: Vec::new(),
173+
item_ub: expr.id,
174+
repeating_ids: vec!(expr.id),
175+
move_data: MoveData::new()
176+
};
177+
178+
match expr.node {
179+
// Just visit the expression if the
180+
// item is taking an address.
181+
ast::ExprAddrOf(..) => {
182+
glcx.visit_expr(expr, ());
183+
}
184+
_ => {}
185+
}
186+
}
174187

175188
fn gather_loans_in_expr(this: &mut GatherLoanCtxt,
176189
ex: &ast::Expr) {

src/librustc/middle/borrowck/mod.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ impl<'a> Visitor<()> for BorrowckCtxt<'a> {
6969
b: &Block, s: Span, n: NodeId, _: ()) {
7070
borrowck_fn(self, fk, fd, b, s, n);
7171
}
72+
73+
fn visit_item(&mut self, item: &ast::Item, _: ()) {
74+
borrowck_item(self, item);
75+
}
7276
}
7377

7478
pub fn check_crate(tcx: &ty::ctxt,
@@ -117,6 +121,20 @@ pub fn check_crate(tcx: &ty::ctxt,
117121
}
118122
}
119123

124+
fn borrowck_item(this: &mut BorrowckCtxt, item: &ast::Item) {
125+
// Gather loans for items. Note that we don't need
126+
// to check loans for single expressions. The check
127+
// loan step is intended for things that have a data
128+
// flow dependent conditions.
129+
match item.node {
130+
ast::ItemStatic(_, _, ex) => {
131+
gather_loans::gather_loans_in_static_initializer(this, ex);
132+
}
133+
_ => {}
134+
}
135+
visit::walk_item(this, item, ());
136+
}
137+
120138
fn borrowck_fn(this: &mut BorrowckCtxt,
121139
fk: &FnKind,
122140
decl: &ast::FnDecl,
@@ -127,7 +145,7 @@ fn borrowck_fn(this: &mut BorrowckCtxt,
127145

128146
// Check the body of fn items.
129147
let (id_range, all_loans, move_data) =
130-
gather_loans::gather_loans(this, decl, body);
148+
gather_loans::gather_loans_in_fn(this, decl, body);
131149
let mut loan_dfcx =
132150
DataFlowContext::new(this.tcx,
133151
this.method_map,

0 commit comments

Comments
 (0)