auto merge of #7244 : bblum/rust/once, r=nikomatsakis
@graydon suggested that once closures not be part of the language for 1.0, but that they might be hidden behind a -Z compile flag as an "experimental feature" in case people decide they need them. Regardless of whether ```-Z once-fns``` is set, this PR will parse the ```once``` keyword and will prevent closures labelled with it from being called more than once. It will also permit moving out of captured vars in heap closures, just to let the runtime writers stop using ```Cell``` sooner. Setting ```-Z once-fns``` only toggles whether the move-out-from-capture privilege is also given for stack closures. r? @nikomatsakis
This commit is contained in:
commit
c80e3bac3e
11 changed files with 304 additions and 52 deletions
29
src/test/compile-fail/once-cant-call-twice-on-heap.rs
Normal file
29
src/test/compile-fail/once-cant-call-twice-on-heap.rs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Testing guarantees provided by once functions.
|
||||
// This program would segfault if it were legal.
|
||||
|
||||
extern mod extra;
|
||||
use extra::arc;
|
||||
use std::util;
|
||||
|
||||
fn foo(blk: ~once fn()) {
|
||||
blk();
|
||||
blk(); //~ ERROR use of moved value
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = arc::ARC(true);
|
||||
do foo {
|
||||
assert!(*x.get());
|
||||
util::ignore(x);
|
||||
}
|
||||
}
|
||||
30
src/test/compile-fail/once-cant-call-twice-on-stack.rs
Normal file
30
src/test/compile-fail/once-cant-call-twice-on-stack.rs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Testing guarantees provided by once functions.
|
||||
// This program would segfault if it were legal.
|
||||
|
||||
// compile-flags:-Z once-fns
|
||||
extern mod extra;
|
||||
use extra::arc;
|
||||
use std::util;
|
||||
|
||||
fn foo(blk: &once fn()) {
|
||||
blk();
|
||||
blk(); //~ ERROR use of moved value
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = arc::ARC(true);
|
||||
do foo {
|
||||
assert!(*x.get());
|
||||
util::ignore(x);
|
||||
}
|
||||
}
|
||||
20
src/test/compile-fail/once-cant-copy-stack-once-fn-copy.rs
Normal file
20
src/test/compile-fail/once-cant-copy-stack-once-fn-copy.rs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Though it should be legal to copy a heap-allocated "once fn:Copy",
|
||||
// stack closures are not deep-copied, so (counterintuitively) it should be
|
||||
// illegal to copy them.
|
||||
|
||||
fn foo<'r>(blk: &'r once fn:Copy()) -> (&'r once fn:Copy(), &'r once fn:Copy()) {
|
||||
(copy blk, blk) //~ ERROR copying a value of non-copyable type
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Testing guarantees provided by once functions.
|
||||
// This program would segfault if it were legal.
|
||||
|
||||
extern mod extra;
|
||||
use extra::arc;
|
||||
use std::util;
|
||||
|
||||
fn foo(blk: ~fn()) {
|
||||
blk();
|
||||
blk();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = arc::ARC(true);
|
||||
do foo {
|
||||
assert!(*x.get());
|
||||
util::ignore(x); //~ ERROR cannot move out of captured outer variable
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Testing guarantees provided by once functions.
|
||||
// This program would segfault if it were legal.
|
||||
|
||||
extern mod extra;
|
||||
use extra::arc;
|
||||
use std::util;
|
||||
|
||||
fn foo(blk: &fn()) {
|
||||
blk();
|
||||
blk();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = arc::ARC(true);
|
||||
do foo {
|
||||
assert!(*x.get());
|
||||
util::ignore(x); //~ ERROR cannot move out of captured outer variable
|
||||
}
|
||||
}
|
||||
29
src/test/run-pass/once-move-out-on-heap.rs
Normal file
29
src/test/run-pass/once-move-out-on-heap.rs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Testing guarantees provided by once functions.
|
||||
|
||||
// xfail-fast
|
||||
|
||||
extern mod extra;
|
||||
use extra::arc;
|
||||
use std::util;
|
||||
|
||||
fn foo(blk: ~once fn()) {
|
||||
blk();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = arc::ARC(true);
|
||||
do foo {
|
||||
assert!(*x.get());
|
||||
util::ignore(x);
|
||||
}
|
||||
}
|
||||
30
src/test/run-pass/once-move-out-on-stack.rs
Normal file
30
src/test/run-pass/once-move-out-on-stack.rs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Testing guarantees provided by once functions.
|
||||
|
||||
// xfail-fast
|
||||
|
||||
// compile-flags:-Z once-fns
|
||||
extern mod extra;
|
||||
use extra::arc;
|
||||
use std::util;
|
||||
|
||||
fn foo(blk: &once fn()) {
|
||||
blk();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = arc::ARC(true);
|
||||
do foo {
|
||||
assert!(*x.get());
|
||||
util::ignore(x);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue