Permit moving out of captured upvars in once fns. Close #2549.
This commit is contained in:
parent
2c7903d599
commit
1496216db6
@ -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(*)) => {
|
||||
@ -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
|
||||
|
@ -78,7 +78,7 @@ pub enum categorization {
|
||||
}
|
||||
|
||||
#[deriving(Eq)]
|
||||
struct CopiedUpvar {
|
||||
pub struct CopiedUpvar {
|
||||
upvar_id: ast::node_id,
|
||||
onceness: ast::Onceness,
|
||||
}
|
||||
@ -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_ {
|
||||
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user