diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index 47ab675aff934..196c38215f463 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -9,7 +9,7 @@ // except according to those terms. #![crate_type = "bin"] -#![feature(phase, slicing_syntax, globs)] +#![feature(phase, slicing_syntax, globs, unboxed_closures)] #![deny(warnings)] @@ -23,6 +23,7 @@ use std::os; use std::io; use std::io::fs; use std::str::FromStr; +use std::thunk::{Thunk}; use getopts::{optopt, optflag, reqopt}; use common::Config; use common::{Pretty, DebugInfoGdb, DebugInfoLldb, Codegen}; @@ -369,16 +370,16 @@ pub fn make_test_closure(config: &Config, testfile: &Path) -> test::TestFn { let config = (*config).clone(); // FIXME (#9639): This needs to handle non-utf8 paths let testfile = testfile.as_str().unwrap().to_string(); - test::DynTestFn(proc() { + test::DynTestFn(Thunk::new(move || { runtest::run(config, testfile) - }) + })) } pub fn make_metrics_test_closure(config: &Config, testfile: &Path) -> test::TestFn { let config = (*config).clone(); // FIXME (#9639): This needs to handle non-utf8 paths let testfile = testfile.as_str().unwrap().to_string(); - test::DynMetricFn(proc(mm) { + test::DynMetricFn(box move |: mm: &mut test::MetricMap| { runtest::run_metrics(config, testfile, mm) }) } diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 5c3e5e12adbcb..ea6f180ec39ac 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -445,7 +445,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { loop { //waiting 1 second for gdbserver start timer::sleep(Duration::milliseconds(1000)); - let result = task::try(proc() { + let result = task::try(move || { tcp::TcpStream::connect("127.0.0.1:5039").unwrap(); }); if result.is_err() { diff --git a/src/doc/guide-tasks.md b/src/doc/guide-tasks.md index c2309ba479ea6..4adca43be18e9 100644 --- a/src/doc/guide-tasks.md +++ b/src/doc/guide-tasks.md @@ -29,10 +29,11 @@ with a closure argument. `spawn` executes the closure in the new task. fn print_message() { println!("I am running in a different task!"); } spawn(print_message); -// Alternatively, use a `proc` expression instead of a named function. -// The `proc` expression evaluates to an (unnamed) proc. -// That proc will call `println!(...)` when the spawned task runs. -spawn(proc() println!("I am also running in a different task!") ); +// Alternatively, use a `move ||` expression instead of a named function. +// `||` expressions evaluate to an unnamed closure. The `move` keyword +// indicates that the closure should take ownership of any variables it +// touches. +spawn(move || println!("I am also running in a different task!")); ``` In Rust, a task is not a concept that appears in the language semantics. @@ -40,11 +41,13 @@ Instead, Rust's type system provides all the tools necessary to implement safe concurrency: particularly, ownership. The language leaves the implementation details to the standard library. -The `spawn` function has a very simple type signature: `fn spawn(f: proc(): -Send)`. Because it accepts only procs, and procs contain only owned data, -`spawn` can safely move the entire proc and all its associated state into an -entirely different task for execution. Like any closure, the function passed to -`spawn` may capture an environment that it carries across tasks. +The `spawn` function has the type signature: `fn +spawn(f: F)`. This indicates that it takes as +argument a closure (of type `F`) that it will run exactly once. This +closure is limited to capturing `Send`-able data from its environment +(that is, data which is deeply owned). Limiting the closure to `Send` +ensures that `spawn` can safely move the entire closure and all its +associated state into an entirely different task for execution. ```{rust} # use std::task::spawn; @@ -52,8 +55,11 @@ entirely different task for execution. Like any closure, the function passed to // Generate some state locally let child_task_number = generate_task_number(); -spawn(proc() { - // Capture it in the remote task +spawn(move || { + // Capture it in the remote task. The `move` keyword indicates + // that this closure should move `child_task_number` into its + // environment, rather than capturing a reference into the + // enclosing stack frame. println!("I am child number {}", child_task_number); }); ``` @@ -74,7 +80,7 @@ example of calculating two results concurrently: let (tx, rx): (Sender, Receiver) = channel(); -spawn(proc() { +spawn(move || { let result = some_expensive_computation(); tx.send(result); }); @@ -102,7 +108,7 @@ task. # use std::task::spawn; # fn some_expensive_computation() -> int { 42 } # let (tx, rx) = channel(); -spawn(proc() { +spawn(move || { let result = some_expensive_computation(); tx.send(result); }); @@ -135,13 +141,13 @@ results across a number of tasks? The following program is ill-typed: # fn some_expensive_computation() -> int { 42 } let (tx, rx) = channel(); -spawn(proc() { +spawn(move || { tx.send(some_expensive_computation()); }); // ERROR! The previous spawn statement already owns the sender, // so the compiler will not allow it to be captured again -spawn(proc() { +spawn(move || { tx.send(some_expensive_computation()); }); ``` @@ -154,7 +160,7 @@ let (tx, rx) = channel(); for init_val in range(0u, 3) { // Create a new channel handle to distribute to the child task let child_tx = tx.clone(); - spawn(proc() { + spawn(move || { child_tx.send(some_expensive_computation(init_val)); }); } @@ -179,7 +185,7 @@ reference, written with multiple streams, it might look like the example below. // Create a vector of ports, one for each child task let rxs = Vec::from_fn(3, |init_val| { let (tx, rx) = channel(); - spawn(proc() { + spawn(move || { tx.send(some_expensive_computation(init_val)); }); rx @@ -207,7 +213,7 @@ fn fib(n: u64) -> u64 { 12586269025 } -let mut delayed_fib = Future::spawn(proc() fib(50)); +let mut delayed_fib = Future::spawn(move || fib(50)); make_a_sandwich(); println!("fib(50) = {}", delayed_fib.get()) # } @@ -236,7 +242,7 @@ fn partial_sum(start: uint) -> f64 { } fn main() { - let mut futures = Vec::from_fn(200, |ind| Future::spawn( proc() { partial_sum(ind) })); + let mut futures = Vec::from_fn(200, |ind| Future::spawn(move || partial_sum(ind))); let mut final_res = 0f64; for ft in futures.iter_mut() { @@ -278,7 +284,7 @@ fn main() { for num in range(1u, 10) { let task_numbers = numbers_arc.clone(); - spawn(proc() { + spawn(move || { println!("{}-norm = {}", num, pnorm(task_numbers.as_slice(), num)); }); } @@ -312,7 +318,7 @@ if it were local. # let numbers_arc = Arc::new(numbers); # let num = 4; let task_numbers = numbers_arc.clone(); -spawn(proc() { +spawn(move || { // Capture task_numbers and use it as if it was the underlying vector println!("{}-norm = {}", num, pnorm(task_numbers.as_slice(), num)); }); @@ -344,7 +350,7 @@ result with an `int` field (representing a successful result) or an `Err` result # use std::task; # fn some_condition() -> bool { false } # fn calculate_result() -> int { 0 } -let result: Result> = task::try(proc() { +let result: Result> = task::try(move || { if some_condition() { calculate_result() } else { diff --git a/src/doc/guide.md b/src/doc/guide.md index 21043cfef1480..6e178a2648dbf 100644 --- a/src/doc/guide.md +++ b/src/doc/guide.md @@ -4235,36 +4235,16 @@ fn main() { } ``` -## Procs +## Moving closures -Rust has a second type of closure, called a **proc**. Procs are created -with the `proc` keyword: - -```{rust} -let x = 5i; - -let p = proc() { x * x }; -println!("{}", p()); // prints 25 -``` - -There is a big difference between procs and closures: procs may only be called once. This -will error when we try to compile: - -```{rust,ignore} -let x = 5i; - -let p = proc() { x * x }; -println!("{}", p()); -println!("{}", p()); // error: use of moved value `p` -``` - -This restriction is important. Procs are allowed to consume values that they -capture, and thus have to be restricted to being called once for soundness -reasons: any value consumed would be invalid on a second call. - -Procs are most useful with Rust's concurrency features, and so we'll just leave -it at this for now. We'll talk about them more in the "Tasks" section of the -guide. +Rust has a second type of closure, called a **moving closure**. Moving +closures are indicated using the `move` keyword (e.g., `move || x * +x`). The difference between a moving closure and an ordinary closure +is that a moving closure always takes ownership of all variables that +it uses. Ordinary closures, in contrast, just create a reference into +the enclosing stack frame. Moving closures are most useful with Rust's +concurrency features, and so we'll just leave it at this for +now. We'll talk about them more in the "Tasks" section of the guide. ## Accepting closures as arguments @@ -5231,28 +5211,30 @@ concurrency libraries can be written for Rust to help in specific scenarios. Here's an example of creating a task: ```{rust} -spawn(proc() { +spawn(move || { println!("Hello from a task!"); }); ``` -The `spawn` function takes a proc as an argument, and runs that proc in a new -task. A proc takes ownership of its entire environment, and so any variables -that you use inside the proc will not be usable afterward: +The `spawn` function takes a closure as an argument, and runs that +closure in a new task. Typically, you will want to use a moving +closure, so that the closure takes ownership of any variables that it +touches. This implies that those variables are not usable from the +parent task after the child task is spawned: ```{rust,ignore} let mut x = vec![1i, 2i, 3i]; -spawn(proc() { +spawn(move || { println!("The value of x[0] is: {}", x[0]); }); println!("The value of x[0] is: {}", x[0]); // error: use of moved value: `x` ``` -`x` is now owned by the proc, and so we can't use it anymore. Many other -languages would let us do this, but it's not safe to do so. Rust's borrow -checker catches the error. +`x` is now owned by the closure, and so we can't use it anymore. Many +other languages would let us do this, but it's not safe to do +so. Rust's borrow checker catches the error. If tasks were only able to capture these values, they wouldn't be very useful. Luckily, tasks can communicate with each other through **channel**s. Channels @@ -5261,7 +5243,7 @@ work like this: ```{rust} let (tx, rx) = channel(); -spawn(proc() { +spawn(move || { tx.send("Hello from a task!".to_string()); }); @@ -5281,7 +5263,7 @@ If you want to send messages to the task as well, create two channels! let (tx1, rx1) = channel(); let (tx2, rx2) = channel(); -spawn(proc() { +spawn(move || { tx1.send("Hello from a task!".to_string()); let message = rx2.recv(); println!("{}", message); @@ -5293,8 +5275,9 @@ println!("{}", message); tx2.send("Goodbye from main!".to_string()); ``` -The proc has one sending end and one receiving end, and the main task has one -of each as well. Now they can talk back and forth in whatever way they wish. +The closure has one sending end and one receiving end, and the main +task has one of each as well. Now they can talk back and forth in +whatever way they wish. Notice as well that because `Sender` and `Receiver` are generic, while you can pass any kind of information through the channel, the ends are strongly typed. @@ -5310,7 +5293,7 @@ a useful thing to use: ```{rust} use std::sync::Future; -let mut delayed_value = Future::spawn(proc() { +let mut delayed_value = Future::spawn(move || { // just return anything for examples' sake 12345i @@ -5318,18 +5301,18 @@ let mut delayed_value = Future::spawn(proc() { println!("value = {}", delayed_value.get()); ``` -Calling `Future::spawn` works just like `spawn()`: it takes a proc. In this -case, though, you don't need to mess with the channel: just have the proc -return the value. +Calling `Future::spawn` works just like `spawn()`: it takes a +closure. In this case, though, you don't need to mess with the +channel: just have the closure return the value. `Future::spawn` will return a value which we can bind with `let`. It needs to be mutable, because once the value is computed, it saves a copy of the value, and if it were immutable, it couldn't update itself. -The proc will go on processing in the background, and when we need the final -value, we can call `get()` on it. This will block until the result is done, -but if it's finished computing in the background, we'll just get the value -immediately. +The future will go on processing in the background, and when we need +the final value, we can call `get()` on it. This will block until the +result is done, but if it's finished computing in the background, +we'll just get the value immediately. ## Success and failure @@ -5337,7 +5320,7 @@ Tasks don't always succeed, they can also panic. A task that wishes to panic can call the `panic!` macro, passing a message: ```{rust} -spawn(proc() { +spawn(move || { panic!("Nope."); }); ``` @@ -5349,7 +5332,7 @@ notify other tasks that it has panicked. We can do this with `task::try`: use std::task; use std::rand; -let result = task::try(proc() { +let result = task::try(move || { if rand::random() { println!("OK"); } else { diff --git a/src/doc/intro.md b/src/doc/intro.md index e2cccef5b4a1d..c0a1d5fa8816f 100644 --- a/src/doc/intro.md +++ b/src/doc/intro.md @@ -391,26 +391,29 @@ Here's an example of a concurrent Rust program: ```{rust} fn main() { for _ in range(0u, 10u) { - spawn(proc() { + spawn(move || { println!("Hello, world!"); }); } } ``` -This program creates ten threads, who all print `Hello, world!`. The `spawn` -function takes one argument, a `proc`. 'proc' is short for 'procedure,' and is -a form of closure. This closure is executed in a new thread, created by `spawn` -itself. - -One common form of problem in concurrent programs is a 'data race.' This occurs -when two different threads attempt to access the same location in memory in a -non-synchronized way, where at least one of them is a write. If one thread is -attempting to read, and one thread is attempting to write, you cannot be sure -that your data will not be corrupted. Note the first half of that requirement: -two threads that attempt to access the same location in memory. Rust's -ownership model can track which pointers own which memory locations, which -solves this problem. +This program creates ten threads, who all print `Hello, world!`. The +`spawn` function takes one argument, a closure, indicated by the +double bars `||`. (The `move` keyword indicates that the closure takes +ownership of any data it uses; we'll have more on the significance of +this shortly.) This closure is executed in a new thread created by +`spawn`. + +One common form of problem in concurrent programs is a 'data race.' +This occurs when two different threads attempt to access the same +location in memory in a non-synchronized way, where at least one of +them is a write. If one thread is attempting to read, and one thread +is attempting to write, you cannot be sure that your data will not be +corrupted. Note the first half of that requirement: two threads that +attempt to access the same location in memory. Rust's ownership model +can track which pointers own which memory locations, which solves this +problem. Let's see an example. This Rust code will not compile: @@ -419,7 +422,7 @@ fn main() { let mut numbers = vec![1i, 2i, 3i]; for i in range(0u, 3u) { - spawn(proc() { + spawn(move || { for j in range(0, 3) { numbers[j] += 1 } }); } @@ -432,8 +435,8 @@ It gives us this error: 6:71 error: capture of moved value: `numbers` for j in range(0, 3) { numbers[j] += 1 } ^~~~~~~ -7:50 note: `numbers` moved into closure environment here because it has type `proc():Send`, which is non-copyable (perhaps you meant to use clone()?) - spawn(proc() { +7:50 note: `numbers` moved into closure environment here + spawn(move || { for j in range(0, 3) { numbers[j] += 1 } }); 6:79 error: cannot assign to immutable dereference (dereference is implicit, due to indexing) @@ -441,11 +444,16 @@ It gives us this error: ^~~~~~~~~~~~~~~ ``` -It mentions that "numbers moved into closure environment". Because we referred -to `numbers` inside of our `proc`, and we create three `proc`s, we would have -three references. Rust detects this and gives us the error: we claim that -`numbers` has ownership, but our code tries to make three owners. This may -cause a safety problem, so Rust disallows it. +It mentions that "numbers moved into closure environment". Because we +declared the closure as a moving closure, and it referred to +`numbers`, the closure will try to take ownership of the vector. But +the closure itself is created in a loop, and hence we will actually +create three closures, one for every iteration of the loop. This means +that all three of those closures would try to own `numbers`, which is +impossible -- `numbers` must have just one owner. Rust detects this +and gives us the error: we claim that `numbers` has ownership, but our +code tries to make three owners. This may cause a safety problem, so +Rust disallows it. What to do here? Rust has two types that helps us: `Arc` and `Mutex`. "Arc" stands for "atomically reference counted." In other words, an Arc will @@ -468,7 +476,7 @@ fn main() { for i in range(0u, 3u) { let number = numbers.clone(); - spawn(proc() { + spawn(move || { let mut array = number.lock(); (*array)[i] += 1; @@ -528,7 +536,7 @@ fn main() { let vec = vec![1i, 2, 3]; for i in range(1u, 3) { - spawn(proc() { + spawn(move || { println!("{}", vec[i]); }); } diff --git a/src/doc/reference.md b/src/doc/reference.md index ee70981d9b254..c24cd6d8bf391 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -187,19 +187,18 @@ grammar as double-quoted strings. Other tokens have exact rules given.

