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:
bors 2013-06-29 02:34:43 -07:00
commit c80e3bac3e
11 changed files with 304 additions and 52 deletions

View 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);
}
}

View 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);
}
}

View 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() {
}

View 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: ~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
}
}

View 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: &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
}
}

View 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);
}
}

View 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);
}
}