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,
|
cmt0: mc::cmt,
|
||||||
cmt: mc::cmt) -> bool {
|
cmt: mc::cmt) -> bool {
|
||||||
match cmt.cat {
|
match cmt.cat {
|
||||||
mc::cat_stack_upvar(*) |
|
|
||||||
mc::cat_implicit_self(*) |
|
mc::cat_implicit_self(*) |
|
||||||
mc::cat_copied_upvar(*) |
|
|
||||||
mc::cat_deref(_, _, mc::region_ptr(*)) |
|
mc::cat_deref(_, _, mc::region_ptr(*)) |
|
||||||
mc::cat_deref(_, _, mc::gc_ptr(*)) |
|
mc::cat_deref(_, _, mc::gc_ptr(*)) |
|
||||||
mc::cat_deref(_, _, mc::unsafe_ptr(*)) => {
|
mc::cat_deref(_, _, mc::unsafe_ptr(*)) => {
|
||||||
@ -114,6 +112,24 @@ fn check_is_legal_to_move_from(bccx: @BorrowckCtxt,
|
|||||||
false
|
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,
|
// It seems strange to allow a move out of a static item,
|
||||||
// but what happens in practice is that you have a
|
// but what happens in practice is that you have a
|
||||||
// reference to a constant with a type that should be
|
// reference to a constant with a type that should be
|
||||||
|
@ -78,7 +78,7 @@ pub enum categorization {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Eq)]
|
#[deriving(Eq)]
|
||||||
struct CopiedUpvar {
|
pub struct CopiedUpvar {
|
||||||
upvar_id: ast::node_id,
|
upvar_id: ast::node_id,
|
||||||
onceness: ast::Onceness,
|
onceness: ast::Onceness,
|
||||||
}
|
}
|
||||||
@ -497,9 +497,8 @@ impl mem_categorization_ctxt {
|
|||||||
let ty = ty::node_id_to_type(self.tcx, fn_node_id);
|
let ty = ty::node_id_to_type(self.tcx, fn_node_id);
|
||||||
match ty::get(ty).sty {
|
match ty::get(ty).sty {
|
||||||
ty::ty_closure(ref closure_ty) => {
|
ty::ty_closure(ref closure_ty) => {
|
||||||
let sigil = closure_ty.sigil;
|
match (closure_ty.sigil, closure_ty.onceness) {
|
||||||
match sigil {
|
(ast::BorrowedSigil, ast::Many) => {
|
||||||
ast::BorrowedSigil => {
|
|
||||||
let upvar_cmt =
|
let upvar_cmt =
|
||||||
self.cat_def(id, span, expr_ty, *inner);
|
self.cat_def(id, span, expr_ty, *inner);
|
||||||
@cmt_ {
|
@cmt_ {
|
||||||
@ -510,7 +509,8 @@ impl mem_categorization_ctxt {
|
|||||||
ty:upvar_cmt.ty
|
ty:upvar_cmt.ty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::OwnedSigil | ast::ManagedSigil => {
|
(ast::BorrowedSigil, ast::Once) |
|
||||||
|
(ast::OwnedSigil, _) | (ast::ManagedSigil, _) => {
|
||||||
// FIXME #2152 allow mutation of moved upvars
|
// FIXME #2152 allow mutation of moved upvars
|
||||||
@cmt_ {
|
@cmt_ {
|
||||||
id:id,
|
id:id,
|
||||||
|
Loading…
Reference in New Issue
Block a user