Skip to content

Commit 6b8b751

Browse files
committed
borrowck -- treak borrows from closures like other borrows
1 parent db38192 commit 6b8b751

File tree

7 files changed

+634
-479
lines changed

7 files changed

+634
-479
lines changed

src/librustc/middle/borrowck/check_loans.rs

Lines changed: 183 additions & 120 deletions
Large diffs are not rendered by default.

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

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,8 @@ use middle::borrowck::move_data::*;
1818
use middle::moves;
1919
use middle::ty;
2020
use syntax::ast;
21-
use syntax::ast_util;
2221
use syntax::codemap::Span;
23-
use util::ppaux::{UserString};
22+
use util::ppaux::{Repr, UserString};
2423

2524
pub fn gather_decl(bccx: &BorrowckCtxt,
2625
move_data: &MoveData,
@@ -35,33 +34,14 @@ pub fn gather_move_from_expr(bccx: &BorrowckCtxt,
3534
move_data: &MoveData,
3635
move_expr: &ast::Expr,
3736
cmt: mc::cmt) {
38-
gather_move_from_expr_or_pat(bccx, move_data, move_expr.id, MoveExpr, cmt);
37+
gather_move(bccx, move_data, move_expr.id, MoveExpr, cmt);
3938
}
4039

4140
pub fn gather_move_from_pat(bccx: &BorrowckCtxt,
4241
move_data: &MoveData,
4342
move_pat: &ast::Pat,
4443
cmt: mc::cmt) {
45-
gather_move_from_expr_or_pat(bccx, move_data, move_pat.id, MovePat, cmt);
46-
}
47-
48-
fn gather_move_from_expr_or_pat(bccx: &BorrowckCtxt,
49-
move_data: &MoveData,
50-
move_id: ast::NodeId,
51-
move_kind: MoveKind,
52-
cmt: mc::cmt) {
53-
if !check_is_legal_to_move_from(bccx, cmt, cmt) {
54-
return;
55-
}
56-
57-
match opt_loan_path(cmt) {
58-
Some(loan_path) => {
59-
move_data.add_move(bccx.tcx, loan_path, move_id, move_kind);
60-
}
61-
None => {
62-
// move from rvalue or unsafe pointer, hence ok
63-
}
64-
}
44+
gather_move(bccx, move_data, move_pat.id, MovePat, cmt);
6545
}
6646

6747
pub fn gather_captures(bccx: &BorrowckCtxt,
@@ -72,16 +52,38 @@ pub fn gather_captures(bccx: &BorrowckCtxt,
7252
for captured_var in captured_vars.borrow().iter() {
7353
match captured_var.mode {
7454
moves::CapMove => {
75-
let fvar_id = ast_util::def_id_of_def(captured_var.def).node;
76-
let loan_path = @LpVar(fvar_id);
77-
move_data.add_move(bccx.tcx, loan_path, closure_expr.id,
78-
Captured);
55+
let cmt = bccx.cat_captured_var(closure_expr.id,
56+
closure_expr.span,
57+
captured_var);
58+
gather_move(bccx, move_data, closure_expr.id, Captured, cmt);
7959
}
8060
moves::CapCopy | moves::CapRef => {}
8161
}
8262
}
8363
}
8464

65+
fn gather_move(bccx: &BorrowckCtxt,
66+
move_data: &MoveData,
67+
move_id: ast::NodeId,
68+
move_kind: MoveKind,
69+
cmt: mc::cmt) {
70+
debug!("gather_move(move_id={}, cmt={})",
71+
move_id, cmt.repr(bccx.tcx));
72+
73+
if !check_is_legal_to_move_from(bccx, cmt, cmt) {
74+
return;
75+
}
76+
77+
match opt_loan_path(cmt) {
78+
Some(loan_path) => {
79+
move_data.add_move(bccx.tcx, loan_path, move_id, move_kind);
80+
}
81+
None => {
82+
// move from rvalue or unsafe pointer, hence ok
83+
}
84+
}
85+
}
86+
8587
pub fn gather_assignment(bccx: &BorrowckCtxt,
8688
move_data: &MoveData,
8789
assignment_id: ast::NodeId,
@@ -99,15 +101,15 @@ fn check_is_legal_to_move_from(bccx: &BorrowckCtxt,
99101
cmt0: mc::cmt,
100102
cmt: mc::cmt) -> bool {
101103
match cmt.cat {
102-
mc::cat_deref(_, _, mc::region_ptr(..)) |
103-
mc::cat_deref(_, _, mc::gc_ptr) |
104-
mc::cat_deref(_, _, mc::unsafe_ptr(..)) |
105-
mc::cat_stack_upvar(..) |
104+
mc::cat_deref(_, _, mc::BorrowedPtr(..)) |
105+
mc::cat_deref(_, _, mc::GcPtr) |
106+
mc::cat_deref(_, _, mc::UnsafePtr(..)) |
107+
mc::cat_upvar(..) |
106108
mc::cat_copied_upvar(mc::CopiedUpvar { onceness: ast::Many, .. }) => {
107109
bccx.span_err(
108110
cmt0.span,
109111
format!("cannot move out of {}",
110-
bccx.cmt_to_str(cmt)));
112+
bccx.cmt_to_str(cmt)));
111113
false
112114
}
113115

@@ -158,7 +160,7 @@ fn check_is_legal_to_move_from(bccx: &BorrowckCtxt,
158160
}
159161
}
160162

161-
mc::cat_deref(b, _, mc::uniq_ptr) |
163+
mc::cat_deref(b, _, mc::OwnedPtr) |
162164
mc::cat_discr(b, _) => {
163165
check_is_legal_to_move_from(bccx, cmt0, b)
164166
}

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

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,19 @@ pub fn guarantee_lifetime(bccx: &BorrowckCtxt,
2626
item_scope_id: ast::NodeId,
2727
root_scope_id: ast::NodeId,
2828
span: Span,
29+
cause: LoanCause,
2930
cmt: mc::cmt,
3031
loan_region: ty::Region,
31-
loan_mutbl: LoanMutability) -> R {
32+
loan_kind: ty::BorrowKind)
33+
-> Result<(),()> {
3234
debug!("guarantee_lifetime(cmt={}, loan_region={})",
3335
cmt.repr(bccx.tcx), loan_region.repr(bccx.tcx));
3436
let ctxt = GuaranteeLifetimeContext {bccx: bccx,
3537
item_scope_id: item_scope_id,
3638
span: span,
39+
cause: cause,
3740
loan_region: loan_region,
38-
loan_mutbl: loan_mutbl,
41+
loan_kind: loan_kind,
3942
cmt_original: cmt,
4043
root_scope_id: root_scope_id};
4144
ctxt.check(cmt, None)
@@ -55,8 +58,9 @@ struct GuaranteeLifetimeContext<'a> {
5558
root_scope_id: ast::NodeId,
5659

5760
span: Span,
61+
cause: LoanCause,
5862
loan_region: ty::Region,
59-
loan_mutbl: LoanMutability,
63+
loan_kind: ty::BorrowKind,
6064
cmt_original: mc::cmt
6165
}
6266

@@ -76,21 +80,18 @@ impl<'a> GuaranteeLifetimeContext<'a> {
7680
mc::cat_copied_upvar(..) | // L-Local
7781
mc::cat_local(..) | // L-Local
7882
mc::cat_arg(..) | // L-Local
79-
mc::cat_deref(_, _, mc::region_ptr(..)) | // L-Deref-Borrowed
80-
mc::cat_deref(_, _, mc::unsafe_ptr(..)) => {
83+
mc::cat_upvar(..) |
84+
mc::cat_deref(_, _, mc::BorrowedPtr(..)) | // L-Deref-Borrowed
85+
mc::cat_deref(_, _, mc::UnsafePtr(..)) => {
8186
let scope = self.scope(cmt);
8287
self.check_scope(scope)
8388
}
8489

85-
mc::cat_stack_upvar(cmt) => {
86-
self.check(cmt, discr_scope)
87-
}
88-
8990
mc::cat_static_item => {
9091
Ok(())
9192
}
9293

93-
mc::cat_deref(base, derefs, mc::gc_ptr) => {
94+
mc::cat_deref(base, derefs, mc::GcPtr) => {
9495
let base_scope = self.scope(base);
9596

9697
// L-Deref-Managed-Imm-User-Root
@@ -112,7 +113,7 @@ impl<'a> GuaranteeLifetimeContext<'a> {
112113
}
113114

114115
mc::cat_downcast(base) |
115-
mc::cat_deref(base, _, mc::uniq_ptr) | // L-Deref-Send
116+
mc::cat_deref(base, _, mc::OwnedPtr) | // L-Deref-Send
116117
mc::cat_interior(base, _) => { // L-Field
117118
self.check(base, discr_scope)
118119
}
@@ -269,12 +270,12 @@ impl<'a> GuaranteeLifetimeContext<'a> {
269270
mc::cat_rvalue(..) |
270271
mc::cat_static_item |
271272
mc::cat_copied_upvar(..) |
272-
mc::cat_deref(..) => {
273+
mc::cat_deref(..) |
274+
mc::cat_upvar(..) => {
273275
false
274276
}
275277
r @ mc::cat_downcast(..) |
276278
r @ mc::cat_interior(..) |
277-
r @ mc::cat_stack_upvar(..) |
278279
r @ mc::cat_discr(..) => {
279280
self.tcx().sess.span_bug(
280281
cmt.span,
@@ -294,6 +295,7 @@ impl<'a> GuaranteeLifetimeContext<'a> {
294295
mc::cat_rvalue(temp_scope) => {
295296
temp_scope
296297
}
298+
mc::cat_upvar(..) |
297299
mc::cat_copied_upvar(_) => {
298300
ty::ReScope(self.item_scope_id)
299301
}
@@ -304,28 +306,26 @@ impl<'a> GuaranteeLifetimeContext<'a> {
304306
mc::cat_arg(local_id) => {
305307
ty::ReScope(self.bccx.tcx.region_maps.var_scope(local_id))
306308
}
307-
mc::cat_deref(_, _, mc::unsafe_ptr(..)) => {
309+
mc::cat_deref(_, _, mc::UnsafePtr(..)) => {
308310
ty::ReStatic
309311
}
310-
mc::cat_deref(_, _, mc::region_ptr(_, r)) => {
312+
mc::cat_deref(_, _, mc::BorrowedPtr(_, r)) => {
311313
r
312314
}
313315
mc::cat_downcast(cmt) |
314-
mc::cat_deref(cmt, _, mc::uniq_ptr) |
315-
mc::cat_deref(cmt, _, mc::gc_ptr) |
316+
mc::cat_deref(cmt, _, mc::OwnedPtr) |
317+
mc::cat_deref(cmt, _, mc::GcPtr) |
316318
mc::cat_interior(cmt, _) |
317-
mc::cat_stack_upvar(cmt) |
318319
mc::cat_discr(cmt, _) => {
319320
self.scope(cmt)
320321
}
321322
}
322323
}
323324

324325
fn report_error(&self, code: bckerr_code) {
325-
self.bccx.report(BckError {
326-
cmt: self.cmt_original,
327-
span: self.span,
328-
code: code
329-
});
326+
self.bccx.report(BckError { cmt: self.cmt_original,
327+
span: self.span,
328+
cause: self.cause,
329+
code: code });
330330
}
331331
}

0 commit comments

Comments
 (0)