Skip to content

Commit 643be38

Browse files
committed
Hide the once-move-out privilege for stack fns behind '-Z once-fns'
1 parent c1f037e commit 643be38

File tree

4 files changed

+66
-48
lines changed

4 files changed

+66
-48
lines changed

src/librustc/driver/session.rs

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -45,32 +45,33 @@ pub struct config {
4545
float_type: float_ty
4646
}
4747

48-
pub static verbose: uint = 1 << 0;
49-
pub static time_passes: uint = 1 << 1;
50-
pub static count_llvm_insns: uint = 1 << 2;
51-
pub static time_llvm_passes: uint = 1 << 3;
52-
pub static trans_stats: uint = 1 << 4;
53-
pub static asm_comments: uint = 1 << 5;
54-
pub static no_verify: uint = 1 << 6;
55-
pub static trace: uint = 1 << 7;
56-
pub static coherence: uint = 1 << 8;
57-
pub static borrowck_stats: uint = 1 << 9;
58-
pub static borrowck_note_pure: uint = 1 << 10;
59-
pub static borrowck_note_loan: uint = 1 << 11;
60-
pub static no_landing_pads: uint = 1 << 12;
61-
pub static debug_llvm: uint = 1 << 13;
62-
pub static count_type_sizes: uint = 1 << 14;
63-
pub static meta_stats: uint = 1 << 15;
64-
pub static no_opt: uint = 1 << 16;
48+
pub static verbose: uint = 1 << 0;
49+
pub static time_passes: uint = 1 << 1;
50+
pub static count_llvm_insns: uint = 1 << 2;
51+
pub static time_llvm_passes: uint = 1 << 3;
52+
pub static trans_stats: uint = 1 << 4;
53+
pub static asm_comments: uint = 1 << 5;
54+
pub static no_verify: uint = 1 << 6;
55+
pub static trace: uint = 1 << 7;
56+
pub static coherence: uint = 1 << 8;
57+
pub static borrowck_stats: uint = 1 << 9;
58+
pub static borrowck_note_pure: uint = 1 << 10;
59+
pub static borrowck_note_loan: uint = 1 << 11;
60+
pub static no_landing_pads: uint = 1 << 12;
61+
pub static debug_llvm: uint = 1 << 13;
62+
pub static count_type_sizes: uint = 1 << 14;
63+
pub static meta_stats: uint = 1 << 15;
64+
pub static no_opt: uint = 1 << 16;
6565
pub static no_monomorphic_collapse: uint = 1 << 17;
66-
pub static gc: uint = 1 << 18;
67-
pub static jit: uint = 1 << 19;
68-
pub static debug_info: uint = 1 << 20;
69-
pub static extra_debug_info: uint = 1 << 21;
70-
pub static statik: uint = 1 << 22;
71-
pub static print_link_args: uint = 1 << 23;
72-
pub static no_debug_borrows: uint = 1 << 24;
73-
pub static lint_llvm : uint = 1 << 25;
66+
pub static gc: uint = 1 << 18;
67+
pub static jit: uint = 1 << 19;
68+
pub static debug_info: uint = 1 << 20;
69+
pub static extra_debug_info: uint = 1 << 21;
70+
pub static statik: uint = 1 << 22;
71+
pub static print_link_args: uint = 1 << 23;
72+
pub static no_debug_borrows: uint = 1 << 24;
73+
pub static lint_llvm: uint = 1 << 25;
74+
pub static once_fns: uint = 1 << 26;
7475

