Skip to content

Commit

Permalink
borrowck -- treak borrows from closures like other borrows
Browse files Browse the repository at this point in the history
  • Loading branch information
nikomatsakis committed Feb 11, 2014
1 parent db38192 commit 6b8b751
Show file tree
Hide file tree
Showing 7 changed files with 634 additions and 479 deletions.
303 changes: 183 additions & 120 deletions src/librustc/middle/borrowck/check_loans.rs

Large diffs are not rendered by default.

68 changes: 35 additions & 33 deletions src/librustc/middle/borrowck/gather_loans/gather_moves.rs
Expand Up @@ -18,9 +18,8 @@ use middle::borrowck::move_data::*;
use middle::moves;
use middle::ty;
use syntax::ast;
use syntax::ast_util;
use syntax::codemap::Span;
use util::ppaux::{UserString};
use util::ppaux::{Repr, UserString};

pub fn gather_decl(bccx: &BorrowckCtxt,
move_data: &MoveData,
Expand All @@ -35,33 +34,14 @@ pub fn gather_move_from_expr(bccx: &BorrowckCtxt,
move_data: &MoveData,
move_expr: &ast::Expr,
cmt: mc::cmt) {
gather_move_from_expr_or_pat(bccx, move_data, move_expr.id, MoveExpr, cmt);
gather_move(bccx, move_data, move_expr.id, MoveExpr, cmt);
}

pub fn gather_move_from_pat(bccx: &BorrowckCtxt,
move_data: &MoveData,
move_pat: &ast::Pat,
cmt: mc::cmt) {
gather_move_from_expr_or_pat(bccx, move_data, move_pat.id, MovePat, cmt);
}

fn gather_move_from_expr_or_pat(bccx: &BorrowckCtxt,
move_data: &MoveData,
move_id: ast::NodeId,
move_kind: MoveKind,
cmt: mc::cmt) {
if !check_is_legal_to_move_from(bccx, cmt, cmt) {
return;
}

match opt_loan_path(cmt) {
Some(loan_path) => {
move_data.add_move(bccx.tcx, loan_path, move_id, move_kind);
}
None => {
// move from rvalue or unsafe pointer, hence ok
}
}
gather_move(bccx, move_data, move_pat.id, MovePat, cmt);
}

pub fn gather_captures(bccx: &BorrowckCtxt,
Expand All @@ -72,16 +52,38 @@ pub fn gather_captures(bccx: &BorrowckCtxt,
for captured_var in captured_vars.borrow().iter() {
match captured_var.mode {
moves::CapMove => {
let fvar_id = ast_util::def_id_of_def(captured_var.def).node;
let loan_path = @LpVar(fvar_id);
move_data.add_move(bccx.tcx, loan_path, closure_expr.id,
Captured);
let cmt = bccx.cat_captured_var(closure_expr.id,
closure_expr.span,
captured_var);
gather_move(bccx, move_data, closure_expr.id, Captured, cmt);
}
moves::CapCopy | moves::CapRef => {}
}
}
}

fn gather_move(bccx: &BorrowckCtxt,
move_data: &MoveData,
move_id: ast::NodeId,
move_kind: MoveKind,
cmt: mc::cmt) {
debug!("gather_move(move_id={}, cmt={})",
move_id, cmt.repr(bccx.tcx));

if !check_is_legal_to_move_from(bccx, cmt, cmt) {
return;
}

match opt_loan_path(cmt) {
Some(loan_path) => {
move_data.add_move(bccx.tcx, loan_path, move_id, move_kind);
}
None => {
// move from rvalue or unsafe pointer, hence ok
}
}
}

pub fn gather_assignment(bccx: &BorrowckCtxt,
move_data: &MoveData,
assignment_id: ast::NodeId,
Expand All @@ -99,15 +101,15 @@ fn check_is_legal_to_move_from(bccx: &BorrowckCtxt,
cmt0: mc::cmt,
cmt: mc::cmt) -> bool {
match cmt.cat {
mc::cat_deref(_, _, mc::region_ptr(..)) |
mc::cat_deref(_, _, mc::gc_ptr) |
mc::cat_deref(_, _, mc::unsafe_ptr(..)) |
mc::cat_stack_upvar(..) |
mc::cat_deref(_, _, mc::BorrowedPtr(..)) |
mc::cat_deref(_, _, mc::GcPtr) |
mc::cat_deref(_, _, mc::UnsafePtr(..)) |
mc::cat_upvar(..) |
mc::cat_copied_upvar(mc::CopiedUpvar { onceness: ast::Many, .. }) => {
bccx.span_err(
cmt0.span,
format!("cannot move out of {}",
bccx.cmt_to_str(cmt)));
bccx.cmt_to_str(cmt)));
false
}

Expand Down Expand Up @@ -158,7 +160,7 @@ fn check_is_legal_to_move_from(bccx: &BorrowckCtxt,
}
}

mc::cat_deref(b, _, mc::uniq_ptr) |
mc::cat_deref(b, _, mc::OwnedPtr) |
mc::cat_discr(b, _) => {
check_is_legal_to_move_from(bccx, cmt0, b)
}
Expand Down
46 changes: 23 additions & 23 deletions src/librustc/middle/borrowck/gather_loans/lifetime.rs
Expand Up @@ -26,16 +26,19 @@ pub fn guarantee_lifetime(bccx: &BorrowckCtxt,
item_scope_id: ast::NodeId,
root_scope_id: ast::NodeId,
span: Span,
cause: LoanCause,
cmt: mc::cmt,
loan_region: ty::Region,
loan_mutbl: LoanMutability) -> R {
loan_kind: ty::BorrowKind)
-> Result<(),()> {
debug!("guarantee_lifetime(cmt={}, loan_region={})",
cmt.repr(bccx.tcx), loan_region.repr(bccx.tcx));
let ctxt = GuaranteeLifetimeContext {bccx: bccx,
item_scope_id: item_scope_id,
span: span,
cause: cause,
loan_region: loan_region,
loan_mutbl: loan_mutbl,
loan_kind: loan_kind,
cmt_original: cmt,
root_scope_id: root_scope_id};
ctxt.check(cmt, None)
Expand All @@ -55,8 +58,9 @@ struct GuaranteeLifetimeContext<'a> {
root_scope_id: ast::NodeId,

span: Span,
cause: LoanCause,
loan_region: ty::Region,
loan_mutbl: LoanMutability,
loan_kind: ty::BorrowKind,
cmt_original: mc::cmt
}

Expand All @@ -76,21 +80,18 @@ impl<'a> GuaranteeLifetimeContext<'a> {
mc::cat_copied_upvar(..) | // L-Local
mc::cat_local(..) | // L-Local
mc::cat_arg(..) | // L-Local
mc::cat_deref(_, _, mc::region_ptr(..)) | // L-Deref-Borrowed
mc::cat_deref(_, _, mc::unsafe_ptr(..)) => {
mc::cat_upvar(..) |
mc::cat_deref(_, _, mc::BorrowedPtr(..)) | // L-Deref-Borrowed
mc::cat_deref(_, _, mc::UnsafePtr(..)) => {
let scope = self.scope(cmt);
self.check_scope(scope)
}

mc::cat_stack_upvar(cmt) => {
self.check(cmt, discr_scope)
}

mc::cat_static_item => {
Ok(())
}

mc::cat_deref(base, derefs, mc::gc_ptr) => {
mc::cat_deref(base, derefs, mc::GcPtr) => {
let base_scope = self.scope(base);

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

mc::cat_downcast(base) |
mc::cat_deref(base, _, mc::uniq_ptr) | // L-Deref-Send
mc::cat_deref(base, _, mc::OwnedPtr) | // L-Deref-Send
mc::cat_interior(base, _) => { // L-Field
self.check(base, discr_scope)
}
Expand Down Expand Up @@ -269,12 +270,12 @@ impl<'a> GuaranteeLifetimeContext<'a> {
mc::cat_rvalue(..) |
mc::cat_static_item |
mc::cat_copied_upvar(..) |
mc::cat_deref(..) => {
mc::cat_deref(..) |
mc::cat_upvar(..) => {
false
}
r @ mc::cat_downcast(..) |
r @ mc::cat_interior(..) |
r @ mc::cat_stack_upvar(..) |
r @ mc::cat_discr(..) => {
self.tcx().sess.span_bug(
cmt.span,
Expand All @@ -294,6 +295,7 @@ impl<'a> GuaranteeLifetimeContext<'a> {
mc::cat_rvalue(temp_scope) => {
temp_scope
}
mc::cat_upvar(..) |
mc::cat_copied_upvar(_) => {
ty::ReScope(self.item_scope_id)
}
Expand All @@ -304,28 +306,26 @@ impl<'a> GuaranteeLifetimeContext<'a> {
mc::cat_arg(local_id) => {
ty::ReScope(self.bccx.tcx.region_maps.var_scope(local_id))
}
mc::cat_deref(_, _, mc::unsafe_ptr(..)) => {
mc::cat_deref(_, _, mc::UnsafePtr(..)) => {
ty::ReStatic
}
mc::cat_deref(_, _, mc::region_ptr(_, r)) => {
mc::cat_deref(_, _, mc::BorrowedPtr(_, r)) => {
r
}
mc::cat_downcast(cmt) |
mc::cat_deref(cmt, _, mc::uniq_ptr) |
mc::cat_deref(cmt, _, mc::gc_ptr) |
mc::cat_deref(cmt, _, mc::OwnedPtr) |
mc::cat_deref(cmt, _, mc::GcPtr) |
mc::cat_interior(cmt, _) |
mc::cat_stack_upvar(cmt) |
mc::cat_discr(cmt, _) => {
self.scope(cmt)
}
}
}

fn report_error(&self, code: bckerr_code) {
self.bccx.report(BckError {
cmt: self.cmt_original,
span: self.span,
code: code
});
self.bccx.report(BckError { cmt: self.cmt_original,
span: self.span,
cause: self.cause,
code: code });
}
}

0 comments on commit 6b8b751

Please sign in to comment.