Skip to content

Commit

Permalink
Permit moving out of captured upvars in once fns. Close #2549.
Browse files Browse the repository at this point in the history
  • Loading branch information
bblum committed Jun 19, 2013
1 parent 2c7903d commit 1496216
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 7 deletions.
20 changes: 18 additions & 2 deletions src/librustc/middle/borrowck/gather_loans/gather_moves.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,7 @@ fn check_is_legal_to_move_from(bccx: @BorrowckCtxt,
cmt0: mc::cmt,
cmt: mc::cmt) -> bool {
match cmt.cat {
mc::cat_stack_upvar(*) |
mc::cat_implicit_self(*) |
mc::cat_copied_upvar(*) |
mc::cat_deref(_, _, mc::region_ptr(*)) |
mc::cat_deref(_, _, mc::gc_ptr(*)) |
mc::cat_deref(_, _, mc::unsafe_ptr(*)) => {
Expand All @@ -114,6 +112,24 @@ fn check_is_legal_to_move_from(bccx: @BorrowckCtxt,
false
}

// These are separate from the above cases for a better error message.
mc::cat_stack_upvar(*) |
mc::cat_copied_upvar(mc::CopiedUpvar { onceness: ast::Many, _ }) => {
bccx.span_err(
cmt0.span,
fmt!("cannot move out of %s \
(unless the destination closure type is `once fn')",
bccx.cmt_to_str(cmt)));
false
}

// Can move out of captured upvars only if the destination closure
// type is 'once'. 1-shot stack closures emit the copied_upvar form
// (see mem_categorization.rs).
mc::cat_copied_upvar(mc::CopiedUpvar { onceness: ast::Once, _ }) => {
true
}

// It seems strange to allow a move out of a static item,
// but what happens in practice is that you have a
// reference to a constant with a type that should be
Expand Down
10 changes: 5 additions & 5 deletions src/librustc/middle/mem_categorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ pub enum categorization {
}

#[deriving(Eq)]
struct CopiedUpvar {
pub struct CopiedUpvar {
upvar_id: ast::node_id,
onceness: ast::Onceness,
}
Expand Down Expand Up @@ -497,9 +497,8 @@ impl mem_categorization_ctxt {
let ty = ty::node_id_to_type(self.tcx, fn_node_id);
match ty::get(ty).sty {
ty::ty_closure(ref closure_ty) => {
let sigil = closure_ty.sigil;
match sigil {
ast::BorrowedSigil => {
match (closure_ty.sigil, closure_ty.onceness) {
(ast::BorrowedSigil, ast::Many) => {
let upvar_cmt =
self.cat_def(id, span, expr_ty, *inner);
@cmt_ {
Expand All @@ -510,7 +509,8 @@ impl mem_categorization_ctxt {
ty:upvar_cmt.ty
}
}
ast::OwnedSigil | ast::ManagedSigil => {
(ast::BorrowedSigil, ast::Once) |
(ast::OwnedSigil, _) | (ast::ManagedSigil, _) => {
// FIXME #2152 allow mutation of moved upvars
@cmt_ {
id:id,
Expand Down

0 comments on commit 1496216

Please sign in to comment.