7576
pub fn debugging_opts_map() -> ~[(~str, ~str, uint)] {
7677
~[(~"verbose", ~"in general, enable more debug printouts", verbose),
@@ -112,6 +113,9 @@ pub fn debugging_opts_map() -> ~[(~str, ~str, uint)] {
112113
(~"lint-llvm",
113114
~"Run the LLVM lint pass on the pre-optimization IR",
114115
lint_llvm),
116+
(~"once-fns",
117+
~"Allow 'once fn' closures to deinitialize captured variables",
118+
once_fns),
115119
]
116120
}
117121

@@ -293,6 +297,7 @@ impl Session_ {
293297
pub fn debug_borrows(@self) -> bool {
294298
self.opts.optimize == No && !self.debugging_opt(no_debug_borrows)
295299
}
300+
pub fn once_fns(@self) -> bool { self.debugging_opt(once_fns) }
296301

297302
// pointless function, now...
298303
pub fn str_of(@self, id: ast::ident) -> @str {

src/librustc/middle/mem_categorization.rs

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -497,30 +497,41 @@ impl mem_categorization_ctxt {
497497
let ty = ty::node_id_to_type(self.tcx, fn_node_id);
498498
match ty::get(ty).sty {
499499
ty::ty_closure(ref closure_ty) => {
500-
match (closure_ty.sigil, closure_ty.onceness) {
501-
(ast::BorrowedSigil, ast::Many) => {
502-
let upvar_cmt =
503-
self.cat_def(id, span, expr_ty, *inner);
504-
@cmt_ {
505-
id:id,
506-
span:span,
507-
cat:cat_stack_upvar(upvar_cmt),
508-
mutbl:upvar_cmt.mutbl.inherit(),
509-
ty:upvar_cmt.ty
510-
}
500+
// Decide whether to use implicit reference or by copy/move
501+
// capture for the upvar. This, combined with the onceness,
502+
// determines whether the closure can move out of it.
503+
let var_is_refd = match (closure_ty.sigil, closure_ty.onceness) {
504+
// Many-shot stack closures can never move out.
505+
(ast::BorrowedSigil, ast::Many) => true,
506+
// 1-shot stack closures can move out with "-Z once-fns".
507+
(ast::BorrowedSigil, ast::Once)
508+
if self.tcx.sess.once_fns() => false,
509+
(ast::BorrowedSigil, ast::Once) => true,
510+
// Heap closures always capture by copy/move, and can
511+
// move out iff they are once.
512+
(ast::OwnedSigil, _) | (ast::ManagedSigil, _) => false,
513+
514+
};
515+
if var_is_refd {
516+
let upvar_cmt =
517+
self.cat_def(id, span, expr_ty, *inner);
518+
@cmt_ {
519+
id:id,
520+
span:span,
521+
cat:cat_stack_upvar(upvar_cmt),
522+
mutbl:upvar_cmt.mutbl.inherit(),
523+
ty:upvar_cmt.ty
511524
}
512-
(ast::BorrowedSigil, ast::Once) |
513-
(ast::OwnedSigil, _) | (ast::ManagedSigil, _) => {
514-
// FIXME #2152 allow mutation of moved upvars
515-
@cmt_ {
516-
id:id,
517-
span:span,
518-
cat:cat_copied_upvar(CopiedUpvar {
519-
upvar_id: upvar_id,
520-
onceness: closure_ty.onceness}),
521-
mutbl:McImmutable,
522-
ty:expr_ty
523-
}
525+
} else {
526+
// FIXME #2152 allow mutation of moved upvars
527+
@cmt_ {
528+
id:id,
529+
span:span,
530+
cat:cat_copied_upvar(CopiedUpvar {
531+
upvar_id: upvar_id,
532+
onceness: closure_ty.onceness}),
533+
mutbl:McImmutable,
534+
ty:expr_ty
524535
}
525536
}
526537
}

src/test/compile-fail/once-cant-call-twice-on-stack.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
// Testing guarantees provided by once functions.
1212
// This program would segfault if it were legal.
1313

14+
// compile-flags:-Z once-fns
1415
extern mod extra;
1516
use extra::arc;
1617
use std::util;

src/test/run-pass/once-move-out-on-stack.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
// Testing guarantees provided by once functions.
1212

13+
// compile-flags:-Z once-fns
1314
extern mod extra;
1415
use extra::arc;
1516
use std::util;

0 commit comments

Comments
 (0)