auto merge of #10561 : pcwalton/rust/procify, r=alexcrichton

r? @alexcrichton
This commit is contained in:
bors 2013-11-18 23:06:29 -08:00
commit f4c22f75d4
65 changed files with 186 additions and 265 deletions

View File

@ -213,7 +213,7 @@ msgstr ""
#. type: Plain text
#: doc/tutorial-tasks.md:102
msgid ""
"The `spawn` function has a very simple type signature: `fn spawn(f: ~fn())`. "
"The `spawn` function has a very simple type signature: `fn spawn(f: proc())`. "
"Because it accepts only owned closures, and owned closures contain only "
"owned data, `spawn` can safely move the entire closure and all its "
"associated state into an entirely different task for execution. Like any "

View File

@ -3509,13 +3509,13 @@ msgstr "## 所有クロージャ"
#. type: Plain text
#: doc/tutorial.md:1510
msgid ""
"Owned closures, written `~fn` in analogy to the `~` pointer type, hold on to "
"Owned closures, written `proc`, hold on to "
"things that can safely be sent between processes. They copy the values they "
"close over, much like managed closures, but they also own them: that is, no "
"other code can access them. Owned closures are used in concurrent code, "
"particularly for spawning [tasks][tasks]."
msgstr ""
"`~` ポインタ型と同様に `~fn` 型 で書き表される所有クロージャは安全にプロセス"
"`~` `proc` で書き表される所有クロージャは安全にプロセス"
"間で送信することができます。所有クローじゃはマネージドクロージャと全く同じよ"
"うに閉じ込める値をコピーしますが、値を所有します。つまり、他のコードは閉じ込"
"められた値にアクセスできなくなります。所有クロージャは並列プログラム、特に "
@ -3666,11 +3666,11 @@ msgstr ""
#: doc/tutorial.md:1582
msgid ""
"`do` is a convenient way to create tasks with the `task::spawn` function. "
"`spawn` has the signature `spawn(fn: ~fn())`. In other words, it is a "
"`spawn` has the signature `spawn(fn: proc())`. In other words, it is a "
"function that takes an owned closure that takes no arguments."
msgstr ""
"`task::spawn` 関数を用いてタスクを生成する場合、 `do` を用いると便利です。"
"`spawn` は、 `spawn(fn: ~fn())` という方を持っています。言い換えると、"
"`spawn` は、 `spawn(fn: proc())` という方を持っています。言い換えると、"
"`spawn` は「引数をとらない所有クロージャ」を引数としてとる関数ということで"
"す。"

View File

@ -213,7 +213,7 @@ msgstr ""
#. type: Plain text
#: doc/tutorial-tasks.md:102
msgid ""
"The `spawn` function has a very simple type signature: `fn spawn(f: ~fn())`. "
"The `spawn` function has a very simple type signature: `fn spawn(f: proc())`. "
"Because it accepts only owned closures, and owned closures contain only "
"owned data, `spawn` can safely move the entire closure and all its "
"associated state into an entirely different task for execution. Like any "

View File

@ -2683,7 +2683,7 @@ msgstr ""
#. type: Plain text
#: doc/tutorial.md:1510
msgid ""
"Owned closures, written `~fn` in analogy to the `~` pointer type, hold on to "
"Owned closures, written `proc`, hold on to "
"things that can safely be sent between processes. They copy the values they "
"close over, much like managed closures, but they also own them: that is, no "
"other code can access them. Owned closures are used in concurrent code, "
@ -2808,7 +2808,7 @@ msgstr ""
#: doc/tutorial.md:1582
msgid ""
"`do` is a convenient way to create tasks with the `task::spawn` function. "
"`spawn` has the signature `spawn(fn: ~fn())`. In other words, it is a "
"`spawn` has the signature `spawn(fn: proc())`. In other words, it is a "
"function that takes an owned closure that takes no arguments."
msgstr ""

View File