-| | | | | | -|----------|----------|----------|----------|--------| -| abstract | alignof | as | be | box | -| break | const | continue | crate | do | -| else | enum | extern | false | final | -| fn | for | if | impl | in | -| let | loop | match | mod | move | -| mut | offsetof | once | override | priv | -| proc | pub | pure | ref | return | -| sizeof | static | self | struct | super | -| true | trait | type | typeof | unsafe | -| unsized | use | virtual | where | while | -| yield | | | | | +| | | | | | +|----------|----------|----------|----------|---------| +| abstract | alignof | as | be | box | +| break | const | continue | crate | do | +| else | enum | extern | false | final | +| fn | for | if | impl | in | +| let | loop | match | mod | move | +| mut | offsetof | once | override | priv | +| pub | pure | ref | return | sizeof | +| static | self | struct | super | true | +| trait | type | typeof | unsafe | unsized | +| use | virtual | where | while | yield | Each of these keywords has special meaning in its grammar, and all of them are @@ -3842,8 +3841,6 @@ x = bo(5,7); ```{.ebnf .notation} closure_type := [ 'unsafe' ] [ '<' lifetime-list '>' ] '|' arg-list '|' [ ':' bound-list ] [ '->' type ] -procedure_type := 'proc' [ '<' lifetime-list '>' ] '(' arg-list ')' - [ ':' bound-list ] [ '->' type ] lifetime-list := lifetime | lifetime ',' lifetime-list arg-list := ident ':' type | ident ':' type ',' arg-list bound-list := bound | bound '+' bound-list @@ -3852,8 +3849,6 @@ bound := path | lifetime The type of a closure mapping an input of type `A` to an output of type `B` is `|A| -> B`. A closure with no arguments or return values has type `||`. -Similarly, a procedure mapping `A` to `B` is `proc(A) -> B` and a no-argument -and no-return value closure has type `proc()`. An example of creating and calling a closure: @@ -3876,30 +3871,6 @@ call_closure(closure_no_args, closure_args); ``` -Unlike closures, procedures may only be invoked once, but own their -environment, and are allowed to move out of their environment. Procedures are -allocated on the heap (unlike closures). An example of creating and calling a -procedure: - -```rust -let string = "Hello".to_string(); - -// Creates a new procedure, passing it to the `spawn` function. -spawn(proc() { - println!("{} world!", string); -}); - -// the variable `string` has been moved into the previous procedure, so it is -// no longer usable. - - -// Create an invoke a procedure. Note that the procedure is *moved* when -// invoked, so it cannot be invoked again. -let f = proc(n: int) { n + 22 }; -println!("answer: {}", f(20)); - -``` - ### Object types Every trait item (see [traits](#traits)) defines a type with the same name as diff --git a/src/doc/rustdoc.md b/src/doc/rustdoc.md index 05475c605ea72..054552559dbec 100644 --- a/src/doc/rustdoc.md +++ b/src/doc/rustdoc.md @@ -210,11 +210,11 @@ that one can still write things like `#[deriving(Eq)]`). # // what's actually being documented. # fn fib(n: int) { n + 2 } -spawn(proc() { fib(200); }) +spawn(move || { fib(200); }) ``` ~~~ -The documentation online would look like `spawn(proc() { fib(200); })`, but when +The documentation online would look like `spawn(move || { fib(200); })`, but when testing this code, the `fib` function will be included (so it can compile). ## Running tests (advanced) diff --git a/src/etc/emacs/rust-mode.el b/src/etc/emacs/rust-mode.el index 0d0e4b35a0b36..6917e9ee354ee 100644 --- a/src/etc/emacs/rust-mode.el +++ b/src/etc/emacs/rust-mode.el @@ -174,7 +174,7 @@ "if" "impl" "in" "let" "loop" "match" "mod" "move" "mut" - "priv" "proc" "pub" + "priv" "pub" "ref" "return" "self" "static" "struct" "super" "true" "trait" "type" diff --git a/src/etc/vim/syntax/rust.vim b/src/etc/vim/syntax/rust.vim index 0c7dcb8be7b02..3bd2051c617eb 100644 --- a/src/etc/vim/syntax/rust.vim +++ b/src/etc/vim/syntax/rust.vim @@ -24,7 +24,7 @@ syn keyword rustKeyword continue syn keyword rustKeyword extern nextgroup=rustExternCrate,rustObsoleteExternMod skipwhite skipempty syn keyword rustKeyword fn nextgroup=rustFuncName skipwhite skipempty syn keyword rustKeyword for in if impl let -syn keyword rustKeyword loop once proc pub +syn keyword rustKeyword loop once pub syn keyword rustKeyword return super syn keyword rustKeyword unsafe virtual where while syn keyword rustKeyword use nextgroup=rustModPath skipwhite skipempty diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 1d2157b7e2fa3..1f1909fd33cc1 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -46,7 +46,7 @@ use heap::deallocate; /// for _ in range(0u, 10) { /// let child_numbers = shared_numbers.clone(); /// -/// spawn(proc() { +/// spawn(move || { /// let local_numbers = child_numbers.as_slice(); /// /// // Work with the local numbers @@ -358,7 +358,7 @@ mod tests { let (tx, rx) = channel(); - task::spawn(proc() { + task::spawn(move || { let arc_v: Arc> = rx.recv(); assert_eq!((*arc_v)[3], 4); }); diff --git a/src/libcollections/dlist.rs b/src/libcollections/dlist.rs index f49a0c037de84..df86ac96424b5 100644 --- a/src/libcollections/dlist.rs +++ b/src/libcollections/dlist.rs @@ -1133,7 +1133,7 @@ mod tests { #[test] fn test_send() { let n = list_from(&[1i,2,3]); - spawn(proc() { + spawn(move || { check_links(&n); let a: &[_] = &[&1,&2,&3]; assert_eq!(a, n.iter().collect::>()); diff --git a/src/libcore/raw.rs b/src/libcore/raw.rs index db1be94b2b83f..be2f4e590a359 100644 --- a/src/libcore/raw.rs +++ b/src/libcore/raw.rs @@ -40,15 +40,6 @@ pub struct Closure { impl Copy for Closure {} -/// The representation of a Rust procedure (`proc()`) -#[repr(C)] -pub struct Procedure { - pub code: *mut (), - pub env: *mut (), -} - -impl Copy for Procedure {} - /// The representation of a Rust trait object. /// /// This struct does not have a `Repr` implementation diff --git a/src/libflate/lib.rs b/src/libflate/lib.rs index cc36c2eef4552..2c8e5638e4949 100644 --- a/src/libflate/lib.rs +++ b/src/libflate/lib.rs @@ -21,7 +21,7 @@ #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "http://www.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/")] -#![feature(phase)] +#![feature(phase, unboxed_closures)] #[cfg(test)] #[phase(plugin, link)] extern crate log; @@ -59,7 +59,7 @@ fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option> { &mut outsz, flags); if !res.is_null() { - Some(CVec::new_with_dtor(res as *mut u8, outsz as uint, proc() libc::free(res))) + Some(CVec::new_with_dtor(res as *mut u8, outsz as uint, move|:| libc::free(res))) } else { None } @@ -84,7 +84,7 @@ fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option> { &mut outsz, flags); if !res.is_null() { - Some(CVec::new_with_dtor(res as *mut u8, outsz as uint, proc() libc::free(res))) + Some(CVec::new_with_dtor(res as *mut u8, outsz as uint, move|:| libc::free(res))) } else { None } diff --git a/src/liblog/lib.rs b/src/liblog/lib.rs index 8b79078eac6ad..8731f7084ed7d 100644 --- a/src/liblog/lib.rs +++ b/src/liblog/lib.rs @@ -165,7 +165,7 @@ html_favicon_url = "http://www.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/", html_playground_url = "http://play.rust-lang.org/")] -#![feature(macro_rules)] +#![feature(macro_rules, unboxed_closures)] #![deny(missing_docs)] extern crate regex; @@ -422,7 +422,7 @@ fn init() { DIRECTIVES = mem::transmute(box directives); // Schedule the cleanup for the globals for when the runtime exits. - rt::at_exit(proc() { + rt::at_exit(move |:| { assert!(!DIRECTIVES.is_null()); let _directives: Box> = mem::transmute(DIRECTIVES); diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs index 0dcb78f6bb04c..b6347278bffda 100644 --- a/src/librustc/middle/cfg/construct.rs +++ b/src/librustc/middle/cfg/construct.rs @@ -498,7 +498,6 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { ast::ExprMac(..) | ast::ExprClosure(..) | - ast::ExprProc(..) | ast::ExprLit(..) | ast::ExprPath(..) => { self.straightline(expr, pred, None::.iter()) diff --git a/src/librustc/middle/check_loop.rs b/src/librustc/middle/check_loop.rs index fee2d810fcb3d..c4ad089d76e6e 100644 --- a/src/librustc/middle/check_loop.rs +++ b/src/librustc/middle/check_loop.rs @@ -52,8 +52,7 @@ impl<'a, 'v> Visitor<'v> for CheckLoopVisitor<'a> { self.visit_expr(&**e); self.with_context(Loop, |v| v.visit_block(&**b)); } - ast::ExprClosure(_, _, _, ref b) | - ast::ExprProc(_, ref b) => { + ast::ExprClosure(_, _, _, ref b) => { self.with_context(Closure, |v| v.visit_block(&**b)); } ast::ExprBreak(_) => self.require_loop("break", e.span), diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 8e00c96535b1e..6501d8d6eb430 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -613,8 +613,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { self.consume_expr(&**count); } - ast::ExprClosure(..) | - ast::ExprProc(..) => { + ast::ExprClosure(..) => { self.walk_captures(expr) } diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs index e2a57629d7eb9..0c346519672d8 100644 --- a/src/librustc/middle/infer/error_reporting.rs +++ b/src/librustc/middle/infer/error_reporting.rs @@ -587,19 +587,6 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { sub, ""); } - infer::ProcCapture(span, id) => { - self.tcx.sess.span_err( - span, - format!("captured variable `{}` must be 'static \ - to be captured in a proc", - ty::local_var_name_str(self.tcx, id).get()) - .as_slice()); - note_and_explain_region( - self.tcx, - "captured variable is only valid for ", - sup, - ""); - } infer::IndexSlice(span) => { self.tcx.sess.span_err(span, "index of slice outside its lifetime"); @@ -625,28 +612,6 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { sup, ""); } - infer::RelateProcBound(span, var_node_id, ty) => { - self.tcx.sess.span_err( - span, - format!( - "the type `{}` of captured variable `{}` \ - outlives the `proc()` it \ - is captured in", - self.ty_to_string(ty), - ty::local_var_name_str(self.tcx, - var_node_id)).as_slice()); - note_and_explain_region( - self.tcx, - "`proc()` is valid for ", - sub, - ""); - note_and_explain_region( - self.tcx, - format!("the type `{}` is only valid for ", - self.ty_to_string(ty)).as_slice(), - sup, - ""); - } infer::RelateParamBound(span, ty) => { self.tcx.sess.span_err( span, @@ -1587,15 +1552,6 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> { self.tcx, id).get().to_string()).as_slice()); } - infer::ProcCapture(span, id) => { - self.tcx.sess.span_note( - span, - format!("...so that captured variable `{}` \ - is 'static", - ty::local_var_name_str( - self.tcx, - id).get()).as_slice()); - } infer::IndexSlice(span) => { self.tcx.sess.span_note( span, @@ -1606,15 +1562,6 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> { span, "...so that it can be closed over into an object"); } - infer::RelateProcBound(span, var_node_id, _ty) => { - self.tcx.sess.span_note( - span, - format!( - "...so that the variable `{}` can be captured \ - into a proc", - ty::local_var_name_str(self.tcx, - var_node_id)).as_slice()); - } infer::CallRcvr(span) => { self.tcx.sess.span_note( span, diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 4c3b7589d76cb..2b1d8776365ec 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -175,9 +175,6 @@ pub enum SubregionOrigin<'tcx> { // Closure bound must not outlive captured free variables FreeVariable(Span, ast::NodeId), - // Proc upvars must be 'static - ProcCapture(Span, ast::NodeId), - // Index into slice must be within its lifetime IndexSlice(Span), @@ -185,10 +182,6 @@ pub enum SubregionOrigin<'tcx> { // relating `'a` to `'b` RelateObjectBound(Span), - // When closing over a variable in a closure/proc, ensure that the - // type of the variable outlives the lifetime bound. - RelateProcBound(Span, ast::NodeId, Ty<'tcx>), - // Some type parameter was instantiated with the given type, // and that type must outlive some region. RelateParamBound(Span, Ty<'tcx>), @@ -1089,10 +1082,8 @@ impl<'tcx> SubregionOrigin<'tcx> { InvokeClosure(a) => a, DerefPointer(a) => a, FreeVariable(a, _) => a, - ProcCapture(a, _) => a, IndexSlice(a) => a, RelateObjectBound(a) => a, - RelateProcBound(a, _, _) => a, RelateParamBound(a, _) => a, RelateRegionParamBound(a) => a, RelateDefaultParamBound(a, _) => a, @@ -1128,21 +1119,12 @@ impl<'tcx> Repr<'tcx> for SubregionOrigin<'tcx> { FreeVariable(a, b) => { format!("FreeVariable({}, {})", a.repr(tcx), b) } - ProcCapture(a, b) => { - format!("ProcCapture({}, {})", a.repr(tcx), b) - } IndexSlice(a) => { format!("IndexSlice({})", a.repr(tcx)) } RelateObjectBound(a) => { format!("RelateObjectBound({})", a.repr(tcx)) } - RelateProcBound(a, b, c) => { - format!("RelateProcBound({},{},{})", - a.repr(tcx), - b, - c.repr(tcx)) - } RelateParamBound(a, b) => { format!("RelateParamBound({},{})", a.repr(tcx), diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 4a20c92d8e21e..8d5528b3709ad 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -114,6 +114,22 @@ impl LanguageItems { } } + pub fn fn_trait_kind(&self, id: ast::DefId) -> Option { + let def_id_kinds = [ + (self.fn_trait(), ty::FnUnboxedClosureKind), + (self.fn_mut_trait(), ty::FnMutUnboxedClosureKind), + (self.fn_once_trait(), ty::FnOnceUnboxedClosureKind), + ]; + + for &(opt_def_id, kind) in def_id_kinds.iter() { + if Some(id) == opt_def_id { + return Some(kind); + } + } + + None + } + $( #[allow(dead_code)] pub fn $method(&self) -> Option { diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 271e903bbdf17..31bcdff9cd593 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -461,7 +461,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) { } visit::walk_expr(ir, expr); } - ast::ExprClosure(..) | ast::ExprProc(..) => { + ast::ExprClosure(..) => { // Interesting control flow (for loops can contain labeled // breaks or continues) ir.add_live_node_for_node(expr.id, ExprNode(expr.span)); @@ -981,9 +981,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { self.propagate_through_expr(&**e, succ) } - ast::ExprClosure(_, _, _, ref blk) | - ast::ExprProc(_, ref blk) => { - debug!("{} is an ExprClosure or ExprProc", + ast::ExprClosure(_, _, _, ref blk) => { + debug!("{} is an ExprClosure", expr_to_string(expr)); /* @@ -1502,8 +1501,7 @@ fn check_expr(this: &mut Liveness, expr: &Expr) { ast::ExprBreak(..) | ast::ExprAgain(..) | ast::ExprLit(_) | ast::ExprBlock(..) | ast::ExprMac(..) | ast::ExprAddrOf(..) | ast::ExprStruct(..) | ast::ExprRepeat(..) | ast::ExprParen(..) | - ast::ExprClosure(..) | ast::ExprProc(..) | - ast::ExprPath(..) | ast::ExprBox(..) | ast::ExprSlice(..) => { + ast::ExprClosure(..) | ast::ExprPath(..) | ast::ExprBox(..) | ast::ExprSlice(..) => { visit::walk_expr(this, expr); } ast::ExprIfLet(..) => { diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index d96cf4495bdde..652847a63436d 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -555,8 +555,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { ast::ExprAddrOf(..) | ast::ExprCall(..) | ast::ExprAssign(..) | ast::ExprAssignOp(..) | - ast::ExprClosure(..) | ast::ExprProc(..) | - ast::ExprRet(..) | + ast::ExprClosure(..) | ast::ExprRet(..) | ast::ExprUnary(..) | ast::ExprSlice(..) | ast::ExprMethodCall(..) | ast::ExprCast(..) | ast::ExprVec(..) | ast::ExprTup(..) | ast::ExprIf(..) | @@ -728,7 +727,6 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { }; match fn_expr.node { - ast::ExprProc(_, ref body) | ast::ExprClosure(_, _, _, ref body) => body.id, _ => unreachable!() } diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 85e0c9294a6ba..9912db69a053f 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -51,7 +51,7 @@ use util::nodemap::{NodeMap, NodeSet, DefIdSet, FnvHashMap}; use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block, Crate, CrateNum}; use syntax::ast::{DeclItem, DefId, Expr, ExprAgain, ExprBreak, ExprField}; use syntax::ast::{ExprClosure, ExprForLoop, ExprLoop, ExprWhile, ExprMethodCall}; -use syntax::ast::{ExprPath, ExprProc, ExprStruct, FnDecl}; +use syntax::ast::{ExprPath, ExprStruct, FnDecl}; use syntax::ast::{ForeignItem, ForeignItemFn, ForeignItemStatic, Generics}; use syntax::ast::{Ident, ImplItem, Item, ItemEnum, ItemFn, ItemForeignMod}; use syntax::ast::{ItemImpl, ItemMac, ItemMod, ItemStatic, ItemStruct}; @@ -64,7 +64,7 @@ use syntax::ast::{RegionTyParamBound, StmtDecl, StructField}; use syntax::ast::{StructVariantKind, TraitRef, TraitTyParamBound}; use syntax::ast::{TupleVariantKind, Ty, TyBool, TyChar, TyClosure, TyF32}; use syntax::ast::{TyF64, TyFloat, TyI, TyI8, TyI16, TyI32, TyI64, TyInt, TyObjectSum}; -use syntax::ast::{TyParam, TyParamBound, TyPath, TyPtr, TyPolyTraitRef, TyProc, TyQPath}; +use syntax::ast::{TyParam, TyParamBound, TyPath, TyPtr, TyPolyTraitRef, TyQPath}; use syntax::ast::{TyRptr, TyStr, TyU, TyU8, TyU16, TyU32, TyU64, TyUint}; use syntax::ast::{TypeImplItem, UnnamedField}; use syntax::ast::{Variant, ViewItem, ViewItemExternCrate}; @@ -5027,7 +5027,7 @@ impl<'a> Resolver<'a> { self.resolve_trait_reference(ty.id, &*qpath.trait_ref, TraitQPath); } - TyClosure(ref c) | TyProc(ref c) => { + TyClosure(ref c) => { self.resolve_type_parameter_bounds( ty.id, &c.bounds, @@ -5902,13 +5902,6 @@ impl<'a> Resolver<'a> { &**block); } - ExprProc(ref fn_decl, ref block) => { - self.capture_mode_map.insert(expr.id, ast::CaptureByValue); - self.resolve_function(ClosureRibKind(expr.id, block.id), - Some(&**fn_decl), NoTypeParameters, - &**block); - } - ExprStruct(ref path, _, _) => { // Resolve the path to the structure it goes to. We don't // check to ensure that the path is actually a structure; that diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 83332d275ce99..ee0fc32702064 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -141,7 +141,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> { fn visit_ty(&mut self, ty: &ast::Ty) { match ty.node { - ast::TyClosure(ref c) | ast::TyProc(ref c) => { + ast::TyClosure(ref c) => { // Careful, the bounds on a closure/proc are *not* within its binder. visit::walk_ty_param_bounds_helper(self, &c.bounds); visit::walk_lifetime_decls_helper(self, &c.lifetimes); diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index 88c70f5557c14..c3c4acd8191c0 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -746,8 +746,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { _ => { return Ok(()); } }; - debug!("assemble_unboxed_candidates: self_ty={} obligation={}", + debug!("assemble_unboxed_candidates: self_ty={} kind={} obligation={}", self_ty.repr(self.tcx()), + kind, obligation.repr(self.tcx())); let closure_kind = match self.typer.unboxed_closures().borrow().get(&closure_def_id) { @@ -760,6 +761,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } }; + debug!("closure_kind = {}", closure_kind); + if closure_kind == kind { candidates.vec.push(UnboxedClosureCandidate(closure_def_id, substs.clone())); } @@ -842,14 +845,24 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { candidate: &Candidate<'tcx>) -> EvaluationResult<'tcx> { - debug!("winnow_candidate: candidate={}", candidate.repr(self.tcx())); - self.infcx.probe(|| { + /*! + * Further evaluate `candidate` to decide whether all type parameters match + * and whether nested obligations are met. Returns true if `candidate` remains + * viable after this further scrutiny. + */ + + debug!("winnow_candidate: depth={} candidate={}", + stack.obligation.recursion_depth, candidate.repr(self.tcx())); + let result = self.infcx.probe(|| { let candidate = (*candidate).clone(); match self.confirm_candidate(stack.obligation, candidate) { Ok(selection) => self.winnow_selection(Some(stack), selection), Err(error) => EvaluatedToErr(error), } - }) + }); + debug!("winnow_candidate depth={} result={}", + stack.obligation.recursion_depth, result); + result } fn winnow_selection<'o>(&mut self, @@ -1562,6 +1575,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { substs: substs, }); + debug!("confirm_unboxed_closure_candidate(closure_def_id={}, trait_ref={})", + closure_def_id.repr(self.tcx()), + trait_ref.repr(self.tcx())); + self.confirm(obligation.cause, obligation.trait_ref.clone(), trait_ref) diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 8e99045cffb58..98d4761508a28 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -4236,7 +4236,6 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind { ast::ExprIf(..) | ast::ExprMatch(..) | ast::ExprClosure(..) | - ast::ExprProc(..) | ast::ExprBlock(..) | ast::ExprRepeat(..) | ast::ExprVec(..) => { diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 5dbf3208595ed..f8276fa8f84d4 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -449,7 +449,14 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String { let unboxed_closures = cx.unboxed_closures.borrow(); unboxed_closures.get(did).map(|cl| { closure_to_string(cx, &cl.closure_type.subst(cx, substs)) - }).unwrap_or_else(|| "closure".to_string()) + }).unwrap_or_else(|| { + if did.krate == ast::LOCAL_CRATE { + let span = cx.map.span(did.node); + format!("closure[{}]", span.repr(cx)) + } else { + format!("closure") + } + }) } ty_vec(t, sz) => { let inner_str = ty_to_string(cx, t); diff --git a/src/librustc_back/svh.rs b/src/librustc_back/svh.rs index 549d636e8cb56..116cff49153be 100644 --- a/src/librustc_back/svh.rs +++ b/src/librustc_back/svh.rs @@ -242,7 +242,6 @@ mod svh_visitor { SawExprWhile, SawExprMatch, SawExprClosure, - SawExprProc, SawExprBlock, SawExprAssign, SawExprAssignOp(ast::BinOp), @@ -274,7 +273,6 @@ mod svh_visitor { ExprLoop(_, id) => SawExprLoop(id.map(content)), ExprMatch(..) => SawExprMatch, ExprClosure(..) => SawExprClosure, - ExprProc(..) => SawExprProc, ExprBlock(..) => SawExprBlock, ExprAssign(..) => SawExprAssign, ExprAssignOp(op, _, _) => SawExprAssignOp(op), diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 1722f9a1f75f2..a3fb91aced007 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -337,7 +337,6 @@ pub fn closure_to_block(closure_id: ast::NodeId, tcx: &ty::ctxt) -> ast::NodeId { match tcx.map.get(closure_id) { ast_map::NodeExpr(expr) => match expr.node { - ast::ExprProc(_, ref block) | ast::ExprClosure(_, _, _, ref block) => { block.id } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index d655b70405309..b0f8b3bdbe7df 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -71,7 +71,7 @@ pub mod driver; pub mod pretty; pub fn run(args: Vec) -> int { - monitor(proc() run_compiler(args.as_slice())); + monitor(move |:| run_compiler(args.as_slice())); 0 } @@ -471,7 +471,7 @@ pub fn list_metadata(sess: &Session, path: &Path, /// /// The diagnostic emitter yielded to the procedure should be used for reporting /// errors of the compiler. -pub fn monitor(f: proc():Send) { +pub fn monitor(f: F) { static STACK_SIZE: uint = 32000000; // 32MB let (tx, rx) = channel(); diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index c52f31532dcd0..24dfe600f2a56 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -842,18 +842,31 @@ pub fn run_passes(sess: &Session, //if sess.time_llvm_passes() { llvm::LLVMRustPrintPassTimings(); } } -type WorkItem = proc(&CodegenContext):Send; +struct WorkItem { + mtrans: ModuleTranslation, + config: ModuleConfig, + output_names: OutputFilenames, + name_extra: String +} fn build_work_item(sess: &Session, mtrans: ModuleTranslation, config: ModuleConfig, output_names: OutputFilenames, - name_extra: String) -> WorkItem { + name_extra: String) + -> WorkItem +{ let mut config = config; config.tm = create_target_machine(sess); + WorkItem { mtrans: mtrans, config: config, output_names: output_names, + name_extra: name_extra } +} - proc(cgcx) unsafe { - optimize_and_codegen(cgcx, mtrans, config, name_extra, output_names); +fn execute_work_item(cgcx: &CodegenContext, + work_item: WorkItem) { + unsafe { + optimize_and_codegen(cgcx, work_item.mtrans, work_item.config, + work_item.name_extra, work_item.output_names); } } @@ -866,7 +879,7 @@ fn run_work_singlethreaded(sess: &Session, // Since we're running single-threaded, we can pass the session to // the proc, allowing `optimize_and_codegen` to perform LTO. for work in Unfold::new((), |_| work_items.pop()) { - work(&cgcx); + execute_work_item(&cgcx, work); } } @@ -883,7 +896,7 @@ fn run_work_multithreaded(sess: &Session, let diag_emitter = diag_emitter.clone(); let remark = sess.opts.cg.remark.clone(); - let future = TaskBuilder::new().named(format!("codegen-{}", i)).try_future(proc() { + let future = TaskBuilder::new().named(format!("codegen-{}", i)).try_future(move |:| { let diag_handler = mk_handler(box diag_emitter); // Must construct cgcx inside the proc because it has non-Send @@ -899,7 +912,7 @@ fn run_work_multithreaded(sess: &Session, let maybe_work = work_items_arc.lock().pop(); match maybe_work { Some(work) => { - work(&cgcx); + execute_work_item(&cgcx, work); // Make sure to fail the worker so the main thread can // tell that there were errors. diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 5170746404e01..b2578fdbc054b 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -1396,8 +1396,7 @@ fn has_nested_returns(tcx: &ty::ctxt, id: ast::NodeId) -> bool { } Some(ast_map::NodeExpr(e)) => { match e.node { - ast::ExprClosure(_, _, _, ref blk) | - ast::ExprProc(_, ref blk) => { + ast::ExprClosure(_, _, _, ref blk) => { let mut explicit = CheckForNestedReturnsVisitor::explicit(); let mut implicit = CheckForNestedReturnsVisitor::implicit(); visit::walk_expr(&mut explicit, e); diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs index b8b2395dde172..67e1735d9a3b7 100644 --- a/src/librustc_trans/trans/callee.rs +++ b/src/librustc_trans/trans/callee.rs @@ -19,8 +19,7 @@ pub use self::CalleeData::*; pub use self::CallArgs::*; use arena::TypedArena; -use back::abi; -use back::link; +use back::{abi,link}; use session; use llvm::{ValueRef, get_param}; use llvm; @@ -357,153 +356,6 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>( llfn } -/// Translates the adapter that deconstructs a `Box` object into -/// `Trait` so that a by-value self method can be called. -pub fn trans_unboxing_shim<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, - llshimmedfn: ValueRef, - fty: &ty::BareFnTy<'tcx>, - method_id: ast::DefId, - substs: &subst::Substs<'tcx>) - -> ValueRef { - let _icx = push_ctxt("trans_unboxing_shim"); - let ccx = bcx.ccx(); - let tcx = bcx.tcx(); - - let fty = fty.subst(tcx, substs); - - // Transform the self type to `Box`. - let self_type = fty.sig.inputs[0]; - let boxed_self_type = ty::mk_uniq(tcx, self_type); - let boxed_function_type = ty::FnSig { - inputs: fty.sig.inputs.iter().enumerate().map(|(i, typ)| { - if i == 0 { - boxed_self_type - } else { - *typ - } - }).collect(), - output: fty.sig.output, - variadic: false, - }; - let boxed_function_type = ty::BareFnTy { - fn_style: fty.fn_style, - abi: fty.abi, - sig: boxed_function_type, - }; - let boxed_function_type = ty::mk_bare_fn(tcx, boxed_function_type); - let function_type = match fty.abi { - synabi::RustCall => { - // We're passing through to a RustCall ABI function, but - // because the shim will already perform untupling, we - // need to pretend the shimmed function does not use - // RustCall so the untupled arguments can be passed - // through verbatim. This is kind of ugly. - let fake_ty = ty::FnSig { - inputs: type_of::untuple_arguments_if_necessary(ccx, - fty.sig.inputs.as_slice(), - fty.abi), - output: fty.sig.output, - variadic: false, - }; - let fake_ty = ty::BareFnTy { - fn_style: fty.fn_style, - abi: synabi::Rust, - sig: fake_ty, - }; - ty::mk_bare_fn(tcx, fake_ty) - } - _ => { - ty::mk_bare_fn(tcx, fty) - } - }; - - let function_name = ty::with_path(tcx, method_id, |path| { - link::mangle_internal_name_by_path_and_seq(path, "unboxing_shim") - }); - let llfn = decl_internal_rust_fn(ccx, - boxed_function_type, - function_name.as_slice()); - - let block_arena = TypedArena::new(); - let empty_param_substs = Substs::trans_empty(); - let return_type = ty::ty_fn_ret(boxed_function_type); - let fcx = new_fn_ctxt(ccx, - llfn, - ast::DUMMY_NODE_ID, - false, - return_type, - &empty_param_substs, - None, - &block_arena); - let mut bcx = init_function(&fcx, false, return_type); - - // Create the substituted versions of the self type. - let arg_scope = fcx.push_custom_cleanup_scope(); - let arg_scope_id = cleanup::CustomScope(arg_scope); - let boxed_self_type = ty::ty_fn_args(boxed_function_type)[0]; - let arg_types = ty::ty_fn_args(function_type); - let self_type = arg_types[0]; - let boxed_self_kind = arg_kind(&fcx, boxed_self_type); - - // Create a datum for self. - let llboxedself = get_param(fcx.llfn, fcx.arg_pos(0) as u32); - let llboxedself = Datum::new(llboxedself, - boxed_self_type, - boxed_self_kind); - let boxed_self = - unpack_datum!(bcx, - llboxedself.to_lvalue_datum_in_scope(bcx, - "boxedself", - arg_scope_id)); - - // This `Load` is needed because lvalue data are always by-ref. - let llboxedself = Load(bcx, boxed_self.val); - - let llself = if type_is_immediate(ccx, self_type) { - let llboxedself = Load(bcx, llboxedself); - immediate_rvalue(llboxedself, self_type) - } else { - let llself = rvalue_scratch_datum(bcx, self_type, "self"); - memcpy_ty(bcx, llself.val, llboxedself, self_type); - llself - }; - - // Make sure we don't free the box twice! - boxed_self.kind.post_store(bcx, boxed_self.val, boxed_self_type); - - // Schedule a cleanup to free the box. - fcx.schedule_free_value(arg_scope_id, - llboxedself, - cleanup::HeapExchange, - self_type); - - // Now call the function. - let mut llshimmedargs = vec!(llself.val); - for i in range(1, arg_types.len()) { - llshimmedargs.push(get_param(fcx.llfn, fcx.arg_pos(i) as u32)); - } - assert!(!fcx.needs_ret_allocas); - let dest = fcx.llretslotptr.get().map(|_| - expr::SaveIn(fcx.get_ret_slot(bcx, return_type, "ret_slot")) - ); - bcx = trans_call_inner(bcx, - None, - function_type, - |bcx, _| { - Callee { - bcx: bcx, - data: Fn(llshimmedfn), - } - }, - ArgVals(llshimmedargs.as_slice()), - dest).bcx; - - bcx = fcx.pop_and_trans_custom_cleanup_scope(bcx, arg_scope); - finish_fn(&fcx, bcx, return_type); - - llfn -} - /// Translates a reference to a fn/method item, monomorphizing and /// inlining as it goes. /// diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index de169fc9d62a6..66258f228cd7b 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -1239,7 +1239,6 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } ast_map::NodeExpr(ref expr) => { match expr.node { - ast::ExprProc(ref fn_decl, ref top_level_block) | ast::ExprClosure(_, _, ref fn_decl, ref top_level_block) => { let name = format!("fn{}", token::gensym("fn")); let name = token::str_to_ident(name.as_slice()); @@ -3588,7 +3587,6 @@ fn populate_scope_map(cx: &CrateContext, }) } - ast::ExprProc(ref decl, ref block) | ast::ExprClosure(_, _, ref decl, ref block) => { with_new_scope(cx, block.span, diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index e1769001942d5..5b9a1d499910e 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -1052,8 +1052,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ast::ExprVec(..) | ast::ExprRepeat(..) => { tvec::trans_fixed_vstore(bcx, expr, dest) } - ast::ExprClosure(_, _, ref decl, ref body) | - ast::ExprProc(ref decl, ref body) => { + ast::ExprClosure(_, _, ref decl, ref body) => { // Check the side-table to see whether this is an unboxed // closure or an older, legacy style closure. Store this // into a variable to ensure the the RefCell-lock is diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs index 94ff526debd1e..9a2bc38acdfdc 100644 --- a/src/librustc_trans/trans/meth.rs +++ b/src/librustc_trans/trans/meth.rs @@ -550,68 +550,12 @@ pub fn get_vtable<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, emit_vtable_methods(bcx, id, substs).into_iter() } traits::VtableUnboxedClosure(closure_def_id, substs) => { - // Look up closure type - let self_ty = ty::node_id_to_type(bcx.tcx(), closure_def_id.node); - // Apply substitutions from closure param environment. - // The substitutions should have no type parameters - // remaining after passing through fulfill_obligation - let self_ty = self_ty.subst(bcx.tcx(), &substs); - - let mut llfn = trans_fn_ref_with_substs( + let llfn = trans_fn_ref_with_substs( bcx, closure_def_id, ExprId(0), substs.clone()); - { - let unboxed_closures = bcx.tcx() - .unboxed_closures - .borrow(); - let closure_info = - unboxed_closures.get(&closure_def_id) - .expect("get_vtable(): didn't find \ - unboxed closure"); - if closure_info.kind == ty::FnOnceUnboxedClosureKind { - // Untuple the arguments and create an unboxing shim. - let (new_inputs, new_output) = match self_ty.sty { - ty::ty_unboxed_closure(_, _, ref substs) => { - let mut new_inputs = vec![self_ty.clone()]; - match closure_info.closure_type.sig.inputs[0].sty { - ty::ty_tup(ref elements) => { - for element in elements.iter() { - new_inputs.push(element.subst(bcx.tcx(), substs)); - } - } - _ => { - bcx.tcx().sess.bug("get_vtable(): closure \ - type wasn't a tuple") - } - } - (new_inputs, - closure_info.closure_type.sig.output.subst(bcx.tcx(), substs)) - }, - _ => bcx.tcx().sess.bug("get_vtable(): def wasn't an unboxed closure") - }; - - let closure_type = ty::BareFnTy { - fn_style: closure_info.closure_type.fn_style, - abi: Rust, - sig: ty::FnSig { - inputs: new_inputs, - output: new_output, - variadic: false, - }, - }; - debug!("get_vtable(): closure type is {}", - closure_type.repr(bcx.tcx())); - llfn = trans_unboxing_shim(bcx, - llfn, - &closure_type, - closure_def_id, - &substs); - } - } - (vec!(llfn)).into_iter() } traits::VtableFnPointer(bare_fn_ty) => { @@ -701,18 +645,15 @@ fn emit_vtable_methods<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, token::get_name(name)); Some(C_null(Type::nil(ccx).ptr_to())).into_iter() } else { - let mut fn_ref = trans_fn_ref_with_substs( + let fn_ref = trans_fn_ref_with_substs( bcx, m_id, ExprId(0), substs.clone()); - if m.explicit_self == ty::ByValueExplicitSelfCategory { - fn_ref = trans_unboxing_shim(bcx, - fn_ref, - &m.fty, - m_id, - &substs); - } + + // currently, at least, by-value self is not object safe + assert!(m.explicit_self != ty::ByValueExplicitSelfCategory); + Some(fn_ref).into_iter() } } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 4ad0d2b8293e1..762aed3dfa8ea 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -235,8 +235,9 @@ fn ast_path_substs_for_ty<'tcx,AC,RS>( convert_angle_bracketed_parameters(this, rscope, data) } ast::ParenthesizedParameters(ref data) => { - span_err!(tcx.sess, path.span, E0169, - "parenthesized parameters may only be used with a trait"); + tcx.sess.span_err( + path.span, + "parenthesized parameters may only be used with a trait"); (Vec::new(), convert_parenthesized_parameters(this, data), Vec::new()) } }; @@ -581,6 +582,19 @@ fn ast_path_to_trait_ref<'tcx,AC,RS>( convert_angle_bracketed_parameters(this, &shifted_rscope, data) } ast::ParenthesizedParameters(ref data) => { + // For now, require that parenthetical notation be used + // only with `Fn()` etc. + if !this.tcx().sess.features.borrow().unboxed_closures && + this.tcx().lang_items.fn_trait_kind(trait_def_id).is_none() + { + this.tcx().sess.span_err(path.span, + "parenthetical notation is only stable when \ + used with the `Fn` family of traits"); + span_help!(this.tcx().sess, path.span, + "add `#![feature(unboxed_closures)]` to \ + the crate attributes to enable"); + } + (Vec::new(), convert_parenthesized_parameters(this, data), Vec::new()) } }; @@ -932,26 +946,6 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>( None); ty::mk_closure(tcx, fn_decl) } - ast::TyProc(ref f) => { - // Use corresponding trait store to figure out default bounds - // if none were specified. - let bounds = conv_existential_bounds(this, - rscope, - ast_ty.span, - None, - f.bounds.as_slice()); - - let fn_decl = ty_of_closure(this, - f.fn_style, - f.onceness, - bounds, - ty::UniqTraitStore, - &*f.decl, - abi::Rust, - None); - - ty::mk_closure(tcx, fn_decl) - } ast::TyPolyTraitRef(ref bounds) => { conv_ty_poly_trait_ref(this, rscope, ast_ty.span, bounds.as_slice()) } @@ -1058,7 +1052,7 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>( } ast::TyInfer => { // TyInfer also appears as the type of arguments or return - // values in a ExprClosure or ExprProc, or as + // values in a ExprClosure, or as // the type of local variables. Both of these cases are // handled specially and will not descend into this routine. this.ty_infer(ast_ty.span) diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 2b34b4a55b7c1..692bd31638e34 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -188,42 +188,35 @@ fn deduce_unboxed_closure_expectations_from_trait_ref<'a,'tcx>( debug!("deduce_unboxed_closure_expectations_from_object_type({})", trait_ref.repr(tcx)); - let def_id_kinds = [ - (tcx.lang_items.fn_trait(), ty::FnUnboxedClosureKind), - (tcx.lang_items.fn_mut_trait(), ty::FnMutUnboxedClosureKind), - (tcx.lang_items.fn_once_trait(), ty::FnOnceUnboxedClosureKind), - ]; - - for &(def_id, kind) in def_id_kinds.iter() { - if Some(trait_ref.def_id) == def_id { - debug!("found object type {}", kind); - - let arg_param_ty = *trait_ref.substs.types.get(subst::TypeSpace, 0); - let arg_param_ty = fcx.infcx().resolve_type_vars_if_possible(arg_param_ty); - debug!("arg_param_ty {}", arg_param_ty.repr(tcx)); - - let input_tys = match arg_param_ty.sty { - ty::ty_tup(ref tys) => { (*tys).clone() } - _ => { continue; } - }; - debug!("input_tys {}", input_tys.repr(tcx)); + let kind = match tcx.lang_items.fn_trait_kind(trait_ref.def_id) { + Some(k) => k, + None => { return None; } + }; - let ret_param_ty = *trait_ref.substs.types.get(subst::TypeSpace, 1); - let ret_param_ty = fcx.infcx().resolve_type_vars_if_possible(ret_param_ty); - debug!("ret_param_ty {}", ret_param_ty.repr(tcx)); + debug!("found object type {}", kind); - let fn_sig = ty::FnSig { - inputs: input_tys, - output: ty::FnConverging(ret_param_ty), - variadic: false - }; - debug!("fn_sig {}", fn_sig.repr(tcx)); + let arg_param_ty = *trait_ref.substs.types.get(subst::TypeSpace, 0); + let arg_param_ty = fcx.infcx().resolve_type_vars_if_possible(arg_param_ty); + debug!("arg_param_ty {}", arg_param_ty.repr(tcx)); - return Some((fn_sig, kind)); - } - } + let input_tys = match arg_param_ty.sty { + ty::ty_tup(ref tys) => { (*tys).clone() } + _ => { return None; } + }; + debug!("input_tys {}", input_tys.repr(tcx)); - None + let ret_param_ty = *trait_ref.substs.types.get(subst::TypeSpace, 1); + let ret_param_ty = fcx.infcx().resolve_type_vars_if_possible(ret_param_ty); + debug!("ret_param_ty {}", ret_param_ty.repr(tcx)); + + let fn_sig = ty::FnSig { + inputs: input_tys, + output: ty::FnConverging(ret_param_ty), + variadic: false + }; + debug!("fn_sig {}", fn_sig.repr(tcx)); + + return Some((fn_sig, kind)); } fn deduce_unboxed_closure_expectations_from_obligations<'a,'tcx>( @@ -257,12 +250,12 @@ fn deduce_unboxed_closure_expectations_from_obligations<'a,'tcx>( } -pub fn check_boxed_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, - expr: &ast::Expr, - store: ty::TraitStore, - decl: &ast::FnDecl, - body: &ast::Block, - expected: Expectation<'tcx>) { +fn check_boxed_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, + expr: &ast::Expr, + store: ty::TraitStore, + decl: &ast::FnDecl, + body: &ast::Block, + expected: Expectation<'tcx>) { let tcx = fcx.ccx.tcx; // Find the expected input/output types (if any). Substitute @@ -300,18 +293,10 @@ pub fn check_boxed_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, } _ => { // Not an error! Means we're inferring the closure type - let (bounds, onceness) = match expr.node { - ast::ExprProc(..) => { - let mut bounds = ty::region_existential_bound(ty::ReStatic); - bounds.builtin_bounds.insert(ty::BoundSend); // FIXME - (bounds, ast::Once) - } - _ => { - let region = fcx.infcx().next_region_var( - infer::AddrOfRegion(expr.span)); - (ty::region_existential_bound(region), ast::Many) - } - }; + let region = fcx.infcx().next_region_var( + infer::AddrOfRegion(expr.span)); + let bounds = ty::region_existential_bound(region); + let onceness = ast::Many; (None, onceness, bounds) } } diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index adcfc491dcc4f..d3879e49034b1 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -315,23 +315,6 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { get_method_index(tcx, &*new_trait_ref, trait_ref.clone(), method_num); - // FIXME Hacky. By-value `self` methods in objects ought to be - // just a special case of passing ownership of a DST value - // as a parameter. *But* we currently hack them in and tie them to - // the particulars of the `Box` type. So basically for a `fn foo(self,...)` - // method invoked on an object, we don't want the receiver type to be - // `TheTrait`, but rather `Box`. Yuck. - let mut m = m; - match m.explicit_self { - ty::ByValueExplicitSelfCategory => { - let mut n = (*m).clone(); - let self_ty = n.fty.sig.inputs[0]; - n.fty.sig.inputs[0] = ty::mk_uniq(tcx, self_ty); - m = Rc::new(n); - } - _ => { } - } - let xform_self_ty = this.xform_self_ty(&m, &new_trait_ref.substs); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 18a773fb949fc..fdc57579d072b 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -136,7 +136,7 @@ mod callee; /// closures defined within the function. For example: /// /// fn foo() { -/// bar(proc() { ... }) +/// bar(move|| { ... }) /// } /// /// Here, the function `foo()` and the closure passed to @@ -2122,14 +2122,6 @@ fn try_overloaded_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, fcx.inh.method_map.borrow_mut().insert(method_call, method_callee); write_call(fcx, call_expression, output_type); - if !fcx.tcx().sess.features.borrow().unboxed_closures { - span_err!(fcx.tcx().sess, call_expression.span, E0056, - "overloaded calls are experimental"); - span_help!(fcx.tcx().sess, call_expression.span, - "add `#![feature(unboxed_closures)]` to \ - the crate attributes to enable"); - } - return true } @@ -2666,7 +2658,7 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, }; for (i, arg) in args.iter().take(t).enumerate() { let is_block = match arg.node { - ast::ExprClosure(..) | ast::ExprProc(..) => true, + ast::ExprClosure(..) => true, _ => false }; @@ -3997,14 +3989,6 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, ast::ExprClosure(_, opt_kind, ref decl, ref body) => { closure::check_expr_closure(fcx, expr, opt_kind, &**decl, &**body, expected); } - ast::ExprProc(ref decl, ref body) => { - closure::check_boxed_closure(fcx, - expr, - ty::UniqTraitStore, - &**decl, - &**body, - expected); - } ast::ExprBlock(ref b) => { check_block_with_expected(fcx, &**b, expected); fcx.write_ty(id, fcx.node_ty(b.id)); @@ -5159,6 +5143,9 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, } ast::ParenthesizedParameters(ref data) => { + fcx.tcx().sess.span_err( + span, + "parenthesized parameters may only be used with a trait"); push_explicit_parenthesized_parameters_from_segment_to_substs( fcx, space, span, type_defs, data, substs); } diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index cadcee43b4402..9f75b9764ebd8 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -714,7 +714,6 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) { visit::walk_expr(rcx, expr); } - ast::ExprProc(_, ref body) | ast::ExprClosure(_, _, _, ref body) => { check_expr_fn_block(rcx, expr, &**body); } @@ -936,8 +935,9 @@ fn check_expr_fn_block(rcx: &mut Rcx, let cause = traits::ObligationCause::new(freevar.span, rcx.fcx.body_id, code); rcx.fcx.register_builtin_bound(var_ty, builtin_bound, cause); } + type_must_outlive( - rcx, infer::RelateProcBound(expr.span, var_node_id, var_ty), + rcx, infer::FreeVariable(expr.span, var_node_id), var_ty, bounds.region_bound); } } diff --git a/src/librustc_typeck/check/vtable.rs b/src/librustc_typeck/check/vtable.rs index 7c5ceb6f5107c..415a3d53fb284 100644 --- a/src/librustc_typeck/check/vtable.rs +++ b/src/librustc_typeck/check/vtable.rs @@ -149,14 +149,6 @@ pub fn check_object_safety<'tcx>(tcx: &ty::ctxt<'tcx>, fn check_object_safety_inner<'tcx>(tcx: &ty::ctxt<'tcx>, object_trait: &ty::TraitRef<'tcx>, span: Span) { - // Skip the fn_once lang item trait since only the compiler should call - // `call_once` which is the method which takes self by value. What could go - // wrong? - match tcx.lang_items.fn_once_trait() { - Some(def_id) if def_id == object_trait.def_id => return, - _ => {} - } - let trait_items = ty::trait_items(tcx, object_trait.def_id); let mut errors = Vec::new(); diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 48f1ef8da1d54..8d94cf5dd5e96 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -121,8 +121,7 @@ impl<'cx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'tcx> { MethodCall::expr(e.id)); match e.node { - ast::ExprClosure(_, _, ref decl, _) | - ast::ExprProc(ref decl, _) => { + ast::ExprClosure(_, _, ref decl, _) => { for input in decl.inputs.iter() { let _ = self.visit_node_id(ResolvingExpr(e.span), input.id); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 630d41fa7e209..8045dab6c2d67 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1165,12 +1165,19 @@ pub enum Type { mutability: Mutability, type_: Box, }, + + // ::Name QPath { name: String, self_type: Box, trait_: Box }, - // region, raw, other boxes, mutable + + // _ + Infer, + + // for<'a> Foo(&'a) + PolyTraitRef(Vec), } #[deriving(Clone, Encodable, Decodable, PartialEq, Eq, Hash)] @@ -1307,11 +1314,18 @@ impl Clean for ast::Ty { } } TyClosure(ref c) => Closure(box c.clean(cx)), - TyProc(ref c) => Proc(box c.clean(cx)), TyBareFn(ref barefn) => BareFunction(box barefn.clean(cx)), TyParen(ref ty) => ty.clean(cx), TyQPath(ref qp) => qp.clean(cx), - ref x => panic!("Unimplemented type {}", x), + TyPolyTraitRef(ref bounds) => { + PolyTraitRef(bounds.clean(cx)) + }, + TyInfer(..) => { + Infer + }, + TyTypeof(..) => { + panic!("Unimplemented type {}", self.node) + }, } } } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 484eed649bbcd..cf92a71369fa3 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -390,6 +390,16 @@ impl fmt::Show for clean::Type { try!(resolved_path(f, did, path, false)); tybounds(f, typarams) } + clean::PolyTraitRef(ref bounds) => { + for (i, bound) in bounds.iter().enumerate() { + if i != 0 { + try!(write!(f, " + ")); + } + try!(write!(f, "{}", *bound)); + } + Ok(()) + } + clean::Infer => write!(f, "_"), clean::Self(..) => f.write("Self".as_bytes()), clean::Primitive(prim) => primitive_link(f, prim, prim.to_string()), clean::Closure(ref decl) => { diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index d3a766285809b..78117c9cb06d4 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -342,7 +342,7 @@ fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matche let cr = Path::new(cratefile); info!("starting to run rustc"); - let (mut krate, analysis) = std::task::try(proc() { + let (mut krate, analysis) = std::task::try(move |:| { let cr = cr; core::run_core(libs, cfgs, externs, &cr, triple) }).map_err(|_| "rustc failed").unwrap(); diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 5759adf32440e..0c64a0d29dffe 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -15,6 +15,7 @@ use std::io; use std::os; use std::str; use std::string::String; +use std::thunk::Thunk; use std::collections::{HashSet, HashMap}; use testing; @@ -142,7 +143,7 @@ fn runtest(test: &str, cratename: &str, libs: Vec, externs: core::Externs, let w1 = io::ChanWriter::new(tx); let w2 = w1.clone(); let old = io::stdio::set_stderr(box w1); - spawn(proc() { + spawn(move |:| { let mut p = io::ChanReader::new(rx); let mut err = match old { Some(old) => { @@ -282,7 +283,7 @@ impl Collector { ignore: should_ignore, should_fail: testing::ShouldFail::No, // compiler failures are test failures }, - testfn: testing::DynTestFn(proc() { + testfn: testing::DynTestFn(Thunk::new(move|| { runtest(test.as_slice(), cratename.as_slice(), libs, @@ -290,7 +291,7 @@ impl Collector { should_fail, no_run, as_test_harness); - }), + })) }); } diff --git a/src/librustrt/at_exit_imp.rs b/src/librustrt/at_exit_imp.rs index ce27decb136c0..8be77d9b34ddd 100644 --- a/src/librustrt/at_exit_imp.rs +++ b/src/librustrt/at_exit_imp.rs @@ -18,10 +18,11 @@ use alloc::boxed::Box; use collections::vec::Vec; use core::atomic; use core::mem; +use thunk::{Thunk}; use exclusive::Exclusive; -type Queue = Exclusive>; +type Queue = Exclusive>; static QUEUE: atomic::AtomicUint = atomic::INIT_ATOMIC_UINT; static RUNNING: atomic::AtomicBool = atomic::INIT_ATOMIC_BOOL; @@ -34,7 +35,7 @@ pub fn init() { } } -pub fn push(f: proc():Send) { +pub fn push(f: Thunk) { unsafe { // Note that the check against 0 for the queue pointer is not atomic at // all with respect to `run`, meaning that this could theoretically be a @@ -59,6 +60,6 @@ pub fn run() { }; for to_run in cur.into_iter() { - to_run(); + to_run.invoke(()); } } diff --git a/src/librustrt/c_str.rs b/src/librustrt/c_str.rs index 865c1af1d1427..bba81383f7b2e 100644 --- a/src/librustrt/c_str.rs +++ b/src/librustrt/c_str.rs @@ -639,7 +639,7 @@ mod tests { #[test] fn test_to_c_str_fail() { - assert!(task::try(proc() { "he\x00llo".to_c_str() }).is_err()); + assert!(task::try(move|| { "he\x00llo".to_c_str() }).is_err()); } #[test] diff --git a/src/librustrt/exclusive.rs b/src/librustrt/exclusive.rs index d40f149a2a1f8..9adcc0a844dff 100644 --- a/src/librustrt/exclusive.rs +++ b/src/librustrt/exclusive.rs @@ -99,7 +99,7 @@ mod tests { let (tx, rx) = channel(); futures.push(rx); - task::spawn(proc() { + task::spawn(move || { for _ in range(0u, count) { **total.lock() += 1; } diff --git a/src/librustrt/lib.rs b/src/librustrt/lib.rs index c2ee91d6acca2..f12f8e4980119 100644 --- a/src/librustrt/lib.rs +++ b/src/librustrt/lib.rs @@ -46,6 +46,7 @@ mod thread_local_storage; mod util; mod libunwind; mod stack_overflow; +pub mod thunk; pub mod args; pub mod bookkeeping; @@ -95,8 +96,8 @@ pub fn init(argc: int, argv: *const *const u8) { /// /// It is forbidden for procedures to register more `at_exit` handlers when they /// are running, and doing so will lead to a process abort. -pub fn at_exit(f: proc():Send) { - at_exit_imp::push(f); +pub fn at_exit(f: F) { + at_exit_imp::push(thunk::Thunk::new(f)); } /// One-time runtime cleanup. diff --git a/src/librustrt/local.rs b/src/librustrt/local.rs index b1d387a9cc358..df733d7ee225b 100644 --- a/src/librustrt/local.rs +++ b/src/librustrt/local.rs @@ -59,7 +59,7 @@ mod test { #[test] fn thread_local_task_smoke_test() { - Thread::start(proc() { + Thread::start(move|| { let task = box Task::new(None, None); Local::put(task); let task: Box = Local::take(); @@ -69,7 +69,7 @@ mod test { #[test] fn thread_local_task_two_instances() { - Thread::start(proc() { + Thread::start(move|| { let task = box Task::new(None, None); Local::put(task); let task: Box = Local::take(); @@ -83,7 +83,7 @@ mod test { #[test] fn borrow_smoke_test() { - Thread::start(proc() { + Thread::start(move|| { let task = box Task::new(None, None); Local::put(task); @@ -97,7 +97,7 @@ mod test { #[test] fn borrow_with_return() { - Thread::start(proc() { + Thread::start(move|| { let task = box Task::new(None, None); Local::put(task); @@ -112,7 +112,7 @@ mod test { #[test] fn try_take() { - Thread::start(proc() { + Thread::start(move|| { let task = box Task::new(None, None); Local::put(task); diff --git a/src/librustrt/mutex.rs b/src/librustrt/mutex.rs index 5b58ec8fd3a8b..cbfb86a6ac7b2 100644 --- a/src/librustrt/mutex.rs +++ b/src/librustrt/mutex.rs @@ -680,7 +680,7 @@ mod test { static LK: StaticNativeMutex = NATIVE_MUTEX_INIT; unsafe { let guard = LK.lock(); - let t = Thread::start(proc() { + let t = Thread::start(move|| { let guard = LK.lock(); guard.signal(); }); @@ -705,7 +705,7 @@ mod test { static LK: StaticNativeMutex = NATIVE_MUTEX_INIT; unsafe { LK.lock_noguard(); - let t = Thread::start(proc() { + let t = Thread::start(move|| { LK.lock_noguard(); LK.signal_noguard(); LK.unlock_noguard(); diff --git a/src/librustrt/task.rs b/src/librustrt/task.rs index 7e657d3aef391..37632f509c14a 100644 --- a/src/librustrt/task.rs +++ b/src/librustrt/task.rs @@ -21,6 +21,7 @@ use core::any::Any; use core::atomic::{AtomicUint, SeqCst}; use core::iter::{IteratorExt, Take}; use core::kinds::marker; +use core::ops::FnOnce; use core::mem; use core::ops::FnMut; use core::prelude::{Clone, Drop, Err, Iterator, None, Ok, Option, Send, Some}; @@ -34,6 +35,7 @@ use stack; use unwind; use unwind::Unwinder; use collections::str::SendStr; +use thunk::Thunk; /// State associated with Rust tasks. /// @@ -67,7 +69,7 @@ enum TaskState { pub struct TaskOpts { /// Invoke this procedure with the result of the task when it finishes. - pub on_exit: Option, + pub on_exit: Option>, /// A name for the task-to-be, for identification in panic messages pub name: Option, /// The size of the stack for the spawned task @@ -92,7 +94,7 @@ pub enum BlockedTask { /// Per-task state related to task death, killing, panic, etc. pub struct Death { - pub on_exit: Option, + pub on_exit: Option>, marker: marker::NoCopy, } @@ -116,7 +118,13 @@ impl Task { } } - pub fn spawn(opts: TaskOpts, f: proc():Send) { + pub fn spawn(opts: TaskOpts, f: F) + where F : FnOnce(), F : Send + { + Task::spawn_thunk(opts, Thunk::new(f)) + } + + fn spawn_thunk(opts: TaskOpts, f: Thunk) { let TaskOpts { name, stack_size, on_exit } = opts; let mut task = box Task::new(None, None); @@ -138,7 +146,7 @@ impl Task { // because by the time that this function is executing we've already // consumed at least a little bit of stack (we don't know the exact byte // address at which our stack started). - Thread::spawn_stack(stack, proc() { + Thread::spawn_stack(stack, move|| { let something_around_the_top_of_the_stack = 1; let addr = &something_around_the_top_of_the_stack as *const int; let my_stack = addr as uint; @@ -150,7 +158,7 @@ impl Task { task.stack_bounds = (my_stack - stack + 1024, my_stack); let mut f = Some(f); - drop(task.run(|| { f.take().unwrap()() }).destroy()); + drop(task.run(|| { f.take().unwrap().invoke(()) }).destroy()); drop(token); }) } @@ -241,7 +249,7 @@ impl Task { // reconsideration to whether it's a reasonable thing to let a // task to do or not. match what_to_do { - Some(f) => { f(result) } + Some(f) => { f.invoke(result) } None => { drop(result) } } @@ -500,14 +508,13 @@ mod test { use super::*; use std::prelude::*; use std::task; - use unwind; #[test] fn unwind() { - let result = task::try(proc()()); + let result = task::try(move|| ()); rtdebug!("trying first assert"); assert!(result.is_ok()); - let result = task::try::<()>(proc() panic!()); + let result = task::try(move|| -> () panic!()); rtdebug!("trying second assert"); assert!(result.is_err()); } diff --git a/src/librustrt/thread.rs b/src/librustrt/thread.rs index 9f3f45ba0981c..175e057c22f2e 100644 --- a/src/librustrt/thread.rs +++ b/src/librustrt/thread.rs @@ -22,6 +22,7 @@ use alloc::boxed::Box; use core::mem; use core::uint; use libc; +use thunk::{Thunk}; use stack; use stack_overflow; @@ -60,8 +61,8 @@ fn start_thread(main: *mut libc::c_void) -> imp::rust_thread_return { unsafe { stack::record_os_managed_stack_bounds(0, uint::MAX); let handler = stack_overflow::Handler::new(); - let f: Box = mem::transmute(main); - (*f)(); + let f: Box = mem::transmute(main); + f.invoke(()); drop(handler); mem::transmute(0 as imp::rust_thread_return) } @@ -113,14 +114,17 @@ impl Thread<()> { /// to finish executing. This means that even if `join` is not explicitly /// called, when the `Thread` falls out of scope its destructor will block /// waiting for the OS thread. - pub fn start(main: proc():Send -> T) -> Thread { + pub fn start(main: F) -> Thread + where T:Send, F:FnOnce() -> T, F:Send + { Thread::start_stack(DEFAULT_STACK_SIZE, main) } /// Performs the same functionality as `start`, but specifies an explicit /// stack size for the new thread. - pub fn start_stack(stack: uint, main: proc():Send -> T) -> Thread { - + pub fn start_stack(stack: uint, main: F) -> Thread + where T:Send, F:FnOnce() -> T, F:Send + { // We need the address of the packet to fill in to be stable so when // `main` fills it in it's still valid, so allocate an extra box to do // so. @@ -128,8 +132,11 @@ impl Thread<()> { let packet2: *mut Option = unsafe { *mem::transmute::<&Box>, *const *mut Option>(&packet) }; - let main = proc() unsafe { *packet2 = Some(main()); }; - let native = unsafe { imp::create(stack, box main) }; + let native = unsafe { + imp::create(stack, Thunk::new(move |:| { + *packet2 = Some(main.call_once(())); + })) + }; Thread { native: native, @@ -144,15 +151,19 @@ impl Thread<()> { /// This corresponds to creating threads in the 'detached' state on unix /// systems. Note that platforms may not keep the main program alive even if /// there are detached thread still running around. - pub fn spawn(main: proc():Send) { + pub fn spawn(main: F) + where F : FnOnce() + Send + { Thread::spawn_stack(DEFAULT_STACK_SIZE, main) } /// Performs the same functionality as `spawn`, but explicitly specifies a /// stack size for the new thread. - pub fn spawn_stack(stack: uint, main: proc():Send) { + pub fn spawn_stack(stack: uint, main: F) + where F : FnOnce() + Send + { unsafe { - let handle = imp::create(stack, box main); + let handle = imp::create(stack, Thunk::new(main)); imp::detach(handle); } } @@ -190,8 +201,6 @@ impl Drop for Thread { #[cfg(windows)] #[allow(non_snake_case)] mod imp { - use core::prelude::*; - use alloc::boxed::Box; use core::cmp; use core::mem; @@ -200,6 +209,7 @@ mod imp { use libc::types::os::arch::extra::{LPSECURITY_ATTRIBUTES, SIZE_T, BOOL, LPVOID, DWORD, LPDWORD, HANDLE}; use stack::RED_ZONE; + use thunk::Thunk; pub type rust_thread = HANDLE; pub type rust_thread_return = DWORD; @@ -217,8 +227,9 @@ mod imp { } } - pub unsafe fn create(stack: uint, p: Box) -> rust_thread { - let arg: *mut libc::c_void = mem::transmute(p); + pub unsafe fn create(stack: uint, p: Thunk) -> rust_thread { + let arg: *mut libc::c_void = mem::transmute(box p); + // FIXME On UNIX, we guard against stack sizes that are too small but // that's because pthreads enforces that stacks are at least // PTHREAD_STACK_MIN bytes big. Windows has no such lower limit, it's @@ -234,7 +245,7 @@ mod imp { if ret as uint == 0 { // be sure to not leak the closure - let _p: Box = mem::transmute(arg); + let _p: Box = mem::transmute(arg); panic!("failed to spawn native thread: {}", ret); } return ret; @@ -279,6 +290,7 @@ mod imp { use core::ptr; use libc::consts::os::posix01::{PTHREAD_CREATE_JOINABLE, PTHREAD_STACK_MIN}; use libc; + use thunk::Thunk; use stack::RED_ZONE; @@ -409,7 +421,7 @@ mod imp { } } - pub unsafe fn create(stack: uint, p: Box) -> rust_thread { + pub unsafe fn create(stack: uint, p: Thunk) -> rust_thread { let mut native: libc::pthread_t = mem::zeroed(); let mut attr: libc::pthread_attr_t = mem::zeroed(); assert_eq!(pthread_attr_init(&mut attr), 0); @@ -437,13 +449,13 @@ mod imp { }, }; - let arg: *mut libc::c_void = mem::transmute(p); + let arg: *mut libc::c_void = mem::transmute(box p); // must box since sizeof(p)=2*uint let ret = pthread_create(&mut native, &attr, super::thread_start, arg); assert_eq!(pthread_attr_destroy(&mut attr), 0); if ret != 0 { // be sure to not leak the closure - let _p: Box = mem::transmute(arg); + let _p: Box> = mem::transmute(arg); panic!("failed to spawn native thread: {}", ret); } native @@ -531,17 +543,17 @@ mod tests { use super::Thread; #[test] - fn smoke() { Thread::start(proc (){}).join(); } + fn smoke() { Thread::start(move|| {}).join(); } #[test] - fn data() { assert_eq!(Thread::start(proc () { 1i }).join(), 1); } + fn data() { assert_eq!(Thread::start(move|| { 1i }).join(), 1); } #[test] - fn detached() { Thread::spawn(proc () {}) } + fn detached() { Thread::spawn(move|| {}) } #[test] fn small_stacks() { - assert_eq!(42i, Thread::start_stack(0, proc () 42i).join()); - assert_eq!(42i, Thread::start_stack(1, proc () 42i).join()); + assert_eq!(42i, Thread::start_stack(0, move|| 42i).join()); + assert_eq!(42i, Thread::start_stack(1, move|| 42i).join()); } } diff --git a/src/librustrt/thunk.rs b/src/librustrt/thunk.rs new file mode 100644 index 0000000000000..42e784959909f --- /dev/null +++ b/src/librustrt/thunk.rs @@ -0,0 +1,52 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use alloc::boxed::Box; +use core::kinds::Send; +use core::ops::FnOnce; + +pub struct Thunk { + invoke: Box+Send> +} + +impl Thunk<(),R> { + pub fn new(func: F) -> Thunk<(),R> + where F : FnOnce() -> R, F : Send + { + Thunk::with_arg(move|: ()| func()) + } +} + +impl Thunk { + pub fn with_arg(func: F) -> Thunk + where F : FnOnce(A) -> R, F : Send + { + Thunk { + invoke: box 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/libstd/c_vec.rs b/src/libstd/c_vec.rs index f89876f7245e6..44e7291150ef9 100644 --- a/src/libstd/c_vec.rs +++ b/src/libstd/c_vec.rs @@ -37,19 +37,20 @@ use kinds::Send; use mem; -use ops::Drop; +use ops::{Drop, FnOnce}; use option::Option; use option::Option::{Some, None}; use ptr::RawPtr; use ptr; use raw; use slice::AsSlice; +use thunk::{Thunk}; /// The type representing a foreign chunk of memory pub struct CVec { base: *mut T, len: uint, - dtor: Option, + dtor: Option, } #[unsafe_destructor] @@ -57,7 +58,7 @@ impl Drop for CVec { fn drop(&mut self) { match self.dtor.take() { None => (), - Some(f) => f() + Some(f) => f.invoke(()) } } } @@ -90,15 +91,20 @@ impl CVec { /// /// * base - A foreign pointer to a buffer /// * len - The number of elements in the buffer - /// * dtor - A proc to run when the value is destructed, useful + /// * dtor - A fn to run when the value is destructed, useful /// for freeing the buffer, etc. - pub unsafe fn new_with_dtor(base: *mut T, len: uint, - dtor: proc():Send) -> CVec { + pub unsafe fn new_with_dtor(base: *mut T, + len: uint, + dtor: F) + -> CVec + where F : FnOnce(), F : Send + { assert!(base != ptr::null_mut()); + let dtor: Thunk = Thunk::new(dtor); CVec { base: base, len: len, - dtor: Some(dtor), + dtor: Some(dtor) } } @@ -177,8 +183,9 @@ mod tests { let mem = libc::malloc(n as libc::size_t); if mem.is_null() { ::alloc::oom() } - CVec::new_with_dtor(mem as *mut u8, n, - proc() { libc::free(mem as *mut libc::c_void); }) + CVec::new_with_dtor(mem as *mut u8, + n, + move|| { libc::free(mem as *mut libc::c_void); }) } } @@ -218,8 +225,9 @@ mod tests { #[test] fn test_unwrap() { unsafe { - let cv = CVec::new_with_dtor(1 as *mut int, 0, - proc() { panic!("Don't run this destructor!") }); + let cv = CVec::new_with_dtor(1 as *mut int, + 0, + move|:| panic!("Don't run this destructor!")); let p = cv.unwrap(); assert_eq!(p, 1 as *mut int); } diff --git a/src/libstd/comm/mod.rs b/src/libstd/comm/mod.rs index 6cff5a3dd239d..0a5b3e5771b79 100644 --- a/src/libstd/comm/mod.rs +++ b/src/libstd/comm/mod.rs @@ -72,7 +72,7 @@ //! ``` //! // Create a simple streaming channel //! let (tx, rx) = channel(); -//! spawn(proc() { +//! spawn(move|| { //! tx.send(10i); //! }); //! assert_eq!(rx.recv(), 10i); @@ -87,7 +87,7 @@ //! let (tx, rx) = channel(); //! for i in range(0i, 10i) { //! let tx = tx.clone(); -//! spawn(proc() { +//! spawn(move|| { //! tx.send(i); //! }) //! } @@ -112,7 +112,7 @@ //! //! ``` //! let (tx, rx) = sync_channel::(0); -//! spawn(proc() { +//! spawn(move|| { //! // This will wait for the parent task to start receiving //! tx.send(53); //! }); @@ -465,7 +465,7 @@ impl UnsafeFlavor for Receiver { /// let (tx, rx) = channel(); /// /// // Spawn off an expensive computation -/// spawn(proc() { +/// spawn(move|| { /// # fn expensive_computation() {} /// tx.send(expensive_computation()); /// }); @@ -504,7 +504,7 @@ pub fn channel() -> (Sender, Receiver) { /// // this returns immediately /// tx.send(1i); /// -/// spawn(proc() { +/// spawn(move|| { /// // this will block until the previous message has been received /// tx.send(2i); /// }); @@ -1065,7 +1065,7 @@ mod test { test!(fn smoke_threads() { let (tx, rx) = channel::(); - spawn(proc() { + spawn(move|| { tx.send(1); }); assert_eq!(rx.recv(), 1); @@ -1093,7 +1093,7 @@ mod test { test!(fn port_gone_concurrent() { let (tx, rx) = channel::(); - spawn(proc() { + spawn(move|| { rx.recv(); }); loop { tx.send(1) } @@ -1102,7 +1102,7 @@ mod test { test!(fn port_gone_concurrent_shared() { let (tx, rx) = channel::(); let tx2 = tx.clone(); - spawn(proc() { + spawn(move|| { rx.recv(); }); loop { @@ -1127,7 +1127,7 @@ mod test { test!(fn chan_gone_concurrent() { let (tx, rx) = channel::(); - spawn(proc() { + spawn(move|| { tx.send(1); tx.send(1); }); @@ -1136,7 +1136,7 @@ mod test { test!(fn stress() { let (tx, rx) = channel::(); - spawn(proc() { + spawn(move|| { for _ in range(0u, 10000) { tx.send(1i); } }); for _ in range(0u, 10000) { @@ -1150,7 +1150,7 @@ mod test { let (tx, rx) = channel::(); let (dtx, drx) = channel::<()>(); - spawn(proc() { + spawn(move|| { for _ in range(0, AMT * NTHREADS) { assert_eq!(rx.recv(), 1); } @@ -1163,7 +1163,7 @@ mod test { for _ in range(0, NTHREADS) { let tx = tx.clone(); - spawn(proc() { + spawn(move|| { for _ in range(0, AMT) { tx.send(1); } }); } @@ -1177,7 +1177,7 @@ mod test { let (tx2, rx2) = channel::(); let (tx3, rx3) = channel::<()>(); let tx4 = tx3.clone(); - spawn(proc() { + spawn(move|| { tx1.send(()); for _ in range(0i, 40) { assert_eq!(rx2.recv(), 1); @@ -1185,7 +1185,7 @@ mod test { tx3.send(()); }); rx1.recv(); - spawn(proc() { + spawn(move|| { for _ in range(0i, 40) { tx2.send(1); } @@ -1199,7 +1199,7 @@ mod test { fn recv_from_outside_runtime() { let (tx, rx) = channel::(); let (dtx, drx) = channel(); - spawn(proc() { + spawn(move|| { for _ in range(0i, 40) { assert_eq!(rx.recv(), 1); } @@ -1217,12 +1217,12 @@ mod test { let (tx2, rx2) = channel::(); let (tx3, rx3) = channel::<()>(); let tx4 = tx3.clone(); - spawn(proc() { + spawn(move|| { assert_eq!(rx1.recv(), 1); tx2.send(2); tx4.send(()); }); - spawn(proc() { + spawn(move|| { tx1.send(1); assert_eq!(rx2.recv(), 2); tx3.send(()); @@ -1252,7 +1252,7 @@ mod test { test!(fn oneshot_single_thread_recv_chan_close() { // Receiving on a closed chan will panic - let res = task::try(proc() { + let res = task::try(move|| { let (tx, rx) = channel::(); drop(tx); rx.recv(); @@ -1312,7 +1312,7 @@ mod test { test!(fn oneshot_multi_task_recv_then_send() { let (tx, rx) = channel::>(); - spawn(proc() { + spawn(move|| { assert!(rx.recv() == box 10); }); @@ -1321,10 +1321,10 @@ mod test { test!(fn oneshot_multi_task_recv_then_close() { let (tx, rx) = channel::>(); - spawn(proc() { + spawn(move|| { drop(tx); }); - let res = task::try(proc() { + let res = task::try(move|| { assert!(rx.recv() == box 10); }); assert!(res.is_err()); @@ -1333,7 +1333,7 @@ mod test { test!(fn oneshot_multi_thread_close_stress() { for _ in range(0, stress_factor()) { let (tx, rx) = channel::(); - spawn(proc() { + spawn(move|| { drop(rx); }); drop(tx); @@ -1343,10 +1343,10 @@ mod test { test!(fn oneshot_multi_thread_send_close_stress() { for _ in range(0, stress_factor()) { let (tx, rx) = channel::(); - spawn(proc() { + spawn(move|| { drop(rx); }); - let _ = task::try(proc() { + let _ = task::try(move|| { tx.send(1); }); } @@ -1355,14 +1355,14 @@ mod test { test!(fn oneshot_multi_thread_recv_close_stress() { for _ in range(0, stress_factor()) { let (tx, rx) = channel::(); - spawn(proc() { - let res = task::try(proc() { + spawn(move|| { + let res = task::try(move|| { rx.recv(); }); assert!(res.is_err()); }); - spawn(proc() { - spawn(proc() { + spawn(move|| { + spawn(move|| { drop(tx); }); }); @@ -1372,10 +1372,10 @@ mod test { test!(fn oneshot_multi_thread_send_recv_stress() { for _ in range(0, stress_factor()) { let (tx, rx) = channel(); - spawn(proc() { + spawn(move|| { tx.send(box 10i); }); - spawn(proc() { + spawn(move|| { assert!(rx.recv() == box 10i); }); } @@ -1391,7 +1391,7 @@ mod test { fn send(tx: Sender>, i: int) { if i == 10 { return } - spawn(proc() { + spawn(move|| { tx.send(box i); send(tx, i + 1); }); @@ -1400,7 +1400,7 @@ mod test { fn recv(rx: Receiver>, i: int) { if i == 10 { return } - spawn(proc() { + spawn(move|| { assert!(rx.recv() == box i); recv(rx, i + 1); }); @@ -1420,7 +1420,7 @@ mod test { let total = stress_factor() + 100; for _ in range(0, total) { let tx = tx.clone(); - spawn(proc() { + spawn(move|| { tx.send(()); }); } @@ -1434,7 +1434,7 @@ mod test { let (tx, rx) = channel::(); let (total_tx, total_rx) = channel::(); - spawn(proc() { + spawn(move|| { let mut acc = 0; for x in rx.iter() { acc += x; @@ -1453,7 +1453,7 @@ mod test { let (tx, rx) = channel::(); let (count_tx, count_rx) = channel(); - spawn(proc() { + spawn(move|| { let mut count = 0; for x in rx.iter() { if count >= 3 { @@ -1477,7 +1477,7 @@ mod test { let (tx1, rx1) = channel::(); let (tx2, rx2) = channel::<()>(); let (tx3, rx3) = channel::<()>(); - spawn(proc() { + spawn(move|| { rx2.recv(); tx1.send(1); tx3.send(()); @@ -1501,7 +1501,7 @@ mod test { test!(fn destroy_upgraded_shared_port_when_sender_still_active() { let (tx, rx) = channel(); let (tx2, rx2) = channel(); - spawn(proc() { + spawn(move|| { rx.recv(); // wait on a oneshot drop(rx); // destroy a shared tx2.send(()); @@ -1522,7 +1522,7 @@ mod test { use rustrt::thread::Thread; let (tx, rx) = channel(); - let t = Thread::start(proc() { + let t = Thread::start(move|| { for _ in range(0u, 1000) { tx.send(()); } @@ -1538,7 +1538,7 @@ mod test { let (tx, rx) = channel(); let (cdone, pdone) = channel(); - let t = Thread::start(proc() { + let t = Thread::start(move|| { let mut hits = 0u; while hits < 10 { match rx.try_recv() { @@ -1591,7 +1591,7 @@ mod sync_tests { test!(fn smoke_threads() { let (tx, rx) = sync_channel::(0); - spawn(proc() { + spawn(move|| { tx.send(1); }); assert_eq!(rx.recv(), 1); @@ -1613,7 +1613,7 @@ mod sync_tests { test!(fn port_gone_concurrent() { let (tx, rx) = sync_channel::(0); - spawn(proc() { + spawn(move|| { rx.recv(); }); loop { tx.send(1) } @@ -1622,7 +1622,7 @@ mod sync_tests { test!(fn port_gone_concurrent_shared() { let (tx, rx) = sync_channel::(0); let tx2 = tx.clone(); - spawn(proc() { + spawn(move|| { rx.recv(); }); loop { @@ -1647,7 +1647,7 @@ mod sync_tests { test!(fn chan_gone_concurrent() { let (tx, rx) = sync_channel::(0); - spawn(proc() { + spawn(move|| { tx.send(1); tx.send(1); }); @@ -1656,7 +1656,7 @@ mod sync_tests { test!(fn stress() { let (tx, rx) = sync_channel::(0); - spawn(proc() { + spawn(move|| { for _ in range(0u, 10000) { tx.send(1); } }); for _ in range(0u, 10000) { @@ -1670,7 +1670,7 @@ mod sync_tests { let (tx, rx) = sync_channel::(0); let (dtx, drx) = sync_channel::<()>(0); - spawn(proc() { + spawn(move|| { for _ in range(0, AMT * NTHREADS) { assert_eq!(rx.recv(), 1); } @@ -1683,7 +1683,7 @@ mod sync_tests { for _ in range(0, NTHREADS) { let tx = tx.clone(); - spawn(proc() { + spawn(move|| { for _ in range(0, AMT) { tx.send(1); } }); } @@ -1712,7 +1712,7 @@ mod sync_tests { test!(fn oneshot_single_thread_recv_chan_close() { // Receiving on a closed chan will panic - let res = task::try(proc() { + let res = task::try(move|| { let (tx, rx) = sync_channel::(0); drop(tx); rx.recv(); @@ -1777,7 +1777,7 @@ mod sync_tests { test!(fn oneshot_multi_task_recv_then_send() { let (tx, rx) = sync_channel::>(0); - spawn(proc() { + spawn(move|| { assert!(rx.recv() == box 10); }); @@ -1786,10 +1786,10 @@ mod sync_tests { test!(fn oneshot_multi_task_recv_then_close() { let (tx, rx) = sync_channel::>(0); - spawn(proc() { + spawn(move|| { drop(tx); }); - let res = task::try(proc() { + let res = task::try(move|| { assert!(rx.recv() == box 10); }); assert!(res.is_err()); @@ -1798,7 +1798,7 @@ mod sync_tests { test!(fn oneshot_multi_thread_close_stress() { for _ in range(0, stress_factor()) { let (tx, rx) = sync_channel::(0); - spawn(proc() { + spawn(move|| { drop(rx); }); drop(tx); @@ -1808,10 +1808,10 @@ mod sync_tests { test!(fn oneshot_multi_thread_send_close_stress() { for _ in range(0, stress_factor()) { let (tx, rx) = sync_channel::(0); - spawn(proc() { + spawn(move|| { drop(rx); }); - let _ = task::try(proc() { + let _ = task::try(move|| { tx.send(1); }); } @@ -1820,14 +1820,14 @@ mod sync_tests { test!(fn oneshot_multi_thread_recv_close_stress() { for _ in range(0, stress_factor()) { let (tx, rx) = sync_channel::(0); - spawn(proc() { - let res = task::try(proc() { + spawn(move|| { + let res = task::try(move|| { rx.recv(); }); assert!(res.is_err()); }); - spawn(proc() { - spawn(proc() { + spawn(move|| { + spawn(move|| { drop(tx); }); }); @@ -1837,10 +1837,10 @@ mod sync_tests { test!(fn oneshot_multi_thread_send_recv_stress() { for _ in range(0, stress_factor()) { let (tx, rx) = sync_channel::>(0); - spawn(proc() { + spawn(move|| { tx.send(box 10i); }); - spawn(proc() { + spawn(move|| { assert!(rx.recv() == box 10i); }); } @@ -1856,7 +1856,7 @@ mod sync_tests { fn send(tx: SyncSender>, i: int) { if i == 10 { return } - spawn(proc() { + spawn(move|| { tx.send(box i); send(tx, i + 1); }); @@ -1865,7 +1865,7 @@ mod sync_tests { fn recv(rx: Receiver>, i: int) { if i == 10 { return } - spawn(proc() { + spawn(move|| { assert!(rx.recv() == box i); recv(rx, i + 1); }); @@ -1885,7 +1885,7 @@ mod sync_tests { let total = stress_factor() + 100; for _ in range(0, total) { let tx = tx.clone(); - spawn(proc() { + spawn(move|| { tx.send(()); }); } @@ -1899,7 +1899,7 @@ mod sync_tests { let (tx, rx) = sync_channel::(0); let (total_tx, total_rx) = sync_channel::(0); - spawn(proc() { + spawn(move|| { let mut acc = 0; for x in rx.iter() { acc += x; @@ -1918,7 +1918,7 @@ mod sync_tests { let (tx, rx) = sync_channel::(0); let (count_tx, count_rx) = sync_channel(0); - spawn(proc() { + spawn(move|| { let mut count = 0; for x in rx.iter() { if count >= 3 { @@ -1942,7 +1942,7 @@ mod sync_tests { let (tx1, rx1) = sync_channel::(1); let (tx2, rx2) = sync_channel::<()>(1); let (tx3, rx3) = sync_channel::<()>(1); - spawn(proc() { + spawn(move|| { rx2.recv(); tx1.send(1); tx3.send(()); @@ -1966,7 +1966,7 @@ mod sync_tests { test!(fn destroy_upgraded_shared_port_when_sender_still_active() { let (tx, rx) = sync_channel::<()>(0); let (tx2, rx2) = sync_channel::<()>(0); - spawn(proc() { + spawn(move|| { rx.recv(); // wait on a oneshot drop(rx); // destroy a shared tx2.send(()); @@ -1988,7 +1988,7 @@ mod sync_tests { let (tx, rx) = sync_channel::<()>(0); let (cdone, pdone) = channel(); - let t = Thread::start(proc() { + let t = Thread::start(move|| { let mut hits = 0u; while hits < 10 { match rx.try_recv() { @@ -2008,20 +2008,20 @@ mod sync_tests { test!(fn send_opt1() { let (tx, rx) = sync_channel::(0); - spawn(proc() { rx.recv(); }); + spawn(move|| { rx.recv(); }); assert_eq!(tx.send_opt(1), Ok(())); }) test!(fn send_opt2() { let (tx, rx) = sync_channel::(0); - spawn(proc() { drop(rx); }); + spawn(move|| { drop(rx); }); assert_eq!(tx.send_opt(1), Err(1)); }) test!(fn send_opt3() { let (tx, rx) = sync_channel::(1); assert_eq!(tx.send_opt(1), Ok(())); - spawn(proc() { drop(rx); }); + spawn(move|| { drop(rx); }); assert_eq!(tx.send_opt(1), Err(1)); }) @@ -2030,11 +2030,11 @@ mod sync_tests { let tx2 = tx.clone(); let (done, donerx) = channel(); let done2 = done.clone(); - spawn(proc() { + spawn(move|| { assert_eq!(tx.send_opt(1), Err(1)); done.send(()); }); - spawn(proc() { + spawn(move|| { assert_eq!(tx2.send_opt(2), Err(2)); done2.send(()); }); @@ -2063,7 +2063,7 @@ mod sync_tests { test!(fn try_send4() { let (tx, rx) = sync_channel::(0); - spawn(proc() { + spawn(move|| { for _ in range(0u, 1000) { task::deschedule(); } assert_eq!(tx.try_send(1), Ok(())); }); @@ -2075,7 +2075,7 @@ mod sync_tests { let (tx1, rx1) = sync_channel::<()>(3); let (tx2, rx2) = sync_channel::<()>(3); - spawn(proc() { + spawn(move|| { rx1.recv(); tx2.try_send(()).unwrap(); }); diff --git a/src/libstd/comm/mpsc_queue.rs b/src/libstd/comm/mpsc_queue.rs index d4249abc3dda1..db4e3eac44950 100644 --- a/src/libstd/comm/mpsc_queue.rs +++ b/src/libstd/comm/mpsc_queue.rs @@ -178,7 +178,7 @@ mod tests { for _ in range(0, nthreads) { let tx = tx.clone(); let q = q.clone(); - spawn(proc() { + spawn(move|| { for i in range(0, nmsgs) { q.push(i); } diff --git a/src/libstd/comm/select.rs b/src/libstd/comm/select.rs index 3191519815ae4..e145b0df7f32a 100644 --- a/src/libstd/comm/select.rs +++ b/src/libstd/comm/select.rs @@ -403,7 +403,7 @@ mod test { let (_tx2, rx2) = channel::(); let (tx3, rx3) = channel::(); - spawn(proc() { + spawn(move|| { for _ in range(0u, 20) { task::deschedule(); } tx1.send(1); rx3.recv(); @@ -426,7 +426,7 @@ mod test { let (tx2, rx2) = channel::(); let (tx3, rx3) = channel::<()>(); - spawn(proc() { + spawn(move|| { for _ in range(0u, 20) { task::deschedule(); } tx1.send(1); tx2.send(2); @@ -452,7 +452,7 @@ mod test { let (tx2, rx2) = channel::(); let (tx3, rx3) = channel::<()>(); - spawn(proc() { + spawn(move|| { for i in range(0, AMT) { if i % 2 == 0 { tx1.send(i); @@ -477,7 +477,7 @@ mod test { let (_tx2, rx2) = channel::(); let (tx3, rx3) = channel::<()>(); - spawn(proc() { + spawn(move|| { rx3.recv(); tx1.clone(); assert_eq!(rx3.try_recv(), Err(Empty)); @@ -498,7 +498,7 @@ mod test { let (_tx2, rx2) = channel::(); let (tx3, rx3) = channel::<()>(); - spawn(proc() { + spawn(move|| { rx3.recv(); tx1.clone(); assert_eq!(rx3.try_recv(), Err(Empty)); @@ -518,7 +518,7 @@ mod test { let (tx1, rx1) = channel::<()>(); let (tx2, rx2) = channel::<()>(); let (tx3, rx3) = channel::<()>(); - spawn(proc() { + spawn(move|| { let s = Select::new(); let mut h1 = s.handle(&rx1); let mut h2 = s.handle(&rx2); @@ -624,7 +624,7 @@ mod test { test!(fn oneshot_data_waiting() { let (tx1, rx1) = channel(); let (tx2, rx2) = channel(); - spawn(proc() { + spawn(move|| { select! { () = rx1.recv() => {} } @@ -643,7 +643,7 @@ mod test { tx1.send(()); rx1.recv(); rx1.recv(); - spawn(proc() { + spawn(move|| { select! { () = rx1.recv() => {} } @@ -661,7 +661,7 @@ mod test { drop(tx1.clone()); tx1.send(()); rx1.recv(); - spawn(proc() { + spawn(move|| { select! { () = rx1.recv() => {} } @@ -683,7 +683,7 @@ mod test { test!(fn sync2() { let (tx, rx) = sync_channel::(0); - spawn(proc() { + spawn(move|| { for _ in range(0u, 100) { task::deschedule() } tx.send(1); }); @@ -695,8 +695,8 @@ mod test { test!(fn sync3() { let (tx1, rx1) = sync_channel::(0); let (tx2, rx2): (Sender, Receiver) = channel(); - spawn(proc() { tx1.send(1); }); - spawn(proc() { tx2.send(2); }); + spawn(move|| { tx1.send(1); }); + spawn(move|| { tx2.send(2); }); select! { n = rx1.recv() => { assert_eq!(n, 1); diff --git a/src/libstd/comm/spsc_queue.rs b/src/libstd/comm/spsc_queue.rs index a6b4ab71bacc1..db8fff772a4d3 100644 --- a/src/libstd/comm/spsc_queue.rs +++ b/src/libstd/comm/spsc_queue.rs @@ -316,7 +316,7 @@ mod test { let (tx, rx) = channel(); let q2 = q.clone(); - spawn(proc() { + spawn(move|| { for _ in range(0u, 100000) { loop { match q2.pop() { diff --git a/src/libstd/io/comm_adapters.rs b/src/libstd/io/comm_adapters.rs index 4ec1a3764db66..308dc09410138 100644 --- a/src/libstd/io/comm_adapters.rs +++ b/src/libstd/io/comm_adapters.rs @@ -161,7 +161,7 @@ mod test { #[test] fn test_rx_reader() { let (tx, rx) = channel(); - task::spawn(proc() { + task::spawn(move|| { tx.send(vec![1u8, 2u8]); tx.send(vec![]); tx.send(vec![3u8, 4u8]); @@ -203,7 +203,7 @@ mod test { #[test] fn test_rx_buffer() { let (tx, rx) = channel(); - task::spawn(proc() { + task::spawn(move|| { tx.send(b"he".to_vec()); tx.send(b"llo wo".to_vec()); tx.send(b"".to_vec()); @@ -229,7 +229,7 @@ mod test { writer.write_be_u32(42).unwrap(); let wanted = vec![0u8, 0u8, 0u8, 42u8]; - let got = match task::try(proc() { rx.recv() }) { + let got = match task::try(move|| { rx.recv() }) { Ok(got) => got, Err(_) => panic!(), }; diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index bad86258bb85d..d21e0f57b0706 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -119,7 +119,7 @@ //! for stream in acceptor.incoming() { //! match stream { //! Err(e) => { /* connection failed */ } -//! Ok(stream) => spawn(proc() { +//! Ok(stream) => spawn(move|| { //! // connection succeeded //! handle_client(stream) //! }) diff --git a/src/libstd/io/net/pipe.rs b/src/libstd/io/net/pipe.rs index ec997b71986cc..9f2f41c002108 100644 --- a/src/libstd/io/net/pipe.rs +++ b/src/libstd/io/net/pipe.rs @@ -273,13 +273,16 @@ mod tests { use io::fs::PathExtensions; use time::Duration; - pub fn smalltest(server: proc(UnixStream):Send, client: proc(UnixStream):Send) { + pub fn smalltest(server: F, client: G) + where F : FnOnce(UnixStream), F : Send, + G : FnOnce(UnixStream), G : Send + { let path1 = next_test_unix(); let path2 = path1.clone(); let mut acceptor = UnixListener::bind(&path1).listen(); - spawn(proc() { + spawn(move|| { match UnixStream::connect(&path2) { Ok(c) => client(c), Err(e) => panic!("failed connect: {}", e), @@ -321,11 +324,11 @@ mod tests { #[test] fn smoke() { - smalltest(proc(mut server) { + smalltest(move |mut server| { let mut buf = [0]; server.read(&mut buf).unwrap(); assert!(buf[0] == 99); - }, proc(mut client) { + }, move|mut client| { client.write(&[99]).unwrap(); }) } @@ -333,18 +336,18 @@ mod tests { #[cfg_attr(windows, ignore)] // FIXME(#12516) #[test] fn read_eof() { - smalltest(proc(mut server) { + smalltest(move|mut server| { let mut buf = [0]; assert!(server.read(&mut buf).is_err()); assert!(server.read(&mut buf).is_err()); - }, proc(_client) { + }, move|_client| { // drop the client }) } #[test] fn write_begone() { - smalltest(proc(mut server) { + smalltest(move|mut server| { let buf = [0]; loop { match server.write(&buf) { @@ -358,7 +361,7 @@ mod tests { } } } - }, proc(_client) { + }, move|_client| { // drop the client }) } @@ -374,7 +377,7 @@ mod tests { Err(e) => panic!("failed listen: {}", e), }; - spawn(proc() { + spawn(move|| { for _ in range(0u, times) { let mut stream = UnixStream::connect(&path2); match stream.write(&[100]) { @@ -408,7 +411,7 @@ mod tests { let addr = next_test_unix(); let mut acceptor = UnixListener::bind(&addr).listen(); - spawn(proc() { + spawn(move|| { let mut s = UnixStream::connect(&addr); let mut buf = [0, 0]; debug!("client reading"); @@ -424,7 +427,7 @@ mod tests { let (tx1, rx1) = channel(); let (tx2, rx2) = channel(); - spawn(proc() { + spawn(move|| { let mut s2 = s2; rx1.recv(); debug!("writer writing"); @@ -447,7 +450,7 @@ mod tests { let (tx1, rx) = channel(); let tx2 = tx1.clone(); - spawn(proc() { + spawn(move|| { let mut s = UnixStream::connect(&addr); s.write(&[1]).unwrap(); rx.recv(); @@ -459,7 +462,7 @@ mod tests { let s2 = s1.clone(); let (done, rx) = channel(); - spawn(proc() { + spawn(move|| { let mut s2 = s2; let mut buf = [0, 0]; s2.read(&mut buf).unwrap(); @@ -478,7 +481,7 @@ mod tests { let addr = next_test_unix(); let mut acceptor = UnixListener::bind(&addr).listen(); - spawn(proc() { + spawn(move|| { let mut s = UnixStream::connect(&addr); let buf = &mut [0, 1]; s.read(buf).unwrap(); @@ -489,7 +492,7 @@ mod tests { let s2 = s1.clone(); let (tx, rx) = channel(); - spawn(proc() { + spawn(move|| { let mut s2 = s2; s2.write(&[1]).unwrap(); tx.send(()); @@ -536,7 +539,7 @@ mod tests { // continue to receive any pending connections. let (tx, rx) = channel(); let addr2 = addr.clone(); - spawn(proc() { + spawn(move|| { tx.send(UnixStream::connect(&addr2).unwrap()); }); let l = rx.recv(); @@ -554,7 +557,7 @@ mod tests { // Unset the timeout and make sure that this always blocks. a.set_timeout(None); let addr2 = addr.clone(); - spawn(proc() { + spawn(move|| { drop(UnixStream::connect(&addr2).unwrap()); }); a.accept().unwrap(); @@ -592,7 +595,7 @@ mod tests { let addr = next_test_unix(); let a = UnixListener::bind(&addr).listen().unwrap(); let (_tx, rx) = channel::<()>(); - spawn(proc() { + spawn(move|| { let mut a = a; let _s = a.accept().unwrap(); let _ = rx.recv_opt(); @@ -629,7 +632,7 @@ mod tests { let addr = next_test_unix(); let a = UnixListener::bind(&addr).listen().unwrap(); let (_tx, rx) = channel::<()>(); - spawn(proc() { + spawn(move|| { let mut a = a; let _s = a.accept().unwrap(); let _ = rx.recv_opt(); @@ -638,7 +641,7 @@ mod tests { let mut s = UnixStream::connect(&addr).unwrap(); let s2 = s.clone(); let (tx, rx) = channel(); - spawn(proc() { + spawn(move|| { let mut s2 = s2; assert!(s2.read(&mut [0]).is_err()); tx.send(()); @@ -655,7 +658,7 @@ mod tests { let addr = next_test_unix(); let mut a = UnixListener::bind(&addr).listen().unwrap(); let (tx, rx) = channel::<()>(); - spawn(proc() { + spawn(move|| { let mut s = UnixStream::connect(&addr).unwrap(); rx.recv(); assert!(s.write(&[0]).is_ok()); @@ -693,7 +696,7 @@ mod tests { let addr = next_test_unix(); let mut a = UnixListener::bind(&addr).listen().unwrap(); let (tx, rx) = channel::<()>(); - spawn(proc() { + spawn(move|| { let mut s = UnixStream::connect(&addr).unwrap(); rx.recv(); let mut amt = 0; @@ -722,7 +725,7 @@ mod tests { let addr = next_test_unix(); let mut a = UnixListener::bind(&addr).listen().unwrap(); let (tx, rx) = channel::<()>(); - spawn(proc() { + spawn(move|| { let mut s = UnixStream::connect(&addr).unwrap(); rx.recv(); assert!(s.write(&[0]).is_ok()); @@ -749,7 +752,7 @@ mod tests { let addr = next_test_unix(); let mut a = UnixListener::bind(&addr).listen().unwrap(); let (tx, rx) = channel::<()>(); - spawn(proc() { + spawn(move|| { let mut s = UnixStream::connect(&addr).unwrap(); rx.recv(); assert!(s.write(&[0]).is_ok()); @@ -759,7 +762,7 @@ mod tests { let mut s = a.accept().unwrap(); let s2 = s.clone(); let (tx2, rx2) = channel(); - spawn(proc() { + spawn(move|| { let mut s2 = s2; assert!(s2.read(&mut [0]).is_ok()); tx2.send(()); @@ -781,10 +784,10 @@ mod tests { let mut a2 = a.clone(); let addr2 = addr.clone(); - spawn(proc() { + spawn(move|| { let _ = UnixStream::connect(&addr2); }); - spawn(proc() { + spawn(move|| { let _ = UnixStream::connect(&addr); }); @@ -804,14 +807,14 @@ mod tests { let (tx, rx) = channel(); let tx2 = tx.clone(); - spawn(proc() { let mut a = a; tx.send(a.accept()) }); - spawn(proc() { let mut a = a2; tx2.send(a.accept()) }); + spawn(move|| { let mut a = a; tx.send(a.accept()) }); + spawn(move|| { let mut a = a2; tx2.send(a.accept()) }); let addr2 = addr.clone(); - spawn(proc() { + spawn(move|| { let _ = UnixStream::connect(&addr2); }); - spawn(proc() { + spawn(move|| { let _ = UnixStream::connect(&addr); }); @@ -837,7 +840,7 @@ mod tests { let mut a2 = a.clone(); let (tx, rx) = channel(); - spawn(proc() { + spawn(move|| { let mut a = a; tx.send(a.accept()); }); diff --git a/src/libstd/io/net/tcp.rs b/src/libstd/io/net/tcp.rs index a7b1b077eff0b..3c38e23183fe7 100644 --- a/src/libstd/io/net/tcp.rs +++ b/src/libstd/io/net/tcp.rs @@ -140,7 +140,7 @@ impl TcpStream { /// let mut stream = TcpStream::connect("127.0.0.1:34254").unwrap(); /// let stream2 = stream.clone(); /// - /// spawn(proc() { + /// spawn(move|| { /// // close this stream after one second /// timer::sleep(Duration::seconds(1)); /// let mut stream = stream2; @@ -293,7 +293,7 @@ impl sys_common::AsInner for TcpStream { /// for stream in acceptor.incoming() { /// match stream { /// Err(e) => { /* connection failed */ } -/// Ok(stream) => spawn(proc() { +/// Ok(stream) => spawn(move|| { /// // connection succeeded /// handle_client(stream) /// }) @@ -420,7 +420,7 @@ impl TcpAcceptor { /// let mut a = TcpListener::bind("127.0.0.1:8482").listen().unwrap(); /// let a2 = a.clone(); /// - /// spawn(proc() { + /// spawn(move|| { /// let mut a2 = a2; /// for socket in a2.incoming() { /// match socket { @@ -509,7 +509,7 @@ mod test { let listener = TcpListener::bind(socket_addr); let mut acceptor = listener.listen(); - spawn(proc() { + spawn(move|| { let mut stream = TcpStream::connect(("localhost", socket_addr.port)); stream.write(&[144]).unwrap(); }); @@ -525,7 +525,7 @@ mod test { let addr = next_test_ip4(); let mut acceptor = TcpListener::bind(addr).listen(); - spawn(proc() { + spawn(move|| { let mut stream = TcpStream::connect(("localhost", addr.port)); stream.write(&[64]).unwrap(); }); @@ -541,7 +541,7 @@ mod test { let addr = next_test_ip4(); let mut acceptor = TcpListener::bind(addr).listen(); - spawn(proc() { + spawn(move|| { let mut stream = TcpStream::connect(("127.0.0.1", addr.port)); stream.write(&[44]).unwrap(); }); @@ -557,7 +557,7 @@ mod test { let addr = next_test_ip6(); let mut acceptor = TcpListener::bind(addr).listen(); - spawn(proc() { + spawn(move|| { let mut stream = TcpStream::connect(("::1", addr.port)); stream.write(&[66]).unwrap(); }); @@ -573,7 +573,7 @@ mod test { let addr = next_test_ip4(); let mut acceptor = TcpListener::bind(addr).listen(); - spawn(proc() { + spawn(move|| { let mut stream = TcpStream::connect(addr); stream.write(&[99]).unwrap(); }); @@ -589,7 +589,7 @@ mod test { let addr = next_test_ip6(); let mut acceptor = TcpListener::bind(addr).listen(); - spawn(proc() { + spawn(move|| { let mut stream = TcpStream::connect(addr); stream.write(&[99]).unwrap(); }); @@ -605,7 +605,7 @@ mod test { let addr = next_test_ip4(); let mut acceptor = TcpListener::bind(addr).listen(); - spawn(proc() { + spawn(move|| { let _stream = TcpStream::connect(addr); // Close }); @@ -621,7 +621,7 @@ mod test { let addr = next_test_ip6(); let mut acceptor = TcpListener::bind(addr).listen(); - spawn(proc() { + spawn(move|| { let _stream = TcpStream::connect(addr); // Close }); @@ -637,7 +637,7 @@ mod test { let addr = next_test_ip4(); let mut acceptor = TcpListener::bind(addr).listen(); - spawn(proc() { + spawn(move|| { let _stream = TcpStream::connect(addr); // Close }); @@ -661,7 +661,7 @@ mod test { let addr = next_test_ip6(); let mut acceptor = TcpListener::bind(addr).listen(); - spawn(proc() { + spawn(move|| { let _stream = TcpStream::connect(addr); // Close }); @@ -686,7 +686,7 @@ mod test { let mut acceptor = TcpListener::bind(addr).listen(); let (tx, rx) = channel(); - spawn(proc() { + spawn(move|| { drop(TcpStream::connect(addr)); tx.send(()); }); @@ -711,7 +711,7 @@ mod test { let mut acceptor = TcpListener::bind(addr).listen(); let (tx, rx) = channel(); - spawn(proc() { + spawn(move|| { drop(TcpStream::connect(addr)); tx.send(()); }); @@ -736,7 +736,7 @@ mod test { let max = 10u; let mut acceptor = TcpListener::bind(addr).listen(); - spawn(proc() { + spawn(move|| { for _ in range(0, max) { let mut stream = TcpStream::connect(addr); stream.write(&[99]).unwrap(); @@ -756,7 +756,7 @@ mod test { let max = 10u; let mut acceptor = TcpListener::bind(addr).listen(); - spawn(proc() { + spawn(move|| { for _ in range(0, max) { let mut stream = TcpStream::connect(addr); stream.write(&[99]).unwrap(); @@ -776,11 +776,11 @@ mod test { static MAX: int = 10; let acceptor = TcpListener::bind(addr).listen(); - spawn(proc() { + spawn(move|| { let mut acceptor = acceptor; for (i, stream) in acceptor.incoming().enumerate().take(MAX as uint) { // Start another task to handle the connection - spawn(proc() { + spawn(move|| { let mut stream = stream; let mut buf = [0]; stream.read(&mut buf).unwrap(); @@ -795,7 +795,7 @@ mod test { fn connect(i: int, addr: SocketAddr) { if i == MAX { return } - spawn(proc() { + spawn(move|| { debug!("connecting"); let mut stream = TcpStream::connect(addr); // Connect again before writing @@ -812,11 +812,11 @@ mod test { static MAX: int = 10; let acceptor = TcpListener::bind(addr).listen(); - spawn(proc() { + spawn(move|| { let mut acceptor = acceptor; for (i, stream) in acceptor.incoming().enumerate().take(MAX as uint) { // Start another task to handle the connection - spawn(proc() { + spawn(move|| { let mut stream = stream; let mut buf = [0]; stream.read(&mut buf).unwrap(); @@ -831,7 +831,7 @@ mod test { fn connect(i: int, addr: SocketAddr) { if i == MAX { return } - spawn(proc() { + spawn(move|| { debug!("connecting"); let mut stream = TcpStream::connect(addr); // Connect again before writing @@ -848,11 +848,11 @@ mod test { let addr = next_test_ip4(); let acceptor = TcpListener::bind(addr).listen(); - spawn(proc() { + spawn(move|| { let mut acceptor = acceptor; for stream in acceptor.incoming().take(MAX as uint) { // Start another task to handle the connection - spawn(proc() { + spawn(move|| { let mut stream = stream; let mut buf = [0]; stream.read(&mut buf).unwrap(); @@ -867,7 +867,7 @@ mod test { fn connect(i: int, addr: SocketAddr) { if i == MAX { return } - spawn(proc() { + spawn(move|| { debug!("connecting"); let mut stream = TcpStream::connect(addr); // Connect again before writing @@ -884,11 +884,11 @@ mod test { let addr = next_test_ip6(); let acceptor = TcpListener::bind(addr).listen(); - spawn(proc() { + spawn(move|| { let mut acceptor = acceptor; for stream in acceptor.incoming().take(MAX as uint) { // Start another task to handle the connection - spawn(proc() { + spawn(move|| { let mut stream = stream; let mut buf = [0]; stream.read(&mut buf).unwrap(); @@ -903,7 +903,7 @@ mod test { fn connect(i: int, addr: SocketAddr) { if i == MAX { return } - spawn(proc() { + spawn(move|| { debug!("connecting"); let mut stream = TcpStream::connect(addr); // Connect again before writing @@ -926,7 +926,7 @@ mod test { pub fn peer_name(addr: SocketAddr) { let acceptor = TcpListener::bind(addr).listen(); - spawn(proc() { + spawn(move|| { let mut acceptor = acceptor; acceptor.accept().unwrap(); }); @@ -961,7 +961,7 @@ mod test { fn partial_read() { let addr = next_test_ip4(); let (tx, rx) = channel(); - spawn(proc() { + spawn(move|| { let mut srv = TcpListener::bind(addr).listen().unwrap(); tx.send(()); let mut cl = srv.accept().unwrap(); @@ -998,7 +998,7 @@ mod test { let addr = next_test_ip4(); let (tx, rx) = channel(); - spawn(proc() { + spawn(move|| { rx.recv(); let _stream = TcpStream::connect(addr).unwrap(); // Close @@ -1023,7 +1023,7 @@ mod test { let addr = next_test_ip4(); let mut acceptor = TcpListener::bind(addr).listen(); - spawn(proc() { + spawn(move|| { let mut s = TcpStream::connect(addr); let mut buf = [0, 0]; assert_eq!(s.read(&mut buf), Ok(1)); @@ -1036,7 +1036,7 @@ mod test { let (tx1, rx1) = channel(); let (tx2, rx2) = channel(); - spawn(proc() { + spawn(move|| { let mut s2 = s2; rx1.recv(); s2.write(&[1]).unwrap(); @@ -1055,7 +1055,7 @@ mod test { let (tx1, rx) = channel(); let tx2 = tx1.clone(); - spawn(proc() { + spawn(move|| { let mut s = TcpStream::connect(addr); s.write(&[1]).unwrap(); rx.recv(); @@ -1067,7 +1067,7 @@ mod test { let s2 = s1.clone(); let (done, rx) = channel(); - spawn(proc() { + spawn(move|| { let mut s2 = s2; let mut buf = [0, 0]; s2.read(&mut buf).unwrap(); @@ -1086,7 +1086,7 @@ mod test { let addr = next_test_ip4(); let mut acceptor = TcpListener::bind(addr).listen(); - spawn(proc() { + spawn(move|| { let mut s = TcpStream::connect(addr); let mut buf = [0, 1]; s.read(&mut buf).unwrap(); @@ -1097,7 +1097,7 @@ mod test { let s2 = s1.clone(); let (done, rx) = channel(); - spawn(proc() { + spawn(move|| { let mut s2 = s2; s2.write(&[1]).unwrap(); done.send(()); @@ -1111,7 +1111,7 @@ mod test { fn shutdown_smoke() { let addr = next_test_ip4(); let a = TcpListener::bind(addr).unwrap().listen(); - spawn(proc() { + spawn(move|| { let mut a = a; let mut c = a.accept().unwrap(); assert_eq!(c.read_to_end(), Ok(vec!())); @@ -1145,7 +1145,7 @@ mod test { // flakiness. if !cfg!(target_os = "freebsd") { let (tx, rx) = channel(); - spawn(proc() { + spawn(move|| { tx.send(TcpStream::connect(addr).unwrap()); }); let _l = rx.recv(); @@ -1162,7 +1162,7 @@ mod test { // Unset the timeout and make sure that this always blocks. a.set_timeout(None); - spawn(proc() { + spawn(move|| { drop(TcpStream::connect(addr).unwrap()); }); a.accept().unwrap(); @@ -1173,7 +1173,7 @@ mod test { let addr = next_test_ip4(); let a = TcpListener::bind(addr).listen().unwrap(); let (_tx, rx) = channel::<()>(); - spawn(proc() { + spawn(move|| { let mut a = a; let _s = a.accept().unwrap(); let _ = rx.recv_opt(); @@ -1210,7 +1210,7 @@ mod test { let addr = next_test_ip4(); let a = TcpListener::bind(addr).listen().unwrap(); let (_tx, rx) = channel::<()>(); - spawn(proc() { + spawn(move|| { let mut a = a; let _s = a.accept().unwrap(); let _ = rx.recv_opt(); @@ -1219,7 +1219,7 @@ mod test { let mut s = TcpStream::connect(addr).unwrap(); let s2 = s.clone(); let (tx, rx) = channel(); - spawn(proc() { + spawn(move|| { let mut s2 = s2; assert!(s2.read(&mut [0]).is_err()); tx.send(()); @@ -1236,7 +1236,7 @@ mod test { let addr = next_test_ip6(); let mut a = TcpListener::bind(addr).listen().unwrap(); let (tx, rx) = channel::<()>(); - spawn(proc() { + spawn(move|| { let mut s = TcpStream::connect(addr).unwrap(); rx.recv(); assert!(s.write(&[0]).is_ok()); @@ -1269,7 +1269,7 @@ mod test { let addr = next_test_ip6(); let mut a = TcpListener::bind(addr).listen().unwrap(); let (tx, rx) = channel::<()>(); - spawn(proc() { + spawn(move|| { let mut s = TcpStream::connect(addr).unwrap(); rx.recv(); let mut amt = 0; @@ -1298,7 +1298,7 @@ mod test { let addr = next_test_ip6(); let mut a = TcpListener::bind(addr).listen().unwrap(); let (tx, rx) = channel::<()>(); - spawn(proc() { + spawn(move|| { let mut s = TcpStream::connect(addr).unwrap(); rx.recv(); assert!(s.write(&[0]).is_ok()); @@ -1326,7 +1326,7 @@ mod test { let addr = next_test_ip6(); let mut a = TcpListener::bind(addr).listen().unwrap(); let (tx, rx) = channel::<()>(); - spawn(proc() { + spawn(move|| { let mut s = TcpStream::connect(addr).unwrap(); rx.recv(); assert_eq!(s.write(&[0]), Ok(())); @@ -1336,7 +1336,7 @@ mod test { let mut s = a.accept().unwrap(); let s2 = s.clone(); let (tx2, rx2) = channel(); - spawn(proc() { + spawn(move|| { let mut s2 = s2; assert_eq!(s2.read(&mut [0]), Ok(1)); tx2.send(()); @@ -1359,7 +1359,7 @@ mod test { let (tx, rx) = channel(); let (txdone, rxdone) = channel(); let txdone2 = txdone.clone(); - spawn(proc() { + spawn(move|| { let mut tcp = TcpStream::connect(addr).unwrap(); rx.recv(); tcp.write_u8(0).unwrap(); @@ -1370,7 +1370,7 @@ mod test { let tcp = accept.accept().unwrap(); let tcp2 = tcp.clone(); let txdone3 = txdone.clone(); - spawn(proc() { + spawn(move|| { let mut tcp2 = tcp2; tcp2.read_u8().unwrap(); txdone3.send(()); @@ -1396,10 +1396,10 @@ mod test { let mut a = l.listen().unwrap(); let mut a2 = a.clone(); - spawn(proc() { + spawn(move|| { let _ = TcpStream::connect(addr); }); - spawn(proc() { + spawn(move|| { let _ = TcpStream::connect(addr); }); @@ -1417,13 +1417,13 @@ mod test { let (tx, rx) = channel(); let tx2 = tx.clone(); - spawn(proc() { let mut a = a; tx.send(a.accept()) }); - spawn(proc() { let mut a = a2; tx2.send(a.accept()) }); + spawn(move|| { let mut a = a; tx.send(a.accept()) }); + spawn(move|| { let mut a = a2; tx2.send(a.accept()) }); - spawn(proc() { + spawn(move|| { let _ = TcpStream::connect(addr); }); - spawn(proc() { + spawn(move|| { let _ = TcpStream::connect(addr); }); @@ -1449,7 +1449,7 @@ mod test { let mut a2 = a.clone(); let (tx, rx) = channel(); - spawn(proc() { + spawn(move|| { let mut a = a; tx.send(a.accept()); }); diff --git a/src/libstd/io/net/udp.rs b/src/libstd/io/net/udp.rs index b23921ba3594d..78951b8dae2b0 100644 --- a/src/libstd/io/net/udp.rs +++ b/src/libstd/io/net/udp.rs @@ -272,7 +272,7 @@ mod test { let (tx1, rx1) = channel(); let (tx2, rx2) = channel(); - spawn(proc() { + spawn(move|| { match UdpSocket::bind(client_ip) { Ok(ref mut client) => { rx1.recv(); @@ -307,7 +307,7 @@ mod test { let client_ip = next_test_ip6(); let (tx, rx) = channel::<()>(); - spawn(proc() { + spawn(move|| { match UdpSocket::bind(client_ip) { Ok(ref mut client) => { rx.recv(); @@ -343,7 +343,7 @@ mod test { let (tx1, rx1) = channel(); let (tx2, rx2) = channel(); - spawn(proc() { + spawn(move|| { let send_as = |ip, val: &[u8]| { match UdpSocket::bind(ip) { Ok(client) => { @@ -387,7 +387,7 @@ mod test { let (tx1, rx1) = channel(); let (tx2, rx2) = channel(); - spawn(proc() { + spawn(move|| { match UdpSocket::bind(client_ip) { Ok(client) => { let client = box client; @@ -449,7 +449,7 @@ mod test { let mut sock1 = UdpSocket::bind(addr1).unwrap(); let sock2 = UdpSocket::bind(addr2).unwrap(); - spawn(proc() { + spawn(move|| { let mut sock2 = sock2; let mut buf = [0, 0]; assert_eq!(sock2.recv_from(&mut buf), Ok((1, addr1))); @@ -461,7 +461,7 @@ mod test { let (tx1, rx1) = channel(); let (tx2, rx2) = channel(); - spawn(proc() { + spawn(move|| { let mut sock3 = sock3; rx1.recv(); sock3.send_to(&[1], addr2).unwrap(); @@ -482,7 +482,7 @@ mod test { let (tx1, rx) = channel(); let tx2 = tx1.clone(); - spawn(proc() { + spawn(move|| { let mut sock2 = sock2; sock2.send_to(&[1], addr1).unwrap(); rx.recv(); @@ -493,7 +493,7 @@ mod test { let sock3 = sock1.clone(); let (done, rx) = channel(); - spawn(proc() { + spawn(move|| { let mut sock3 = sock3; let mut buf = [0, 0]; sock3.recv_from(&mut buf).unwrap(); @@ -517,7 +517,7 @@ mod test { let (tx, rx) = channel(); let (serv_tx, serv_rx) = channel(); - spawn(proc() { + spawn(move|| { let mut sock2 = sock2; let mut buf = [0, 1]; @@ -533,7 +533,7 @@ mod test { let (done, rx) = channel(); let tx2 = tx.clone(); - spawn(proc() { + spawn(move|| { let mut sock3 = sock3; match sock3.send_to(&[1], addr2) { Ok(..) => { let _ = tx2.send_opt(()); } @@ -560,7 +560,7 @@ mod test { let (tx, rx) = channel(); let (tx2, rx2) = channel(); - spawn(proc() { + spawn(move|| { let mut a = UdpSocket::bind(addr2).unwrap(); assert_eq!(a.recv_from(&mut [0]), Ok((1, addr1))); assert_eq!(a.send_to(&[0], addr1), Ok(())); diff --git a/src/libstd/io/pipe.rs b/src/libstd/io/pipe.rs index 41676cdf6e9cc..73a893c4f2dcd 100644 --- a/src/libstd/io/pipe.rs +++ b/src/libstd/io/pipe.rs @@ -123,7 +123,7 @@ mod test { let out = PipeStream::open(writer); let mut input = PipeStream::open(reader); let (tx, rx) = channel(); - spawn(proc() { + spawn(move|| { let mut out = out; out.write(&[10]).unwrap(); rx.recv(); // don't close the pipe until the other read has finished diff --git a/src/libstd/io/process.rs b/src/libstd/io/process.rs index c46a6e82e4486..9ba6381c8c3b3 100644 --- a/src/libstd/io/process.rs +++ b/src/libstd/io/process.rs @@ -693,7 +693,7 @@ impl Process { fn read(stream: Option) -> Receiver>> { let (tx, rx) = channel(); match stream { - Some(stream) => spawn(proc() { + Some(stream) => spawn(move |:| { let mut stream = stream; tx.send(stream.read_to_end()) }), @@ -1155,14 +1155,14 @@ mod tests { fn wait_timeout2() { let (tx, rx) = channel(); let tx2 = tx.clone(); - spawn(proc() { + spawn(move|| { let mut p = sleeper(); p.set_timeout(Some(10)); assert_eq!(p.wait().err().unwrap().kind, TimedOut); p.signal_kill().unwrap(); tx.send(()); }); - spawn(proc() { + spawn(move|| { let mut p = sleeper(); p.set_timeout(Some(10)); assert_eq!(p.wait().err().unwrap().kind, TimedOut); diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index 8438c9fb441ed..344012a09a0e3 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -528,7 +528,7 @@ mod tests { let (tx, rx) = channel(); let (mut r, w) = (ChanReader::new(rx), ChanWriter::new(tx)); - spawn(proc() { + spawn(move|| { set_stdout(box w); println!("hello!"); }); @@ -542,7 +542,7 @@ mod tests { let (tx, rx) = channel(); let (mut r, w) = (ChanReader::new(rx), ChanWriter::new(tx)); - spawn(proc() { + spawn(move|| { ::realstd::io::stdio::set_stderr(box w); panic!("my special message"); }); diff --git a/src/libstd/io/timer.rs b/src/libstd/io/timer.rs index ad02b534d04c6..79048c37ab5bb 100644 --- a/src/libstd/io/timer.rs +++ b/src/libstd/io/timer.rs @@ -357,7 +357,7 @@ mod test { let mut timer = Timer::new().unwrap(); let timer_rx = timer.periodic(Duration::milliseconds(1000)); - spawn(proc() { + spawn(move|| { let _ = timer_rx.recv_opt(); }); @@ -371,7 +371,7 @@ mod test { let mut timer = Timer::new().unwrap(); let timer_rx = timer.periodic(Duration::milliseconds(1000)); - spawn(proc() { + spawn(move|| { let _ = timer_rx.recv_opt(); }); @@ -384,7 +384,7 @@ mod test { let mut timer = Timer::new().unwrap(); let timer_rx = timer.periodic(Duration::milliseconds(1000)); - spawn(proc() { + spawn(move|| { let _ = timer_rx.recv_opt(); }); diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index c2363c9946a96..e99aba9b67380 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -171,6 +171,8 @@ pub use rustrt::c_str; pub use unicode::char; +pub use rustrt::thunk; + /* Exported macros */ pub mod macros; diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index 76419bee41c22..900c223c70bd3 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -358,8 +358,8 @@ macro_rules! vec[ /// # fn long_running_task() {} /// # fn calculate_the_answer() -> int { 42i } /// -/// spawn(proc() { long_running_task(); tx1.send(()) }); -/// spawn(proc() { tx2.send(calculate_the_answer()) }); +/// spawn(move|| { long_running_task(); tx1.send(()) }); +/// spawn(move|| { tx2.send(calculate_the_answer()) }); /// /// select! ( /// () = rx1.recv() => println!("the long running task finished first"), diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs index 3daba53cd866e..4041a6f60d71d 100644 --- a/src/libstd/path/posix.rs +++ b/src/libstd/path/posix.rs @@ -515,17 +515,17 @@ mod tests { #[test] fn test_null_byte() { use task; - let result = task::try(proc() { + let result = task::try(move|| { Path::new(b"foo/bar\0") }); assert!(result.is_err()); - let result = task::try(proc() { + let result = task::try(move|| { Path::new("test").set_filename(b"f\0o") }); assert!(result.is_err()); - let result = task::try(proc() { + let result = task::try(move|| { Path::new("test").push(b"f\0o"); }); assert!(result.is_err()); diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs index e1b0d9b139542..3983e365ae1f6 100644 --- a/src/libstd/path/windows.rs +++ b/src/libstd/path/windows.rs @@ -1299,17 +1299,17 @@ mod tests { #[test] fn test_null_byte() { use task; - let result = task::try(proc() { + let result = task::try(move|| { Path::new(b"foo/bar\0") }); assert!(result.is_err()); - let result = task::try(proc() { + let result = task::try(move|| { Path::new("test").set_filename(b"f\0o") }); assert!(result.is_err()); - let result = task::try(proc() { + let result = task::try(move|| { Path::new("test").push(b"f\0o"); }); assert!(result.is_err()); diff --git a/src/libstd/rand/os.rs b/src/libstd/rand/os.rs index 37628b65388e7..5405892535cfe 100644 --- a/src/libstd/rand/os.rs +++ b/src/libstd/rand/os.rs @@ -355,7 +355,7 @@ mod test { for _ in range(0u, 20) { let (tx, rx) = channel(); txs.push(tx); - task::spawn(proc() { + task::spawn(move|| { // wait until all the tasks are ready to go. rx.recv(); diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index 5ecd3ff04f1cd..eb517047ddc0b 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -52,6 +52,7 @@ use borrow::IntoCow; use failure; use rustrt; use os; +use thunk::Thunk; // Reexport some of our utilities which are expected by other crates. pub use self::util::{default_sched_threads, min_stack, running_on_valgrind}; @@ -87,10 +88,10 @@ static OS_DEFAULT_STACK_ESTIMATE: uint = 2 * (1 << 20); #[lang = "start"] fn lang_start(main: *const u8, argc: int, argv: *const *const u8) -> int { use mem; - start(argc, argv, proc() { + start(argc, argv, Thunk::new(move|| { let main: extern "Rust" fn() = unsafe { mem::transmute(main) }; main(); - }) + })) } /// Executes the given procedure after initializing the runtime with the given @@ -102,7 +103,7 @@ fn lang_start(main: *const u8, argc: int, argv: *const *const u8) -> int { /// /// This function will only return once *all* native threads in the system have /// exited. -pub fn start(argc: int, argv: *const *const u8, main: proc()) -> int { +pub fn start(argc: int, argv: *const *const u8, main: Thunk) -> int { use prelude::*; use rt; use rustrt::task::Task; @@ -144,7 +145,7 @@ pub fn start(argc: int, argv: *const *const u8, main: proc()) -> int { unsafe { rustrt::stack::record_os_managed_stack_bounds(my_stack_bottom, my_stack_top); } - (main.take().unwrap())(); + (main.take().unwrap()).invoke(()); exit_code = Some(os::get_exit_status()); }).destroy()); unsafe { rt::cleanup(); } diff --git a/src/libstd/sync/atomic.rs b/src/libstd/sync/atomic.rs index 2bb5518811382..fe5b962fa4b74 100644 --- a/src/libstd/sync/atomic.rs +++ b/src/libstd/sync/atomic.rs @@ -47,7 +47,7 @@ //! let spinlock = Arc::new(AtomicUint::new(1)); //! //! let spinlock_clone = spinlock.clone(); -//! spawn(proc() { +//! spawn(move|| { //! spinlock_clone.store(0, SeqCst); //! }); //! @@ -68,7 +68,7 @@ //! let shared_big_object = Arc::new(AtomicOption::empty()); //! //! let shared_big_object_clone = shared_big_object.clone(); -//! spawn(proc() { +//! spawn(move|| { //! let unwrapped_big_object = shared_big_object_clone.take(SeqCst); //! if unwrapped_big_object.is_some() { //! println!("got a big object from another task"); diff --git a/src/libstd/sync/barrier.rs b/src/libstd/sync/barrier.rs index 5e6dc6ec65083..1b8574604a0c1 100644 --- a/src/libstd/sync/barrier.rs +++ b/src/libstd/sync/barrier.rs @@ -21,7 +21,7 @@ use sync::{Mutex, Condvar}; /// let c = barrier.clone(); /// // The same messages will be printed together. /// // You will NOT see any interleaving. -/// spawn(proc() { +/// spawn(move|| { /// println!("before wait"); /// c.wait(); /// println!("after wait"); @@ -94,7 +94,7 @@ mod tests { for _ in range(0u, 9) { let c = barrier.clone(); let tx = tx.clone(); - spawn(proc() { + spawn(move|| { c.wait(); tx.send(true); }); diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs index 0fdd57b27922c..3bdab261e1957 100644 --- a/src/libstd/sync/condvar.rs +++ b/src/libstd/sync/condvar.rs @@ -41,7 +41,7 @@ use time::Duration; /// let pair2 = pair.clone(); /// /// // Inside of our lock, spawn a new thread, and then wait for it to start -/// spawn(proc() { +/// spawn(move|| { /// let &(ref lock, ref cvar) = &*pair2; /// let mut started = lock.lock(); /// *started = true; @@ -282,7 +282,7 @@ mod tests { static M: StaticMutex = MUTEX_INIT; let g = M.lock(); - spawn(proc() { + spawn(move|| { let _g = M.lock(); C.notify_one(); }); @@ -300,7 +300,7 @@ mod tests { for _ in range(0, N) { let data = data.clone(); let tx = tx.clone(); - spawn(proc() { + spawn(move|| { let &(ref lock, ref cond) = &*data; let mut cnt = lock.lock(); *cnt += 1; @@ -334,7 +334,7 @@ mod tests { let g = M.lock(); assert!(!C.wait_timeout(&g, Duration::nanoseconds(1000))); - spawn(proc() { + spawn(move|| { let _g = M.lock(); C.notify_one(); }); @@ -351,7 +351,7 @@ mod tests { static C: StaticCondvar = CONDVAR_INIT; let g = M1.lock(); - spawn(proc() { + spawn(move|| { let _g = M1.lock(); C.notify_one(); }); diff --git a/src/libstd/sync/future.rs b/src/libstd/sync/future.rs index a8c9983e5aac5..e5a1e09967ce9 100644 --- a/src/libstd/sync/future.rs +++ b/src/libstd/sync/future.rs @@ -17,7 +17,7 @@ //! use std::sync::Future; //! # fn fib(n: uint) -> uint {42}; //! # fn make_a_sandwich() {}; -//! let mut delayed_fib = Future::spawn(proc() { fib(5000) }); +//! let mut delayed_fib = Future::spawn(move|| { fib(5000) }); //! make_a_sandwich(); //! println!("fib(5000) = {}", delayed_fib.get()) //! ``` @@ -30,6 +30,7 @@ use core::mem::replace; use self::FutureState::*; use comm::{Receiver, channel}; use task::spawn; +use thunk::{Thunk}; /// A type encapsulating the result of a computation which may not be complete pub struct Future { @@ -37,7 +38,7 @@ pub struct Future { } enum FutureState { - Pending(proc():Send -> A), + Pending(Thunk<(),A>), Evaluating, Forced(A) } @@ -78,7 +79,7 @@ impl Future { match replace(&mut self.state, Evaluating) { Forced(_) | Evaluating => panic!("Logic error."), Pending(f) => { - self.state = Forced(f()); + self.state = Forced(f.invoke(())); self.get_ref() } } @@ -97,7 +98,9 @@ impl Future { Future {state: Forced(val)} } - pub fn from_fn(f: proc():Send -> A) -> Future { + pub fn from_fn(f: F) -> Future + where F : FnOnce() -> A, F : Send + { /*! * Create a future from a function. * @@ -106,7 +109,7 @@ impl Future { * function. It is not spawned into another task. */ - Future {state: Pending(f)} + Future {state: Pending(Thunk::new(f))} } } @@ -119,12 +122,14 @@ impl Future { * waiting for the result to be received on the port. */ - Future::from_fn(proc() { + Future::from_fn(move|:| { rx.recv() }) } - pub fn spawn(blk: proc():Send -> A) -> Future { + pub fn spawn(blk: F) -> Future + where F : FnOnce() -> A, F : Send + { /*! * Create a future from a unique closure. * @@ -134,7 +139,7 @@ impl Future { let (tx, rx) = channel(); - spawn(proc() { + spawn(move |:| { // Don't panic if the other end has hung up let _ = tx.send_opt(blk()); }); @@ -166,7 +171,7 @@ mod test { #[test] fn test_from_fn() { - let mut f = Future::from_fn(proc() "brail".to_string()); + let mut f = Future::from_fn(move|| "brail".to_string()); assert_eq!(f.get(), "brail"); } @@ -190,14 +195,14 @@ mod test { #[test] fn test_spawn() { - let mut f = Future::spawn(proc() "bale".to_string()); + let mut f = Future::spawn(move|| "bale".to_string()); assert_eq!(f.get(), "bale"); } #[test] #[should_fail] fn test_future_panic() { - let mut f = Future::spawn(proc() panic!()); + let mut f = Future::spawn(move|| panic!()); let _x: String = f.get(); } @@ -205,8 +210,8 @@ mod test { fn test_sendable_future() { let expected = "schlorf"; let (tx, rx) = channel(); - let f = Future::spawn(proc() { expected }); - task::spawn(proc() { + let f = Future::spawn(move|| { expected }); + task::spawn(move|| { let mut f = f; tx.send(f.get()); }); diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index 4e07d54c57e7d..33f8d254c71a4 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -47,7 +47,7 @@ use sys_common::mutex as sys; /// let (tx, rx) = channel(); /// for _ in range(0u, 10) { /// let (data, tx) = (data.clone(), tx.clone()); -/// spawn(proc() { +/// spawn(move|| { /// // The shared static can only be accessed once the lock is held. /// // Our non-atomic increment is safe because we're the only thread /// // which can access the shared state when the lock is held. @@ -313,9 +313,9 @@ mod test { let (tx, rx) = channel(); for _ in range(0, K) { let tx2 = tx.clone(); - spawn(proc() { inc(); tx2.send(()); }); + spawn(move|| { inc(); tx2.send(()); }); let tx2 = tx.clone(); - spawn(proc() { inc(); tx2.send(()); }); + spawn(move|| { inc(); tx2.send(()); }); } drop(tx); @@ -339,7 +339,7 @@ mod test { let arc = Arc::new((Mutex::new(false), Condvar::new())); let arc2 = arc.clone(); let (tx, rx) = channel(); - spawn(proc() { + spawn(move|| { // wait until parent gets in rx.recv(); let &(ref lock, ref cvar) = &*arc2; @@ -364,7 +364,7 @@ mod test { let arc2 = arc.clone(); let (tx, rx) = channel(); - spawn(proc() { + spawn(move|| { rx.recv(); let &(ref lock, ref cvar) = &*arc2; let _g = lock.lock(); @@ -386,7 +386,7 @@ mod test { fn test_mutex_arc_poison() { let arc = Arc::new(Mutex::new(1i)); let arc2 = arc.clone(); - let _ = task::try(proc() { + let _ = task::try(move|| { let lock = arc2.lock(); assert_eq!(*lock, 2); }); @@ -401,7 +401,7 @@ mod test { let arc = Arc::new(Mutex::new(1i)); let arc2 = Arc::new(Mutex::new(arc)); let (tx, rx) = channel(); - spawn(proc() { + spawn(move|| { let lock = arc2.lock(); let lock2 = lock.deref().lock(); assert_eq!(*lock2, 1); @@ -414,7 +414,7 @@ mod test { fn test_mutex_arc_access_in_unwind() { let arc = Arc::new(Mutex::new(1i)); let arc2 = arc.clone(); - let _ = task::try::<()>(proc() { + let _ = task::try(move|| -> () { struct Unwinder { i: Arc>, } diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs index 1bcdc760fc680..263937c5cbec7 100644 --- a/src/libstd/sync/once.rs +++ b/src/libstd/sync/once.rs @@ -142,7 +142,7 @@ mod test { let (tx, rx) = channel(); for _ in range(0u, 10) { let tx = tx.clone(); - spawn(proc() { + spawn(move|| { for _ in range(0u, 4) { task::deschedule() } unsafe { O.doit(|| { diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs index a4f8b1df6af52..b6d6aa989c58e 100644 --- a/src/libstd/sync/rwlock.rs +++ b/src/libstd/sync/rwlock.rs @@ -387,7 +387,7 @@ mod tests { let (tx, rx) = channel::<()>(); for _ in range(0, N) { let tx = tx.clone(); - spawn(proc() { + spawn(move|| { let mut rng = rand::task_rng(); for _ in range(0, M) { if rng.gen_weighted_bool(N) { @@ -409,7 +409,7 @@ mod tests { fn test_rw_arc_poison_wr() { let arc = Arc::new(RWLock::new(1i)); let arc2 = arc.clone(); - let _ = task::try(proc() { + let _ = task::try(move|| { let lock = arc2.write(); assert_eq!(*lock, 2); }); @@ -422,7 +422,7 @@ mod tests { fn test_rw_arc_poison_ww() { let arc = Arc::new(RWLock::new(1i)); let arc2 = arc.clone(); - let _ = task::try(proc() { + let _ = task::try(move|| { let lock = arc2.write(); assert_eq!(*lock, 2); }); @@ -434,7 +434,7 @@ mod tests { fn test_rw_arc_no_poison_rr() { let arc = Arc::new(RWLock::new(1i)); let arc2 = arc.clone(); - let _ = task::try(proc() { + let _ = task::try(move|| { let lock = arc2.read(); assert_eq!(*lock, 2); }); @@ -445,7 +445,7 @@ mod tests { fn test_rw_arc_no_poison_rw() { let arc = Arc::new(RWLock::new(1i)); let arc2 = arc.clone(); - let _ = task::try(proc() { + let _ = task::try(move|| { let lock = arc2.read(); assert_eq!(*lock, 2); }); @@ -459,7 +459,7 @@ mod tests { let arc2 = arc.clone(); let (tx, rx) = channel(); - task::spawn(proc() { + task::spawn(move|| { let mut lock = arc2.write(); for _ in range(0u, 10) { let tmp = *lock; @@ -474,7 +474,7 @@ mod tests { let mut children = Vec::new(); for _ in range(0u, 5) { let arc3 = arc.clone(); - children.push(task::try_future(proc() { + children.push(task::try_future(move|| { let lock = arc3.read(); assert!(*lock >= 0); })); @@ -495,7 +495,7 @@ mod tests { fn test_rw_arc_access_in_unwind() { let arc = Arc::new(RWLock::new(1i)); let arc2 = arc.clone(); - let _ = task::try::<()>(proc() { + let _ = task::try(move|| -> () { struct Unwinder { i: Arc>, } diff --git a/src/libstd/sync/semaphore.rs b/src/libstd/sync/semaphore.rs index 03fb84c38d470..574b0f22bee00 100644 --- a/src/libstd/sync/semaphore.rs +++ b/src/libstd/sync/semaphore.rs @@ -127,7 +127,7 @@ mod tests { fn test_sem_as_mutex() { let s = Arc::new(Semaphore::new(1)); let s2 = s.clone(); - spawn(proc() { + spawn(move|| { let _g = s2.access(); }); let _g = s.access(); @@ -139,7 +139,7 @@ mod tests { let (tx, rx) = channel(); let s = Arc::new(Semaphore::new(0)); let s2 = s.clone(); - spawn(proc() { + spawn(move|| { s2.acquire(); tx.send(()); }); @@ -150,7 +150,7 @@ mod tests { let (tx, rx) = channel(); let s = Arc::new(Semaphore::new(0)); let s2 = s.clone(); - spawn(proc() { + spawn(move|| { s2.release(); let _ = rx.recv(); }); @@ -166,7 +166,7 @@ mod tests { let s2 = s.clone(); let (tx1, rx1) = channel(); let (tx2, rx2) = channel(); - spawn(proc() { + spawn(move|| { let _g = s2.access(); let _ = rx2.recv(); tx1.send(()); @@ -183,7 +183,7 @@ mod tests { let (tx, rx) = channel(); { let _g = s.access(); - spawn(proc() { + spawn(move|| { tx.send(()); drop(s2.access()); tx.send(()); diff --git a/src/libstd/sync/task_pool.rs b/src/libstd/sync/task_pool.rs index 4ae5cd054f620..fa5b62a202bfd 100644 --- a/src/libstd/sync/task_pool.rs +++ b/src/libstd/sync/task_pool.rs @@ -12,17 +12,18 @@ use core::prelude::*; -use task::spawn; +use task::{spawn}; use comm::{channel, Sender, Receiver}; use sync::{Arc, Mutex}; +use thunk::Thunk; struct Sentinel<'a> { - jobs: &'a Arc>>, + jobs: &'a Arc>>, active: bool } impl<'a> Sentinel<'a> { - fn new(jobs: &Arc>>) -> Sentinel { + fn new(jobs: &Arc>>) -> Sentinel { Sentinel { jobs: jobs, active: true @@ -60,7 +61,7 @@ impl<'a> Drop for Sentinel<'a> { /// let (tx, rx) = channel(); /// for _ in range(0, 8u) { /// let tx = tx.clone(); -/// pool.execute(proc() { +/// pool.execute(move|| { /// tx.send(1u); /// }); /// } @@ -72,7 +73,7 @@ pub struct TaskPool { // // This is the only such Sender, so when it is dropped all subtasks will // quit. - jobs: Sender + jobs: Sender } impl TaskPool { @@ -84,7 +85,7 @@ impl TaskPool { pub fn new(tasks: uint) -> TaskPool { assert!(tasks >= 1); - let (tx, rx) = channel::(); + let (tx, rx) = channel::(); let rx = Arc::new(Mutex::new(rx)); // Taskpool tasks. @@ -96,13 +97,15 @@ impl TaskPool { } /// Executes the function `job` on a task in the pool. - pub fn execute(&self, job: proc():Send) { - self.jobs.send(job); + pub fn execute(&self, job: F) + where F : FnOnce(), F : Send + { + self.jobs.send(Thunk::new(job)); } } -fn spawn_in_pool(jobs: Arc>>) { - spawn(proc() { +fn spawn_in_pool(jobs: Arc>>) { + spawn(move |:| { // Will spawn a new task on panic unless it is cancelled. let sentinel = Sentinel::new(&jobs); @@ -115,7 +118,7 @@ fn spawn_in_pool(jobs: Arc>>) { }; match message { - Ok(job) => job(), + Ok(job) => job.invoke(()), // The Taskpool was dropped. Err(..) => break @@ -144,7 +147,7 @@ mod test { let (tx, rx) = channel(); for _ in range(0, TEST_TASKS) { let tx = tx.clone(); - pool.execute(proc() { + pool.execute(move|| { tx.send(1u); }); } @@ -166,14 +169,14 @@ mod test { // Panic all the existing tasks. for _ in range(0, TEST_TASKS) { - pool.execute(proc() { panic!() }); + pool.execute(move|| -> () { panic!() }); } // Ensure new tasks were spawned to compensate. let (tx, rx) = channel(); for _ in range(0, TEST_TASKS) { let tx = tx.clone(); - pool.execute(proc() { + pool.execute(move|| { tx.send(1u); }); } @@ -191,7 +194,7 @@ mod test { // Panic all the existing tasks in a bit. for _ in range(0, TEST_TASKS) { let waiter = waiter.clone(); - pool.execute(proc() { + pool.execute(move|| { waiter.wait(); panic!(); }); diff --git a/src/libstd/sys/common/helper_thread.rs b/src/libstd/sys/common/helper_thread.rs index 6c5fc3005edd2..96b4accd4bd03 100644 --- a/src/libstd/sys/common/helper_thread.rs +++ b/src/libstd/sys/common/helper_thread.rs @@ -83,7 +83,7 @@ impl Helper { *self.signal.get() = send as uint; let t = f(); - task::spawn(proc() { + task::spawn(move |:| { bookkeeping::decrement(); helper(receive, rx, t); let _g = self.lock.lock(); @@ -91,7 +91,7 @@ impl Helper { self.cond.notify_one() }); - rustrt::at_exit(proc() { self.shutdown() }); + rustrt::at_exit(move|:| { self.shutdown() }); *self.initialized.get() = true; } } diff --git a/src/libstd/sys/unix/process.rs b/src/libstd/sys/unix/process.rs index dfbba0f335cdd..4ef1757cc3aca 100644 --- a/src/libstd/sys/unix/process.rs +++ b/src/libstd/sys/unix/process.rs @@ -94,8 +94,8 @@ impl Process { mem::transmute::<&ProcessConfig,&'static ProcessConfig>(cfg) }; - with_envp(cfg.env(), proc(envp) { - with_argv(cfg.program(), cfg.args(), proc(argv) unsafe { + with_envp(cfg.env(), move|: envp: *const c_void| { + with_argv(cfg.program(), cfg.args(), move|: argv: *const *const libc::c_char| unsafe { let (input, mut output) = try!(sys::os::pipe()); // We may use this in the child, so perform allocations before the @@ -531,8 +531,11 @@ impl Process { } } -fn with_argv(prog: &CString, args: &[CString], - cb: proc(*const *const libc::c_char) -> T) -> T { +fn with_argv(prog: &CString, args: &[CString], + cb: F) + -> T + where F : FnOnce(*const *const libc::c_char) -> T +{ let mut ptrs: Vec<*const libc::c_char> = Vec::with_capacity(args.len()+1); // Convert the CStrings into an array of pointers. Note: the @@ -549,9 +552,12 @@ fn with_argv(prog: &CString, args: &[CString], cb(ptrs.as_ptr()) } -fn with_envp(env: Option<&collections::HashMap>, - cb: proc(*const c_void) -> T) -> T - where K: BytesContainer + Eq + Hash, V: BytesContainer +fn with_envp(env: Option<&collections::HashMap>, + cb: F) + -> T + where F : FnOnce(*const c_void) -> T, + K : BytesContainer + Eq + Hash, + V : BytesContainer { // On posixy systems we can pass a char** for envp, which is a // null-terminated array of "k=v\0" strings. Since we must create diff --git a/src/libstd/sys/windows/thread_local.rs b/src/libstd/sys/windows/thread_local.rs index b841f6d3a2b2f..969b322af991f 100644 --- a/src/libstd/sys/windows/thread_local.rs +++ b/src/libstd/sys/windows/thread_local.rs @@ -131,7 +131,7 @@ fn init_dtors() { DTORS = mem::transmute(dtors); } - rustrt::at_exit(proc() unsafe { + rustrt::at_exit(move|| unsafe { mem::transmute::<_, Box>>>(DTORS); DTORS = 0 as *mut _; }); diff --git a/src/libstd/task.rs b/src/libstd/task.rs index 5a1a5b4fb7a10..340e283708a48 100644 --- a/src/libstd/task.rs +++ b/src/libstd/task.rs @@ -35,7 +35,7 @@ //! ## Example //! //! ```rust -//! spawn(proc() { +//! spawn(move|| { //! println!("Hello, World!"); //! }) //! ``` @@ -47,6 +47,7 @@ use any::Any; use borrow::IntoCow; use boxed::Box; use comm::channel; +use core::ops::FnOnce; use io::{Writer, stdio}; use kinds::{Send, marker}; use option::Option; @@ -57,6 +58,7 @@ use rustrt::task::Task; use rustrt::task; use str::SendStr; use string::{String, ToString}; +use thunk::{Thunk}; use sync::Future; /// The task builder type. @@ -80,7 +82,7 @@ pub struct TaskBuilder { // Task-local stderr stderr: Option>, // Optionally wrap the eventual task body - gen_body: Option proc():Send>, + gen_body: Option>, nocopy: marker::NoCopy, } @@ -129,41 +131,46 @@ impl TaskBuilder { } // Where spawning actually happens (whether yielding a future or not) - fn spawn_internal(self, f: proc():Send, - on_exit: Option>):Send>) { + fn spawn_internal( + self, + f: Thunk, + on_exit: Option>) + { let TaskBuilder { name, stack_size, stdout, stderr, mut gen_body, nocopy: _ } = self; + let f = match gen_body.take() { - Some(gen) => gen(f), + Some(gen) => gen.invoke(f), None => f }; + let opts = task::TaskOpts { on_exit: on_exit, name: name, stack_size: stack_size, }; if stdout.is_some() || stderr.is_some() { - Task::spawn(opts, proc() { + Task::spawn(opts, move|:| { let _ = stdout.map(stdio::set_stdout); let _ = stderr.map(stdio::set_stderr); - f(); - }) + f.invoke(()); + }); } else { - Task::spawn(opts, f) + Task::spawn(opts, move|:| f.invoke(())) } } /// Creates and executes a new child task. /// /// Sets up a new task with its own call stack and schedules it to run - /// the provided proc. The task has the properties and behavior + /// the provided function. The task has the properties and behavior /// specified by the `TaskBuilder`. - pub fn spawn(self, f: proc():Send) { - self.spawn_internal(f, None) + pub fn spawn(self, f: F) { + self.spawn_internal(Thunk::new(f), None) } - /// Execute a proc in a newly-spawned task and return a future representing + /// Execute a function in a newly-spawned task and return a future representing /// the task's result. The task has the properties and behavior /// specified by the `TaskBuilder`. /// @@ -178,20 +185,22 @@ impl TaskBuilder { /// `result::Result::Err` containing the argument to `panic!(...)` as an /// `Any` trait object. #[experimental = "Futures are experimental."] - pub fn try_future(self, f: proc():Send -> T) - -> Future>> { - // currently, the on_exit proc provided by librustrt only works for unit + pub fn try_future(T)+Send>(self, f: F) + -> Future>> { + // currently, the on_exit fn provided by librustrt only works for unit // results, so we use an additional side-channel to communicate the // result. let (tx_done, rx_done) = channel(); // signal that task has exited let (tx_retv, rx_retv) = channel(); // return value from task - let on_exit = proc(res) { let _ = tx_done.send_opt(res); }; - self.spawn_internal(proc() { let _ = tx_retv.send_opt(f()); }, + let on_exit: Thunk = Thunk::with_arg(move |: res: task::Result| { + let _ = tx_done.send_opt(res); + }); + self.spawn_internal(Thunk::new(move |:| { let _ = tx_retv.send_opt(f()); }), Some(on_exit)); - Future::from_fn(proc() { + Future::from_fn(move|:| { rx_done.recv().map(|_| rx_retv.recv()) }) } @@ -199,7 +208,9 @@ impl TaskBuilder { /// Execute a function in a newly-spawnedtask and block until the task /// completes or panics. Equivalent to `.try_future(f).unwrap()`. #[unstable = "Error type may change."] - pub fn try(self, f: proc():Send -> T) -> Result> { + pub fn try(self, f: F) -> Result> + where F : FnOnce() -> T, F : Send, T : Send + { self.try_future(f).into_inner() } } @@ -212,7 +223,7 @@ impl TaskBuilder { /// the provided unique closure. /// /// This function is equivalent to `TaskBuilder::new().spawn(f)`. -pub fn spawn(f: proc(): Send) { +pub fn spawn(f: F) { TaskBuilder::new().spawn(f) } @@ -221,7 +232,9 @@ pub fn spawn(f: proc(): Send) { /// /// This is equivalent to `TaskBuilder::new().try`. #[unstable = "Error type may change."] -pub fn try(f: proc(): Send -> T) -> Result> { +pub fn try(f: F) -> Result> + where T : Send, F : FnOnce() -> T, F : Send +{ TaskBuilder::new().try(f) } @@ -230,11 +243,12 @@ pub fn try(f: proc(): Send -> T) -> Result> { /// /// This is equivalent to `TaskBuilder::new().try_future`. #[experimental = "Futures are experimental."] -pub fn try_future(f: proc():Send -> T) -> Future>> { +pub fn try_future(f: F) -> Future>> + where T:Send, F:FnOnce()->T, F:Send +{ TaskBuilder::new().try_future(f) } - /* Lifecycle functions */ /// Read the name of the current task. @@ -274,6 +288,8 @@ mod test { use result; use std::io::{ChanReader, ChanWriter}; use string::String; + use thunk::Thunk; + use prelude::*; use super::*; // !!! These tests are dangerous. If something is buggy, they will hang, !!! @@ -281,28 +297,28 @@ mod test { #[test] fn test_unnamed_task() { - try(proc() { + try(move|| { assert!(name().is_none()); }).map_err(|_| ()).unwrap(); } #[test] fn test_owned_named_task() { - TaskBuilder::new().named("ada lovelace".to_string()).try(proc() { + TaskBuilder::new().named("ada lovelace".to_string()).try(move|| { assert!(name().unwrap() == "ada lovelace"); }).map_err(|_| ()).unwrap(); } #[test] fn test_static_named_task() { - TaskBuilder::new().named("ada lovelace").try(proc() { + TaskBuilder::new().named("ada lovelace").try(move|| { assert!(name().unwrap() == "ada lovelace"); }).map_err(|_| ()).unwrap(); } #[test] fn test_send_named_task() { - TaskBuilder::new().named("ada lovelace".into_cow()).try(proc() { + TaskBuilder::new().named("ada lovelace".into_cow()).try(move|| { assert!(name().unwrap() == "ada lovelace"); }).map_err(|_| ()).unwrap(); } @@ -310,7 +326,7 @@ mod test { #[test] fn test_run_basic() { let (tx, rx) = channel(); - TaskBuilder::new().spawn(proc() { + TaskBuilder::new().spawn(move|| { tx.send(()); }); rx.recv(); @@ -318,10 +334,10 @@ mod test { #[test] fn test_try_future() { - let result = TaskBuilder::new().try_future(proc() {}); + let result = TaskBuilder::new().try_future(move|| {}); assert!(result.unwrap().is_ok()); - let result = TaskBuilder::new().try_future(proc() -> () { + let result = TaskBuilder::new().try_future(move|| -> () { panic!(); }); assert!(result.unwrap().is_err()); @@ -329,7 +345,7 @@ mod test { #[test] fn test_try_success() { - match try(proc() { + match try(move|| { "Success!".to_string() }).as_ref().map(|s| s.as_slice()) { result::Result::Ok("Success!") => (), @@ -339,7 +355,7 @@ mod test { #[test] fn test_try_panic() { - match try(proc() { + match try(move|| { panic!() }) { result::Result::Err(_) => (), @@ -355,7 +371,7 @@ mod test { fn f(i: int, tx: Sender<()>) { let tx = tx.clone(); - spawn(proc() { + spawn(move|| { if i == 0 { tx.send(()); } else { @@ -372,8 +388,8 @@ mod test { fn test_spawn_sched_childs_on_default_sched() { let (tx, rx) = channel(); - spawn(proc() { - spawn(proc() { + spawn(move|| { + spawn(move|| { tx.send(()); }); }); @@ -382,17 +398,17 @@ mod test { } fn avoid_copying_the_body(spawnfn: F) where - F: FnOnce(proc():Send), + F: FnOnce(Thunk), { let (tx, rx) = channel::(); let x = box 1; let x_in_parent = (&*x) as *const int as uint; - spawnfn(proc() { + spawnfn(Thunk::new(move|| { let x_in_child = (&*x) as *const int as uint; tx.send(x_in_child); - }); + })); let x_in_child = rx.recv(); assert_eq!(x_in_parent, x_in_child); @@ -400,25 +416,21 @@ mod test { #[test] fn test_avoid_copying_the_body_spawn() { - avoid_copying_the_body(spawn); + avoid_copying_the_body(|t| spawn(move|| t.invoke(()))); } #[test] fn test_avoid_copying_the_body_task_spawn() { avoid_copying_the_body(|f| { let builder = TaskBuilder::new(); - builder.spawn(proc() { - f(); - }); + builder.spawn(move|| f.invoke(())); }) } #[test] fn test_avoid_copying_the_body_try() { avoid_copying_the_body(|f| { - let _ = try(proc() { - f() - }); + let _ = try(move|| f.invoke(())); }) } @@ -429,24 +441,24 @@ mod test { // (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) -> proc(): Send { - return proc() { + fn child_no(x: uint) -> Thunk { + return Thunk::new(move|| { if x < GENERATIONS { - TaskBuilder::new().spawn(child_no(x+1)); + TaskBuilder::new().spawn(move|| child_no(x+1).invoke(())); } - } + }); } - TaskBuilder::new().spawn(child_no(0)); + TaskBuilder::new().spawn(|| child_no(0).invoke(())); } #[test] fn test_simple_newsched_spawn() { - spawn(proc()()) + spawn(move|| ()) } #[test] fn test_try_panic_message_static_str() { - match try(proc() { + match try(move|| { panic!("static string"); }) { Err(e) => { @@ -460,7 +472,7 @@ mod test { #[test] fn test_try_panic_message_owned_str() { - match try(proc() { + match try(move|| { panic!("owned string".to_string()); }) { Err(e) => { @@ -474,7 +486,7 @@ mod test { #[test] fn test_try_panic_message_any() { - match try(proc() { + match try(move|| { panic!(box 413u16 as Box); }) { Err(e) => { @@ -492,7 +504,7 @@ mod test { fn test_try_panic_message_unit_struct() { struct Juju; - match try(proc() { + match try(move|| { panic!(Juju) }) { Err(ref e) if e.is::() => {} @@ -507,7 +519,7 @@ mod test { let stdout = ChanWriter::new(tx); let r = TaskBuilder::new().stdout(box stdout as Box) - .try(proc() { + .try(move|| { print!("Hello, world!"); }); assert!(r.is_ok()); @@ -527,7 +539,7 @@ fn task_abort_no_kill_runtime() { use mem; let tb = TaskBuilder::new(); - let rx = tb.try_future(proc() {}); + let rx = tb.try_future(move|| {}); mem::drop(rx); timer::sleep(Duration::milliseconds(1000)); } diff --git a/src/libstd/thread_local/mod.rs b/src/libstd/thread_local/mod.rs index b85b6eccb7718..2d5766c2393c9 100644 --- a/src/libstd/thread_local/mod.rs +++ b/src/libstd/thread_local/mod.rs @@ -77,7 +77,7 @@ pub mod scoped; /// }); /// /// // each thread starts out with the initial value of 1 -/// spawn(proc() { +/// spawn(move|| { /// FOO.with(|f| { /// assert_eq!(*f.borrow(), 1); /// *f.borrow_mut() = 3; @@ -471,7 +471,7 @@ mod tests { *f.get() = 2; }); let (tx, rx) = channel(); - spawn(proc() { + spawn(move|| { FOO.with(|f| unsafe { assert_eq!(*f.get(), 1); }); @@ -491,7 +491,7 @@ mod tests { }) let (tx, rx) = channel(); - spawn(proc() unsafe { + spawn(move|| unsafe { let mut tx = Some(tx); FOO.with(|f| { *f.get() = Some(Foo(tx.take().unwrap())); @@ -539,7 +539,7 @@ mod tests { } } - Thread::start(proc() { + Thread::start(move|| { drop(S1); }).join(); } @@ -557,7 +557,7 @@ mod tests { } } - Thread::start(proc() unsafe { + Thread::start(move|| unsafe { K1.with(|s| *s.get() = Some(S1)); }).join(); } @@ -584,7 +584,7 @@ mod tests { } let (tx, rx) = channel(); - spawn(proc() unsafe { + spawn(move|| unsafe { let mut tx = Some(tx); K1.with(|s| *s.get() = Some(S1(tx.take().unwrap()))); }); diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index ea8de458ce225..ae7a2127e9f60 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -719,7 +719,6 @@ pub enum Expr_ { ExprLoop(P, Option), ExprMatch(P, Vec, MatchSource), ExprClosure(CaptureClause, Option, P, P), - ExprProc(P, P), ExprBlock(P), ExprAssign(P, P), @@ -1225,8 +1224,6 @@ pub enum Ty_ { TyRptr(Option, MutTy), /// A closure (e.g. `|uint| -> bool`) TyClosure(P), - /// A procedure (e.g `proc(uint) -> bool`) - TyProc(P), /// A bare function (e.g. `fn(uint) -> bool`) TyBareFn(P), /// A tuple (`(A, B, C, D,...)`) diff --git a/src/libsyntax/ast_map/blocks.rs b/src/libsyntax/ast_map/blocks.rs index 75f69f2f6d062..5462918b66283 100644 --- a/src/libsyntax/ast_map/blocks.rs +++ b/src/libsyntax/ast_map/blocks.rs @@ -37,7 +37,7 @@ use visit; /// /// More specifically, it is one of either: /// - A function item, -/// - A closure expr (i.e. an ExprClosure or ExprProc), or +/// - A closure expr (i.e. an ExprClosure), or /// - The default implementation for a trait method. /// /// To construct one, use the `Code::from_node` function. @@ -73,7 +73,7 @@ impl MaybeFnLike for ast::TraitItem { impl MaybeFnLike for ast::Expr { fn is_fn_like(&self) -> bool { match self.node { - ast::ExprClosure(..) | ast::ExprProc(..) => true, + ast::ExprClosure(..) => true, _ => false, } } @@ -222,8 +222,6 @@ impl<'a> FnLikeNode<'a> { ast_map::NodeExpr(e) => match e.node { ast::ExprClosure(_, _, ref decl, ref block) => closure(ClosureParts::new(&**decl, &**block, e.id, e.span)), - ast::ExprProc(ref decl, ref block) => - closure(ClosureParts::new(&**decl, &**block, e.id, e.span)), _ => panic!("expr FnLikeNode that is not fn-like"), }, _ => panic!("other FnLikeNode that is not fn-like"), diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs index 907ac6b19fc0d..6f1d2d39b3049 100644 --- a/src/libsyntax/ast_map/mod.rs +++ b/src/libsyntax/ast_map/mod.rs @@ -859,7 +859,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { fn visit_ty(&mut self, ty: &'ast Ty) { match ty.node { - TyClosure(ref fd) | TyProc(ref fd) => { + TyClosure(ref fd) => { self.visit_fn_decl(&*fd.decl); } TyBareFn(ref fd) => { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 9c4e85f16ff85..1a004ca7c44cc 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -217,13 +217,6 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { P(ast::Expr{id:id, node: new_node, span: fld.new_span(span)}) } - ast::ExprProc(fn_decl, block) => { - let (rewritten_fn_decl, rewritten_block) - = expand_and_rename_fn_decl_and_block(fn_decl, block, fld); - let new_node = ast::ExprProc(rewritten_fn_decl, rewritten_block); - P(ast::Expr{id:id, node: new_node, span: fld.new_span(span)}) - } - _ => { P(noop_fold_expr(ast::Expr { id: id, @@ -1576,17 +1569,6 @@ mod test { 0) } - // closure arg hygiene (ExprProc) - // expands to fn f(){(proc(x_1 : int) {(x_2 + x_1)})(3);} - #[test] fn closure_arg_hygiene_2(){ - run_renaming_test( - &("macro_rules! inject_x (()=>(x)) - fn f(){ (proc(x : int){(inject_x!() + x)})(3); }", - vec!(vec!(1)), - true), - 0) - } - // macro_rules in method position. Sadly, unimplemented. #[test] fn macro_in_method_posn(){ expand_crate_str( diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index b8f60e77601cf..66fe672c3e5e8 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -306,12 +306,6 @@ impl<'a, 'v> Visitor<'v> for Context<'a> { fn visit_expr(&mut self, e: &ast::Expr) { match e.node { - ast::ExprClosure(_, Some(_), _, _) => { - self.gate_feature("unboxed_closures", - e.span, - "unboxed closures are a work-in-progress \ - feature with known bugs"); - } ast::ExprSlice(..) => { self.gate_feature("slicing_syntax", e.span, @@ -374,19 +368,6 @@ impl<'a, 'v> Visitor<'v> for Context<'a> { } visit::walk_fn(self, fn_kind, fn_decl, block, span); } - - fn visit_path_parameters(&mut self, path_span: Span, parameters: &'v ast::PathParameters) { - match *parameters { - ast::ParenthesizedParameters(..) => { - self.gate_feature("unboxed_closures", - path_span, - "parenthetical parameter notation is subject to change"); - } - ast::AngleBracketedParameters(..) => { } - } - - visit::walk_path_parameters(self, path_span, parameters) - } } pub fn check_crate(span_handler: &SpanHandler, krate: &ast::Crate) -> (Features, Vec) { diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 0318dd5b0cd2d..611faa2c2c909 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -425,17 +425,6 @@ pub fn noop_fold_ty(t: P, fld: &mut T) -> P { } })) } - TyProc(f) => { - TyProc(f.map(|ClosureTy {fn_style, onceness, bounds, decl, lifetimes}| { - ClosureTy { - fn_style: fn_style, - onceness: onceness, - bounds: fld.fold_bounds(bounds), - decl: fld.fold_fn_decl(decl), - lifetimes: fld.fold_lifetime_defs(lifetimes) - } - })) - } TyBareFn(f) => { TyBareFn(f.map(|BareFnTy {lifetimes, fn_style, abi, decl}| BareFnTy { lifetimes: fld.fold_lifetime_defs(lifetimes), @@ -1360,10 +1349,6 @@ pub fn noop_fold_expr(Expr {id, node, span}: Expr, folder: &mut T) -> arms.move_map(|x| folder.fold_arm(x)), source) } - ExprProc(decl, body) => { - ExprProc(folder.fold_fn_decl(decl), - folder.fold_block(body)) - } ExprClosure(capture_clause, opt_kind, decl, body) => { ExprClosure(capture_clause, opt_kind, diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index 2a2bb42cef012..3a7cc77515dbe 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -32,6 +32,8 @@ pub enum ObsoleteSyntax { ObsoleteImportRenaming, ObsoleteSubsliceMatch, ObsoleteExternCrateRenaming, + ObsoleteProcType, + ObsoleteProcExpr, } impl Copy for ObsoleteSyntax {} @@ -55,6 +57,14 @@ impl<'a> ParserObsoleteMethods for parser::Parser<'a> { /// Reports an obsolete syntax non-fatal error. fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax) { let (kind_str, desc) = match kind { + ObsoleteProcType => ( + "the `proc` type", + "use unboxed closures instead", + ), + ObsoleteProcExpr => ( + "`proc` expression", + "use a `move ||` expression instead", + ), ObsoleteOwnedType => ( "`~` notation for owned pointers", "use `Box` in `std::owned` instead" diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index e9cc91d94151a..381942a3e622f 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -27,10 +27,10 @@ use ast::{ExprAssign, ExprAssignOp, ExprBinary, ExprBlock, ExprBox}; use ast::{ExprBreak, ExprCall, ExprCast}; use ast::{ExprField, ExprTupField, ExprClosure, ExprIf, ExprIfLet, ExprIndex, ExprSlice}; use ast::{ExprLit, ExprLoop, ExprMac}; -use ast::{ExprMethodCall, ExprParen, ExprPath, ExprProc}; +use ast::{ExprMethodCall, ExprParen, ExprPath}; use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary}; use ast::{ExprVec, ExprWhile, ExprWhileLet, ExprForLoop, Field, FnDecl}; -use ast::{Once, Many}; +use ast::{Many}; use ast::{FnUnboxedClosureKind, FnMutUnboxedClosureKind}; use ast::{FnOnceUnboxedClosureKind}; use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod, FunctionRetTy}; @@ -54,7 +54,7 @@ use ast::{SelfExplicit, SelfRegion, SelfStatic, SelfValue}; use ast::{Delimited, SequenceRepetition, TokenTree, TraitItem, TraitRef}; use ast::{TtDelimited, TtSequence, TtToken}; use ast::{TupleVariantKind, Ty, Ty_, TypeBinding}; -use ast::{TypeField, TyFixedLengthVec, TyClosure, TyProc, TyBareFn}; +use ast::{TypeField, TyFixedLengthVec, TyClosure, TyBareFn}; use ast::{TyTypeof, TyInfer, TypeMethod}; use ast::{TyParam, TyParamBound, TyParen, TyPath, TyPolyTraitRef, TyPtr, TyQPath}; use ast::{TyRptr, TyTup, TyU32, TyVec, UnUniq}; @@ -1064,7 +1064,6 @@ impl<'a> Parser<'a> { Deprecated: - for <'lt> |S| -> T - - for <'lt> proc(S) -> T Eventually: @@ -1158,26 +1157,21 @@ impl<'a> Parser<'a> { | | | Bounds | | Argument types | Legacy lifetimes - the `proc` keyword + the `proc` keyword (already consumed) */ - let lifetime_defs = self.parse_legacy_lifetime_defs(lifetime_defs); - let (inputs, variadic) = self.parse_fn_args(false, false); - let bounds = self.parse_colon_then_ty_param_bounds(); - let ret_ty = self.parse_ret_ty(); - let decl = P(FnDecl { - inputs: inputs, - output: ret_ty, - variadic: variadic - }); - TyProc(P(ClosureTy { - fn_style: NormalFn, - onceness: Once, - bounds: bounds, - decl: decl, - lifetimes: lifetime_defs, - })) + let proc_span = self.last_span; + + // To be helpful, parse the proc as ever + let _ = self.parse_legacy_lifetime_defs(lifetime_defs); + let _ = self.parse_fn_args(false, false); + let _ = self.parse_colon_then_ty_param_bounds(); + let _ = self.parse_ret_ty(); + + self.obsolete(proc_span, ObsoleteProcType); + + TyInfer } /// Parses an optional unboxed closure kind (`&:`, `&mut:`, or `:`). @@ -2294,17 +2288,10 @@ impl<'a> Parser<'a> { return self.parse_lambda_expr(CaptureByValue); } if self.eat_keyword(keywords::Proc) { - let decl = self.parse_proc_decl(); - let body = self.parse_expr(); - let fakeblock = P(ast::Block { - id: ast::DUMMY_NODE_ID, - view_items: Vec::new(), - stmts: Vec::new(), - rules: DefaultBlock, - span: body.span, - expr: Some(body), - }); - return self.mk_expr(lo, fakeblock.span.hi, ExprProc(decl, fakeblock)); + let span = self.last_span; + let _ = self.parse_proc_decl(); + let _ = self.parse_expr(); + return self.obsolete_expr(span, ObsoleteProcExpr); } if self.eat_keyword(keywords::If) { return self.parse_if_expr(); diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 6d8b8dcb8ba5d..87905db22f349 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -450,7 +450,7 @@ pub fn visibility_qualified(vis: ast::Visibility, s: &str) -> String { fn needs_parentheses(expr: &ast::Expr) -> bool { match expr.node { ast::ExprAssign(..) | ast::ExprBinary(..) | - ast::ExprClosure(..) | ast::ExprProc(..) | + ast::ExprClosure(..) | ast::ExprAssignOp(..) | ast::ExprCast(..) => true, _ => false, } @@ -734,25 +734,6 @@ impl<'a> State<'a> { Some(&generics), None)); } - ast::TyProc(ref f) => { - let generics = ast::Generics { - lifetimes: f.lifetimes.clone(), - ty_params: OwnedSlice::empty(), - where_clause: ast::WhereClause { - id: ast::DUMMY_NODE_ID, - predicates: Vec::new(), - }, - }; - try!(self.print_ty_fn(None, - Some('~'), - f.fn_style, - f.onceness, - &*f.decl, - None, - &f.bounds, - Some(&generics), - None)); - } ast::TyPath(ref path, _) => { try!(self.print_path(path, false)); } @@ -1696,33 +1677,6 @@ impl<'a> State<'a> { // empty box to satisfy the close. try!(self.ibox(0)); } - ast::ExprProc(ref decl, ref body) => { - // in do/for blocks we don't want to show an empty - // argument list, but at this point we don't know which - // we are inside. - // - // if !decl.inputs.is_empty() { - try!(self.print_proc_args(&**decl)); - try!(space(&mut self.s)); - // } - assert!(body.stmts.is_empty()); - assert!(body.expr.is_some()); - // we extract the block, so as not to create another set of boxes - match body.expr.as_ref().unwrap().node { - ast::ExprBlock(ref blk) => { - try!(self.print_block_unclosed(&**blk)); - } - _ => { - // this is a bare expression - try!(self.print_expr(body.expr.as_ref().map(|e| &**e).unwrap())); - try!(self.end()); // need to close a box - } - } - // a box will be closed by print_expr, but we didn't want an overall - // wrapper so we closed the corresponding opening. so create an - // empty box to satisfy the close. - try!(self.ibox(0)); - } ast::ExprBlock(ref blk) => { // containing cbox, will be closed by print-block at } try!(self.cbox(indent_unit)); @@ -2010,6 +1964,7 @@ impl<'a> State<'a> { match data.output { None => { } Some(ref ty) => { + try!(self.space_if_not_bol()); try!(self.word_space("->")); try!(self.print_type(&**ty)); } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index a36f8b23ca322..eca99df8e5561 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -389,14 +389,6 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) { walk_ty_param_bounds_helper(visitor, &function_declaration.bounds); walk_lifetime_decls_helper(visitor, &function_declaration.lifetimes); } - TyProc(ref function_declaration) => { - for argument in function_declaration.decl.inputs.iter() { - visitor.visit_ty(&*argument.ty) - } - walk_fn_ret_ty(visitor, &function_declaration.decl.output); - walk_ty_param_bounds_helper(visitor, &function_declaration.bounds); - walk_lifetime_decls_helper(visitor, &function_declaration.lifetimes); - } TyBareFn(ref function_declaration) => { for argument in function_declaration.decl.inputs.iter() { visitor.visit_ty(&*argument.ty) @@ -831,13 +823,6 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { expression.span, expression.id) } - ExprProc(ref function_declaration, ref body) => { - visitor.visit_fn(FkFnBlock, - &**function_declaration, - &**body, - expression.span, - expression.id) - } ExprBlock(ref block) => visitor.visit_block(&**block), ExprAssign(ref left_hand_expression, ref right_hand_expression) => { visitor.visit_expr(&**right_hand_expression); diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 7436a8af30765..211c5906f4533 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -32,7 +32,7 @@ html_root_url = "http://doc.rust-lang.org/nightly/")] #![feature(asm, macro_rules, phase, globs, slicing_syntax)] -#![feature(unboxed_closures)] +#![feature(unboxed_closures, default_type_params)] extern crate getopts; extern crate regex; @@ -71,6 +71,7 @@ use std::str::FromStr; use std::string::String; use std::task::TaskBuilder; use std::time::Duration; +use std::thunk::{Thunk, Invoke}; // to be used by rustc to compile tests in libtest pub mod test { @@ -149,9 +150,9 @@ pub trait TDynBenchFn { pub enum TestFn { StaticTestFn(fn()), StaticBenchFn(fn(&mut Bencher)), - StaticMetricFn(proc(&mut MetricMap):'static), - DynTestFn(proc():Send), - DynMetricFn(proc(&mut MetricMap):'static), + StaticMetricFn(fn(&mut MetricMap)), + DynTestFn(Thunk), + DynMetricFn(Box Invoke<&'a mut MetricMap>+'static>), DynBenchFn(Box) } @@ -1119,8 +1120,8 @@ pub fn run_test(opts: &TestOpts, fn run_test_inner(desc: TestDesc, monitor_ch: Sender, nocapture: bool, - testfn: proc():Send) { - spawn(proc() { + testfn: Thunk) { + spawn(move || { let (tx, rx) = channel(); let mut reader = ChanReader::new(rx); let stdout = ChanWriter::new(tx.clone()); @@ -1135,7 +1136,7 @@ pub fn run_test(opts: &TestOpts, task = task.stdout(box stdout as Box); task = task.stderr(box stderr as Box); } - let result_future = task.try_future(testfn); + let result_future = task.try_future(move || testfn.invoke(())); let stdout = reader.read_to_end().unwrap().into_iter().collect(); let task_result = result_future.into_inner(); @@ -1157,7 +1158,7 @@ pub fn run_test(opts: &TestOpts, } DynMetricFn(f) => { let mut mm = MetricMap::new(); - f(&mut mm); + f.invoke(&mut mm); monitor_ch.send((desc, TrMetrics(mm), Vec::new())); return; } @@ -1169,7 +1170,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, - proc() f()) + Thunk::new(move|| f())) } } @@ -1467,6 +1468,7 @@ mod tests { Improvement, Regression, LikelyNoise, StaticTestName, DynTestName, DynTestFn, ShouldFail}; use std::io::TempDir; + use std::thunk::Thunk; #[test] pub fn do_not_run_ignored_tests() { @@ -1477,7 +1479,7 @@ mod tests { ignore: true, should_fail: ShouldFail::No, }, - testfn: DynTestFn(proc() f()), + testfn: DynTestFn(Thunk::new(move|| f())), }; let (tx, rx) = channel(); run_test(&TestOpts::new(), false, desc, tx); @@ -1494,7 +1496,7 @@ mod tests { ignore: true, should_fail: ShouldFail::No, }, - testfn: DynTestFn(proc() f()), + testfn: DynTestFn(Thunk::new(move|| f())), }; let (tx, rx) = channel(); run_test(&TestOpts::new(), false, desc, tx); @@ -1511,7 +1513,7 @@ mod tests { ignore: false, should_fail: ShouldFail::Yes(None) }, - testfn: DynTestFn(proc() f()), + testfn: DynTestFn(Thunk::new(move|| f())), }; let (tx, rx) = channel(); run_test(&TestOpts::new(), false, desc, tx); @@ -1528,7 +1530,7 @@ mod tests { ignore: false, should_fail: ShouldFail::Yes(Some("error message")) }, - testfn: DynTestFn(proc() f()), + testfn: DynTestFn(Thunk::new(move|| f())), }; let (tx, rx) = channel(); run_test(&TestOpts::new(), false, desc, tx); @@ -1545,7 +1547,7 @@ mod tests { ignore: false, should_fail: ShouldFail::Yes(Some("foobar")) }, - testfn: DynTestFn(proc() f()), + testfn: DynTestFn(Thunk::new(move|| f())), }; let (tx, rx) = channel(); run_test(&TestOpts::new(), false, desc, tx); @@ -1562,7 +1564,7 @@ mod tests { ignore: false, should_fail: ShouldFail::Yes(None) }, - testfn: DynTestFn(proc() f()), + testfn: DynTestFn(Thunk::new(move|| f())), }; let (tx, rx) = channel(); run_test(&TestOpts::new(), false, desc, tx); @@ -1608,7 +1610,7 @@ mod tests { ignore: true, should_fail: ShouldFail::No, }, - testfn: DynTestFn(proc() {}), + testfn: DynTestFn(Thunk::new(move|| {})), }, TestDescAndFn { desc: TestDesc { @@ -1616,7 +1618,7 @@ mod tests { ignore: false, should_fail: ShouldFail::No, }, - testfn: DynTestFn(proc() {}), + testfn: DynTestFn(Thunk::new(move|| {})), }); let filtered = filter_tests(&opts, tests); @@ -1652,7 +1654,7 @@ mod tests { ignore: false, should_fail: ShouldFail::No, }, - testfn: DynTestFn(testfn), + testfn: DynTestFn(Thunk::new(testfn)), }; tests.push(test); } @@ -1693,7 +1695,7 @@ mod tests { ignore: false, should_fail: ShouldFail::No, }, - testfn: DynTestFn(test_fn) + testfn: DynTestFn(Thunk::new(test_fn)) } }).collect(); let filtered = filter_tests(&opts, tests); diff --git a/src/test/auxiliary/cci_capture_clause.rs b/src/test/auxiliary/cci_capture_clause.rs index 88692cf3f5e3c..1cccb0f7ccbe6 100644 --- a/src/test/auxiliary/cci_capture_clause.rs +++ b/src/test/auxiliary/cci_capture_clause.rs @@ -12,7 +12,7 @@ use std::task; pub fn foo(x: T) -> Receiver { let (tx, rx) = channel(); - task::spawn(proc() { + task::spawn(move|| { tx.send(x.clone()); }); rx diff --git a/src/test/bench/msgsend-pipes-shared.rs b/src/test/bench/msgsend-pipes-shared.rs index cea03f13a4bbd..f20fb8d0cd75e 100644 --- a/src/test/bench/msgsend-pipes-shared.rs +++ b/src/test/bench/msgsend-pipes-shared.rs @@ -64,7 +64,7 @@ fn run(args: &[String]) { let mut worker_results = Vec::new(); for _ in range(0u, workers) { let to_child = to_child.clone(); - worker_results.push(task::try_future(proc() { + worker_results.push(task::try_future(move|| { for _ in range(0u, size / workers) { //println!("worker {}: sending {} bytes", i, num_bytes); to_child.send(request::bytes(num_bytes)); @@ -72,7 +72,7 @@ fn run(args: &[String]) { //println!("worker {} exiting", i); })); } - task::spawn(proc() { + task::spawn(move|| { server(&from_parent, &to_parent); }); diff --git a/src/test/bench/msgsend-pipes.rs b/src/test/bench/msgsend-pipes.rs index 476e7d42d45bb..179011be8bf4e 100644 --- a/src/test/bench/msgsend-pipes.rs +++ b/src/test/bench/msgsend-pipes.rs @@ -58,7 +58,7 @@ fn run(args: &[String]) { let mut worker_results = Vec::new(); let from_parent = if workers == 1 { let (to_child, from_parent) = channel(); - worker_results.push(task::try_future(proc() { + worker_results.push(task::try_future(move|| { for _ in range(0u, size / workers) { //println!("worker {}: sending {} bytes", i, num_bytes); to_child.send(request::bytes(num_bytes)); @@ -70,7 +70,7 @@ fn run(args: &[String]) { let (to_child, from_parent) = channel(); for _ in range(0u, workers) { let to_child = to_child.clone(); - worker_results.push(task::try_future(proc() { + worker_results.push(task::try_future(move|| { for _ in range(0u, size / workers) { //println!("worker {}: sending {} bytes", i, num_bytes); to_child.send(request::bytes(num_bytes)); @@ -80,7 +80,7 @@ fn run(args: &[String]) { } from_parent }; - task::spawn(proc() { + task::spawn(move|| { server(&from_parent, &to_parent); }); diff --git a/src/test/bench/msgsend-ring-mutex-arcs.rs b/src/test/bench/msgsend-ring-mutex-arcs.rs index 863c3c879a7c1..49f53bf9d3883 100644 --- a/src/test/bench/msgsend-ring-mutex-arcs.rs +++ b/src/test/bench/msgsend-ring-mutex-arcs.rs @@ -89,7 +89,7 @@ fn main() { //println!("spawning %?", i); let (new_chan, num_port) = init(); let num_chan_2 = num_chan.clone(); - let new_future = Future::spawn(proc() { + let new_future = Future::spawn(move|| { thread_ring(i, msg_per_task, num_chan_2, num_port) }); futures.push(new_future); diff --git a/src/test/bench/rt-messaging-ping-pong.rs b/src/test/bench/rt-messaging-ping-pong.rs index b00adf4bdb1d4..73d54372b274f 100644 --- a/src/test/bench/rt-messaging-ping-pong.rs +++ b/src/test/bench/rt-messaging-ping-pong.rs @@ -34,7 +34,7 @@ fn ping_pong_bench(n: uint, m: uint) { // Create a stream B->A let (btx, brx) = channel::<()>(); - spawn(proc() { + spawn(move|| { let (tx, rx) = (atx, brx); for _ in range(0, n) { tx.send(()); @@ -42,7 +42,7 @@ fn ping_pong_bench(n: uint, m: uint) { } }); - spawn(proc() { + spawn(move|| { let (tx, rx) = (btx, arx); for _ in range(0, n) { rx.recv(); diff --git a/src/test/bench/rt-parfib.rs b/src/test/bench/rt-parfib.rs index 4072dc0064afb..bdf22cd739588 100644 --- a/src/test/bench/rt-parfib.rs +++ b/src/test/bench/rt-parfib.rs @@ -21,7 +21,7 @@ fn parfib(n: uint) -> uint { } let (tx, rx) = channel(); - spawn(proc() { + spawn(move|| { tx.send(parfib(n-1)); }); let m2 = parfib(n-2); diff --git a/src/test/bench/shootout-binarytrees.rs b/src/test/bench/shootout-binarytrees.rs index 509cb37b2e6ff..0b16e8011e832 100644 --- a/src/test/bench/shootout-binarytrees.rs +++ b/src/test/bench/shootout-binarytrees.rs @@ -95,7 +95,7 @@ fn main() { let mut messages = range_step(min_depth, max_depth + 1, 2).map(|depth| { use std::num::Int; let iterations = 2i.pow((max_depth - depth + min_depth) as uint); - Future::spawn(proc() { + Future::spawn(move|| { let mut chk = 0; for i in range(1, iterations + 1) { let arena = TypedArena::new(); diff --git a/src/test/bench/shootout-chameneos-redux.rs b/src/test/bench/shootout-chameneos-redux.rs index e954d0fed5e59..dcdb90a11c88c 100644 --- a/src/test/bench/shootout-chameneos-redux.rs +++ b/src/test/bench/shootout-chameneos-redux.rs @@ -188,7 +188,7 @@ fn rendezvous(nn: uint, set: Vec) { let to_rendezvous = to_rendezvous.clone(); let to_rendezvous_log = to_rendezvous_log.clone(); let (to_creature, from_rendezvous) = channel(); - spawn(proc() { + spawn(move|| { creature(ii, col, from_rendezvous, diff --git a/src/test/bench/shootout-fannkuch-redux.rs b/src/test/bench/shootout-fannkuch-redux.rs index 4b890bbd8d30e..4849421a3f01e 100644 --- a/src/test/bench/shootout-fannkuch-redux.rs +++ b/src/test/bench/shootout-fannkuch-redux.rs @@ -168,7 +168,7 @@ fn fannkuch(n: i32) -> (i32, i32) { for (i, j) in range(0, N).zip(iter::count(0, k)) { let max = cmp::min(j+k, perm.max()); - futures.push(Future::spawn(proc() { + futures.push(Future::spawn(move|| { work(perm, j as uint, max as uint) })) } diff --git a/src/test/bench/shootout-k-nucleotide-pipes.rs b/src/test/bench/shootout-k-nucleotide-pipes.rs index 45d2cbea8fad9..8c11c3673d527 100644 --- a/src/test/bench/shootout-k-nucleotide-pipes.rs +++ b/src/test/bench/shootout-k-nucleotide-pipes.rs @@ -168,7 +168,7 @@ fn main() { let (to_child, from_parent) = channel(); - spawn(proc() { + spawn(move|| { make_sequence_processor(sz, &from_parent, &to_parent_); }); diff --git a/src/test/bench/shootout-k-nucleotide.rs b/src/test/bench/shootout-k-nucleotide.rs index 847ae2c1c88cc..d112fe60674da 100644 --- a/src/test/bench/shootout-k-nucleotide.rs +++ b/src/test/bench/shootout-k-nucleotide.rs @@ -303,11 +303,11 @@ fn main() { let nb_freqs: Vec<(uint, Future)> = range(1u, 3).map(|i| { let input = input.clone(); - (i, Future::spawn(proc() generate_frequencies(input.as_slice(), i))) + (i, Future::spawn(move|| generate_frequencies(input.as_slice(), i))) }).collect(); let occ_freqs: Vec> = OCCURRENCES.iter().map(|&occ| { let input = input.clone(); - Future::spawn(proc() generate_frequencies(input.as_slice(), occ.len())) + Future::spawn(move|| generate_frequencies(input.as_slice(), occ.len())) }).collect(); for (i, freq) in nb_freqs.into_iter() { diff --git a/src/test/bench/shootout-mandelbrot.rs b/src/test/bench/shootout-mandelbrot.rs index 454b445dea0dc..bb0e09370d8e9 100644 --- a/src/test/bench/shootout-mandelbrot.rs +++ b/src/test/bench/shootout-mandelbrot.rs @@ -82,7 +82,7 @@ fn mandelbrot(w: uint, mut out: W) -> io::IoResult<()> { let mut precalc_i = Vec::with_capacity(h); let precalc_futures = Vec::from_fn(WORKERS, |i| { - Future::spawn(proc () { + Future::spawn(move|| { let mut rs = Vec::with_capacity(w / WORKERS); let mut is = Vec::with_capacity(w / WORKERS); @@ -123,7 +123,7 @@ fn mandelbrot(w: uint, mut out: W) -> io::IoResult<()> { let vec_init_r = arc_init_r.clone(); let vec_init_i = arc_init_i.clone(); - Future::spawn(proc () { + Future::spawn(move|| { let mut res: Vec = Vec::with_capacity((chunk_size * w) / 8); let init_r_slice = vec_init_r.as_slice(); diff --git a/src/test/bench/shootout-meteor.rs b/src/test/bench/shootout-meteor.rs index ca749d47b63bd..9a3b6953062b4 100644 --- a/src/test/bench/shootout-meteor.rs +++ b/src/test/bench/shootout-meteor.rs @@ -310,7 +310,7 @@ fn par_search(masks: Vec>>) -> Data { let masks = masks.clone(); let tx = tx.clone(); let m = *m; - spawn(proc() { + spawn(move|| { let mut data = Data::new(); search(&*masks, m, 1, List::Cons(m, &List::Nil), &mut data); tx.send(data); diff --git a/src/test/bench/shootout-pfib.rs b/src/test/bench/shootout-pfib.rs index 15a5cb0c9bfff..fae6d2cc3aa65 100644 --- a/src/test/bench/shootout-pfib.rs +++ b/src/test/bench/shootout-pfib.rs @@ -34,15 +34,15 @@ fn fib(n: int) -> int { } else { let (tx1, rx) = channel(); let tx2 = tx1.clone(); - task::spawn(proc() pfib(&tx2, n - 1)); + task::spawn(move|| pfib(&tx2, n - 1)); let tx2 = tx1.clone(); - task::spawn(proc() pfib(&tx2, n - 2)); + task::spawn(move|| pfib(&tx2, n - 2)); tx.send(rx.recv() + rx.recv()); } } let (tx, rx) = channel(); - spawn(proc() pfib(&tx, n) ); + spawn(move|| pfib(&tx, n) ); rx.recv() } @@ -77,7 +77,7 @@ fn stress_task(id: int) { fn stress(num_tasks: int) { let mut results = Vec::new(); for i in range(0, num_tasks) { - results.push(task::try_future(proc() { + results.push(task::try_future(move|| { stress_task(i); })); } diff --git a/src/test/bench/shootout-regex-dna.rs b/src/test/bench/shootout-regex-dna.rs index 81de7a1269067..9b8fd51c1c5dd 100644 --- a/src/test/bench/shootout-regex-dna.rs +++ b/src/test/bench/shootout-regex-dna.rs @@ -72,7 +72,7 @@ fn main() { let seq_arc = Arc::new(seq.clone()); // copy before it moves let clen = seq.len(); - let mut seqlen = Future::spawn(proc() { + let mut seqlen = Future::spawn(move|| { let substs = vec![ (regex!("B"), "(c|g|t)"), (regex!("D"), "(a|g|t)"), @@ -108,7 +108,7 @@ fn main() { for variant in variants.into_iter() { let seq_arc_copy = seq_arc.clone(); variant_strs.push(variant.to_string()); - counts.push(Future::spawn(proc() { + counts.push(Future::spawn(move|| { count_matches(seq_arc_copy.as_slice(), &variant) })); } diff --git a/src/test/bench/shootout-reverse-complement.rs b/src/test/bench/shootout-reverse-complement.rs index ffe5739e0bb5e..312ee2dd27e4d 100644 --- a/src/test/bench/shootout-reverse-complement.rs +++ b/src/test/bench/shootout-reverse-complement.rs @@ -236,7 +236,7 @@ fn parallel<'a, I, T, F>(mut iter: I, f: F) // boundary. let f = &f as *const F as *const uint; let raw = chunk.repr(); - spawn(proc() { + spawn(move|| { let f = f as *const F; unsafe { (*f)(mem::transmute(raw)) } drop(tx) diff --git a/src/test/bench/shootout-spectralnorm.rs b/src/test/bench/shootout-spectralnorm.rs index f76391b596bb3..647c47b00a0b7 100644 --- a/src/test/bench/shootout-spectralnorm.rs +++ b/src/test/bench/shootout-spectralnorm.rs @@ -124,7 +124,7 @@ fn parallel<'a, T, F>(v: &'a mut [T], f: F) // boundary. let f = &f as *const _ as *const uint; let raw = chunk.repr(); - spawn(proc() { + spawn(move|| { let f = f as *const F; unsafe { (*f)(i * size, mem::transmute(raw)) } drop(tx) diff --git a/src/test/bench/shootout-threadring.rs b/src/test/bench/shootout-threadring.rs index cda0feb8b55a3..111a92b083aa3 100644 --- a/src/test/bench/shootout-threadring.rs +++ b/src/test/bench/shootout-threadring.rs @@ -43,10 +43,10 @@ fn start(n_tasks: int, token: int) { tx.send(token); for i in range(2, n_tasks + 1) { let (tx, next_rx) = channel(); - spawn(proc() roundtrip(i, tx, rx)); + spawn(move|| roundtrip(i, tx, rx)); rx = next_rx; } - spawn(proc() roundtrip(1, tx, rx)); + spawn(move|| roundtrip(1, tx, rx)); } fn roundtrip(id: int, tx: Sender, rx: Receiver) { diff --git a/src/test/bench/spawnone.rs b/src/test/bench/spawnone.rs index b55f471bdb24d..ca36d99014cf4 100644 --- a/src/test/bench/spawnone.rs +++ b/src/test/bench/spawnone.rs @@ -10,5 +10,5 @@ // Useful for checking syscall usage of baseline scheduler usage fn main() { - spawn(proc() {}); + spawn(move|| {}); } diff --git a/src/test/bench/task-perf-alloc-unwind.rs b/src/test/bench/task-perf-alloc-unwind.rs index 77078b2c68d39..8bcf30b4859ff 100644 --- a/src/test/bench/task-perf-alloc-unwind.rs +++ b/src/test/bench/task-perf-alloc-unwind.rs @@ -36,7 +36,7 @@ fn main() { fn run(repeat: int, depth: int) { for _ in range(0, repeat) { let dur = Duration::span(|| { - task::try(proc() { + task::try(move|| { recurse_or_panic(depth, None) }); }); diff --git a/src/test/bench/task-perf-jargon-metal-smoke.rs b/src/test/bench/task-perf-jargon-metal-smoke.rs index 3d2822e14597f..789ccb6142a11 100644 --- a/src/test/bench/task-perf-jargon-metal-smoke.rs +++ b/src/test/bench/task-perf-jargon-metal-smoke.rs @@ -26,7 +26,7 @@ fn child_generation(gens_left: uint, tx: comm::Sender<()>) { // This used to be O(n^2) in the number of generations that ever existed. // With this code, only as many generations are alive at a time as tasks // alive at a time, - spawn(proc() { + spawn(move|| { if gens_left & 1 == 1 { task::deschedule(); // shake things up a bit } diff --git a/src/test/bench/task-perf-one-million.rs b/src/test/bench/task-perf-one-million.rs index 0f903be39223d..e3b51cb6b5bfd 100644 --- a/src/test/bench/task-perf-one-million.rs +++ b/src/test/bench/task-perf-one-million.rs @@ -21,7 +21,7 @@ fn calc(children: uint, parent_wait_chan: &Sender>>) { let wait_ports: Vec>>> = vec::from_fn(children, |_| { let (wait_port, wait_chan) = stream::>>(); - task::spawn(proc() { + task::spawn(move|| { calc(children / 2, &wait_chan); }); wait_port @@ -58,7 +58,7 @@ fn main() { let children = from_str::(args[1]).unwrap(); let (wait_port, wait_chan) = stream(); - task::spawn(proc() { + task::spawn(move|| { calc(children, &wait_chan); }); diff --git a/src/test/bench/task-perf-spawnalot.rs b/src/test/bench/task-perf-spawnalot.rs index 533005b1fb38c..a6852d396d9cf 100644 --- a/src/test/bench/task-perf-spawnalot.rs +++ b/src/test/bench/task-perf-spawnalot.rs @@ -15,7 +15,7 @@ use std::uint; fn f(n: uint) { let mut i = 0u; while i < n { - task::try(proc() g()); + task::try(move|| g()); i += 1u; } } @@ -33,5 +33,5 @@ fn main() { }; let n = from_str::(args[1].as_slice()).unwrap(); let mut i = 0u; - while i < n { task::spawn(proc() f(n) ); i += 1u; } + while i < n { task::spawn(move|| f(n) ); i += 1u; } } diff --git a/src/test/compile-fail/borrowck-call-sendfn.rs b/src/test/compile-fail/borrowck-call-sendfn.rs deleted file mode 100644 index eb2ea6b3de42f..0000000000000 --- a/src/test/compile-fail/borrowck-call-sendfn.rs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2012-2014 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -struct Foo { - f: proc():'static -} - -fn call(x: Foo) { - x.f(); //~ ERROR does not implement any method in scope named `f` -} - -fn main() {} diff --git a/src/test/compile-fail/borrowck-loan-blocks-move-cc.rs b/src/test/compile-fail/borrowck-loan-blocks-move-cc.rs index b6ecb50fac873..cecb8a09c665a 100644 --- a/src/test/compile-fail/borrowck-loan-blocks-move-cc.rs +++ b/src/test/compile-fail/borrowck-loan-blocks-move-cc.rs @@ -17,7 +17,7 @@ fn borrow(v: &int, f: |x: &int|) { fn box_imm() { let v = box 3i; let _w = &v; - task::spawn(proc() { + task::spawn(move|| { println!("v={}", *v); //~^ ERROR cannot move `v` into closure }); @@ -26,7 +26,7 @@ fn box_imm() { fn box_imm_explicit() { let v = box 3i; let _w = &v; - task::spawn(proc() { + task::spawn(move|| { println!("v={}", *v); //~^ ERROR cannot move }); diff --git a/src/test/compile-fail/borrowck-move-by-capture.rs b/src/test/compile-fail/borrowck-move-by-capture.rs index c52924ebdb789..aae661e5c5379 100644 --- a/src/test/compile-fail/borrowck-move-by-capture.rs +++ b/src/test/compile-fail/borrowck-move-by-capture.rs @@ -11,6 +11,6 @@ pub fn main() { let bar = box 3; let _g = || { - let _h: proc() -> int = proc() *bar; //~ ERROR cannot move out of captured outer variable + let _h = move|| -> int { *bar }; //~ ERROR cannot move out of captured outer variable }; } diff --git a/src/test/compile-fail/borrowck-move-moved-value-into-closure.rs b/src/test/compile-fail/borrowck-move-moved-value-into-closure.rs index b385305d74aaa..ca484738cb6c8 100644 --- a/src/test/compile-fail/borrowck-move-moved-value-into-closure.rs +++ b/src/test/compile-fail/borrowck-move-moved-value-into-closure.rs @@ -8,13 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn call_f(f: proc() -> int) -> int { +fn call_f int>(f: F) -> int { f() } fn main() { let t = box 3; - call_f(proc() { *t + 1 }); - call_f(proc() { *t + 1 }); //~ ERROR capture of moved value + call_f(move|| { *t + 1 }); + call_f(move|| { *t + 1 }); //~ ERROR capture of moved value } diff --git a/src/test/compile-fail/borrowck-multiple-captures.rs b/src/test/compile-fail/borrowck-multiple-captures.rs index 6faa634ad00b8..a9c368fb05258 100644 --- a/src/test/compile-fail/borrowck-multiple-captures.rs +++ b/src/test/compile-fail/borrowck-multiple-captures.rs @@ -17,7 +17,7 @@ fn different_vars_after_borrows() { let p1 = &x1; let x2 = box 2i; let p2 = &x2; - task::spawn(proc() { + task::spawn(move|| { drop(x1); //~ ERROR cannot move `x1` into closure because it is borrowed drop(x2); //~ ERROR cannot move `x2` into closure because it is borrowed }); @@ -30,7 +30,7 @@ fn different_vars_after_moves() { drop(x1); let x2 = box 2i; drop(x2); - task::spawn(proc() { + task::spawn(move|| { drop(x1); //~ ERROR capture of moved value: `x1` drop(x2); //~ ERROR capture of moved value: `x2` }); @@ -39,7 +39,7 @@ fn different_vars_after_moves() { fn same_var_after_borrow() { let x = box 1i; let p = &x; - task::spawn(proc() { + task::spawn(move|| { drop(x); //~ ERROR cannot move `x` into closure because it is borrowed drop(x); //~ ERROR use of moved value: `x` }); @@ -49,7 +49,7 @@ fn same_var_after_borrow() { fn same_var_after_move() { let x = box 1i; drop(x); - task::spawn(proc() { + task::spawn(move|| { drop(x); //~ ERROR capture of moved value: `x` drop(x); //~ ERROR use of moved value: `x` }); diff --git a/src/test/compile-fail/cannot-mutate-captured-non-mut-var.rs b/src/test/compile-fail/cannot-mutate-captured-non-mut-var.rs index daad1afedaaea..143e78e5d9f00 100644 --- a/src/test/compile-fail/cannot-mutate-captured-non-mut-var.rs +++ b/src/test/compile-fail/cannot-mutate-captured-non-mut-var.rs @@ -10,10 +10,10 @@ fn main() { let x = 1i; - proc() { x = 2; }; - //~^ ERROR: cannot assign to immutable captured outer variable in a proc `x` + move|:| { x = 2; }; + //~^ ERROR: cannot assign to immutable captured outer variable let s = std::io::stdin(); - proc() { s.read_to_end(); }; - //~^ ERROR: cannot borrow immutable captured outer variable in a proc `s` as mutable + move|:| { s.read_to_end(); }; + //~^ ERROR: cannot borrow immutable captured outer variable } diff --git a/src/test/compile-fail/coerce-bare-fn-to-closure-and-proc.rs b/src/test/compile-fail/coerce-bare-fn-to-closure-and-proc.rs index 9f258aee746f2..27e339180a6cf 100644 --- a/src/test/compile-fail/coerce-bare-fn-to-closure-and-proc.rs +++ b/src/test/compile-fail/coerce-bare-fn-to-closure-and-proc.rs @@ -12,10 +12,8 @@ fn foo() {} fn main() { let f = foo; + let f_closure: || = f; //~^ ERROR: cannot coerce non-statically resolved bare fn to closure //~^^ HELP: consider embedding the function in a closure - let f_proc: proc() = f; - //~^ ERROR: cannot coerce non-statically resolved bare fn to closure - //~^^ HELP: consider embedding the function in a closure } diff --git a/src/test/compile-fail/issue-10398.rs b/src/test/compile-fail/issue-10398.rs index 9141ab669bbc2..c90f064bf904c 100644 --- a/src/test/compile-fail/issue-10398.rs +++ b/src/test/compile-fail/issue-10398.rs @@ -10,7 +10,7 @@ fn main() { let x = box 1i; - let f: proc() = proc() { + let f = move|:| { let _a = x; drop(x); //~^ ERROR: use of moved value: `x` diff --git a/src/test/compile-fail/issue-11515.rs b/src/test/compile-fail/issue-11515.rs index 82cd38ad5b043..46fcb2ec340f9 100644 --- a/src/test/compile-fail/issue-11515.rs +++ b/src/test/compile-fail/issue-11515.rs @@ -9,10 +9,10 @@ // except according to those terms. struct Test<'s> { - func: ||: 's, + func: Box } fn main() { - let test = box Test { func: proc() {} }; - //~^ ERROR: expected `||`, found `proc()` + let closure: Box = box || (); + let test = box Test { func: closure }; //~ ERROR mismatched types } diff --git a/src/test/compile-fail/issue-11925.rs b/src/test/compile-fail/issue-11925.rs index 5d62c25ea171b..c561f0a696a9f 100644 --- a/src/test/compile-fail/issue-11925.rs +++ b/src/test/compile-fail/issue-11925.rs @@ -11,7 +11,7 @@ fn main() { let r = { let x = box 42i; - let f = proc() &x; //~ ERROR: `x` does not live long enough + let f = move|:| &x; //~ ERROR: `x` does not live long enough f() }; diff --git a/src/test/compile-fail/issue-12041.rs b/src/test/compile-fail/issue-12041.rs index f824a06aed1b3..1878b5f5dea8d 100644 --- a/src/test/compile-fail/issue-12041.rs +++ b/src/test/compile-fail/issue-12041.rs @@ -10,7 +10,7 @@ fn main() { let (tx, rx) = channel(); - spawn(proc() { + spawn(move|| { loop { let tx = tx; //~^ ERROR: use of moved value: `tx` diff --git a/src/test/compile-fail/issue-12127.rs b/src/test/compile-fail/issue-12127.rs index 7889242577029..5f2837d28755d 100644 --- a/src/test/compile-fail/issue-12127.rs +++ b/src/test/compile-fail/issue-12127.rs @@ -8,9 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +fn do_it(x: &int) { } + fn main() { - let f = proc() {}; - (proc() { + let x = box 22; + let f = move|:| do_it(&*x); + (move|:| { f(); f(); //~^ ERROR: use of moved value: `f` diff --git a/src/test/compile-fail/issue-13599.rs b/src/test/compile-fail/issue-13599.rs deleted file mode 100644 index eee23f1feba27..0000000000000 --- a/src/test/compile-fail/issue-13599.rs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2012-2014 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test that a mismatched proc / closure type is correctly reported. - -fn expect_closure(_: ||) {} - -fn expect_proc(_: proc()) {} - -fn main() { - expect_closure(proc() {}); - //~^ ERROR mismatched types: expected `||`, found `proc()` (expected closure, found proc) - - expect_proc(|| {}); - //~^ ERROR mismatched types: expected `proc()`, found `||` (expected proc, found closure) -} diff --git a/src/test/compile-fail/kindck-nonsendable-1.rs b/src/test/compile-fail/kindck-nonsendable-1.rs index d694fd2c79512..c96054afc2f31 100644 --- a/src/test/compile-fail/kindck-nonsendable-1.rs +++ b/src/test/compile-fail/kindck-nonsendable-1.rs @@ -13,14 +13,10 @@ use std::rc::Rc; fn foo(_x: Rc) {} -fn bar() { - let x = Rc::new(3u); - let _: proc():Send = proc() foo(x); //~ ERROR `core::kinds::Send` is not implemented -} +fn bar(_: F) { } -fn bar2() { +fn main() { let x = Rc::new(3u); - let _: proc() = proc() foo(x); + bar(move|| foo(x)); //~ ERROR `core::kinds::Send` is not implemented } -fn main() { } diff --git a/src/test/compile-fail/kindck-send-object.rs b/src/test/compile-fail/kindck-send-object.rs index 4fbb3eab8c416..3b67e98f42ca8 100644 --- a/src/test/compile-fail/kindck-send-object.rs +++ b/src/test/compile-fail/kindck-send-object.rs @@ -27,10 +27,6 @@ fn box_object_with_no_bound_not_ok<'a>() { assert_send::>(); //~ ERROR the trait `core::kinds::Send` is not implemented } -fn proc_with_no_bound_not_ok<'a>() { - assert_send::(); //~ ERROR the trait `core::kinds::Send` is not implemented -} - fn closure_with_no_bound_not_ok<'a>() { assert_send::<||:'static>(); //~ ERROR the trait `core::kinds::Send` is not implemented } @@ -38,7 +34,6 @@ fn closure_with_no_bound_not_ok<'a>() { fn object_with_send_bound_ok() { assert_send::<&'static (Dummy+Send)>(); assert_send::>(); - assert_send::; assert_send::<||:Send>; } diff --git a/src/test/compile-fail/kindck-send-object1.rs b/src/test/compile-fail/kindck-send-object1.rs index 35e928d417c3b..d83a8031c45db 100644 --- a/src/test/compile-fail/kindck-send-object1.rs +++ b/src/test/compile-fail/kindck-send-object1.rs @@ -35,11 +35,6 @@ fn test61() { // closure and object types can have lifetime bounds which make // them not ok -fn test_70<'a>() { - assert_send::(); - //~^ ERROR the trait `core::kinds::Send` is not implemented -} - fn test_71<'a>() { assert_send::>(); //~^ ERROR the trait `core::kinds::Send` is not implemented diff --git a/src/test/compile-fail/moves-based-on-type-capture-clause-bad.rs b/src/test/compile-fail/moves-based-on-type-capture-clause-bad.rs index 97287c147d73f..458e2aaf451a0 100644 --- a/src/test/compile-fail/moves-based-on-type-capture-clause-bad.rs +++ b/src/test/compile-fail/moves-based-on-type-capture-clause-bad.rs @@ -12,7 +12,7 @@ use std::task; fn main() { let x = "Hello world!".to_string(); - task::spawn(proc() { + task::spawn(move|| { println!("{}", x); }); println!("{}", x); //~ ERROR use of moved value diff --git a/src/test/compile-fail/moves-sru-moved-field.rs b/src/test/compile-fail/moves-sru-moved-field.rs index 74e5e6b12027f..2cf7618d92dbc 100644 --- a/src/test/compile-fail/moves-sru-moved-field.rs +++ b/src/test/compile-fail/moves-sru-moved-field.rs @@ -9,7 +9,7 @@ // except according to those terms. -type Noncopyable = proc():'static; +type Noncopyable = Box; struct Foo { copied: int, diff --git a/src/test/compile-fail/no-capture-arc.rs b/src/test/compile-fail/no-capture-arc.rs index a07317176e410..affe979268d21 100644 --- a/src/test/compile-fail/no-capture-arc.rs +++ b/src/test/compile-fail/no-capture-arc.rs @@ -17,7 +17,7 @@ fn main() { let v = vec!(1i, 2, 3, 4, 5, 6, 7, 8, 9, 10); let arc_v = Arc::new(v); - task::spawn(proc() { + task::spawn(move|| { assert_eq!((*arc_v)[3], 4); }); diff --git a/src/test/compile-fail/no-reuse-move-arc.rs b/src/test/compile-fail/no-reuse-move-arc.rs index 9f33f35838e27..60982a84b791e 100644 --- a/src/test/compile-fail/no-reuse-move-arc.rs +++ b/src/test/compile-fail/no-reuse-move-arc.rs @@ -15,7 +15,7 @@ fn main() { let v = vec!(1i, 2, 3, 4, 5, 6, 7, 8, 9, 10); let arc_v = Arc::new(v); - task::spawn(proc() { + task::spawn(move|| { assert_eq!((*arc_v)[3], 4); }); diff --git a/src/test/compile-fail/no-send-res-ports.rs b/src/test/compile-fail/no-send-res-ports.rs index 83dbd9ac1bf72..e1ba36de7c032 100644 --- a/src/test/compile-fail/no-send-res-ports.rs +++ b/src/test/compile-fail/no-send-res-ports.rs @@ -35,9 +35,9 @@ fn main() { let x = foo(Port(Rc::new(()))); - task::spawn(proc() { - let y = x; + task::spawn(move|| { //~^ ERROR `core::kinds::Send` is not implemented + let y = x; println!("{}", y); }); } diff --git a/src/test/compile-fail/regions-proc-bounds.rs b/src/test/compile-fail/obsolete-proc.rs similarity index 70% rename from src/test/compile-fail/regions-proc-bounds.rs rename to src/test/compile-fail/obsolete-proc.rs index 4c95e1eac6d58..5208cdb6ad231 100644 --- a/src/test/compile-fail/regions-proc-bounds.rs +++ b/src/test/compile-fail/obsolete-proc.rs @@ -8,13 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn is_static() {} +// Test that we generate obsolete syntax errors around usages of `proc`. -fn foo<'a>() { - is_static::(); - //~^ ERROR declared lifetime bound not satisfied +fn foo(p: proc()) { } //~ ERROR obsolete syntax: the `proc` type - is_static::(); -} +fn bar() { proc() 1; } //~ ERROR obsolete syntax: `proc` expression fn main() { } diff --git a/src/test/compile-fail/once-cant-call-twice-on-heap.rs b/src/test/compile-fail/once-cant-call-twice-on-heap.rs index 68687773f278f..6441f308f29c6 100644 --- a/src/test/compile-fail/once-cant-call-twice-on-heap.rs +++ b/src/test/compile-fail/once-cant-call-twice-on-heap.rs @@ -14,14 +14,14 @@ #![feature(once_fns)] use std::sync::Arc; -fn foo(blk: proc()) { +fn foo(blk: F) { blk(); blk(); //~ ERROR use of moved value } fn main() { let x = Arc::new(true); - foo(proc() { + foo(move|| { assert!(*x); drop(x); }); diff --git a/src/test/compile-fail/regions-bounded-by-send.rs b/src/test/compile-fail/regions-bounded-by-send.rs index ec679a7dda170..67655f323f065 100644 --- a/src/test/compile-fail/regions-bounded-by-send.rs +++ b/src/test/compile-fail/regions-bounded-by-send.rs @@ -66,11 +66,6 @@ fn object_with_send_bound_not_ok<'a>() { //~^ ERROR declared lifetime bound not satisfied } -fn proc_with_lifetime_not_ok<'a>() { - assert_send::(); - //~^ ERROR not implemented -} - fn closure_with_lifetime_not_ok<'a>() { assert_send::<||:'a>(); //~^ ERROR not implemented diff --git a/src/test/compile-fail/regions-infer-proc-static-upvar.rs b/src/test/compile-fail/regions-infer-proc-static-upvar.rs index 7fe85290da0ec..8b2fdfe7cdd15 100644 --- a/src/test/compile-fail/regions-infer-proc-static-upvar.rs +++ b/src/test/compile-fail/regions-infer-proc-static-upvar.rs @@ -11,14 +11,14 @@ // Test that, when a variable of type `&T` is captured inside a proc, // we correctly infer/require that its lifetime is 'static. -fn foo(_p: proc():'static) { } +fn foo(_p: F) { } static i: int = 3; fn capture_local() { let x = 3i; let y = &x; //~ ERROR `x` does not live long enough - foo(proc() { + foo(move|| { let _a = *y; }); } @@ -26,7 +26,7 @@ fn capture_local() { fn capture_static() { // Legal because &i can have static lifetime: let y = &i; - foo(proc() { + foo(move|| { let _a = *y; }); } diff --git a/src/test/compile-fail/regions-proc-bound-capture.rs b/src/test/compile-fail/regions-proc-bound-capture.rs index e32ef2752566b..0841c1852f883 100644 --- a/src/test/compile-fail/regions-proc-bound-capture.rs +++ b/src/test/compile-fail/regions-proc-bound-capture.rs @@ -8,19 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn borrowed_proc<'a>(x: &'a int) -> proc():'a -> int { +fn borrowed_proc<'a>(x: &'a int) -> Box(int) + 'a> { // This is legal, because the region bound on `proc` // states that it captures `x`. - proc() { - *x - } + box move|| { *x } } -fn static_proc<'a>(x: &'a int) -> proc():'static -> int { +fn static_proc(x: &int) -> Box(int) + 'static> { // This is illegal, because the region bound on `proc` is 'static. - proc() { //~ ERROR captured variable `x` outlives the `proc()` - *x - } + box move|| { *x } //~ ERROR cannot infer } fn main() { } diff --git a/src/test/compile-fail/spawn-non-nil-fn.rs b/src/test/compile-fail/spawn-non-nil-fn.rs index 3a35d9cc309ab..6cc45090b9024 100644 --- a/src/test/compile-fail/spawn-non-nil-fn.rs +++ b/src/test/compile-fail/spawn-non-nil-fn.rs @@ -8,8 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: mismatched types - use std::task; -fn main() { task::spawn(|| -> int { 10 }); } +fn main() { + // We get an error because return type is `->int` and not `->()`. + task::spawn(|| -> int { 10 }); + //~^ ERROR type mismatch +} diff --git a/src/test/run-pass/issue-14039.rs b/src/test/compile-fail/unboxed-closure-feature-gate.rs similarity index 59% rename from src/test/run-pass/issue-14039.rs rename to src/test/compile-fail/unboxed-closure-feature-gate.rs index c017a9dad6446..9bb8037e2c344 100644 --- a/src/test/run-pass/issue-14039.rs +++ b/src/test/compile-fail/unboxed-closure-feature-gate.rs @@ -8,10 +8,18 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Check that parenthetical notation is feature-gated except with the +// `Fn` traits. + +trait Foo { +} + fn main() { - if true { - proc(_) {} - } else { - proc(_: &mut ()) {} - }; + let x: Box; + //~^ ERROR parenthetical notation is only stable when used with the `Fn` family + + // No errors with these: + let x: Box; + let x: Box; + let x: Box; } diff --git a/src/test/compile-fail/kindck-proc-bounds.rs b/src/test/compile-fail/unboxed-closure-sugar-used-on-struct-1.rs similarity index 66% rename from src/test/compile-fail/kindck-proc-bounds.rs rename to src/test/compile-fail/unboxed-closure-sugar-used-on-struct-1.rs index d87d1a33ca131..a6184caf68b1f 100644 --- a/src/test/compile-fail/kindck-proc-bounds.rs +++ b/src/test/compile-fail/unboxed-closure-sugar-used-on-struct-1.rs @@ -8,15 +8,17 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn is_send() {} -fn is_freeze() {} -fn foo<'a>() { - is_send::(); - //~^ ERROR: the trait `core::kinds::Send` is not implemented +// Test that parentheses form doesn't work with struct types appearing in local variables. - is_freeze::(); - //~^ ERROR: the trait `core::kinds::Sync` is not implemented +struct Bar { + f: A, r: R +} + +fn bar() { + let x: Box = panic!(); + //~^ ERROR parenthesized parameters may only be used with a trait } fn main() { } + diff --git a/src/test/run-pass/issue-18883.rs b/src/test/compile-fail/unboxed-closure-sugar-used-on-struct-3.rs similarity index 60% rename from src/test/run-pass/issue-18883.rs rename to src/test/compile-fail/unboxed-closure-sugar-used-on-struct-3.rs index c54844f570b9d..5e16adc4e4247 100644 --- a/src/test/run-pass/issue-18883.rs +++ b/src/test/compile-fail/unboxed-closure-sugar-used-on-struct-3.rs @@ -8,12 +8,22 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Test that we don't ICE due to encountering unsubstituted type -// parameters when untupling FnOnce parameters during translation of -// an unboxing shim. +// Test that parentheses form doesn't work in expression paths. -#![feature(unboxed_closures)] +struct Bar { + f: A, r: R +} + +impl Bar { + fn new() -> Bar { panic!() } +} -fn main() { - let _: Box> = box move |&mut:| {}; +fn bar() { + let b = Box::Bar::::new(); // OK + + let b = Box::Bar::()::new(); + //~^ ERROR expected ident, found `(` } + +fn main() { } + diff --git a/src/test/run-pass/unboxed-closures-unboxing-shim.rs b/src/test/compile-fail/unboxed-closure-sugar-used-on-struct.rs similarity index 66% rename from src/test/run-pass/unboxed-closures-unboxing-shim.rs rename to src/test/compile-fail/unboxed-closure-sugar-used-on-struct.rs index c41aeaa673f80..d5fb505715e90 100644 --- a/src/test/run-pass/unboxed-closures-unboxing-shim.rs +++ b/src/test/compile-fail/unboxed-closure-sugar-used-on-struct.rs @@ -8,12 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(unboxed_closures)] +// Test that parentheses form doesn't work with struct types appearing in argument types. -use std::ops::FnOnce; +struct Bar { + f: A, r: R +} -fn main() { - let task: Box int> = box |: x| x; - assert!(task.call_once((1234i,)) == 1234i); +fn foo(b: Box) { + //~^ ERROR parenthesized parameters may only be used with a trait } +fn main() { } + diff --git a/src/test/compile-fail/unboxed-closures-static-call-wrong-trait.rs b/src/test/compile-fail/unboxed-closures-static-call-wrong-trait.rs index 4fa72b383067d..ddd2649a3fee5 100644 --- a/src/test/compile-fail/unboxed-closures-static-call-wrong-trait.rs +++ b/src/test/compile-fail/unboxed-closures-static-call-wrong-trait.rs @@ -12,6 +12,6 @@ fn main() { let mut_ = |&mut: x| x; - mut_.call((0i, )); //~ ERROR type `closure` does not implement + mut_.call((0i, )); //~ ERROR does not implement any method in scope named `call` } diff --git a/src/test/compile-fail/unused-mut-warning-captured-var.rs b/src/test/compile-fail/unused-mut-warning-captured-var.rs index a3db84b0ac65f..2c000e03ce43a 100644 --- a/src/test/compile-fail/unused-mut-warning-captured-var.rs +++ b/src/test/compile-fail/unused-mut-warning-captured-var.rs @@ -13,5 +13,5 @@ fn main() { let mut x = 1i; //~^ ERROR: variable does not need to be mutable - proc() { println!("{}", x); }; + move|:| { println!("{}", x); }; } diff --git a/src/test/debuginfo/lexical-scope-in-unique-closure.rs b/src/test/debuginfo/lexical-scope-in-unique-closure.rs index 6ed6a2731257a..fa7822495d5f1 100644 --- a/src/test/debuginfo/lexical-scope-in-unique-closure.rs +++ b/src/test/debuginfo/lexical-scope-in-unique-closure.rs @@ -77,7 +77,7 @@ fn main() { zzz(); // #break sentinel(); - let unique_closure: proc(int) = proc(x) { + let unique_closure = |: x:int| { zzz(); // #break sentinel(); diff --git a/src/test/debuginfo/type-names.rs b/src/test/debuginfo/type-names.rs index e7664d1029bd8..d72b080409e1d 100644 --- a/src/test/debuginfo/type-names.rs +++ b/src/test/debuginfo/type-names.rs @@ -167,9 +167,6 @@ // CLOSURES -// gdb-command:whatis some_proc -// gdb-check:type = struct (once proc(int, u8) -> (int, u8), uint) - // gdb-command:whatis stack_closure1 // gdb-check:type = struct (&mut|int|, uint) @@ -322,8 +319,6 @@ fn main() { // how that maps to rustc's internal representation of these forms. // Once closures have reached their 1.0 form, the tests below should // probably be expanded. - let some_proc = (proc(a:int, b:u8) (a, b), 0u); - let stack_closure1 = (|x:int| {}, 0u); let stack_closure2 = (|x:i8, y: f32| { (x as f32) + y }, 0u); diff --git a/src/test/pretty/closure-reform-pretty.rs b/src/test/pretty/closure-reform-pretty.rs index eb20a09477d3c..328d4245eb610 100644 --- a/src/test/pretty/closure-reform-pretty.rs +++ b/src/test/pretty/closure-reform-pretty.rs @@ -13,7 +13,7 @@ // pp-exact -fn call_it(f: proc(String) -> String) { } +fn call_it(f: Box String>) { } fn call_this(f: |&str|: Send) { } diff --git a/src/test/pretty/fn-types.rs b/src/test/pretty/fn-types.rs index ffa6f03909b02..1313af2df3d88 100644 --- a/src/test/pretty/fn-types.rs +++ b/src/test/pretty/fn-types.rs @@ -12,5 +12,4 @@ fn from_foreign_fn(_x: fn()) { } fn from_stack_closure(_x: ||) { } -fn from_unique_closure(_x: proc()) { } fn main() { } diff --git a/src/test/run-fail/extern-panic.rs b/src/test/run-fail/extern-panic.rs index 21a332a46cb59..e7c6dcc2df7e7 100644 --- a/src/test/run-fail/extern-panic.rs +++ b/src/test/run-fail/extern-panic.rs @@ -42,7 +42,7 @@ fn count(n: uint) -> uint { fn main() { for _ in range(0, 10u) { - task::spawn(proc() { + task::spawn(move|| { let result = count(5u); println!("result = %?", result); panic!(); diff --git a/src/test/run-fail/panic-task-name-none.rs b/src/test/run-fail/panic-task-name-none.rs index 3f8abc41ff74a..b363838593209 100644 --- a/src/test/run-fail/panic-task-name-none.rs +++ b/src/test/run-fail/panic-task-name-none.rs @@ -13,7 +13,7 @@ use std::task; fn main() { - let r: Result = task::try(proc() { + let r: Result = task::try(move|| { panic!("test"); 1i }); diff --git a/src/test/run-fail/panic-task-name-owned.rs b/src/test/run-fail/panic-task-name-owned.rs index 0a303475a29ff..3c442861a44a3 100644 --- a/src/test/run-fail/panic-task-name-owned.rs +++ b/src/test/run-fail/panic-task-name-owned.rs @@ -14,7 +14,7 @@ use std::task::TaskBuilder; fn main() { let r: Result = TaskBuilder::new().named("owned name".to_string()) - .try(proc() { + .try(move|| { panic!("test"); 1i }); diff --git a/src/test/run-fail/panic-task-name-send-str.rs b/src/test/run-fail/panic-task-name-send-str.rs index fb4fb5c2f7081..92ebb3b4587af 100644 --- a/src/test/run-fail/panic-task-name-send-str.rs +++ b/src/test/run-fail/panic-task-name-send-str.rs @@ -13,7 +13,7 @@ fn main() { let r: Result = ::std::task::TaskBuilder::new().named("send name".into_cow()) - .try(proc() { + .try(move|| { panic!("test"); 3i }); diff --git a/src/test/run-fail/panic-task-name-static.rs b/src/test/run-fail/panic-task-name-static.rs index 21c019e1a7422..f8dfe9245b438 100644 --- a/src/test/run-fail/panic-task-name-static.rs +++ b/src/test/run-fail/panic-task-name-static.rs @@ -12,7 +12,7 @@ fn main() { let r: Result = - ::std::task::TaskBuilder::new().named("static name").try(proc() { + ::std::task::TaskBuilder::new().named("static name").try(move|| { panic!("test"); }); assert!(r.is_ok()); diff --git a/src/test/run-fail/rt-set-exit-status-panic2.rs b/src/test/run-fail/rt-set-exit-status-panic2.rs index 1cfc6c36a6397..58de34e92a09d 100644 --- a/src/test/run-fail/rt-set-exit-status-panic2.rs +++ b/src/test/run-fail/rt-set-exit-status-panic2.rs @@ -36,7 +36,7 @@ fn r(x:int) -> r { fn main() { error!("whatever"); - task::spawn(proc() { + task::spawn(move|| { let _i = r(5); }); panic!(); diff --git a/src/test/run-make/bootstrap-from-c-with-native/lib.rs b/src/test/run-make/bootstrap-from-c-with-native/lib.rs index 34d9cc48ffe20..d2fd5393834eb 100644 --- a/src/test/run-make/bootstrap-from-c-with-native/lib.rs +++ b/src/test/run-make/bootstrap-from-c-with-native/lib.rs @@ -12,12 +12,13 @@ #![crate_type="dylib"] use std::rt; +use std::thunk::Thunk; #[no_mangle] // this needs to get called from C pub extern "C" fn foo(argc: int, argv: *const *const u8) -> int { - rt::start(argc, argv, proc() { - spawn(proc() { + rt::start(argc, argv, Thunk::new(move|| { + spawn(move|| { println!("hello"); }); - }) + })) } diff --git a/src/test/run-make/static-unwinding/main.rs b/src/test/run-make/static-unwinding/main.rs index 9918fbb1ab701..e2cca4d11f9a9 100644 --- a/src/test/run-make/static-unwinding/main.rs +++ b/src/test/run-make/static-unwinding/main.rs @@ -22,7 +22,7 @@ impl Drop for A { } fn main() { - task::try(proc() { + task::try(move|| { let _a = A; lib::callback(|| panic!()); 1i diff --git a/src/test/run-pass/block-arg-call-as.rs b/src/test/run-pass/block-arg-call-as.rs index fd40f0b4b8002..b4e3662965174 100644 --- a/src/test/run-pass/block-arg-call-as.rs +++ b/src/test/run-pass/block-arg-call-as.rs @@ -8,17 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn asSendfn(f: proc() -> uint) -> uint { - return f(); -} - fn asBlock(f: || -> uint) -> uint { return f(); } pub fn main() { - let x = asSendfn(proc() 22u); - assert_eq!(x, 22u); let x = asBlock(|| 22u); assert_eq!(x, 22u); } diff --git a/src/test/run-pass/block-arg.rs b/src/test/run-pass/block-arg.rs index 4b81654a1d0a2..d017a0dbf9a3b 100644 --- a/src/test/run-pass/block-arg.rs +++ b/src/test/run-pass/block-arg.rs @@ -8,14 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn inty(fun: proc(int) -> int) -> int { - fun(100) -} - -fn booly(fun: proc(bool) -> bool) -> bool { - fun(true) -} - // Check usage and precedence of block arguments in expressions: pub fn main() { let v = vec!(-1.0f64, 0.0, 1.0, 2.0, 3.0); diff --git a/src/test/run-pass/borrowck-move-by-capture-ok.rs b/src/test/run-pass/borrowck-move-by-capture-ok.rs index 48ddf927722a3..a6b142bb12654 100644 --- a/src/test/run-pass/borrowck-move-by-capture-ok.rs +++ b/src/test/run-pass/borrowck-move-by-capture-ok.rs @@ -8,8 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(unboxed_closures)] + pub fn main() { let bar = box 3; - let h: proc() -> int = proc() *bar; + let h = |:| -> int *bar; assert_eq!(h(), 3); } + diff --git a/src/test/run-pass/capturing-logging.rs b/src/test/run-pass/capturing-logging.rs index a6744585e47a3..f2df5ef38c382 100644 --- a/src/test/run-pass/capturing-logging.rs +++ b/src/test/run-pass/capturing-logging.rs @@ -32,7 +32,7 @@ impl Logger for MyWriter { fn main() { let (tx, rx) = channel(); let (mut r, w) = (ChanReader::new(rx), ChanWriter::new(tx)); - spawn(proc() { + spawn(move|| { set_logger(box MyWriter(w) as Box); debug!("debug"); info!("info"); diff --git a/src/test/run-pass/child-outlives-parent.rs b/src/test/run-pass/child-outlives-parent.rs index 82855729fa882..bdd92919ef05b 100644 --- a/src/test/run-pass/child-outlives-parent.rs +++ b/src/test/run-pass/child-outlives-parent.rs @@ -15,5 +15,5 @@ use std::task; fn child2(_s: String) { } pub fn main() { - let _x = task::spawn(proc() child2("hi".to_string())); + let _x = task::spawn(move|| child2("hi".to_string())); } diff --git a/src/test/run-pass/clone-with-exterior.rs b/src/test/run-pass/clone-with-exterior.rs index f676a6f09594e..d3c703b258f73 100644 --- a/src/test/run-pass/clone-with-exterior.rs +++ b/src/test/run-pass/clone-with-exterior.rs @@ -18,10 +18,8 @@ struct Pair { pub fn main() { let z = box Pair { a : 10, b : 12}; - let f: proc():Send = proc() { + spawn(move|| { assert_eq!(z.a, 10); assert_eq!(z.b, 12); - }; - - spawn(f); + }); } diff --git a/src/test/run-pass/closure-bounds-can-capture-chan.rs b/src/test/run-pass/closure-bounds-can-capture-chan.rs index 3c4b7236ad50f..cdcdad47ea497 100644 --- a/src/test/run-pass/closure-bounds-can-capture-chan.rs +++ b/src/test/run-pass/closure-bounds-can-capture-chan.rs @@ -8,15 +8,17 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(unboxed_closures)] + use std::comm; -fn foo(blk: proc()) { +fn foo(blk: F) { blk(); } pub fn main() { let (tx, rx) = channel(); - foo(proc() { + foo(move || { tx.send(()); }); rx.recv(); diff --git a/src/test/run-pass/closure-reform.rs b/src/test/run-pass/closure-reform.rs index aa4d48e5ae0e1..03d9511b41c78 100644 --- a/src/test/run-pass/closure-reform.rs +++ b/src/test/run-pass/closure-reform.rs @@ -11,10 +11,14 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ +#![feature(unboxed_closures)] + use std::mem; use std::io::stdio::println; -fn call_it(f: proc(String) -> String) { +fn call_it(f: F) + where F : FnOnce(String) -> String +{ println!("{}", f("Fred".to_string())) } @@ -49,15 +53,15 @@ pub fn main() { // Procs let greeting = "Hello ".to_string(); - call_it(proc(s) { + call_it(|s| { format!("{}{}", greeting, s) }); let greeting = "Goodbye ".to_string(); - call_it(proc(s) format!("{}{}", greeting, s)); + call_it(|s| format!("{}{}", greeting, s)); let greeting = "How's life, ".to_string(); - call_it(proc(s: String) -> String { + call_it(|s: String| -> String { format!("{}{}", greeting, s) }); diff --git a/src/test/run-pass/closure-syntax.rs b/src/test/run-pass/closure-syntax.rs index 6716c3468d0f8..4caa234ac7ae3 100644 --- a/src/test/run-pass/closure-syntax.rs +++ b/src/test/run-pass/closure-syntax.rs @@ -15,35 +15,23 @@ fn foo() {} -trait Bar1 {} -impl Bar1 for proc():'static {} - -trait Bar2 {} -impl Bar2 for proc():Send {} - trait Bar3 {} impl<'b> Bar3 for <'a>|&'a int|: 'b + Send -> &'a int {} -trait Bar4 {} -impl Bar4 for proc<'a>(&'a int):'static -> &'a int {} - struct Foo<'a> { a: ||: 'a, b: ||: 'static, c: <'b>||: 'a, d: ||: 'a + Sync, e: <'b>|int|: 'a + Sync -> &'b f32, - f: proc():'static, - g: proc():'static+Sync, - h: proc<'b>(int):'static+Sync -> &'b f32, } fn f<'a>(a: &'a int, f: <'b>|&'b int| -> &'b int) -> &'a int { f(a) } -fn g<'a>(a: &'a int, f: proc<'b>(&'b int) -> &'b int) -> &'a int { - f(a) +fn g<'a>(a: &'a int) -> &'a int { + a } struct A; @@ -60,11 +48,6 @@ fn bar<'b>() { foo::<||:'b + Sync>(); foo::<||:Sync>(); foo::< <'a>|int, f32, &'a int|:'b + Sync -> &'a int>(); - foo::(); - foo:: ()>(); - foo::(); - foo::(); - foo::(int, f32, &'a int):'static + Sync -> &'a int>(); foo::<<'a>||>(); @@ -84,7 +67,6 @@ fn bar<'b>() { // issue #13490 let _ = || -> ! loop {}; - let _ = proc() -> ! loop {}; // issue #17021 let c = box |&:| {}; diff --git a/src/test/run-pass/coerce-to-closure-and-proc.rs b/src/test/run-pass/coerce-to-closure-and-proc.rs index 6dbc402e7852c..5a1b401177e01 100644 --- a/src/test/run-pass/coerce-to-closure-and-proc.rs +++ b/src/test/run-pass/coerce-to-closure-and-proc.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(unboxed_closures)] + fn id(x: T) -> T { x } @@ -24,24 +26,12 @@ pub fn main() { let f: |int| -> int = id; assert_eq!(f(5), 5); - let f: proc(int) -> int = id; - assert_eq!(f(5), 5); - let f: |int| -> Foo = Foo; assert_eq!(f(5), Foo(5)); - let f: proc(int) -> Foo = Foo; - assert_eq!(f(5), Foo(5)); - let f: |int| -> Bar = Bar::Baz; assert_eq!(f(5), Bar::Baz(5)); - let f: proc(int) -> Bar = Bar::Baz; - assert_eq!(f(5), Bar::Baz(5)); - let f: |int| -> Option = Some; assert_eq!(f(5), Some(5)); - - let f: proc(int) -> Option = Some; - assert_eq!(f(5), Some(5)); } diff --git a/src/test/run-pass/comm.rs b/src/test/run-pass/comm.rs index 18cc92f335dff..edd4d5642b5bf 100644 --- a/src/test/run-pass/comm.rs +++ b/src/test/run-pass/comm.rs @@ -12,7 +12,7 @@ use std::task; pub fn main() { let (tx, rx) = channel(); - let _t = task::spawn(proc() { child(&tx) }); + let _t = task::spawn(move|| { child(&tx) }); let y = rx.recv(); println!("received"); println!("{}", y); diff --git a/src/test/run-pass/core-run-destroy.rs b/src/test/run-pass/core-run-destroy.rs index d8dfb433e6d49..4e625ce1d1f96 100644 --- a/src/test/run-pass/core-run-destroy.rs +++ b/src/test/run-pass/core-run-destroy.rs @@ -84,7 +84,7 @@ pub fn test_destroy_actually_kills(force: bool) { let (tx, rx1) = channel(); let mut t = timer::Timer::new().unwrap(); let rx2 = t.oneshot(Duration::milliseconds(1000)); - spawn(proc() { + spawn(move|| { select! { () = rx2.recv() => unsafe { libc::exit(1) }, () = rx1.recv() => {} diff --git a/src/test/run-pass/drop-trait-enum.rs b/src/test/run-pass/drop-trait-enum.rs index 15f028e1716f0..24915d84e7eb1 100644 --- a/src/test/run-pass/drop-trait-enum.rs +++ b/src/test/run-pass/drop-trait-enum.rs @@ -65,7 +65,7 @@ pub fn main() { assert_eq!(receiver.recv_opt().ok(), None); let (sender, receiver) = channel(); - task::spawn(proc() { + task::spawn(move|| { let v = Foo::FailingVariant { on_drop: SendOnDrop { sender: sender } }; }); assert_eq!(receiver.recv(), Message::Dropped); @@ -73,7 +73,7 @@ pub fn main() { let (sender, receiver) = channel(); { - task::spawn(proc() { + task::spawn(move|| { let mut v = Foo::NestedVariant(box 42u, SendOnDrop { sender: sender.clone() }, sender.clone()); diff --git a/src/test/run-pass/enum-null-pointer-opt.rs b/src/test/run-pass/enum-null-pointer-opt.rs index 3e22c83318393..2d4819231fad0 100644 --- a/src/test/run-pass/enum-null-pointer-opt.rs +++ b/src/test/run-pass/enum-null-pointer-opt.rs @@ -14,8 +14,7 @@ use std::mem::size_of; trait Trait {} fn main() { - // Closures - || / proc() - assert_eq!(size_of::(), size_of::>()); + // Closures - || assert_eq!(size_of::<||>(), size_of::>()); // Functions diff --git a/src/test/run-pass/explicit-self-generic.rs b/src/test/run-pass/explicit-self-generic.rs index eeda299c71fa6..87f1adba8ddcf 100644 --- a/src/test/run-pass/explicit-self-generic.rs +++ b/src/test/run-pass/explicit-self-generic.rs @@ -8,14 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -/** - * A function that returns a hash of a value - * - * The hash should concentrate entropy in the lower bits. - */ -type HashFn = proc(K):'static -> uint; -type EqFn = proc(K, K):'static -> bool; - struct LM { resize_at: uint, size: uint } impl Copy for LM {} diff --git a/src/test/run-pass/extern-call-deep2.rs b/src/test/run-pass/extern-call-deep2.rs index bc5ccc30c527c..aed1392c8b68b 100644 --- a/src/test/run-pass/extern-call-deep2.rs +++ b/src/test/run-pass/extern-call-deep2.rs @@ -40,7 +40,7 @@ fn count(n: libc::uintptr_t) -> libc::uintptr_t { pub fn main() { // Make sure we're on a task with small Rust stacks (main currently // has a large stack) - task::spawn(proc() { + task::spawn(move|| { let result = count(1000); println!("result = {}", result); assert_eq!(result, 1000); diff --git a/src/test/run-pass/extern-call-scrub.rs b/src/test/run-pass/extern-call-scrub.rs index ae9430370d520..3f5faabe59598 100644 --- a/src/test/run-pass/extern-call-scrub.rs +++ b/src/test/run-pass/extern-call-scrub.rs @@ -44,7 +44,7 @@ fn count(n: libc::uintptr_t) -> libc::uintptr_t { pub fn main() { // Make sure we're on a task with small Rust stacks (main currently // has a large stack) - task::spawn(proc() { + task::spawn(move|| { let result = count(12); println!("result = {}", result); assert_eq!(result, 2048); diff --git a/src/test/run-pass/extern-stress.rs b/src/test/run-pass/extern-stress.rs index 87d96880e4bd3..8b080712b9661 100644 --- a/src/test/run-pass/extern-stress.rs +++ b/src/test/run-pass/extern-stress.rs @@ -42,7 +42,7 @@ fn count(n: libc::uintptr_t) -> libc::uintptr_t { pub fn main() { for _ in range(0u, 100) { - task::spawn(proc() { + task::spawn(move|| { assert_eq!(count(5), 16); }); } diff --git a/src/test/run-pass/extern-yield.rs b/src/test/run-pass/extern-yield.rs index 7fb68e9f8a038..1c89d8ae1ce9d 100644 --- a/src/test/run-pass/extern-yield.rs +++ b/src/test/run-pass/extern-yield.rs @@ -39,7 +39,7 @@ fn count(n: libc::uintptr_t) -> libc::uintptr_t { pub fn main() { for _ in range(0, 10u) { - task::spawn(proc() { + task::spawn(move|| { let result = count(5); println!("result = {}", result); assert_eq!(result, 16); diff --git a/src/test/run-pass/foreign-call-no-runtime.rs b/src/test/run-pass/foreign-call-no-runtime.rs index af36387f06c2c..3f659f1dbfbf7 100644 --- a/src/test/run-pass/foreign-call-no-runtime.rs +++ b/src/test/run-pass/foreign-call-no-runtime.rs @@ -22,7 +22,7 @@ extern { pub fn main() { unsafe { - Thread::start(proc() { + Thread::start(move|| { let i = &100i; rust_dbg_call(callback, mem::transmute(i)); }).join(); diff --git a/src/test/run-pass/hashmap-memory.rs b/src/test/run-pass/hashmap-memory.rs index 8efd3af4bcedb..a92b361dd3355 100644 --- a/src/test/run-pass/hashmap-memory.rs +++ b/src/test/run-pass/hashmap-memory.rs @@ -37,7 +37,7 @@ mod map_reduce { for i in inputs.iter() { let ctrl = ctrl.clone(); let i = i.clone(); - task::spawn(proc() map_task(ctrl.clone(), i.clone()) ); + task::spawn(move|| map_task(ctrl.clone(), i.clone()) ); } } diff --git a/src/test/run-pass/hrtb-parse.rs b/src/test/run-pass/hrtb-parse.rs index 02d3bc120da8c..53749f09f741e 100644 --- a/src/test/run-pass/hrtb-parse.rs +++ b/src/test/run-pass/hrtb-parse.rs @@ -43,7 +43,5 @@ fn foo23(t: for<'a> unsafe extern "C" fn(int) -> int) { } fn foo30(t: for<'a> |int| -> int) { } fn foo31(t: for<'a> unsafe |int| -> int) { } -//fn foo40(t: for<'a> proc(int) -> int) { } - fn main() { } diff --git a/src/test/run-pass/infinite-loops.rs b/src/test/run-pass/infinite-loops.rs index f4de938c66e7d..e4168ea145212 100644 --- a/src/test/run-pass/infinite-loops.rs +++ b/src/test/run-pass/infinite-loops.rs @@ -15,7 +15,7 @@ // ignore-test fn loopy(n: int) { - if n > 0 { spawn(proc() { loopy(n - 1) }); spawn(proc() { loopy(n - 1) }); } + if n > 0 { spawn(move|| { loopy(n - 1) }); spawn(move|| { loopy(n - 1) }); } loop { } } @@ -23,5 +23,5 @@ pub fn main() { // Commenting this out, as this will hang forever otherwise. // Even after seeing the comment above, I'm not sure what the // intention of this test is. - // spawn(proc() { loopy(5) }); + // spawn(move|| { loopy(5) }); } diff --git a/src/test/run-pass/issue-10682.rs b/src/test/run-pass/issue-10682.rs index f2f8b17daa264..fd0ad1ef47ecb 100644 --- a/src/test/run-pass/issue-10682.rs +++ b/src/test/run-pass/issue-10682.rs @@ -11,11 +11,10 @@ // Regression test for issue #10682 // Nested `proc` usage can't use outer owned data - fn work(_: Box) {} -fn foo(_: proc()) {} +fn foo(_: F) {} pub fn main() { let a = box 1; - foo(proc() { foo(proc() { work(a) }) }) + foo(move|| { foo(move|| { work(a) }) }) } diff --git a/src/test/run-pass/issue-10718.rs b/src/test/run-pass/issue-10718.rs index 34804eda287cd..71b4cbe933427 100644 --- a/src/test/run-pass/issue-10718.rs +++ b/src/test/run-pass/issue-10718.rs @@ -8,11 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn f(p: proc()) { +#![feature(unboxed_closures)] + +fn f(p: F) { p(); } pub fn main() { - let p = proc() (); + let p = |:| (); f(p); } diff --git a/src/test/run-pass/issue-11709.rs b/src/test/run-pass/issue-11709.rs index 0567a5836abfa..f9d7956793297 100644 --- a/src/test/run-pass/issue-11709.rs +++ b/src/test/run-pass/issue-11709.rs @@ -15,14 +15,17 @@ // when this bug was opened. The cases where the compiler // panics before the fix have a comment. -struct S {x:()} +#![feature(default_type_params)] + +use std::thunk::Thunk; +struct S {x:()} -fn test(slot: &mut Option proc()>, _: proc()) -> () { +fn test(slot: &mut Option>) -> () { let a = slot.take(); let _a = match a { // `{let .. a(); }` would break - Some(a) => { let _a = a(); }, + Some(a) => { let _a = a.invoke(()); }, None => (), }; } @@ -41,7 +44,7 @@ pub fn main() { let _r = {}; let mut slot = None; // `{ test(...); }` would break - let _s : S = S{ x: { test(&mut slot, proc() {}); } }; + let _s : S = S{ x: { test(&mut slot); } }; let _b = not(true); } diff --git a/src/test/run-pass/issue-11958.rs b/src/test/run-pass/issue-11958.rs index f4ed7c5d9c871..13177880c5ab7 100644 --- a/src/test/run-pass/issue-11958.rs +++ b/src/test/run-pass/issue-11958.rs @@ -16,7 +16,9 @@ // We shouldn't need to rebind a moved upvar as mut if it's already // marked as mut +use std::thunk::Thunk; + pub fn main() { let mut x = 1i; - proc() { x = 2; }; + let _thunk = Thunk::new(move|| { x = 2; }); } diff --git a/src/test/run-pass/issue-12684.rs b/src/test/run-pass/issue-12684.rs index c3aba9e8dc954..e24cf5a0f2670 100644 --- a/src/test/run-pass/issue-12684.rs +++ b/src/test/run-pass/issue-12684.rs @@ -11,7 +11,7 @@ use std::time::Duration; fn main() { - std::task::spawn(proc() customtask()); + std::task::spawn(move|| customtask()); } fn customtask() { diff --git a/src/test/run-pass/issue-13352.rs b/src/test/run-pass/issue-13352.rs index afebcb3cdfc7d..46a81301dc3cf 100644 --- a/src/test/run-pass/issue-13352.rs +++ b/src/test/run-pass/issue-13352.rs @@ -10,7 +10,9 @@ extern crate libc; -fn foo(_: proc()) {} +use std::thunk::Thunk; + +fn foo(_: Thunk) {} fn main() { foo(loop { diff --git a/src/test/run-pass/issue-13494.rs b/src/test/run-pass/issue-13494.rs index 9fe41f7e0243e..be851ddefc645 100644 --- a/src/test/run-pass/issue-13494.rs +++ b/src/test/run-pass/issue-13494.rs @@ -19,7 +19,7 @@ fn helper(rx: Receiver>) { fn main() { let (tx, rx) = channel(); - spawn(proc() { helper(rx) }); + spawn(move|| { helper(rx) }); let (snd, rcv) = channel::(); for _ in range(1i, 100000i) { snd.send(1i); diff --git a/src/test/run-pass/issue-15571.rs b/src/test/run-pass/issue-15571.rs index 0ef0fc83c9456..03d18cf8c9815 100644 --- a/src/test/run-pass/issue-15571.rs +++ b/src/test/run-pass/issue-15571.rs @@ -45,7 +45,7 @@ fn match_on_binding() { fn match_on_upvar() { let mut foo = Some(box 8i); - (proc() { + let f = move|:| { match foo { None => {}, Some(x) => { @@ -53,7 +53,8 @@ fn match_on_upvar() { } } println!("'{}'", foo.unwrap()); - })(); + }; + f(); } fn main() { diff --git a/src/test/run-pass/issue-16560.rs b/src/test/run-pass/issue-16560.rs index 77eba0245b1c3..f329e7eed0d5d 100644 --- a/src/test/run-pass/issue-16560.rs +++ b/src/test/run-pass/issue-16560.rs @@ -19,7 +19,7 @@ fn main() { // Check that both closures are capturing by value assert_eq!(1, mem::size_of_val(&closure)); - spawn(proc() { + spawn(move|| { let ok = closure; }) } diff --git a/src/test/run-pass/issue-16671.rs b/src/test/run-pass/issue-16671.rs index 20bf1b260de68..c695a9e8f9abc 100644 --- a/src/test/run-pass/issue-16671.rs +++ b/src/test/run-pass/issue-16671.rs @@ -20,7 +20,7 @@ pub fn main() { let mut stdin = std::io::stdin(); - spawn(proc() { + spawn(move|| { let _ = stdin.read_to_end(); }); } diff --git a/src/test/run-pass/issue-16739.rs b/src/test/run-pass/issue-16739.rs index 6dcdc1d1086c3..552ce565f6b17 100644 --- a/src/test/run-pass/issue-16739.rs +++ b/src/test/run-pass/issue-16739.rs @@ -11,29 +11,29 @@ #![feature(unboxed_closures)] // Test that unboxing shim for calling rust-call ABI methods through a -// trait box works and does not cause an ICE +// trait box works and does not cause an ICE. struct Foo { foo: uint } -impl FnOnce<(), uint> for Foo { - extern "rust-call" fn call_once(self, _: ()) -> uint { self.foo } +impl FnMut<(), uint> for Foo { + extern "rust-call" fn call_mut(&mut self, _: ()) -> uint { self.foo } } -impl FnOnce<(uint,), uint> for Foo { - extern "rust-call" fn call_once(self, (x,): (uint,)) -> uint { self.foo + x } +impl FnMut<(uint,), uint> for Foo { + extern "rust-call" fn call_mut(&mut self, (x,): (uint,)) -> uint { self.foo + x } } -impl FnOnce<(uint, uint), uint> for Foo { - extern "rust-call" fn call_once(self, (x, y): (uint, uint)) -> uint { self.foo + x + y } +impl FnMut<(uint, uint), uint> for Foo { + extern "rust-call" fn call_mut(&mut self, (x, y): (uint, uint)) -> uint { self.foo + x + y } } fn main() { - let f = box Foo { foo: 42 } as Box>; - assert_eq!(f.call_once(()), 42); + let mut f = box Foo { foo: 42 } as Box>; + assert_eq!(f.call_mut(()), 42); - let f = box Foo { foo: 40 } as Box>; - assert_eq!(f.call_once((2,)), 42); + let mut f = box Foo { foo: 40 } as Box>; + assert_eq!(f.call_mut((2,)), 42); - let f = box Foo { foo: 40 } as Box>; - assert_eq!(f.call_once((1, 1)), 42); + let mut f = box Foo { foo: 40 } as Box>; + assert_eq!(f.call_mut((1, 1)), 42); } diff --git a/src/test/run-pass/issue-2190-1.rs b/src/test/run-pass/issue-2190-1.rs index 4ff735708b5ab..3554f2e8f0c31 100644 --- a/src/test/run-pass/issue-2190-1.rs +++ b/src/test/run-pass/issue-2190-1.rs @@ -9,19 +9,20 @@ // except according to those terms. use std::task::TaskBuilder; +use std::thunk::Thunk; static generations: uint = 1024+256+128+49; -fn spawn(f: proc():Send) { - TaskBuilder::new().stack_size(32 * 1024).spawn(f) +fn spawn(f: Thunk) { + TaskBuilder::new().stack_size(32 * 1024).spawn(move|| f.invoke(())) } -fn child_no(x: uint) -> proc():Send { - proc() { +fn child_no(x: uint) -> Thunk { + Thunk::new(move|| { if x < generations { spawn(child_no(x+1)); } - } + }) } pub fn main() { diff --git a/src/test/run-pass/issue-3424.rs b/src/test/run-pass/issue-3424.rs index 81efacb9bcbad..651315ea64173 100644 --- a/src/test/run-pass/issue-3424.rs +++ b/src/test/run-pass/issue-3424.rs @@ -11,20 +11,23 @@ // rustc --test ignores2.rs && ./ignores2 +#![feature(unboxed_closures)] + use std::path::{Path}; use std::path; use std::result; +use std::thunk::Thunk; -type rsrc_loader = proc(path: &Path):'static -> result::Result; +type rsrc_loader = Box (result::Result) + 'static>; fn tester() { - let loader: rsrc_loader = proc(_path) { + let mut loader: rsrc_loader = box move|_path| { result::Result::Ok("more blah".to_string()) }; let path = path::Path::new("blah"); - assert!(loader(&path).is_ok()); + assert!(loader.call_mut((&path,)).is_ok()); } pub fn main() {} diff --git a/src/test/run-pass/issue-3609.rs b/src/test/run-pass/issue-3609.rs index be5387b23c29c..f17f9411d15e8 100644 --- a/src/test/run-pass/issue-3609.rs +++ b/src/test/run-pass/issue-3609.rs @@ -8,10 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(default_type_params)] + use std::task; +use std::thunk::Invoke; type RingBuffer = Vec ; -type SamplesFn = proc(samples: &RingBuffer):Send; +type SamplesFn = Box; enum Msg { @@ -19,13 +22,16 @@ enum Msg } fn foo(name: String, samples_chan: Sender) { - task::spawn(proc() { + task::spawn(move|| { let mut samples_chan = samples_chan; - let callback: SamplesFn = proc(buffer) { + + // `box() (...)` syntax is needed to make pretty printer converge in one try: + let callback: SamplesFn = box() (move |buffer| { for i in range(0u, buffer.len()) { println!("{}: {}", i, buffer[i]) } - }; + }); + samples_chan.send(Msg::GetSamples(name.clone(), callback)); }); } diff --git a/src/test/run-pass/issue-4446.rs b/src/test/run-pass/issue-4446.rs index 2266e62eb77cb..daa80aec28c04 100644 --- a/src/test/run-pass/issue-4446.rs +++ b/src/test/run-pass/issue-4446.rs @@ -15,7 +15,7 @@ pub fn main() { tx.send("hello, world"); - spawn(proc() { + spawn(move|| { println(rx.recv()); }); } diff --git a/src/test/run-pass/issue-4448.rs b/src/test/run-pass/issue-4448.rs index dda90ef1a0fbd..3ea968c416f45 100644 --- a/src/test/run-pass/issue-4448.rs +++ b/src/test/run-pass/issue-4448.rs @@ -13,7 +13,7 @@ use std::task; pub fn main() { let (tx, rx) = channel::<&'static str>(); - task::spawn(proc() { + task::spawn(move|| { assert_eq!(rx.recv(), "hello, world"); }); diff --git a/src/test/run-pass/issue-8460.rs b/src/test/run-pass/issue-8460.rs index 762152c92038f..b9b365e3e660a 100644 --- a/src/test/run-pass/issue-8460.rs +++ b/src/test/run-pass/issue-8460.rs @@ -12,24 +12,24 @@ use std::{int, i8, i16, i32, i64}; use std::task; fn main() { - assert!(task::try(proc() int::MIN / -1).is_err()); - assert!(task::try(proc() i8::MIN / -1).is_err()); - assert!(task::try(proc() i16::MIN / -1).is_err()); - assert!(task::try(proc() i32::MIN / -1).is_err()); - assert!(task::try(proc() i64::MIN / -1).is_err()); - assert!(task::try(proc() 1i / 0).is_err()); - assert!(task::try(proc() 1i8 / 0).is_err()); - assert!(task::try(proc() 1i16 / 0).is_err()); - assert!(task::try(proc() 1i32 / 0).is_err()); - assert!(task::try(proc() 1i64 / 0).is_err()); - assert!(task::try(proc() int::MIN % -1).is_err()); - assert!(task::try(proc() i8::MIN % -1).is_err()); - assert!(task::try(proc() i16::MIN % -1).is_err()); - assert!(task::try(proc() i32::MIN % -1).is_err()); - assert!(task::try(proc() i64::MIN % -1).is_err()); - assert!(task::try(proc() 1i % 0).is_err()); - assert!(task::try(proc() 1i8 % 0).is_err()); - assert!(task::try(proc() 1i16 % 0).is_err()); - assert!(task::try(proc() 1i32 % 0).is_err()); - assert!(task::try(proc() 1i64 % 0).is_err()); + assert!(task::try(move|| int::MIN / -1).is_err()); + assert!(task::try(move|| i8::MIN / -1).is_err()); + assert!(task::try(move|| i16::MIN / -1).is_err()); + assert!(task::try(move|| i32::MIN / -1).is_err()); + assert!(task::try(move|| i64::MIN / -1).is_err()); + assert!(task::try(move|| 1i / 0).is_err()); + assert!(task::try(move|| 1i8 / 0).is_err()); + assert!(task::try(move|| 1i16 / 0).is_err()); + assert!(task::try(move|| 1i32 / 0).is_err()); + assert!(task::try(move|| 1i64 / 0).is_err()); + assert!(task::try(move|| int::MIN % -1).is_err()); + assert!(task::try(move|| i8::MIN % -1).is_err()); + assert!(task::try(move|| i16::MIN % -1).is_err()); + assert!(task::try(move|| i32::MIN % -1).is_err()); + assert!(task::try(move|| i64::MIN % -1).is_err()); + assert!(task::try(move|| 1i % 0).is_err()); + assert!(task::try(move|| 1i8 % 0).is_err()); + assert!(task::try(move|| 1i16 % 0).is_err()); + assert!(task::try(move|| 1i32 % 0).is_err()); + assert!(task::try(move|| 1i64 % 0).is_err()); } diff --git a/src/test/run-pass/issue-8827.rs b/src/test/run-pass/issue-8827.rs index 173414d1d41cb..7397ad744950e 100644 --- a/src/test/run-pass/issue-8827.rs +++ b/src/test/run-pass/issue-8827.rs @@ -10,7 +10,7 @@ fn periodical(n: int) -> Receiver { let (chan, port) = channel(); - spawn(proc() { + spawn(move|| { loop { for _ in range(1, n) { match chan.send_opt(false) { @@ -29,7 +29,7 @@ fn periodical(n: int) -> Receiver { fn integers() -> Receiver { let (chan, port) = channel(); - spawn(proc() { + spawn(move|| { let mut i = 1; loop { match chan.send_opt(i) { diff --git a/src/test/run-pass/issue-9396.rs b/src/test/run-pass/issue-9396.rs index c16319a16f282..588e0c1cf16cf 100644 --- a/src/test/run-pass/issue-9396.rs +++ b/src/test/run-pass/issue-9396.rs @@ -14,7 +14,7 @@ use std::time::Duration; pub fn main() { let (tx, rx) = channel(); - spawn(proc (){ + spawn(move||{ let mut timer = Timer::new().unwrap(); timer.sleep(Duration::milliseconds(10)); tx.send(()); diff --git a/src/test/run-pass/ivec-tag.rs b/src/test/run-pass/ivec-tag.rs index 81ff6fd7adc94..1f7edcf43b887 100644 --- a/src/test/run-pass/ivec-tag.rs +++ b/src/test/run-pass/ivec-tag.rs @@ -18,7 +18,7 @@ fn producer(tx: &Sender>) { pub fn main() { let (tx, rx) = channel::>(); - let _prod = task::spawn(proc() { + let _prod = task::spawn(move|| { producer(&tx) }); diff --git a/src/test/run-pass/kindck-implicit-close-over-mut-var.rs b/src/test/run-pass/kindck-implicit-close-over-mut-var.rs index 3f45e864da35a..d745226af4408 100644 --- a/src/test/run-pass/kindck-implicit-close-over-mut-var.rs +++ b/src/test/run-pass/kindck-implicit-close-over-mut-var.rs @@ -16,7 +16,7 @@ fn foo() { // Here, i is *copied* into the proc (heap closure). // Requires allocation. The proc's copy is not mutable. let mut i = 0; - task::spawn(proc() { + task::spawn(move|| { user(i); println!("spawned {}", i) }); @@ -29,7 +29,7 @@ fn bar() { // mutable outside of the proc. let mut i = 0; while i < 10 { - task::spawn(proc() { + task::spawn(move|| { user(i); }); i += 1; @@ -40,7 +40,7 @@ fn car() { // Here, i must be shadowed in the proc to be mutable. let mut i = 0; while i < 10 { - task::spawn(proc() { + task::spawn(move|| { let mut i = i; i += 1; user(i); diff --git a/src/test/run-pass/logging-only-prints-once.rs b/src/test/run-pass/logging-only-prints-once.rs index c1f7e569feb40..1e05c05cc0dd1 100644 --- a/src/test/run-pass/logging-only-prints-once.rs +++ b/src/test/run-pass/logging-only-prints-once.rs @@ -27,7 +27,7 @@ impl fmt::Show for Foo { pub fn main() { let (tx, rx) = channel(); - spawn(proc() { + spawn(move|| { let mut f = Foo(Cell::new(0)); println!("{}", f); let Foo(ref mut f) = f; diff --git a/src/test/run-pass/macro-with-braces-in-expr-position.rs b/src/test/run-pass/macro-with-braces-in-expr-position.rs index f9b1b951cf03d..8b59f26d86976 100644 --- a/src/test/run-pass/macro-with-braces-in-expr-position.rs +++ b/src/test/run-pass/macro-with-braces-in-expr-position.rs @@ -14,7 +14,7 @@ macro_rules! expr (($e: expr) => { $e }) macro_rules! spawn { ($($code: tt)*) => { - expr!(spawn(proc() {$($code)*})) + expr!(spawn(move|| {$($code)*})) } } diff --git a/src/test/run-pass/moves-based-on-type-capture-clause.rs b/src/test/run-pass/moves-based-on-type-capture-clause.rs index 7fd37969e6721..e5694aefdf4c3 100644 --- a/src/test/run-pass/moves-based-on-type-capture-clause.rs +++ b/src/test/run-pass/moves-based-on-type-capture-clause.rs @@ -12,7 +12,7 @@ use std::task; pub fn main() { let x = "Hello world!".to_string(); - task::spawn(proc() { + task::spawn(move|| { println!("{}", x); }); } diff --git a/src/test/run-pass/newlambdas-ret-infer.rs b/src/test/run-pass/newlambdas-ret-infer.rs index f704545af3375..d74f1349506c1 100644 --- a/src/test/run-pass/newlambdas-ret-infer.rs +++ b/src/test/run-pass/newlambdas-ret-infer.rs @@ -11,7 +11,7 @@ // Test that the lambda kind is inferred correctly as a return // expression -fn unique() -> proc():'static { return proc() (); } +fn unique() -> Box { return box || (); } pub fn main() { } diff --git a/src/test/run-pass/newlambdas-ret-infer2.rs b/src/test/run-pass/newlambdas-ret-infer2.rs index 22e51ea9a7583..43a6ac296e9dc 100644 --- a/src/test/run-pass/newlambdas-ret-infer2.rs +++ b/src/test/run-pass/newlambdas-ret-infer2.rs @@ -11,7 +11,7 @@ // Test that the lambda kind is inferred correctly as a return // expression -fn unique() -> proc():'static { proc() () } +fn unique() -> Box { box || () } pub fn main() { } diff --git a/src/test/run-pass/no-landing-pads.rs b/src/test/run-pass/no-landing-pads.rs index eda36fad215fe..e8bf366df957d 100644 --- a/src/test/run-pass/no-landing-pads.rs +++ b/src/test/run-pass/no-landing-pads.rs @@ -23,7 +23,7 @@ impl Drop for A { } fn main() { - task::try::<()>(proc() { + task::try(move|| -> () { let _a = A; panic!(); }); diff --git a/src/test/run-pass/once-move-out-on-heap.rs b/src/test/run-pass/once-move-out-on-heap.rs index e24e809ed018a..8fe57a655aa53 100644 --- a/src/test/run-pass/once-move-out-on-heap.rs +++ b/src/test/run-pass/once-move-out-on-heap.rs @@ -13,13 +13,13 @@ use std::sync::Arc; -fn foo(blk: proc()) { +fn foo(blk: F) { blk(); } pub fn main() { let x = Arc::new(true); - foo(proc() { + foo(move|| { assert!(*x); drop(x); }); diff --git a/src/test/run-pass/operator-overloading.rs b/src/test/run-pass/operator-overloading.rs index a896d2b06f7bd..49396d800297a 100644 --- a/src/test/run-pass/operator-overloading.rs +++ b/src/test/run-pass/operator-overloading.rs @@ -73,6 +73,7 @@ pub fn main() { assert_eq!(q.y, !(p.y)); // Issue #1733 - let result: proc(int) = proc(_)(); result(p[true]); } + +fn result(i: int) { } diff --git a/src/test/run-pass/out-of-stack-new-thread-no-split.rs b/src/test/run-pass/out-of-stack-new-thread-no-split.rs index 21847a486d949..419d9b5d824b1 100644 --- a/src/test/run-pass/out-of-stack-new-thread-no-split.rs +++ b/src/test/run-pass/out-of-stack-new-thread-no-split.rs @@ -37,7 +37,7 @@ fn main() { let args = args.as_slice(); if args.len() > 1 && args[1].as_slice() == "recurse" { let (tx, rx) = channel(); - spawn(proc() { + spawn(move|| { recurse(); tx.send(()); }); diff --git a/src/test/run-pass/panic-in-dtor-drops-fields.rs b/src/test/run-pass/panic-in-dtor-drops-fields.rs index 46924c74a8c46..39252d6b14268 100644 --- a/src/test/run-pass/panic-in-dtor-drops-fields.rs +++ b/src/test/run-pass/panic-in-dtor-drops-fields.rs @@ -33,7 +33,7 @@ impl Drop for B { } pub fn main() { - let ret = task::try(proc() { + let ret = task::try(move|| { let _a = A { b: B { foo: 3 } }; }); assert!(ret.is_err()); diff --git a/src/test/run-pass/preempt.rs b/src/test/run-pass/preempt.rs index 53d2a47863b9d..bcfc39ee7e4e6 100644 --- a/src/test/run-pass/preempt.rs +++ b/src/test/run-pass/preempt.rs @@ -26,7 +26,7 @@ pub fn main() { let (port, chan) = stream(); println!("main started"); - spawn(proc() { + spawn(move|| { starve_main(port); }); let mut i: int = 0; diff --git a/src/test/run-pass/proc-bounds.rs b/src/test/run-pass/proc-bounds.rs deleted file mode 100644 index 7241b0b88b96b..0000000000000 --- a/src/test/run-pass/proc-bounds.rs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2014 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -fn foo() {} -fn bar(_: T) {} - -fn is_send() {} -fn is_freeze() {} -fn is_static() {} - -pub fn main() { - foo::(); - foo::(); - foo::(); - foo::(); - foo::(); - - is_send::(); - is_freeze::(); - is_static::(); - - - let a = 3i; - bar::(proc() { - let b = &a; - println!("{}", *b); - }); -} diff --git a/src/test/compile-fail/regions-infer-region-in-fn-but-not-type.rs b/src/test/run-pass/regions-infer-region-in-fn-but-not-type.rs similarity index 81% rename from src/test/compile-fail/regions-infer-region-in-fn-but-not-type.rs rename to src/test/run-pass/regions-infer-region-in-fn-but-not-type.rs index 0fa4969b54ca1..9174b53be86e6 100644 --- a/src/test/compile-fail/regions-infer-region-in-fn-but-not-type.rs +++ b/src/test/run-pass/regions-infer-region-in-fn-but-not-type.rs @@ -11,9 +11,12 @@ // check that the &int here does not cause us to think that `foo` // contains region pointers -struct foo(proc(x: &int):'static); +struct foo(Box); -fn take_foo(x: foo<'static>) {} //~ ERROR wrong number of lifetime parameters +fn take_foo(x: T) {} -fn main() { +fn have_foo(f: foo) { + take_foo(f); } + +fn main() {} diff --git a/src/test/run-pass/regions-infer-static-from-proc.rs b/src/test/run-pass/regions-infer-static-from-proc.rs index 823644ddfb519..cb45b8e131d28 100644 --- a/src/test/run-pass/regions-infer-static-from-proc.rs +++ b/src/test/run-pass/regions-infer-static-from-proc.rs @@ -13,11 +13,11 @@ // give `x` a very short lifetime). static i: uint = 3; -fn foo(_: proc():'static) {} +fn foo(_: F) {} fn read(_: uint) { } pub fn main() { let x = &i; - foo(proc() { + foo(move|| { read(*x); }); } diff --git a/src/test/run-pass/return-from-closure.rs b/src/test/run-pass/return-from-closure.rs index 2709904fb4cac..b905ebf52fcb3 100644 --- a/src/test/run-pass/return-from-closure.rs +++ b/src/test/run-pass/return-from-closure.rs @@ -23,8 +23,7 @@ fn surrounding() { return_works(10); return_works(20); - - let return_works_proc = proc(n: int) { + let return_works_proc = |: n: int| { unsafe { calls += 1 } if n >= 0 { return; } diff --git a/src/test/run-pass/running-with-no-runtime.rs b/src/test/run-pass/running-with-no-runtime.rs index 683f7038ead7a..36b90a9168f71 100644 --- a/src/test/run-pass/running-with-no-runtime.rs +++ b/src/test/run-pass/running-with-no-runtime.rs @@ -14,6 +14,7 @@ use std::io::process::{Command, ProcessOutput}; use std::os; use std::str; use std::rt; +use std::thunk::Thunk; use rustrt::unwind::try; @@ -26,7 +27,7 @@ fn start(argc: int, argv: *const *const u8) -> int { 2 => println!("foo"), 3 => assert!(try(|| {}).is_ok()), 4 => assert!(try(|| panic!()).is_err()), - 5 => assert!(try(|| spawn(proc() {})).is_err()), + 5 => assert!(try(|| spawn(move|| {})).is_err()), 6 => assert!(Command::new("test").spawn().is_err()), _ => panic!() } @@ -34,7 +35,7 @@ fn start(argc: int, argv: *const *const u8) -> int { return 0 } - rt::start(argc, argv, main) + rt::start(argc, argv, Thunk::new(main)) } fn main() { diff --git a/src/test/run-pass/rust-log-filter.rs b/src/test/run-pass/rust-log-filter.rs index 275a390d5d317..88d30318f2a99 100644 --- a/src/test/run-pass/rust-log-filter.rs +++ b/src/test/run-pass/rust-log-filter.rs @@ -34,7 +34,7 @@ impl log::Logger for ChannelLogger { pub fn main() { let (logger, rx) = ChannelLogger::new(); - spawn(proc() { + spawn(move|| { log::set_logger(logger); // our regex is "f.o" diff --git a/src/test/run-pass/send-resource.rs b/src/test/run-pass/send-resource.rs index e368116f26c3a..6001c360ab99f 100644 --- a/src/test/run-pass/send-resource.rs +++ b/src/test/run-pass/send-resource.rs @@ -27,7 +27,7 @@ fn test(f: int) -> test { pub fn main() { let (tx, rx) = channel(); - task::spawn(proc() { + task::spawn(move|| { let (tx2, rx2) = channel(); tx.send(tx2); diff --git a/src/test/run-pass/sendfn-spawn-with-fn-arg.rs b/src/test/run-pass/sendfn-spawn-with-fn-arg.rs index c03094d4f1581..838c627040dbc 100644 --- a/src/test/run-pass/sendfn-spawn-with-fn-arg.rs +++ b/src/test/run-pass/sendfn-spawn-with-fn-arg.rs @@ -12,17 +12,17 @@ use std::task; pub fn main() { test05(); } -fn test05_start(f: proc(int)) { +fn test05_start(f: F) { f(22); } fn test05() { let three = box 3; - let fn_to_send: proc(int):Send = proc(n) { + let fn_to_send = move|: n:int| { println!("{}", *three + n); // will copy x into the closure assert_eq!(*three, 3); }; - task::spawn(proc() { + task::spawn(move|| { test05_start(fn_to_send); }); } diff --git a/src/test/run-pass/sepcomp-unwind.rs b/src/test/run-pass/sepcomp-unwind.rs index c2c7a48815cc0..ccebfa72384f9 100644 --- a/src/test/run-pass/sepcomp-unwind.rs +++ b/src/test/run-pass/sepcomp-unwind.rs @@ -34,5 +34,5 @@ mod b { } fn main() { - std::task::try(proc() { ::b::g() }).unwrap_err(); + std::task::try(move|| { ::b::g() }).unwrap_err(); } diff --git a/src/test/run-pass/slice-panic-1.rs b/src/test/run-pass/slice-panic-1.rs index b07cf59596852..b66641affc910 100644 --- a/src/test/run-pass/slice-panic-1.rs +++ b/src/test/run-pass/slice-panic-1.rs @@ -28,6 +28,6 @@ fn foo() { } fn main() { - let _ = task::try(proc() foo()); + let _ = task::try(move|| foo()); unsafe { assert!(DTOR_COUNT == 2); } } diff --git a/src/test/run-pass/slice-panic-2.rs b/src/test/run-pass/slice-panic-2.rs index 0ac7a2001fc67..f7e241554c1e8 100644 --- a/src/test/run-pass/slice-panic-2.rs +++ b/src/test/run-pass/slice-panic-2.rs @@ -32,6 +32,6 @@ fn foo() { } fn main() { - let _ = task::try(proc() foo()); + let _ = task::try(move|| foo()); unsafe { assert!(DTOR_COUNT == 2); } } diff --git a/src/test/run-pass/spawn-fn.rs b/src/test/run-pass/spawn-fn.rs index dba3fe325fa7d..b632bc77c7582 100644 --- a/src/test/run-pass/spawn-fn.rs +++ b/src/test/run-pass/spawn-fn.rs @@ -16,9 +16,9 @@ fn x(s: String, n: int) { } pub fn main() { - task::spawn(proc() x("hello from first spawned fn".to_string(), 65) ); - task::spawn(proc() x("hello from second spawned fn".to_string(), 66) ); - task::spawn(proc() x("hello from third spawned fn".to_string(), 67) ); + task::spawn(move|| x("hello from first spawned fn".to_string(), 65) ); + task::spawn(move|| x("hello from second spawned fn".to_string(), 66) ); + task::spawn(move|| x("hello from third spawned fn".to_string(), 67) ); let mut i: int = 30; while i > 0 { i = i - 1; diff --git a/src/test/run-pass/spawn-types.rs b/src/test/run-pass/spawn-types.rs index 1418ab86174f3..9b533c69f3209 100644 --- a/src/test/run-pass/spawn-types.rs +++ b/src/test/run-pass/spawn-types.rs @@ -24,5 +24,5 @@ fn iotask(_tx: &ctx, ip: String) { pub fn main() { let (tx, _rx) = channel::(); - task::spawn(proc() iotask(&tx, "localhost".to_string()) ); + task::spawn(move|| iotask(&tx, "localhost".to_string()) ); } diff --git a/src/test/run-pass/spawn.rs b/src/test/run-pass/spawn.rs index 741e20d42db8d..cfc1967ae24f1 100644 --- a/src/test/run-pass/spawn.rs +++ b/src/test/run-pass/spawn.rs @@ -11,7 +11,7 @@ use std::task; pub fn main() { - task::spawn(proc() child(10) ); + task::spawn(move|| child(10) ); } fn child(i: int) { println!("{}", i); assert!((i == 10)); } diff --git a/src/test/run-pass/spawn2.rs b/src/test/run-pass/spawn2.rs index 6bac7f2a06e76..72db4de2c8d40 100644 --- a/src/test/run-pass/spawn2.rs +++ b/src/test/run-pass/spawn2.rs @@ -10,7 +10,7 @@ use std::task; -pub fn main() { task::spawn(proc() child((10, 20, 30, 40, 50, 60, 70, 80, 90)) ); } +pub fn main() { task::spawn(move|| child((10, 20, 30, 40, 50, 60, 70, 80, 90)) ); } fn child(args: (int, int, int, int, int, int, int, int, int)) { let (i1, i2, i3, i4, i5, i6, i7, i8, i9) = args; diff --git a/src/test/run-pass/spawning-with-debug.rs b/src/test/run-pass/spawning-with-debug.rs index 264662d7d8bb2..0f12827e60ef4 100644 --- a/src/test/run-pass/spawning-with-debug.rs +++ b/src/test/run-pass/spawning-with-debug.rs @@ -17,5 +17,5 @@ use std::task::TaskBuilder; pub fn main() { let mut t = TaskBuilder::new(); - t.spawn(proc() ()); + t.spawn(move|| ()); } diff --git a/src/test/run-pass/swap-overlapping.rs b/src/test/run-pass/swap-overlapping.rs index 06092200a1456..b25b350aa4b72 100644 --- a/src/test/run-pass/swap-overlapping.rs +++ b/src/test/run-pass/swap-overlapping.rs @@ -18,7 +18,7 @@ pub fn main() { name: TestName::DynTestName("test".to_string()), should_fail: false }, - testfn: TestFn::DynTestFn(proc() ()), + testfn: TestFn::DynTestFn(22), }; do_swap(&mut test); } @@ -34,8 +34,8 @@ pub enum TestName { } pub enum TestFn { - DynTestFn(proc():'static), - DynBenchFn(proc(&mut int):'static) + DynTestFn(int), + DynBenchFn(int), } pub struct TestDesc { diff --git a/src/test/run-pass/task-comm-0.rs b/src/test/run-pass/task-comm-0.rs index 469c1b868db91..9e3511ba6034f 100644 --- a/src/test/run-pass/task-comm-0.rs +++ b/src/test/run-pass/task-comm-0.rs @@ -24,7 +24,7 @@ fn test05_start(tx : &Sender) { fn test05() { let (tx, rx) = channel(); - task::spawn(proc() { test05_start(&tx) }); + task::spawn(move|| { test05_start(&tx) }); let mut value: int = rx.recv(); println!("{}", value); value = rx.recv(); diff --git a/src/test/run-pass/task-comm-1.rs b/src/test/run-pass/task-comm-1.rs index 8eaa7f2e31d95..4117f201547b1 100644 --- a/src/test/run-pass/task-comm-1.rs +++ b/src/test/run-pass/task-comm-1.rs @@ -15,6 +15,6 @@ pub fn main() { test00(); } fn start() { println!("Started / Finished task."); } fn test00() { - task::try(proc() start() ); + task::try(move|| start() ); println!("Completing."); } diff --git a/src/test/run-pass/task-comm-10.rs b/src/test/run-pass/task-comm-10.rs index 8054fb0f43b91..dd3c90991f627 100644 --- a/src/test/run-pass/task-comm-10.rs +++ b/src/test/run-pass/task-comm-10.rs @@ -27,7 +27,7 @@ fn start(tx: &Sender>) { pub fn main() { let (tx, rx) = channel(); - let _child = task::spawn(proc() { start(&tx) }); + let _child = task::spawn(move|| { start(&tx) }); let mut c = rx.recv(); c.send("A".to_string()); diff --git a/src/test/run-pass/task-comm-11.rs b/src/test/run-pass/task-comm-11.rs index 719d8e8120e7c..aefc91df4e780 100644 --- a/src/test/run-pass/task-comm-11.rs +++ b/src/test/run-pass/task-comm-11.rs @@ -18,7 +18,7 @@ fn start(tx: &Sender>) { pub fn main() { let (tx, rx) = channel(); - let _child = task::spawn(proc() { + let _child = task::spawn(move|| { start(&tx) }); let _tx = rx.recv(); diff --git a/src/test/run-pass/task-comm-12.rs b/src/test/run-pass/task-comm-12.rs index f72c0ef8d7b3c..d950eb8aec450 100644 --- a/src/test/run-pass/task-comm-12.rs +++ b/src/test/run-pass/task-comm-12.rs @@ -16,7 +16,7 @@ fn start(_task_number: int) { println!("Started / Finished task."); } fn test00() { let i: int = 0; - let mut result = task::try_future(proc() { + let mut result = task::try_future(move|| { start(i) }); diff --git a/src/test/run-pass/task-comm-13.rs b/src/test/run-pass/task-comm-13.rs index 3f3d674297117..c6c0691b74989 100644 --- a/src/test/run-pass/task-comm-13.rs +++ b/src/test/run-pass/task-comm-13.rs @@ -19,6 +19,6 @@ fn start(tx: &Sender, start: int, number_of_messages: int) { pub fn main() { println!("Check that we don't deadlock."); let (tx, rx) = channel(); - task::try(proc() { start(&tx, 0, 10) }); + task::try(move|| { start(&tx, 0, 10) }); println!("Joined task"); } diff --git a/src/test/run-pass/task-comm-14.rs b/src/test/run-pass/task-comm-14.rs index 3f20495f6525e..0e48381366555 100644 --- a/src/test/run-pass/task-comm-14.rs +++ b/src/test/run-pass/task-comm-14.rs @@ -19,7 +19,7 @@ pub fn main() { while (i > 0) { println!("{}", i); let tx = tx.clone(); - task::spawn({let i = i; proc() { child(i, &tx) }}); + task::spawn({let i = i; move|| { child(i, &tx) }}); i = i - 1; } diff --git a/src/test/run-pass/task-comm-15.rs b/src/test/run-pass/task-comm-15.rs index fe4c233224d45..3095c2098ff33 100644 --- a/src/test/run-pass/task-comm-15.rs +++ b/src/test/run-pass/task-comm-15.rs @@ -25,7 +25,7 @@ pub fn main() { // the child's point of view the receiver may die. We should // drop messages on the floor in this case, and not crash! let (tx, rx) = channel(); - task::spawn(proc() { + task::spawn(move|| { start(&tx, 10) }); rx.recv(); diff --git a/src/test/run-pass/task-comm-17.rs b/src/test/run-pass/task-comm-17.rs index 4f4d365901e79..3a591d12864af 100644 --- a/src/test/run-pass/task-comm-17.rs +++ b/src/test/run-pass/task-comm-17.rs @@ -18,5 +18,5 @@ fn f() { } pub fn main() { - task::spawn(proc() f() ); + task::spawn(move|| f() ); } diff --git a/src/test/run-pass/task-comm-3.rs b/src/test/run-pass/task-comm-3.rs index 583840ede5f3e..2908ec1e56115 100644 --- a/src/test/run-pass/task-comm-3.rs +++ b/src/test/run-pass/task-comm-3.rs @@ -41,7 +41,7 @@ fn test00() { let tx = tx.clone(); results.push(task::try_future({ let i = i; - proc() { + move|| { test00_start(&tx, i, number_of_messages) } })); diff --git a/src/test/run-pass/task-comm-7.rs b/src/test/run-pass/task-comm-7.rs index 170e1e8597bfc..9d8caa426269b 100644 --- a/src/test/run-pass/task-comm-7.rs +++ b/src/test/run-pass/task-comm-7.rs @@ -28,19 +28,19 @@ fn test00() { let number_of_messages: int = 10; let tx2 = tx.clone(); - task::spawn(proc() { + task::spawn(move|| { test00_start(&tx2, number_of_messages * 0, number_of_messages); }); let tx2 = tx.clone(); - task::spawn(proc() { + task::spawn(move|| { test00_start(&tx2, number_of_messages * 1, number_of_messages); }); let tx2 = tx.clone(); - task::spawn(proc() { + task::spawn(move|| { test00_start(&tx2, number_of_messages * 2, number_of_messages); }); let tx2 = tx.clone(); - task::spawn(proc() { + task::spawn(move|| { test00_start(&tx2, number_of_messages * 3, number_of_messages); }); diff --git a/src/test/run-pass/task-comm-9.rs b/src/test/run-pass/task-comm-9.rs index cc71ccdfa1960..1c197e823f2a4 100644 --- a/src/test/run-pass/task-comm-9.rs +++ b/src/test/run-pass/task-comm-9.rs @@ -23,7 +23,7 @@ fn test00() { let (tx, rx) = channel(); let number_of_messages: int = 10; - let result = task::try_future(proc() { + let result = task::try_future(move|| { test00_start(&tx, number_of_messages); }); diff --git a/src/test/run-pass/task-life-0.rs b/src/test/run-pass/task-life-0.rs index 5e0d184683129..5c73f44f2d66a 100644 --- a/src/test/run-pass/task-life-0.rs +++ b/src/test/run-pass/task-life-0.rs @@ -11,7 +11,7 @@ use std::task; pub fn main() { - task::spawn(proc() child("Hello".to_string()) ); + task::spawn(move|| child("Hello".to_string()) ); } fn child(_s: String) { diff --git a/src/test/run-pass/task-spawn-move-and-copy.rs b/src/test/run-pass/task-spawn-move-and-copy.rs index fafb9412c01e5..8d6b6005a63ba 100644 --- a/src/test/run-pass/task-spawn-move-and-copy.rs +++ b/src/test/run-pass/task-spawn-move-and-copy.rs @@ -16,7 +16,7 @@ pub fn main() { let x = box 1; let x_in_parent = &(*x) as *const int as uint; - task::spawn(proc() { + task::spawn(move || { let x_in_child = &(*x) as *const int as uint; tx.send(x_in_child); }); diff --git a/src/test/run-pass/task-stderr.rs b/src/test/run-pass/task-stderr.rs index 0dbe74d722bca..72cf7599f89f9 100644 --- a/src/test/run-pass/task-stderr.rs +++ b/src/test/run-pass/task-stderr.rs @@ -16,7 +16,7 @@ fn main() { let mut reader = ChanReader::new(rx); let stderr = ChanWriter::new(tx); - let res = TaskBuilder::new().stderr(box stderr as Box).try(proc() -> () { + let res = TaskBuilder::new().stderr(box stderr as Box).try(move|| -> () { panic!("Hello, world!") }); assert!(res.is_err()); diff --git a/src/test/run-pass/tcp-accept-stress.rs b/src/test/run-pass/tcp-accept-stress.rs index 1ed2efa4b3203..780cf23446639 100644 --- a/src/test/run-pass/tcp-accept-stress.rs +++ b/src/test/run-pass/tcp-accept-stress.rs @@ -35,7 +35,7 @@ fn test() { let a = a.clone(); let cnt = cnt.clone(); let srv_tx = srv_tx.clone(); - spawn(proc() { + spawn(move|| { let mut a = a; loop { match a.accept() { @@ -54,7 +54,7 @@ fn test() { for _ in range(0, N) { let cli_tx = cli_tx.clone(); - spawn(proc() { + spawn(move|| { for _ in range(0, M) { let _s = TcpStream::connect(addr).unwrap(); } diff --git a/src/test/run-pass/tcp-connect-timeouts.rs b/src/test/run-pass/tcp-connect-timeouts.rs index 7dcbccdb17af0..2e4b9da691e39 100644 --- a/src/test/run-pass/tcp-connect-timeouts.rs +++ b/src/test/run-pass/tcp-connect-timeouts.rs @@ -34,7 +34,7 @@ fn eventual_timeout() { let (tx1, rx1) = channel(); let (_tx2, rx2) = channel::<()>(); - std::task::spawn(proc() { + std::task::spawn(move|| { let _l = TcpListener::bind(addr).unwrap().listen(); tx1.send(()); let _ = rx2.recv_opt(); diff --git a/src/test/run-pass/tcp-stress.rs b/src/test/run-pass/tcp-stress.rs index 34fbe1c9a956b..4d691dd252656 100644 --- a/src/test/run-pass/tcp-stress.rs +++ b/src/test/run-pass/tcp-stress.rs @@ -24,7 +24,7 @@ use std::time::Duration; fn main() { // This test has a chance to time out, try to not let it time out - spawn(proc() { + spawn(move|| { use std::io::timer; timer::sleep(Duration::milliseconds(30 * 1000)); println!("timed out!"); @@ -32,7 +32,7 @@ fn main() { }); let (tx, rx) = channel(); - spawn(proc() { + spawn(move|| { let mut listener = TcpListener::bind("127.0.0.1:0").unwrap(); tx.send(listener.socket_name().unwrap()); let mut acceptor = listener.listen(); @@ -53,7 +53,7 @@ fn main() { let (tx, rx) = channel(); for _ in range(0u, 1000) { let tx = tx.clone(); - TaskBuilder::new().stack_size(64 * 1024).spawn(proc() { + TaskBuilder::new().stack_size(64 * 1024).spawn(move|| { match TcpStream::connect(addr) { Ok(stream) => { let mut stream = stream; diff --git a/src/test/run-pass/tempfile.rs b/src/test/run-pass/tempfile.rs index 7400c52a73b4a..a866f497b8615 100644 --- a/src/test/run-pass/tempfile.rs +++ b/src/test/run-pass/tempfile.rs @@ -36,7 +36,7 @@ fn test_tempdir() { fn test_rm_tempdir() { let (tx, rx) = channel(); - let f: proc():Send = proc() { + let f = move|:| -> () { let tmp = TempDir::new("test_rm_tempdir").unwrap(); tx.send(tmp.path().clone()); panic!("panic to unwind past `tmp`"); @@ -47,7 +47,7 @@ fn test_rm_tempdir() { let tmp = TempDir::new("test_rm_tempdir").unwrap(); let path = tmp.path().clone(); - let f: proc():Send = proc() { + let f = move|:| -> () { let _tmp = tmp; panic!("panic to unwind past `tmp`"); }; @@ -56,7 +56,7 @@ fn test_rm_tempdir() { let path; { - let f = proc() { + let f = move|:| { TempDir::new("test_rm_tempdir").unwrap() }; let tmp = task::try(f).ok().expect("test_rm_tmdir"); @@ -77,7 +77,7 @@ fn test_rm_tempdir() { fn test_rm_tempdir_close() { let (tx, rx) = channel(); - let f: proc():Send = proc() { + let f = move|:| -> () { let tmp = TempDir::new("test_rm_tempdir").unwrap(); tx.send(tmp.path().clone()); tmp.close(); @@ -89,7 +89,7 @@ fn test_rm_tempdir_close() { let tmp = TempDir::new("test_rm_tempdir").unwrap(); let path = tmp.path().clone(); - let f: proc():Send = proc() { + let f = move|:| -> () { let tmp = tmp; tmp.close(); panic!("panic when unwinding past `tmp`"); @@ -99,7 +99,7 @@ fn test_rm_tempdir_close() { let path; { - let f = proc() { + let f = move|:| { TempDir::new("test_rm_tempdir").unwrap() }; let tmp = task::try(f).ok().expect("test_rm_tmdir"); @@ -176,7 +176,7 @@ pub fn test_rmdir_recursive_ok() { } pub fn dont_double_panic() { - let r: Result<(), _> = task::try(proc() { + let r: Result<(), _> = task::try(move|| { let tmpdir = TempDir::new("test").unwrap(); // Remove the temporary directory so that TempDir sees // an error on drop diff --git a/src/test/run-pass/terminate-in-initializer.rs b/src/test/run-pass/terminate-in-initializer.rs index 2a71148216d64..28bbac1d0871c 100644 --- a/src/test/run-pass/terminate-in-initializer.rs +++ b/src/test/run-pass/terminate-in-initializer.rs @@ -22,13 +22,13 @@ fn test_ret() { let _x: Box = return; } fn test_panic() { fn f() { let _x: Box = panic!(); } - task::try(proc() f() ); + task::try(move|| f() ); } fn test_panic_indirect() { fn f() -> ! { panic!(); } fn g() { let _x: Box = f(); } - task::try(proc() g() ); + task::try(move|| g() ); } pub fn main() { diff --git a/src/test/run-pass/threads.rs b/src/test/run-pass/threads.rs index dc862f201c244..71adf16c0511a 100644 --- a/src/test/run-pass/threads.rs +++ b/src/test/run-pass/threads.rs @@ -12,7 +12,7 @@ use std::task; pub fn main() { let mut i = 10; - while i > 0 { task::spawn({let i = i; proc() child(i)}); i = i - 1; } + while i > 0 { task::spawn({let i = i; move|| child(i)}); i = i - 1; } println!("main thread exiting"); } diff --git a/src/test/run-pass/trait-bounds-in-arc.rs b/src/test/run-pass/trait-bounds-in-arc.rs index 50d3531b632f4..d2c1461d65d0b 100644 --- a/src/test/run-pass/trait-bounds-in-arc.rs +++ b/src/test/run-pass/trait-bounds-in-arc.rs @@ -77,13 +77,13 @@ pub fn main() { box dogge2 as Box)); let (tx1, rx1) = channel(); let arc1 = arc.clone(); - task::spawn(proc() { check_legs(arc1); tx1.send(()); }); + task::spawn(move|| { check_legs(arc1); tx1.send(()); }); let (tx2, rx2) = channel(); let arc2 = arc.clone(); - task::spawn(proc() { check_names(arc2); tx2.send(()); }); + task::spawn(move|| { check_names(arc2); tx2.send(()); }); let (tx3, rx3) = channel(); let arc3 = arc.clone(); - task::spawn(proc() { check_pedigree(arc3); tx3.send(()); }); + task::spawn(move|| { check_pedigree(arc3); tx3.send(()); }); rx1.recv(); rx2.recv(); rx3.recv(); diff --git a/src/test/run-pass/unboxed-closures-monomorphization.rs b/src/test/run-pass/unboxed-closures-monomorphization.rs index cd97fd96fa3bb..dfc234e87cda1 100644 --- a/src/test/run-pass/unboxed-closures-monomorphization.rs +++ b/src/test/run-pass/unboxed-closures-monomorphization.rs @@ -14,26 +14,26 @@ #![feature(unboxed_closures)] fn main(){ - fn bar<'a, T:'a> (t: T) -> Box + 'a> { - box move |:| t + fn bar<'a, T:Clone+'a> (t: T) -> Box + 'a> { + box move |&mut:| t.clone() } - let f = bar(42u); - assert_eq!(f.call_once(()), 42); + let mut f = bar(42u); + assert_eq!(f.call_mut(()), 42); - let f = bar("forty-two"); - assert_eq!(f.call_once(()), "forty-two"); + let mut f = bar("forty-two"); + assert_eq!(f.call_mut(()), "forty-two"); let x = 42u; - let f = bar(&x); - assert_eq!(f.call_once(()), &x); + let mut f = bar(&x); + assert_eq!(f.call_mut(()), &x); - #[deriving(Show, PartialEq)] + #[deriving(Clone, Show, PartialEq)] struct Foo(uint, &'static str); impl Copy for Foo {} let x = Foo(42, "forty-two"); - let f = bar(x); - assert_eq!(f.call_once(()), x); + let mut f = bar(x); + assert_eq!(f.call_mut(()), x); } diff --git a/src/test/run-pass/unboxed-closures-prelude.rs b/src/test/run-pass/unboxed-closures-prelude.rs index 6f672f2f2828c..e31ef169e16eb 100644 --- a/src/test/run-pass/unboxed-closures-prelude.rs +++ b/src/test/run-pass/unboxed-closures-prelude.rs @@ -13,7 +13,16 @@ #![feature(unboxed_closures)] fn main() { - let task: Box int> = box |: x| x; - task.call_once((0i, )); + let task: Box int> = box |&: x| x; + task.call((0i, )); + + let mut task: Box int> = box |&mut: x| x; + task.call_mut((0i, )); + + call(|:x| x, 22); +} + +fn call int>(f: F, x: int) -> int { + f.call_once((x,)) } diff --git a/src/test/run-pass/unique-send-2.rs b/src/test/run-pass/unique-send-2.rs index 432a0527adaae..672cd2d00e8bd 100644 --- a/src/test/run-pass/unique-send-2.rs +++ b/src/test/run-pass/unique-send-2.rs @@ -20,7 +20,7 @@ pub fn main() { let mut expected = 0u; for i in range(0u, n) { let tx = tx.clone(); - task::spawn(proc() { + task::spawn(move|| { child(&tx, i) }); expected += i; diff --git a/src/test/run-pass/unit-like-struct-drop-run.rs b/src/test/run-pass/unit-like-struct-drop-run.rs index c12303b009f46..e3cd694c0de6b 100644 --- a/src/test/run-pass/unit-like-struct-drop-run.rs +++ b/src/test/run-pass/unit-like-struct-drop-run.rs @@ -22,7 +22,7 @@ impl Drop for Foo { } pub fn main() { - let x = task::try(proc() { + let x = task::try(move|| { let _b = Foo; }); diff --git a/src/test/run-pass/unwind-resource.rs b/src/test/run-pass/unwind-resource.rs index 60f07663bef0e..9789deef63649 100644 --- a/src/test/run-pass/unwind-resource.rs +++ b/src/test/run-pass/unwind-resource.rs @@ -37,7 +37,7 @@ fn f(tx: Sender) { pub fn main() { let (tx, rx) = channel(); - task::spawn(proc() f(tx.clone())); + task::spawn(move|| f(tx.clone())); println!("hiiiiiiiii"); assert!(rx.recv()); } diff --git a/src/test/run-pass/vector-sort-panic-safe.rs b/src/test/run-pass/vector-sort-panic-safe.rs index ce9cc68bd3654..c969e66957ccb 100644 --- a/src/test/run-pass/vector-sort-panic-safe.rs +++ b/src/test/run-pass/vector-sort-panic-safe.rs @@ -77,7 +77,7 @@ pub fn main() { let v = main.clone(); - let _ = task::try(proc() { + let _ = task::try(move|| { let mut v = v; let mut panic_countdown = panic_countdown; v.as_mut_slice().sort_by(|a, b| { diff --git a/src/test/run-pass/weak-lang-item.rs b/src/test/run-pass/weak-lang-item.rs index d44e25550ef81..87226eedfdcbf 100644 --- a/src/test/run-pass/weak-lang-item.rs +++ b/src/test/run-pass/weak-lang-item.rs @@ -15,7 +15,7 @@ extern crate "weak-lang-items" as other; use std::task; fn main() { - let _ = task::try(proc() { + let _ = task::try(move|| { other::foo() }); }