diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index 7fd09f9e1f5..f00ff9bcbe5 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -31,7 +31,6 @@ extern crate log; use std::env; use std::fs; use std::path::{Path, PathBuf}; -use std::thunk::Thunk; use getopts::{optopt, optflag, reqopt}; use common::Config; use common::{Pretty, DebugInfoGdb, DebugInfoLldb, Codegen}; @@ -351,7 +350,7 @@ pub fn make_test_name(config: &Config, testfile: &Path) -> test::TestName { pub fn make_test_closure(config: &Config, testfile: &Path) -> test::TestFn { let config = (*config).clone(); let testfile = testfile.to_path_buf(); - test::DynTestFn(Thunk::new(move || { + test::DynTestFn(Box::new(move || { runtest::run(config, &testfile) })) } diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 8d3a63ceb50..8e3be7dd05b 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -393,28 +393,25 @@ impl<'a, 'b> From<&'b str> for Box { /// } /// } /// ``` -#[cfg(not(stage0))] #[rustc_paren_sugar] #[unstable(feature = "core", reason = "Newly introduced")] pub trait FnBox { type Output; - extern "rust-call" fn call_box(self: Box, args: A) -> Self::Output; + fn call_box(self: Box, args: A) -> Self::Output; } -#[cfg(not(stage0))] impl FnBox for F where F: FnOnce { type Output = F::Output; - extern "rust-call" fn call_box(self: Box, args: A) -> F::Output { + fn call_box(self: Box, args: A) -> F::Output { self.call_once(args) } } -#[cfg(not(stage0))] -impl FnOnce for Box> { +impl<'a,A,R> FnOnce for Box+'a> { type Output = R; extern "rust-call" fn call_once(self, args: A) -> R { @@ -422,8 +419,7 @@ impl FnOnce for Box> { } } -#[cfg(not(stage0))] -impl FnOnce for Box+Send> { +impl<'a,A,R> FnOnce for Box+Send+'a> { type Output = R; extern "rust-call" fn call_once(self, args: A) -> R { diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index babbe15b17d..f5bee6240d4 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -19,7 +19,6 @@ use std::path::PathBuf; use std::process::Command; use std::str; use std::sync::{Arc, Mutex}; -use std::thunk::Thunk; use testing; use rustc_lint; @@ -366,7 +365,7 @@ impl Collector { ignore: should_ignore, should_panic: testing::ShouldPanic::No, // compiler failures are test failures }, - testfn: testing::DynTestFn(Thunk::new(move|| { + testfn: testing::DynTestFn(Box::new(move|| { runtest(&test, &cratename, libs, diff --git a/src/libstd/rt/at_exit_imp.rs b/src/libstd/rt/at_exit_imp.rs index 9079c0aaffb..beb2870807a 100644 --- a/src/libstd/rt/at_exit_imp.rs +++ b/src/libstd/rt/at_exit_imp.rs @@ -64,7 +64,7 @@ pub fn cleanup() { if queue as usize != 0 { let queue: Box = Box::from_raw(queue); for to_run in *queue { - to_run.invoke(()); + to_run(); } } } diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index 696c7960c3e..632d9647212 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -21,7 +21,6 @@ use prelude::v1::*; use sys; -use thunk::Thunk; use usize; // Reexport some of our utilities which are expected by other crates. @@ -153,7 +152,7 @@ fn lang_start(main: *const u8, argc: isize, argv: *const *const u8) -> isize { /// that the closure could not be registered, meaning that it is not scheduled /// to be rune. pub fn at_exit(f: F) -> Result<(), ()> { - if at_exit_imp::push(Thunk::new(f)) {Ok(())} else {Err(())} + if at_exit_imp::push(Box::new(f)) {Ok(())} else {Err(())} } /// One-time runtime cleanup. diff --git a/src/libstd/sync/future.rs b/src/libstd/sync/future.rs index b2afe28fed4..2cdde1aca9e 100644 --- a/src/libstd/sync/future.rs +++ b/src/libstd/sync/future.rs @@ -36,6 +36,7 @@ use core::prelude::*; use core::mem::replace; +use boxed::Box; use self::FutureState::*; use sync::mpsc::{Receiver, channel}; use thunk::Thunk; @@ -84,7 +85,7 @@ impl Future { match replace(&mut self.state, Evaluating) { Forced(_) | Evaluating => panic!("Logic error."), Pending(f) => { - self.state = Forced(f.invoke(())); + self.state = Forced(f()); self.get_ref() } } @@ -114,7 +115,7 @@ impl Future { * function. It is not spawned into another task. */ - Future {state: Pending(Thunk::new(f))} + Future {state: Pending(Box::new(f))} } } diff --git a/src/libstd/sys/common/thread.rs b/src/libstd/sys/common/thread.rs index f45daea18a2..1845b6266ed 100644 --- a/src/libstd/sys/common/thread.rs +++ b/src/libstd/sys/common/thread.rs @@ -25,6 +25,7 @@ pub fn start_thread(main: *mut libc::c_void) { unsafe { stack::record_os_managed_stack_bounds(0, usize::MAX); let _handler = stack_overflow::Handler::new(); - Box::from_raw(main as *mut Thunk).invoke(()); + let main: Box = Box::from_raw(main as *mut Thunk); + main(); } } diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 1202b353317..9ab35382845 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -257,7 +257,7 @@ impl Builder { pub fn spawn(self, f: F) -> io::Result where F: FnOnce(), F: Send + 'static { - self.spawn_inner(Thunk::new(f)).map(|i| JoinHandle(i)) + self.spawn_inner(Box::new(f)).map(|i| JoinHandle(i)) } /// Spawn a new child thread that must be joined within a given @@ -279,7 +279,7 @@ impl Builder { pub fn scoped<'a, T, F>(self, f: F) -> io::Result> where T: Send + 'a, F: FnOnce() -> T, F: Send + 'a { - self.spawn_inner(Thunk::new(f)).map(|inner| { + self.spawn_inner(Box::new(f)).map(|inner| { JoinGuard { inner: inner, _marker: PhantomData } }) } @@ -315,7 +315,7 @@ impl Builder { thread_info::set(imp::guard::current(), their_thread); } - let mut output = None; + let mut output: Option = None; let try_result = { let ptr = &mut output; @@ -327,7 +327,11 @@ impl Builder { // 'unwinding' flag in the thread itself. For these reasons, // this unsafety should be ok. unsafe { - unwind::try(move || *ptr = Some(f.invoke(()))) + unwind::try(move || { + let f: Thunk<(), T> = f; + let v: T = f(); + *ptr = Some(v) + }) } }; unsafe { @@ -340,7 +344,7 @@ impl Builder { }; Ok(JoinInner { - native: try!(unsafe { imp::create(stack_size, Thunk::new(main)) }), + native: try!(unsafe { imp::create(stack_size, Box::new(main)) }), thread: my_thread, packet: my_packet, joined: false, @@ -820,7 +824,7 @@ mod test { let x: Box<_> = box 1; let x_in_parent = (&*x) as *const i32 as usize; - spawnfn(Thunk::new(move|| { + spawnfn(Box::new(move|| { let x_in_child = (&*x) as *const i32 as usize; tx.send(x_in_child).unwrap(); })); @@ -832,7 +836,7 @@ mod test { #[test] fn test_avoid_copying_the_body_spawn() { avoid_copying_the_body(|v| { - thread::spawn(move || v.invoke(())); + thread::spawn(move || v()); }); } @@ -840,7 +844,7 @@ mod test { fn test_avoid_copying_the_body_thread_spawn() { avoid_copying_the_body(|f| { thread::spawn(move|| { - f.invoke(()); + f(); }); }) } @@ -849,7 +853,7 @@ mod test { fn test_avoid_copying_the_body_join() { avoid_copying_the_body(|f| { let _ = thread::spawn(move|| { - f.invoke(()) + f() }).join(); }) } @@ -862,13 +866,13 @@ mod test { // valgrind-friendly. try this at home, instead..!) const GENERATIONS: u32 = 16; fn child_no(x: u32) -> Thunk<'static> { - return Thunk::new(move|| { + return Box::new(move|| { if x < GENERATIONS { - thread::spawn(move|| child_no(x+1).invoke(())); + thread::spawn(move|| child_no(x+1)()); } }); } - thread::spawn(|| child_no(0).invoke(())); + thread::spawn(|| child_no(0)()); } #[test] diff --git a/src/libstd/thunk.rs b/src/libstd/thunk.rs index a9cb05b368f..6091794ed42 100644 --- a/src/libstd/thunk.rs +++ b/src/libstd/thunk.rs @@ -12,45 +12,9 @@ #![allow(missing_docs)] #![unstable(feature = "std_misc")] -use alloc::boxed::Box; +use alloc::boxed::{Box, FnBox}; use core::marker::Send; -use core::ops::FnOnce; -pub struct Thunk<'a, A=(),R=()> { - invoke: Box+Send + 'a>, -} +pub type Thunk<'a, A=(), R=()> = + Box + Send + 'a>; -impl<'a, R> Thunk<'a,(),R> { - pub fn new(func: F) -> Thunk<'a,(),R> - where F : FnOnce() -> R, F : Send + 'a - { - Thunk::with_arg(move|()| func()) - } -} - -impl<'a,A,R> Thunk<'a,A,R> { - pub fn with_arg(func: F) -> Thunk<'a,A,R> - where F : FnOnce(A) -> R, F : Send + 'a - { - Thunk { - invoke: Box::::new(func) - } - } - - pub fn invoke(self, arg: A) -> R { - self.invoke.invoke(arg) - } -} - -pub trait Invoke { - fn invoke(self: Box, arg: A) -> R; -} - -impl Invoke for F - where F : FnOnce(A) -> R -{ - fn invoke(self: Box, arg: A) -> R { - let f = *self; - f(arg) - } -} diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index f7e5c9f1dee..879ed03009f 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -62,6 +62,7 @@ use self::OutputLocation::*; use stats::Stats; use getopts::{OptGroup, optflag, optopt}; use serialize::Encodable; +use std::boxed::FnBox; use term::Terminal; use term::color::{Color, RED, YELLOW, GREEN, CYAN}; @@ -79,7 +80,7 @@ use std::path::PathBuf; use std::sync::mpsc::{channel, Sender}; use std::sync::{Arc, Mutex}; use std::thread; -use std::thunk::{Thunk, Invoke}; +use std::thunk::Thunk; use std::time::Duration; // to be used by rustc to compile tests in libtest @@ -158,7 +159,7 @@ pub enum TestFn { StaticBenchFn(fn(&mut Bencher)), StaticMetricFn(fn(&mut MetricMap)), DynTestFn(Thunk<'static>), - DynMetricFn(Box Invoke<&'a mut MetricMap>+'static>), + DynMetricFn(Box), DynBenchFn(Box) } @@ -936,7 +937,7 @@ pub fn run_test(opts: &TestOpts, io::set_print(box Sink(data2.clone())); io::set_panic(box Sink(data2)); } - testfn.invoke(()) + testfn() }).unwrap(); let test_result = calc_result(&desc, result_guard.join()); let stdout = data.lock().unwrap().to_vec(); @@ -957,7 +958,7 @@ pub fn run_test(opts: &TestOpts, } DynMetricFn(f) => { let mut mm = MetricMap::new(); - f.invoke(&mut mm); + f.call_box((&mut mm,)); // TODO unfortunate monitor_ch.send((desc, TrMetrics(mm), Vec::new())).unwrap(); return; } @@ -969,7 +970,7 @@ pub fn run_test(opts: &TestOpts, } DynTestFn(f) => run_test_inner(desc, monitor_ch, opts.nocapture, f), StaticTestFn(f) => run_test_inner(desc, monitor_ch, opts.nocapture, - Thunk::new(move|| f())) + Box::new(move|| f())) } } @@ -1185,7 +1186,7 @@ mod tests { ignore: true, should_panic: ShouldPanic::No, }, - testfn: DynTestFn(Thunk::new(move|| f())), + testfn: DynTestFn(Box::new(move|| f())), }; let (tx, rx) = channel(); run_test(&TestOpts::new(), false, desc, tx); @@ -1202,7 +1203,7 @@ mod tests { ignore: true, should_panic: ShouldPanic::No, }, - testfn: DynTestFn(Thunk::new(move|| f())), + testfn: DynTestFn(Box::new(move|| f())), }; let (tx, rx) = channel(); run_test(&TestOpts::new(), false, desc, tx); @@ -1219,7 +1220,7 @@ mod tests { ignore: false, should_panic: ShouldPanic::Yes(None) }, - testfn: DynTestFn(Thunk::new(move|| f())), + testfn: DynTestFn(Box::new(move|| f())), }; let (tx, rx) = channel(); run_test(&TestOpts::new(), false, desc, tx); @@ -1236,7 +1237,7 @@ mod tests { ignore: false, should_panic: ShouldPanic::Yes(Some("error message")) }, - testfn: DynTestFn(Thunk::new(move|| f())), + testfn: DynTestFn(Box::new(move|| f())), }; let (tx, rx) = channel(); run_test(&TestOpts::new(), false, desc, tx); @@ -1253,7 +1254,7 @@ mod tests { ignore: false, should_panic: ShouldPanic::Yes(Some("foobar")) }, - testfn: DynTestFn(Thunk::new(move|| f())), + testfn: DynTestFn(Box::new(move|| f())), }; let (tx, rx) = channel(); run_test(&TestOpts::new(), false, desc, tx); @@ -1270,7 +1271,7 @@ mod tests { ignore: false, should_panic: ShouldPanic::Yes(None) }, - testfn: DynTestFn(Thunk::new(move|| f())), + testfn: DynTestFn(Box::new(move|| f())), }; let (tx, rx) = channel(); run_test(&TestOpts::new(), false, desc, tx); @@ -1306,7 +1307,7 @@ mod tests { ignore: true, should_panic: ShouldPanic::No, }, - testfn: DynTestFn(Thunk::new(move|| {})), + testfn: DynTestFn(Box::new(move|| {})), }, TestDescAndFn { desc: TestDesc { @@ -1314,7 +1315,7 @@ mod tests { ignore: false, should_panic: ShouldPanic::No, }, - testfn: DynTestFn(Thunk::new(move|| {})), + testfn: DynTestFn(Box::new(move|| {})), }); let filtered = filter_tests(&opts, tests); @@ -1350,7 +1351,7 @@ mod tests { ignore: false, should_panic: ShouldPanic::No, }, - testfn: DynTestFn(Thunk::new(testfn)), + testfn: DynTestFn(Box::new(testfn)), }; tests.push(test); } diff --git a/src/test/run-pass/issue-11709.rs b/src/test/run-pass/issue-11709.rs index da3efb4fea8..3ad78f088f9 100644 --- a/src/test/run-pass/issue-11709.rs +++ b/src/test/run-pass/issue-11709.rs @@ -25,7 +25,7 @@ fn test(slot: &mut Option>) -> () { let a = slot.take(); let _a = match a { // `{let .. a(); }` would break - Some(a) => { let _a = a.invoke(()); }, + Some(a) => { let _a = a(); }, None => (), }; } diff --git a/src/test/run-pass/issue-11958.rs b/src/test/run-pass/issue-11958.rs index ed2009dab1b..def85b47667 100644 --- a/src/test/run-pass/issue-11958.rs +++ b/src/test/run-pass/issue-11958.rs @@ -23,5 +23,5 @@ use std::thunk::Thunk; pub fn main() { let mut x = 1; - let _thunk = Thunk::new(move|| { x = 2; }); + let _thunk = Box::new(move|| { x = 2; }); } diff --git a/src/test/run-pass/issue-17897.rs b/src/test/run-pass/issue-17897.rs index 3fbdb92e906..cf8c54fdd80 100644 --- a/src/test/run-pass/issue-17897.rs +++ b/src/test/run-pass/issue-17897.rs @@ -12,10 +12,10 @@ use std::thunk::Thunk; -fn action(cb: Thunk) -> usize { - cb.invoke(1) +fn action(cb: Thunk<(usize,), usize>) -> usize { + cb(1) } pub fn main() { - println!("num: {}", action(Thunk::with_arg(move |u| u))); + println!("num: {}", action(Box::new(move |u| u))); } diff --git a/src/test/run-pass/issue-18188.rs b/src/test/run-pass/issue-18188.rs index cd28d642551..059d25173c2 100644 --- a/src/test/run-pass/issue-18188.rs +++ b/src/test/run-pass/issue-18188.rs @@ -16,13 +16,13 @@ use std::thunk::Thunk; pub trait Promisable: Send + Sync {} impl Promisable for T {} -pub fn propagate<'a, T, E, F, G>(action: F) -> Thunk<'a,Result, Result> +pub fn propagate<'a, T, E, F, G>(action: F) -> Thunk<'a, (Result,), Result> where T: Promisable + Clone + 'a, E: Promisable + Clone + 'a, F: FnOnce(&T) -> Result + Send + 'a, G: FnOnce(Result) -> Result + 'a { - Thunk::with_arg(move |result: Result| { + Box::new(move |result: Result| { match result { Ok(ref t) => action(t), Err(ref e) => Err(e.clone()), diff --git a/src/test/run-pass/issue-2190-1.rs b/src/test/run-pass/issue-2190-1.rs index b2c21a274cb..5c84c30aa7f 100644 --- a/src/test/run-pass/issue-2190-1.rs +++ b/src/test/run-pass/issue-2190-1.rs @@ -18,11 +18,11 @@ use std::thunk::Thunk; static generations: usize = 1024+256+128+49; fn spawn(f: Thunk<'static>) { - Builder::new().stack_size(32 * 1024).spawn(move|| f.invoke(())); + Builder::new().stack_size(32 * 1024).spawn(move|| f()); } fn child_no(x: usize) -> Thunk<'static> { - Thunk::new(move|| { + Box::new(move|| { if x < generations { spawn(child_no(x+1)); } diff --git a/src/test/run-pass/issue-3609.rs b/src/test/run-pass/issue-3609.rs index 45eb21374e2..2167a3df976 100644 --- a/src/test/run-pass/issue-3609.rs +++ b/src/test/run-pass/issue-3609.rs @@ -13,7 +13,6 @@ use std::thread; use std::sync::mpsc::Sender; -use std::thunk::Invoke; type RingBuffer = Vec ; type SamplesFn = Box;