@ -91,7 +91,7 @@ _owned types_. The language leaves the implementation details to the standard
library.
The `spawn` function has a very simple type signature: `fn spawn(f:
~fn())`. Because it accepts only owned closures, and owned closures
proc())`. Because it accepts only owned closures, and owned closures
contain only owned data, `spawn` can safely move the entire closure
and all its associated state into an entirely different task for
execution. Like any closure, the function passed to `spawn` may capture

View File

@ -1409,7 +1409,7 @@ pervasively in Rust code.
## Owned closures
Owned closures, written `~fn` in analogy to the `~` pointer type,
Owned closures, written `proc`,
hold on to things that can safely be sent between
processes. They copy the values they close over, much like managed
closures, but they also own them: that is, no other code can access
@ -1484,7 +1484,7 @@ parentheses, where it looks more like a typical block of
code.
`do` is a convenient way to create tasks with the `task::spawn`
function. `spawn` has the signature `spawn(fn: ~fn())`. In other
function. `spawn` has the signature `spawn(fn: proc())`. In other
words, it is a function that takes an owned closure that takes no
arguments.

View File

@ -36,7 +36,7 @@ pub struct Future<A> {
}
enum FutureState<A> {
Pending(~fn() -> A),
Pending(proc() -> A),
Evaluating,
Forced(A)
}
@ -92,7 +92,7 @@ impl<A> Future<A> {
Future {state: Forced(val)}
}
pub fn from_fn(f: ~fn() -> A) -> Future<A> {
pub fn from_fn(f: proc() -> A) -> Future<A> {
/*!
* Create a future from a function.
*
@ -120,7 +120,7 @@ impl<A:Send> Future<A> {
}
}
pub fn spawn(blk: ~fn() -> A) -> Future<A> {
pub fn spawn(blk: proc() -> A) -> Future<A> {
/*!
* Create a future from a unique closure.
*
@ -137,7 +137,7 @@ impl<A:Send> Future<A> {
Future::from_port(port)
}
pub fn spawn_with<B: Send>(v: B, blk: ~fn(B) -> A) -> Future<A> {
pub fn spawn_with<B: Send>(v: B, blk: proc(B) -> A) -> Future<A> {
/*!
* Create a future from a unique closure taking one argument.
*

View File

@ -23,7 +23,7 @@ use std::vec;
#[cfg(test)] use std::task::SingleThreaded;
enum Msg<T> {
Execute(~fn(&T)),
Execute(proc(&T)),
Quit
}
@ -49,7 +49,7 @@ impl<T> TaskPool<T> {
/// local data to be kept around in that task.
pub fn new(n_tasks: uint,
opt_sched_mode: Option<SchedMode>,
init_fn_factory: ~fn() -> ~fn(uint) -> T)
init_fn_factory: &fn() -> proc(uint) -> T)
-> TaskPool<T> {
assert!(n_tasks >= 1);
@ -57,7 +57,7 @@ impl<T> TaskPool<T> {
let (port, chan) = comm::stream::<Msg<T>>();
let init_fn = init_fn_factory();
let task_body: ~fn() = || {
let task_body: proc() = || {
let local_data = init_fn(i);
loop {
match port.recv() {
@ -88,7 +88,7 @@ impl<T> TaskPool<T> {
/// Executes the function `f` on a task in the pool. The function
/// receives a reference to the local data returned by the `init_fn`.
pub fn execute(&mut self, f: ~fn(&T)) {
pub fn execute(&mut self, f: proc(&T)) {
self.channels[self.next_index].send(Execute(f));
self.next_index += 1;
if self.next_index == self.channels.len() { self.next_index = 0; }
@ -97,8 +97,8 @@ impl<T> TaskPool<T> {
#[test]
fn test_task_pool() {
let f: ~fn() -> ~fn(uint) -> uint = || {
let g: ~fn(uint) -> uint = |i| i;
let f: &fn() -> proc(uint) -> uint = || {
let g: proc(uint) -> uint = |i| i;
g
};
let mut pool = TaskPool::new(4, Some(SingleThreaded), f);

View File

@ -74,6 +74,11 @@ impl TestDesc {
}
}
/// Represents a benchmark function.
pub trait TDynBenchFn {
fn run(&self, harness: &mut BenchHarness);
}
// A function that runs a test. If the function returns successfully,
// the test succeeds; if the function fails then the test fails. We
// may need to come up with a more clever definition of test in order
@ -81,10 +86,10 @@ impl TestDesc {
pub enum TestFn {
StaticTestFn(extern fn()),
StaticBenchFn(extern fn(&mut BenchHarness)),
StaticMetricFn(~fn(&mut MetricMap)),
DynTestFn(~fn()),
DynMetricFn(~fn(&mut MetricMap)),
DynBenchFn(~fn(&mut BenchHarness))
StaticMetricFn(proc(&mut MetricMap)),
DynTestFn(proc()),
DynMetricFn(proc(&mut MetricMap)),
DynBenchFn(~TDynBenchFn)
}
impl TestFn {
@ -859,7 +864,7 @@ pub fn run_test(force_ignore: bool,
fn run_test_inner(desc: TestDesc,
monitor_ch: SharedChan<MonitorMsg>,
testfn: ~fn()) {
testfn: proc()) {
let testfn_cell = ::std::cell::Cell::new(testfn);
do task::spawn {
let mut task = task::task();
@ -878,8 +883,8 @@ pub fn run_test(force_ignore: bool,
}
match testfn {
DynBenchFn(benchfn) => {
let bs = ::test::bench::benchmark(benchfn);
DynBenchFn(bencher) => {
let bs = ::test::bench::benchmark(|harness| bencher.run(harness));
monitor_ch.send((desc, TrBench(bs)));
return;
}

View File

@ -394,14 +394,14 @@ impl<'self> Prep<'self> {
pub fn exec<T:Send +
Encodable<json::Encoder> +
Decodable<json::Decoder>>(
&'self self, blk: ~fn(&mut Exec) -> T) -> T {
&'self self, blk: proc(&mut Exec) -> T) -> T {
self.exec_work(blk).unwrap()
}
fn exec_work<T:Send +
Encodable<json::Encoder> +
Decodable<json::Decoder>>( // FIXME(#5121)
&'self self, blk: ~fn(&mut Exec) -> T) -> Work<'self, T> {
&'self self, blk: proc(&mut Exec) -> T) -> Work<'self, T> {
let mut bo = Some(blk);
debug!("exec_work: looking up {} and {:?}", self.fn_name,

View File

@ -322,7 +322,7 @@ diagnostic emitter which records when we hit a fatal error. If the task
fails without recording a fatal error then we've encountered a compiler
bug and need to present an error.
*/
pub fn monitor(f: ~fn(@diagnostic::Emitter)) {
pub fn monitor(f: proc(@diagnostic::Emitter)) {
use std::comm::*;
// XXX: This is a hack for newsched since it doesn't support split stacks.

View File

@ -1101,7 +1101,7 @@ mod test {
let handle2 = Cell::new(sched2.make_handle());
let tasksFriendHandle = Cell::new(sched2.make_handle());
let on_exit: ~fn(UnwindResult) = |exit_status| {
let on_exit: proc(UnwindResult) = |exit_status| {
handle1.take().send(Shutdown);
handle2.take().send(Shutdown);
assert!(exit_status.is_success());
@ -1115,7 +1115,7 @@ mod test {
}
}
let test_function: ~fn() = || {
let test_function: proc() = || {
let io = unsafe { local_io() };
let addr = next_test_ip4();
let maybe_socket = io.udp_bind(addr);

View File

@ -157,7 +157,7 @@ mod tests {
use io::*;
use rt::comm::oneshot;
fn smalltest(server: ~fn(UnixStream), client: ~fn(UnixStream)) {
fn smalltest(server: proc(UnixStream), client: proc(UnixStream)) {
let server = Cell::new(server);
let client = Cell::new(client);
do run_in_mt_newsched_task {

View File

@ -478,11 +478,11 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
}
fn visit_closure_ptr(&mut self, ck: uint) -> bool {
self.align_to::<~fn()>();
self.align_to::<proc()>();
if ! self.inner.visit_closure_ptr(ck) {
return false
}
self.bump_past::<~fn()>();
self.bump_past::<proc()>();
true
}
}

View File

@ -25,7 +25,7 @@ pub static RED_ZONE: uint = 20 * 1024;
// then misalign the regs again.
pub struct Context {
/// The context entry point, saved here for later destruction
priv start: Option<~~fn()>,
priv start: Option<~proc()>,
/// Hold the registers while the task or scheduler is suspended
priv regs: ~Registers,
/// Lower bound and upper bound for the stack
@ -41,18 +41,24 @@ impl Context {
}
}
/// Create a new context that will resume execution by running ~fn()
pub fn new(start: ~fn(), stack: &mut StackSegment) -> Context {
/// Create a new context that will resume execution by running proc()
pub fn new(start: proc(), stack: &mut StackSegment) -> Context {
// FIXME #7767: Putting main into a ~ so it's a thin pointer and can
// be passed to the spawn function. Another unfortunate
// allocation
let start = ~start;
// The C-ABI function that is the task entry point
extern fn task_start_wrapper(f: &~fn()) { (*f)() }
extern fn task_start_wrapper(f: &proc()) {
// XXX(pcwalton): This may be sketchy.
unsafe {
let f: &|| = transmute(f);
(*f)()
}
}
let fp: *c_void = task_start_wrapper as *c_void;
let argp: *c_void = unsafe { transmute::<&~fn(), *c_void>(&*start) };
let argp: *c_void = unsafe { transmute::<&proc(), *c_void>(&*start) };
let sp: *uint = stack.end();
let sp: *mut uint = unsafe { transmute_mut_unsafe(sp) };
// Save and then immediately load the current context,

View File

@ -110,7 +110,7 @@ see a failure from the grandchild task. While we could achieve this by having
each intermediate task block on its handle, this keeps around the other resources
the task was using. To be more efficient, this is accomplished via "tombstones".
A tombstone is a closure, ~fn() -> bool, which will perform any waiting necessary
A tombstone is a closure, proc() -> bool, which will perform any waiting necessary
to collect the exit code of descendant tasks. In its environment is captured
the KillHandle of whichever task created the tombstone, and perhaps also any
tombstones that that task itself had, and finally also another tombstone,
@ -205,7 +205,7 @@ struct KillHandleInner {
// Locklessly accessed; protected by the enclosing refcount's barriers.
any_child_failed: bool,
// A lazy list, consuming which may unwrap() many child tombstones.
child_tombstones: Option<~fn() -> bool>,
child_tombstones: Option<proc() -> bool>,
// Protects multiple children simultaneously creating tombstones.
graveyard_lock: LittleLock,
}
@ -223,7 +223,7 @@ pub struct Death {
priv watching_parent: Option<KillHandle>,
// Action to be done with the exit code. If set, also makes the task wait
// until all its watched children exit before collecting the status.
on_exit: Option<~fn(UnwindResult)>,
on_exit: Option<proc(UnwindResult)>,
// nesting level counter for task::unkillable calls (0 == killable).
priv unkillable: int,
// nesting level counter for unstable::atomically calls (0 == can deschedule).
@ -525,7 +525,8 @@ impl KillHandle {
// NB: Takes a pthread mutex -- 'blk' not allowed to reschedule.
#[inline]
fn add_lazy_tombstone(parent: &mut KillHandle,
blk: &fn(Option<~fn() -> bool>) -> ~fn() -> bool) {
blk: &fn(Option<proc() -> bool>)
-> proc() -> bool) {
let inner: &mut KillHandleInner = unsafe { &mut *parent.get() };
unsafe {

View File

@ -207,7 +207,7 @@ pub mod borrowck;
/// # Return value
///
/// The return value is used as the process return code. 0 on success, 101 on error.
pub fn start(argc: int, argv: **u8, main: ~fn()) -> int {
pub fn start(argc: int, argv: **u8, main: proc()) -> int {
init(argc, argv);
let exit_code = run(main);
@ -221,7 +221,7 @@ pub fn start(argc: int, argv: **u8, main: ~fn()) -> int {
///
/// This is appropriate for running code that must execute on the main thread,
/// such as the platform event loop and GUI.
pub fn start_on_main_thread(argc: int, argv: **u8, main: ~fn()) -> int {
pub fn start_on_main_thread(argc: int, argv: **u8, main: proc()) -> int {
init(argc, argv);
let exit_code = run_on_main_thread(main);
cleanup();
@ -254,15 +254,15 @@ pub fn cleanup() {
/// Configures the runtime according to the environment, by default
/// using a task scheduler with the same number of threads as cores.
/// Returns a process exit code.
pub fn run(main: ~fn()) -> int {
pub fn run(main: proc()) -> int {
run_(main, false)
}
pub fn run_on_main_thread(main: ~fn()) -> int {
pub fn run_on_main_thread(main: proc()) -> int {
run_(main, true)
}
fn run_(main: ~fn(), use_main_sched: bool) -> int {
fn run_(main: proc(), use_main_sched: bool) -> int {
static DEFAULT_ERROR_CODE: int = 101;
let nscheds = util::default_sched_threads();
@ -341,7 +341,7 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
// When the main task exits, after all the tasks in the main
// task tree, shut down the schedulers and set the exit code.
let handles = Cell::new(handles);
let on_exit: ~fn(UnwindResult) = |exit_success| {
let on_exit: proc(UnwindResult) = |exit_success| {
unsafe {
assert!(!(*exited_already.get()).swap(true, SeqCst),
"the runtime already exited");

View File

@ -990,7 +990,9 @@ mod test {
assert!(Task::on_appropriate_sched());
};
let on_exit: ~fn(UnwindResult) = |exit_status| rtassert!(exit_status.is_success());
let on_exit: proc(UnwindResult) = |exit_status| {
rtassert!(exit_status.is_success())
};
task.death.on_exit = Some(on_exit);
sched.bootstrap(task);

View File

@ -139,7 +139,10 @@ impl Task {
// A helper to build a new task using the dynamically found
// scheduler and task. Only works in GreenTask context.
pub fn build_homed_child(stack_size: Option<uint>, f: ~fn(), home: SchedHome) -> ~Task {
pub fn build_homed_child(stack_size: Option<uint>,
f: proc(),
home: SchedHome)
-> ~Task {
let f = Cell::new(f);
let home = Cell::new(home);
do Local::borrow |running_task: &mut Task| {
@ -153,11 +156,14 @@ impl Task {
}
}
pub fn build_child(stack_size: Option<uint>, f: ~fn()) -> ~Task {
pub fn build_child(stack_size: Option<uint>, f: proc()) -> ~Task {
Task::build_homed_child(stack_size, f, AnySched)
}
pub fn build_homed_root(stack_size: Option<uint>, f: ~fn(), home: SchedHome) -> ~Task {
pub fn build_homed_root(stack_size: Option<uint>,
f: proc(),
home: SchedHome)
-> ~Task {
let f = Cell::new(f);
let home = Cell::new(home);
do Local::borrow |running_task: &mut Task| {
@ -171,7 +177,7 @@ impl Task {
}
}
pub fn build_root(stack_size: Option<uint>, f: ~fn()) -> ~Task {
pub fn build_root(stack_size: Option<uint>, f: proc()) -> ~Task {
Task::build_homed_root(stack_size, f, AnySched)
}
@ -196,21 +202,21 @@ impl Task {
pub fn new_root(stack_pool: &mut StackPool,
stack_size: Option<uint>,
start: ~fn()) -> Task {
start: proc()) -> Task {
Task::new_root_homed(stack_pool, stack_size, AnySched, start)
}
pub fn new_child(&mut self,
stack_pool: &mut StackPool,
stack_size: Option<uint>,
start: ~fn()) -> Task {
start: proc()) -> Task {
self.new_child_homed(stack_pool, stack_size, AnySched, start)
}
pub fn new_root_homed(stack_pool: &mut StackPool,
stack_size: Option<uint>,
home: SchedHome,
start: ~fn()) -> Task {
start: proc()) -> Task {
Task {
heap: LocalHeap::new(),
gc: GarbageCollector,
@ -233,7 +239,7 @@ impl Task {
stack_pool: &mut StackPool,
stack_size: Option<uint>,
home: SchedHome,
start: ~fn()) -> Task {
start: proc()) -> Task {
Task {
heap: LocalHeap::new(),
gc: GarbageCollector,
@ -404,7 +410,10 @@ impl Drop for Task {
impl Coroutine {
pub fn new(stack_pool: &mut StackPool, stack_size: Option<uint>, start: ~fn()) -> Coroutine {
pub fn new(stack_pool: &mut StackPool,
stack_size: Option<uint>,
start: proc())
-> Coroutine {
let stack_size = match stack_size {
Some(size) => size,
None => env::min_stack()
@ -425,9 +434,9 @@ impl Coroutine {
}
}
fn build_start_wrapper(start: ~fn()) -> ~fn() {
fn build_start_wrapper(start: proc()) -> proc() {
let start_cell = Cell::new(start);
let wrapper: ~fn() = || {
let wrapper: proc() = || {
// First code after swap to this new context. Run our
// cleanup job.
unsafe {

View File

@ -64,28 +64,28 @@ pub fn new_test_sched() -> Scheduler {
return sched;
}
pub fn run_in_uv_task(f: ~fn()) {
pub fn run_in_uv_task(f: proc()) {
let f = Cell::new(f);
do run_in_bare_thread {
run_in_uv_task_core(f.take());
}
}
pub fn run_in_newsched_task(f: ~fn()) {
pub fn run_in_newsched_task(f: proc()) {
let f = Cell::new(f);
do run_in_bare_thread {
run_in_newsched_task_core(f.take());
}
}
pub fn run_in_uv_task_core(f: ~fn()) {
pub fn run_in_uv_task_core(f: proc()) {
use rt::sched::Shutdown;
let mut sched = ~new_test_uv_sched();
let exit_handle = Cell::new(sched.make_handle());
let on_exit: ~fn(UnwindResult) = |exit_status| {
let on_exit: proc(UnwindResult) = |exit_status| {
exit_handle.take().send(Shutdown);
rtassert!(exit_status.is_success());
};
@ -95,13 +95,13 @@ pub fn run_in_uv_task_core(f: ~fn()) {
sched.bootstrap(task);
}
pub fn run_in_newsched_task_core(f: ~fn()) {
pub fn run_in_newsched_task_core(f: proc()) {
use rt::sched::Shutdown;
let mut sched = ~new_test_sched();
let exit_handle = Cell::new(sched.make_handle());
let on_exit: ~fn(UnwindResult) = |exit_status| {
let on_exit: proc(UnwindResult) = |exit_status| {
exit_handle.take().send(Shutdown);
rtassert!(exit_status.is_success());
};
@ -195,7 +195,7 @@ pub fn prepare_for_lots_of_tests() {
/// Create more than one scheduler and run a function in a task
/// in one of the schedulers. The schedulers will stay alive
/// until the function `f` returns.
pub fn run_in_mt_newsched_task(f: ~fn()) {
pub fn run_in_mt_newsched_task(f: proc()) {
use os;
use from_str::FromStr;
use rt::sched::Shutdown;
@ -245,7 +245,7 @@ pub fn run_in_mt_newsched_task(f: ~fn()) {
}
let handles = Cell::new(handles);
let on_exit: ~fn(UnwindResult) = |exit_status| {
let on_exit: proc(UnwindResult) = |exit_status| {
let mut handles = handles.take();
// Tell schedulers to exit
for handle in handles.mut_iter() {
@ -294,16 +294,16 @@ pub fn run_in_mt_newsched_task(f: ~fn()) {
}
/// Test tasks will abort on failure instead of unwinding
pub fn spawntask(f: ~fn()) {
pub fn spawntask(f: proc()) {
Scheduler::run_task(Task::build_child(None, f));
}
/// Create a new task and run it right now. Aborts on failure
pub fn spawntask_later(f: ~fn()) {
pub fn spawntask_later(f: proc()) {
Scheduler::run_task_later(Task::build_child(None, f));
}
pub fn spawntask_random(f: ~fn()) {
pub fn spawntask_random(f: proc()) {
use rand::{Rand, rng};
let mut rng = rng();
@ -316,11 +316,11 @@ pub fn spawntask_random(f: ~fn()) {
}
}
pub fn spawntask_try(f: ~fn()) -> Result<(),()> {
pub fn spawntask_try(f: proc()) -> Result<(),()> {
let (port, chan) = oneshot();
let chan = Cell::new(chan);
let on_exit: ~fn(UnwindResult) = |exit_status| chan.take().send(exit_status);
let on_exit: proc(UnwindResult) = |exit_status| chan.take().send(exit_status);
let mut new_task = Task::build_root(None, f);
new_task.death.on_exit = Some(on_exit);
@ -333,7 +333,7 @@ pub fn spawntask_try(f: ~fn()) -> Result<(),()> {
}
/// Spawn a new task in a new scheduler and return a thread handle.
pub fn spawntask_thread(f: ~fn()) -> Thread {
pub fn spawntask_thread(f: proc()) -> Thread {
let f = Cell::new(f);
@ -345,7 +345,7 @@ pub fn spawntask_thread(f: ~fn()) -> Thread {
}
/// Get a ~Task for testing purposes other than actually scheduling it.
pub fn with_test_task(blk: ~fn(~Task) -> ~Task) {
pub fn with_test_task(blk: proc(~Task) -> ~Task) {
do run_in_bare_thread {
let mut sched = ~new_test_sched();
let task = blk(~Task::new_root(&mut sched.stack_pool, None, ||{}));

View File

@ -35,7 +35,7 @@ static DEFAULT_STACK_SIZE: libc::size_t = 1024*1024;
impl Thread {
pub fn start(main: ~fn()) -> Thread {
pub fn start(main: proc()) -> Thread {
// This is the starting point of rust os threads. The first thing we do
// is make sure that we don't trigger __morestack (also why this has a
// no_split_stack annotation), and then we extract the main function
@ -45,7 +45,7 @@ impl Thread {
use rt::context;
unsafe {
context::record_stack_bounds(0, uint::max_value);
let f: ~~fn() = cast::transmute(trampoline);
let f: ~proc() = cast::transmute(trampoline);
(*f)();
}
unsafe { cast::transmute(0) }
@ -67,7 +67,7 @@ impl Thread {
#[cfg(windows)]
fn native_thread_create(thread_start: extern "C" fn(*libc::c_void) -> rust_thread_return,
tramp: ~~fn()) -> rust_thread {
tramp: ~proc()) -> rust_thread {
unsafe {
let ptr: *mut libc::c_void = cast::transmute(tramp);
CreateThread(ptr::mut_null(), DEFAULT_STACK_SIZE, thread_start, ptr, 0, ptr::mut_null())
@ -82,7 +82,7 @@ fn native_thread_join(native: rust_thread) {
#[cfg(unix)]
fn native_thread_create(thread_start: extern "C" fn(*libc::c_void) -> rust_thread_return,
tramp: ~~fn()) -> rust_thread {
tramp: ~proc()) -> rust_thread {
use unstable::intrinsics;
let mut native: libc::pthread_t = unsafe { intrinsics::uninit() };

View File

@ -195,7 +195,7 @@ pub struct TaskOpts {
// FIXME (#3724): Replace the 'consumed' bit with move mode on self
pub struct TaskBuilder {
opts: TaskOpts,
priv gen_body: Option<~fn(v: ~fn()) -> ~fn()>,
priv gen_body: Option<proc(v: proc()) -> proc()>,
priv can_not_copy: Option<util::NonCopyable>,
priv consumed: bool,
}
@ -340,18 +340,18 @@ impl TaskBuilder {
* generator by applying the task body which results from the
* existing body generator to the new body generator.
*/
pub fn add_wrapper(&mut self, wrapper: ~fn(v: ~fn()) -> ~fn()) {
pub fn add_wrapper(&mut self, wrapper: proc(v: proc()) -> proc()) {
let prev_gen_body = self.gen_body.take();
let prev_gen_body = match prev_gen_body {
Some(gen) => gen,
None => {
let f: ~fn(~fn()) -> ~fn() = |body| body;
let f: proc(proc()) -> proc() = |body| body;
f
}
};
let prev_gen_body = Cell::new(prev_gen_body);
let next_gen_body = {
let f: ~fn(~fn()) -> ~fn() = |body| {
let f: proc(proc()) -> proc() = |body| {
let prev_gen_body = prev_gen_body.take();
wrapper(prev_gen_body(body))
};
@ -372,7 +372,7 @@ impl TaskBuilder {
* When spawning into a new scheduler, the number of threads requested
* must be greater than zero.
*/
pub fn spawn(&mut self, f: ~fn()) {
pub fn spawn(&mut self, f: proc()) {
let gen_body = self.gen_body.take();
let notify_chan = self.opts.notify_chan.take();
let name = self.opts.name.take();
@ -399,7 +399,7 @@ impl TaskBuilder {
}
/// Runs a task, while transferring ownership of one argument to the child.
pub fn spawn_with<A:Send>(&mut self, arg: A, f: ~fn(v: A)) {
pub fn spawn_with<A:Send>(&mut self, arg: A, f: proc(v: A)) {
let arg = Cell::new(arg);
do self.spawn {
f(arg.take());
@ -419,7 +419,7 @@ impl TaskBuilder {
* # Failure
* Fails if a future_result was already set for this task.
*/
pub fn try<T:Send>(&mut self, f: ~fn() -> T) -> Result<T, ~Any> {
pub fn try<T:Send>(&mut self, f: proc() -> T) -> Result<T, ~Any> {
let (po, ch) = stream::<T>();
let result = self.future_result();
@ -468,20 +468,20 @@ pub fn default_task_opts() -> TaskOpts {
/// the provided unique closure.
///
/// This function is equivalent to `task().spawn(f)`.
pub fn spawn(f: ~fn()) {
pub fn spawn(f: proc()) {
let mut task = task();
task.spawn(f)
}
/// Creates a child task unlinked from the current one. If either this
/// task or the child task fails, the other will not be killed.
pub fn spawn_unlinked(f: ~fn()) {
pub fn spawn_unlinked(f: proc()) {
let mut task = task();
task.unlinked();
task.spawn(f)
}
pub fn spawn_supervised(f: ~fn()) {
pub fn spawn_supervised(f: proc()) {
/*!
* Creates a child task supervised by the current one. If the child
* task fails, the parent will not be killed, but if the parent fails,
@ -498,13 +498,13 @@ pub fn spawn_supervised(f: ~fn()) {
/// (Note that this convenience wrapper still uses linked-failure, so the
/// child's children will still be killable by the parent. For the fastest
/// possible spawn mode, use task::task().unlinked().indestructible().spawn.)
pub fn spawn_indestructible(f: ~fn()) {
pub fn spawn_indestructible(f: proc()) {
let mut task = task();
task.indestructible();
task.spawn(f)
}
pub fn spawn_with<A:Send>(arg: A, f: ~fn(v: A)) {
pub fn spawn_with<A:Send>(arg: A, f: proc(v: A)) {
/*!
* Runs a task, while transferring ownership of one argument to the
* child.
@ -519,7 +519,7 @@ pub fn spawn_with<A:Send>(arg: A, f: ~fn(v: A)) {
task.spawn_with(arg, f)
}
pub fn spawn_sched(mode: SchedMode, f: ~fn()) {
pub fn spawn_sched(mode: SchedMode, f: proc()) {
/*!
* Creates a new task on a new or existing scheduler.
*
@ -537,7 +537,7 @@ pub fn spawn_sched(mode: SchedMode, f: ~fn()) {
task.spawn(f)
}
pub fn try<T:Send>(f: ~fn() -> T) -> Result<T, ~Any> {
pub fn try<T:Send>(f: proc() -> T) -> Result<T, ~Any> {
/*!
* Execute a function in another task and return either the return value
* of the function or result::err.
@ -1033,7 +1033,7 @@ fn test_add_wrapper() {
let ch = Cell::new(ch);
do b0.add_wrapper |body| {
let ch = Cell::new(ch.take());
let result: ~fn() = || {
let result: proc() = || {
let ch = ch.take();
body();
ch.send(());
@ -1201,7 +1201,7 @@ fn test_spawn_sched_blocking() {
}
#[cfg(test)]
fn avoid_copying_the_body(spawnfn: &fn(v: ~fn())) {
fn avoid_copying_the_body(spawnfn: &fn(v: proc())) {
let (p, ch) = stream::<uint>();
let x = ~1;
@ -1327,7 +1327,7 @@ fn test_child_doesnt_ref_parent() {
// (well, it would if the constant were 8000+ - I lowered it to be more
// valgrind-friendly. try this at home, instead..!)
static generations: uint = 16;
fn child_no(x: uint) -> ~fn() {
fn child_no(x: uint) -> proc() {
return || {
if x < generations {
let mut t = task();

View File

@ -562,13 +562,13 @@ fn enlist_many(child: &KillHandle, child_arc: &TaskGroupArc,
result
}
pub fn spawn_raw(mut opts: TaskOpts, f: ~fn()) {
pub fn spawn_raw(mut opts: TaskOpts, f: proc()) {
assert!(in_green_task_context());
let child_data = Cell::new(gen_child_taskgroup(opts.linked, opts.supervised));
let indestructible = opts.indestructible;
let child_wrapper: ~fn() = || {
let child_wrapper: proc() = || {
// Child task runs this code.
// If child data is 'None', the enlist is vacuously successful.
@ -589,12 +589,14 @@ pub fn spawn_raw(mut opts: TaskOpts, f: ~fn()) {
}
}
};
// Should be run after the local-borrowed task is returned.
let f_cell = Cell::new(f);
if enlist_success {
if indestructible {
do unkillable { f() }
do unkillable { f_cell.take()() }
} else {
f()
f_cell.take()()
}
}
};
@ -683,7 +685,7 @@ pub fn spawn_raw(mut opts: TaskOpts, f: ~fn()) {
if opts.notify_chan.is_some() {
let notify_chan = opts.notify_chan.take_unwrap();
let notify_chan = Cell::new(notify_chan);
let on_exit: ~fn(UnwindResult) = |task_result| {
let on_exit: proc(UnwindResult) = |task_result| {
notify_chan.take().send(task_result)
};
task.death.on_exit = Some(on_exit);

View File

@ -54,7 +54,6 @@ impl<'self,T> Finally<T> for &'self fn() -> T {
}
}
finally_fn!(~fn() -> T)
finally_fn!(extern "Rust" fn() -> T)
struct Finallyalizer<'self> {
@ -109,12 +108,3 @@ fn test_compact() {
but_always_run_this_function);
}
#[test]
fn test_owned() {
fn spawn_with_finalizer(f: ~fn()) {
do spawn { do f.finally { } }
}
let owned: ~fn() = || { };
spawn_with_finalizer(owned);
}

View File

@ -36,7 +36,7 @@ for it to terminate.
The executing thread has no access to a task pointer and will be using
a normal large stack.
*/
pub fn run_in_bare_thread(f: ~fn()) {
pub fn run_in_bare_thread(f: proc()) {
use cell::Cell;
use rt::thread::Thread;

View File

@ -41,7 +41,8 @@ pub enum ObsoleteSyntax {
ObsoleteLoopAsContinue,
ObsoleteEnumWildcard,
ObsoleteStructWildcard,
ObsoleteVecDotDotWildcard
ObsoleteVecDotDotWildcard,
ObsoleteBoxedClosure,
}
impl to_bytes::IterBytes for ObsoleteSyntax {
@ -128,6 +129,11 @@ impl ParserObsoleteMethods for Parser {
"vec slice wildcard",
"use `..` instead of `.._` for matching slices"
),
ObsoleteBoxedClosure => (
"managed or owned closure",
"managed closures have been removed and owned closures are \
now written `proc()`"
),
};
self.report(sp, kind, kind_str, desc);

View File

@ -1273,15 +1273,17 @@ impl Parser {
pub fn parse_box_or_uniq_pointee(&self,
sigil: ast::Sigil,
ctor: &fn(v: mt) -> ty_) -> ty_ {
// ~'foo fn() or ~fn() are parsed directly as fn types:
// ~'foo fn() or ~fn() are parsed directly as obsolete fn types:
match *self.token {
token::LIFETIME(*) => {
let lifetime = self.parse_lifetime();
self.obsolete(*self.last_span, ObsoleteBoxedClosure);
return self.parse_ty_closure(Some(sigil), Some(lifetime));
}
token::IDENT(*) => {
token::IDENT(*) if sigil == ast::BorrowedSigil => {
if self.token_is_old_style_closure_keyword() {
self.obsolete(*self.last_span, ObsoleteBoxedClosure);
return self.parse_ty_closure(Some(sigil), None);
}
}

View File

@ -53,7 +53,7 @@ fn grandchild_group(num_tasks: uint) {
// Master grandchild task exits early.
}
fn spawn_supervised_blocking(myname: &str, f: ~fn()) {
fn spawn_supervised_blocking(myname: &str, f: proc()) {
let mut builder = task::task();
let res = builder.future_result();
builder.supervised();

View File

@ -11,7 +11,7 @@
// xfail-test #2978
struct Foo {
f: ~fn()
f: proc()
}
fn call(x: @Foo) {

View File

@ -1,13 +1,8 @@
pub fn main() {
let foo = ~3;
let _pfoo = &foo;
let _f: ~fn() -> int = || *foo + 5;
//~^ ERROR cannot move `foo`
// FIXME(#2202) - Due to the way that borrowck treats closures,
// you get two error reports here.
let bar = ~3;
let _g = || { //~ ERROR capture of moved value
let _h: ~fn() -> int = || *bar; //~ ERROR capture of moved value
let _h: proc() -> int = || *bar; //~ ERROR capture of moved value
};
}

View File

@ -1,4 +1,4 @@
fn call_f(f: ~fn:Send() -> int) -> int {
fn call_f(f: proc() -> int) -> int {
f()
}

View File

@ -9,10 +9,10 @@
// except according to those terms.
struct X {
field: ~fn:Send(),
field: &'static fn:Send(),
}
fn foo(blk: ~fn:()) -> X {
fn foo(blk: &'static fn:()) -> X {
return X { field: blk }; //~ ERROR expected bounds `Send` but found no bounds
}

View File

@ -1,14 +0,0 @@
// 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.
fn main() {
let _: @'static whatever fn(); //~ ERROR expected `fn`, found `whatever`
let _: @'static fn();
}

View File

@ -14,7 +14,7 @@ fn foo(_x: @uint) {}
fn main() {
let x = @3u;
let _: ~fn() = || foo(x); //~ ERROR does not fulfill `Send`
let _: ~fn() = || foo(x); //~ ERROR does not fulfill `Send`
let _: ~fn() = || foo(x); //~ ERROR does not fulfill `Send`
let _: proc() = || foo(x); //~ ERROR does not fulfill `Send`
let _: proc() = || foo(x); //~ ERROR does not fulfill `Send`
let _: proc() = || foo(x); //~ ERROR does not fulfill `Send`
}

View File

@ -47,7 +47,7 @@ fn test<'a,T,U:Send>(_: &'a int) {
// but closure and object types can have lifetime bounds which make
// them not ok (FIXME #5121)
// assert_send::<~fn:'a()>(); // ERROR does not fulfill `Send`
// assert_send::<proc:'a()>(); // ERROR does not fulfill `Send`
// assert_send::<~Dummy:'a>(); // ERROR does not fulfill `Send`
// unsafe ptrs are ok unless they point at unsendable things

View File

@ -1,4 +1,4 @@
type Noncopyable = ~fn();
type Noncopyable = proc();
struct Foo {
copied: int,

View File

@ -16,7 +16,7 @@ extern mod extra;
use extra::arc;
use std::util;
fn foo(blk: ~once fn()) {
fn foo(blk: proc()) {
blk();
blk(); //~ ERROR use of moved value
}

View File

@ -1,29 +0,0 @@
// 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::new(true);
do foo {
assert!(*x.get());
util::ignore(x); //~ ERROR cannot move out of captured outer variable
}
}

View File

@ -11,7 +11,7 @@
// check that the &int here does not cause us to think that `foo`
// contains region pointers
struct foo(~fn(x: &int));
struct foo(proc(x: &int));
fn take_foo(x: foo<'static>) {} //~ ERROR wrong number of lifetime parameters

View File

@ -51,7 +51,7 @@ fn main() {
zzz();
sentinel();
let unique_closure: ~fn(int) = |x| {
let unique_closure: proc(int) = |x| {
zzz();
sentinel();

View File

@ -39,7 +39,7 @@ fn main() {
let owned = ~5;
let closure: ~fn() = || {
let closure: proc() = || {
zzz();
do_something(&constant, &a_struct.a, owned);
};

View File

@ -12,5 +12,5 @@
fn from_foreign_fn(_x: fn()) { }
fn from_stack_closure(_x: ||) { }
fn from_unique_closure(_x: ~fn()) { }
fn from_unique_closure(_x: proc()) { }
fn main() { }

View File

@ -18,7 +18,7 @@ fn failfn() {
fn main() {
let y = ~0;
let x: @~fn() = @(|| {
let x: @proc() = @(|| {
error!("{:?}", y.clone());
});
failfn();

View File

@ -10,7 +10,7 @@
extern mod extra;
fn asSendfn( f : ~fn()->uint ) -> uint {
fn asSendfn( f : proc()->uint ) -> uint {
return f();
}

View File

@ -1,5 +1,5 @@
pub fn main() {
let bar = ~3;
let h: ~fn() -> int = || *bar;
let h: proc() -> int = || *bar;
assert_eq!(h(), 3);
}

View File

@ -13,11 +13,11 @@ use std::ptr;
pub fn main() {
let x = ~3;
let y = ptr::to_unsafe_ptr(&(*x)) as uint;
let snd_move: ~fn() -> uint = || ptr::to_unsafe_ptr(&(*x)) as uint;
let snd_move: proc() -> uint = || ptr::to_unsafe_ptr(&(*x)) as uint;
assert_eq!(snd_move(), y);
let x = ~4;
let y = ptr::to_unsafe_ptr(&(*x)) as uint;
let lam_move: ~fn() -> uint = || ptr::to_unsafe_ptr(&(*x)) as uint;
let lam_move: proc() -> uint = || ptr::to_unsafe_ptr(&(*x)) as uint;
assert_eq!(lam_move(), y);
}

View File

@ -19,7 +19,7 @@ struct Pair {
pub fn main() {
let z = ~Pair { a : 10, b : 12};
let f: ~fn() = || {
let f: proc() = || {
assert_eq!(z.a, 10);
assert_eq!(z.b, 12);
};

View File

@ -10,7 +10,7 @@
use std::comm;
fn foo(blk: ~fn:Send()) {
fn foo(blk: proc()) {
blk();
}

View File

@ -15,8 +15,8 @@ extern mod extra;
*
* The hash should concentrate entropy in the lower bits.
*/
type HashFn<K> = ~fn(K) -> uint;
type EqFn<K> = ~fn(K, K) -> bool;
type HashFn<K> = proc(K) -> uint;
type EqFn<K> = proc(K, K) -> bool;
struct LM { resize_at: uint, size: uint }

View File

@ -11,7 +11,7 @@
// xfail-test
static generations: uint = 1024+256+128+49;
fn child_no(x: uint) -> ~fn() {
fn child_no(x: uint) -> proc() {
|| {
if x < generations {
task::spawn(child_no(x+1));

View File

@ -10,7 +10,7 @@
// xfail-test
type t = {
f: ~fn()
f: proc()
};
pub fn main() {

View File

@ -17,7 +17,7 @@ use std::path::{Path};
use std::path;
use std::result;
type rsrc_loader = ~fn(path: &Path) -> result::Result<~str, ~str>;
type rsrc_loader = proc(path: &Path) -> result::Result<~str, ~str>;
fn tester()
{

View File

@ -4,7 +4,7 @@ use std::comm::Chan;
use std::task;
type RingBuffer = ~[f64];
type SamplesFn = ~fn(samples: &RingBuffer);
type SamplesFn = proc(samples: &RingBuffer);
enum Msg
{

View File

@ -1,8 +0,0 @@
fn run(f: &fn()) {
f()
}
pub fn main() {
let f: ~fn() = || ();
run(f);
}

View File

@ -11,7 +11,7 @@
// Test that the lambda kind is inferred correctly as a return
// expression
fn unique() -> ~fn() { return || (); }
fn unique() -> proc() { return || (); }
pub fn main() {
}

View File

@ -11,7 +11,7 @@
// Test that the lambda kind is inferred correctly as a return
// expression
fn unique() -> ~fn() { || () }
fn unique() -> proc() { || () }
pub fn main() {
}

View File

@ -17,7 +17,7 @@ extern mod extra;
use extra::arc;
use std::util;
fn foo(blk: ~once fn()) {
fn foo(blk: proc()) {
blk();
}

View File

@ -69,6 +69,6 @@ pub fn main() {
assert_eq!(q.y, !(p.y));
// Issue #1733
let result: ~fn(int) = |_|();
let result: proc(int) = |_|();
result(p[true]);
}

View File

@ -1,46 +0,0 @@
// Copyright 2012 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.
// xfail-fast
use std::task;
pub fn main() { test05(); }
#[deriving(Clone)]
struct Pair<A,B> {
a: A,
b: B,
}
fn make_generic_record<A,B>(a: A, b: B) -> Pair<A,B> {
return Pair {a: a, b: b};
}
fn test05_start(f: &~fn(v: f64, v: ~str) -> Pair<f64, ~str>) {
let p = (*f)(22.22, ~"Hi");
info!("{:?}", p.clone());
assert!(p.a == 22.22);
assert!(p.b == ~"Hi");
let q = (*f)(44.44, ~"Ho");
info!("{:?}", q.clone());
assert!(q.a == 44.44);
assert!(q.b == ~"Ho");
}
fn spawn<A,B>(f: extern fn(&~fn(A,B)->Pair<A,B>)) {
let arg: ~fn(A, B) -> Pair<A,B> = |a, b| make_generic_record(a, b);
task::spawn(|| f(&arg));
}
fn test05() {
spawn::<f64,~str>(test05_start);
}

View File

@ -13,13 +13,13 @@ use std::task;
pub fn main() { test05(); }
fn test05_start(f: ~fn(int)) {
fn test05_start(f: proc(int)) {
f(22);
}
fn test05() {
let three = ~3;
let fn_to_send: ~fn(int) = |n| {
let fn_to_send: proc(int) = |n| {
error!("{}", *three + n); // will copy x into the closure
assert_eq!(*three, 3);
};

View File

@ -34,8 +34,8 @@ pub enum TestName {
}
pub enum TestFn {
DynTestFn(~fn()),
DynBenchFn(~fn(&mut int))
DynTestFn(proc()),
DynBenchFn(proc(&mut int))
}
pub struct TestDesc {

View File

@ -44,7 +44,7 @@ fn notify(ch: Chan<bool>, v: @mut bool) -> notify {
}
}
fn joinable(f: ~fn()) -> Port<bool> {
fn joinable(f: proc()) -> Port<bool> {
fn wrapper(c: Chan<bool>, f: &fn()) {
let b = @mut false;
error!("wrapper: task=%? allocated v=%x",

View File

@ -40,7 +40,7 @@ fn test_tempdir() {
fn test_rm_tempdir() {
let (rd, wr) = stream();
let f: ~fn() = || {
let f: proc() = || {
let tmp = TempDir::new("test_rm_tempdir").unwrap();
wr.send(tmp.path().clone());
fail!("fail to unwind past `tmp`");
@ -52,7 +52,7 @@ fn test_rm_tempdir() {
let tmp = TempDir::new("test_rm_tempdir").unwrap();
let path = tmp.path().clone();
let cell = Cell::new(tmp);
let f: ~fn() = || {
let f: proc() = || {
let _tmp = cell.take();
fail!("fail to unwind past `tmp`");
};
@ -61,7 +61,7 @@ fn test_rm_tempdir() {
let path;
{
let f: ~fn() -> TempDir = || {
let f: proc() -> TempDir = || {
TempDir::new("test_rm_tempdir").unwrap()
};
let tmp = task::try(f).expect("test_rm_tmdir");

View File

@ -19,11 +19,11 @@ enum maybe_pointy {
struct Pointy {
a : maybe_pointy,
d : ~fn() -> uint,
d : proc() -> uint,
}
fn make_uniq_closure<A:Send>(a: A) -> ~fn() -> uint {
let result: ~fn() -> uint = || ptr::to_unsafe_ptr(&a) as uint;
fn make_uniq_closure<A:Send>(a: A) -> proc() -> uint {
let result: proc() -> uint = || ptr::to_unsafe_ptr(&a) as uint;
result
}

View File

@ -18,7 +18,7 @@ enum maybe_pointy {
struct Pointy {
a : maybe_pointy,
c : ~int,
d : ~fn()->(),
d : proc()->(),
}
fn empty_pointy() -> @mut Pointy {