From d8f8f7a58c7c8b3352c1c577347865f5a823fee3 Mon Sep 17 00:00:00 2001 From: Aaron Turon Date: Tue, 17 Feb 2015 01:08:53 -0800 Subject: Revise std::thread semantics This commit makes several changes to `std::thread` in preparation for final stabilization: * It removes the ability to handle panics from `scoped` children; see #20807 for discussion * It adds a `JoinHandle` structure, now returned from `spawn`, which makes it possible to join on children that do not share data from their parent's stack. The child is automatically detached when the handle is dropped, and the handle cannot be copied due to Posix semantics. * It moves all static methods from `std::thread::Thread` to free functions in `std::thread`. This was done in part because, due to the above changes, there are effectively no direct `Thread` constructors, and the static methods have tended to feel a bit awkward. * Adds an `io::Result` around the `Builder` methods `scoped` and `spawn`, making it possible to handle OS errors when creating threads. The convenience free functions entail an unwrap. * Stabilizes the entire module. Despite the fact that the API is changing somewhat here, this is part of a long period of baking and the changes are addressing all known issues prior to alpha2. If absolutely necessary, further breaking changes can be made prior to beta. Closes #20807 [breaking-change] --- src/libstd/sys/windows/thread.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/libstd/sys/windows/thread.rs') diff --git a/src/libstd/sys/windows/thread.rs b/src/libstd/sys/windows/thread.rs index a38dc9b2d34..d7f86e1842e 100644 --- a/src/libstd/sys/windows/thread.rs +++ b/src/libstd/sys/windows/thread.rs @@ -10,6 +10,7 @@ use boxed::Box; use cmp; +use io; use mem; use ptr; use libc; @@ -42,7 +43,7 @@ pub mod guard { } } -pub unsafe fn create(stack: uint, p: Thunk) -> rust_thread { +pub unsafe fn create(stack: uint, p: Thunk) -> io::Result { 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 @@ -60,9 +61,10 @@ pub unsafe fn create(stack: uint, p: Thunk) -> rust_thread { if ret as uint == 0 { // be sure to not leak the closure let _p: Box = mem::transmute(arg); - panic!("failed to spawn native thread: {:?}", ret); + Err(io::Error::last_os_error()) + } else { + Ok(ret) } - return ret; } pub unsafe fn set_name(_name: &str) { -- cgit 1.4.1-3-g733a5 From 6ac3799b75780f8c18bc38331403e1e517b89bab Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 17 Feb 2015 15:24:34 -0800 Subject: Test fixes and rebase conflicts --- src/doc/trpl/concurrency.md | 62 ++++++++-------------- src/libcore/cmp.rs | 9 ++-- src/libgetopts/lib.rs | 1 + src/librustc_driver/lib.rs | 5 +- src/librustc_trans/back/write.rs | 2 +- src/librustdoc/lib.rs | 12 +++-- src/libstd/sys/windows/thread.rs | 3 +- src/libstd/thread.rs | 36 ++++++------- src/libterm/lib.rs | 1 + src/libtest/lib.rs | 4 +- src/test/compile-fail/issue-8460-const.rs | 40 +++++++------- src/test/compile-fail/lint-uppercase-variables.rs | 4 +- src/test/run-fail/panic-task-name-none.rs | 3 +- src/test/run-fail/panic-task-name-owned.rs | 8 +-- .../cleanup-rvalue-temp-during-incomplete-alloc.rs | 4 +- src/test/run-pass/issue-12684.rs | 4 +- src/test/run-pass/issue-16560.rs | 4 +- src/test/run-pass/issue-16671.rs | 4 +- src/test/run-pass/issue-4446.rs | 4 +- src/test/run-pass/issue-4448.rs | 4 +- src/test/run-pass/issue-8460.rs | 42 +++++++-------- src/test/run-pass/logging-only-prints-once.rs | 4 +- src/test/run-pass/no-landing-pads.rs | 4 +- src/test/run-pass/panic-in-dtor-drops-fields.rs | 4 +- src/test/run-pass/sendfn-spawn-with-fn-arg.rs | 4 +- src/test/run-pass/sepcomp-unwind.rs | 4 +- src/test/run-pass/slice-panic-1.rs | 4 +- src/test/run-pass/slice-panic-2.rs | 4 +- src/test/run-pass/spawn-types.rs | 4 +- src/test/run-pass/spawn.rs | 4 +- src/test/run-pass/spawn2.rs | 4 +- src/test/run-pass/task-stderr.rs | 5 +- src/test/run-pass/tempfile.rs | 16 +++--- src/test/run-pass/terminate-in-initializer.rs | 6 +-- 34 files changed, 155 insertions(+), 168 deletions(-) (limited to 'src/libstd/sys/windows/thread.rs') diff --git a/src/doc/trpl/concurrency.md b/src/doc/trpl/concurrency.md index 3c933c1c5af..9f8f76e1fea 100644 --- a/src/doc/trpl/concurrency.md +++ b/src/doc/trpl/concurrency.md @@ -57,13 +57,13 @@ place! ## Threads Rust's standard library provides a library for 'threads', which allow you to -run Rust code in parallel. Here's a basic example of using `Thread`: +run Rust code in parallel. Here's a basic example of using `std::thread`: ``` -use std::thread::Thread; +use std::thread; fn main() { - Thread::scoped(|| { + thread::scoped(|| { println!("Hello from a thread!"); }); } @@ -73,10 +73,10 @@ The `Thread::scoped()` method accepts a closure, which is executed in a new thread. It's called `scoped` because this thread returns a join guard: ``` -use std::thread::Thread; +use std::thread; fn main() { - let guard = Thread::scoped(|| { + let guard = thread::scoped(|| { println!("Hello from a thread!"); }); @@ -85,15 +85,15 @@ fn main() { ``` When `guard` goes out of scope, it will block execution until the thread is -finished. If we didn't want this behaviour, we could use `Thread::spawn()`: +finished. If we didn't want this behaviour, we could use `thread::spawn()`: ``` -use std::thread::Thread; +use std::thread; use std::old_io::timer; use std::time::Duration; fn main() { - Thread::spawn(|| { + thread::spawn(|| { println!("Hello from a thread!"); }); @@ -101,24 +101,6 @@ fn main() { } ``` -Or call `.detach()`: - -``` -use std::thread::Thread; -use std::old_io::timer; -use std::time::Duration; - -fn main() { - let guard = Thread::scoped(|| { - println!("Hello from a thread!"); - }); - - guard.detach(); - - timer::sleep(Duration::milliseconds(50)); -} -``` - We need to `sleep` here because when `main()` ends, it kills all of the running threads. @@ -164,7 +146,7 @@ As an example, here is a Rust program that would have a data race in many languages. It will not compile: ```ignore -use std::thread::Thread; +use std::thread; use std::old_io::timer; use std::time::Duration; @@ -172,7 +154,7 @@ fn main() { let mut data = vec![1u32, 2, 3]; for i in 0..2 { - Thread::spawn(move || { + thread::spawn(move || { data[i] += 1; }); } @@ -203,7 +185,7 @@ only one person at a time can mutate what's inside. For that, we can use the but for a different reason: ```ignore -use std::thread::Thread; +use std::thread; use std::old_io::timer; use std::time::Duration; use std::sync::Mutex; @@ -213,7 +195,7 @@ fn main() { for i in 0..2 { let data = data.lock().unwrap(); - Thread::spawn(move || { + thread::spawn(move || { data[i] += 1; }); } @@ -255,7 +237,7 @@ We can use `Arc` to fix this. Here's the working version: ``` use std::sync::{Arc, Mutex}; -use std::thread::Thread; +use std::thread; use std::old_io::timer; use std::time::Duration; @@ -264,7 +246,7 @@ fn main() { for i in 0us..2 { let data = data.clone(); - Thread::spawn(move || { + thread::spawn(move || { let mut data = data.lock().unwrap(); data[i] += 1; }); @@ -280,14 +262,14 @@ thread more closely: ``` # use std::sync::{Arc, Mutex}; -# use std::thread::Thread; +# use std::thread; # use std::old_io::timer; # use std::time::Duration; # fn main() { # let data = Arc::new(Mutex::new(vec![1u32, 2, 3])); # for i in 0us..2 { # let data = data.clone(); -Thread::spawn(move || { +thread::spawn(move || { let mut data = data.lock().unwrap(); data[i] += 1; }); @@ -315,7 +297,7 @@ than waiting for a specific time: ``` use std::sync::{Arc, Mutex}; -use std::thread::Thread; +use std::thread; use std::sync::mpsc; fn main() { @@ -326,7 +308,7 @@ fn main() { for _ in 0..10 { let (data, tx) = (data.clone(), tx.clone()); - Thread::spawn(move || { + thread::spawn(move || { let mut data = data.lock().unwrap(); *data += 1; @@ -348,7 +330,7 @@ is `Send` over the channel! ``` use std::sync::{Arc, Mutex}; -use std::thread::Thread; +use std::thread; use std::sync::mpsc; fn main() { @@ -357,7 +339,7 @@ fn main() { for _ in 0..10 { let tx = tx.clone(); - Thread::spawn(move || { + thread::spawn(move || { let answer = 42u32; tx.send(answer); @@ -378,9 +360,9 @@ A `panic!` will crash the currently executing thread. You can use Rust's threads as a simple isolation mechanism: ``` -use std::thread::Thread; +use std::thread; -let result = Thread::scoped(move || { +let result = thread::spawn(move || { panic!("oops!"); }).join(); diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 5bc634936cf..19ec245300d 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -87,8 +87,8 @@ pub trait PartialEq { /// - symmetric: `a == b` implies `b == a`; and /// - transitive: `a == b` and `b == c` implies `a == c`. /// -/// This property cannot be checked by the compiler, and therefore `Eq` implies `PartialEq`, and -/// has no extra methods. +/// This property cannot be checked by the compiler, and therefore `Eq` implies +/// `PartialEq`, and has no extra methods. #[stable(feature = "rust1", since = "1.0.0")] pub trait Eq: PartialEq { // FIXME #13101: this method is used solely by #[deriving] to @@ -100,6 +100,7 @@ pub trait Eq: PartialEq { // This should never be implemented by hand. #[doc(hidden)] #[inline(always)] + #[stable(feature = "rust1", since = "1.0.0")] fn assert_receiver_is_total_eq(&self) {} } @@ -408,7 +409,7 @@ pub fn max(v1: T, v2: T) -> T { /// ``` /// use std::cmp; /// -/// let result = cmp::partial_min(std::f64::NAN, &1.0); +/// let result = cmp::partial_min(std::f64::NAN, 1.0); /// assert_eq!(result, None); /// ``` #[inline] @@ -439,7 +440,7 @@ pub fn partial_min(v1: T, v2: T) -> Option { /// ``` /// use std::cmp; /// -/// let result = cmp::partial_max(std::f64::NAN, &1.0); +/// let result = cmp::partial_max(std::f64::NAN, 1.0); /// assert_eq!(result, None); /// ``` #[inline] diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs index ca184fb8736..c743119f409 100644 --- a/src/libgetopts/lib.rs +++ b/src/libgetopts/lib.rs @@ -92,6 +92,7 @@ #![feature(collections)] #![feature(int_uint)] #![feature(staged_api)] +#![feature(str_words)] #![cfg_attr(test, feature(rustc_private))] #[cfg(test)] #[macro_use] extern crate log; diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 19a290282d6..234809e5284 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -37,7 +37,6 @@ #![feature(rustc_private)] #![feature(unsafe_destructor)] #![feature(staged_api)] -#![feature(std_misc)] #![feature(unicode)] extern crate arena; @@ -73,7 +72,7 @@ use rustc::metadata; use rustc::util::common::time; use std::cmp::Ordering::Equal; -use std::old_io; +use std::old_io::{self, stdio}; use std::iter::repeat; use std::env; use std::sync::mpsc::channel; @@ -780,7 +779,7 @@ pub fn monitor(f: F) { cfg = cfg.stack_size(STACK_SIZE); } - match cfg.scoped(move || { std::old_io::stdio::set_stderr(box w); f() }).join() { + match cfg.spawn(move || { stdio::set_stderr(box w); f() }).unwrap().join() { Ok(()) => { /* fallthrough */ } Err(value) => { // Thread panicked without emitting a fatal diagnostic diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 68f413eff85..9934d9993d6 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -939,7 +939,7 @@ fn run_work_multithreaded(sess: &Session, } tx.take().unwrap().send(()).unwrap(); - }); + }).unwrap(); } let mut panicked = false; diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index e2799eec90a..bab734db126 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -34,6 +34,7 @@ #![feature(std_misc)] #![feature(test)] #![feature(unicode)] +#![feature(str_words)] extern crate arena; extern crate getopts; @@ -55,6 +56,7 @@ use std::env; use std::old_io::File; use std::old_io; use std::rc::Rc; +use std::sync::mpsc::channel; use externalfiles::ExternalHtml; use serialize::Decodable; use serialize::json::{self, Json}; @@ -125,8 +127,8 @@ pub fn main() { let res = std::thread::Builder::new().stack_size(STACK_SIZE).scoped(move || { let s = env::args().collect::>(); main_args(&s) - }).join(); - env::set_exit_status(res.ok().unwrap() as i32); + }).unwrap().join(); + env::set_exit_status(res as i32); } pub fn opts() -> Vec { @@ -365,12 +367,14 @@ 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::thread::spawn(move || { + let (tx, rx) = channel(); + std::thread::spawn(move || { use rustc::session::config::Input; let cr = cr; - core::run_core(paths, cfgs, externs, Input::File(cr), triple) + tx.send(core::run_core(paths, cfgs, externs, Input::File(cr), triple)).unwrap(); }).join().map_err(|_| "rustc failed").unwrap(); + let (mut krate, analysis) = rx.recv().unwrap(); info!("finished with rustc"); let mut analysis = Some(analysis); ANALYSISKEY.with(|s| { diff --git a/src/libstd/sys/windows/thread.rs b/src/libstd/sys/windows/thread.rs index d7f86e1842e..f3a27877e5c 100644 --- a/src/libstd/sys/windows/thread.rs +++ b/src/libstd/sys/windows/thread.rs @@ -8,7 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use boxed::Box; +use prelude::v1::*; + use cmp; use io; use mem; diff --git a/src/libstd/thread.rs b/src/libstd/thread.rs index d0fde8344b2..a8355c34000 100644 --- a/src/libstd/thread.rs +++ b/src/libstd/thread.rs @@ -147,21 +147,16 @@ #![stable(feature = "rust1", since = "1.0.0")] +use prelude::v1::*; + use any::Any; -use boxed::Box; use cell::UnsafeCell; -use clone::Clone; use fmt; use io; -use marker::{Send, Sync}; -use ops::{Drop, FnOnce}; -use option::Option::{self, Some, None}; -use result::Result::{Err, Ok}; -use sync::{Mutex, Condvar, Arc}; -use str::Str; -use string::String; +use marker; +use old_io::stdio; use rt::{self, unwind}; -use old_io::{Writer, stdio}; +use sync::{Mutex, Condvar, Arc}; use thunk::Thunk; use time::Duration; @@ -264,7 +259,9 @@ impl Builder { pub fn scoped<'a, T, F>(self, f: F) -> io::Result> where T: Send + 'a, F: FnOnce() -> T, F: Send + 'a { - self.spawn_inner(Thunk::new(f)).map(JoinGuard) + self.spawn_inner(Thunk::new(f)).map(|inner| { + JoinGuard { inner: inner, _marker: marker::PhantomData } + }) } fn spawn_inner(self, f: Thunk<(), T>) -> io::Result> { @@ -643,7 +640,10 @@ impl Drop for JoinHandle { /// permission. #[must_use] #[stable(feature = "rust1", since = "1.0.0")] -pub struct JoinGuard<'a, T: 'a>(JoinInner); +pub struct JoinGuard<'a, T: 'a> { + inner: JoinInner, + _marker: marker::PhantomData<&'a T>, +} #[stable(feature = "rust1", since = "1.0.0")] unsafe impl<'a, T: Send + 'a> Sync for JoinGuard<'a, T> {} @@ -652,7 +652,7 @@ impl<'a, T: Send + 'a> JoinGuard<'a, T> { /// Extract a handle to the thread this guard will join on. #[stable(feature = "rust1", since = "1.0.0")] pub fn thread(&self) -> &Thread { - &self.0.thread + &self.inner.thread } /// Wait for the associated thread to finish, returning the result of the thread's @@ -663,7 +663,7 @@ impl<'a, T: Send + 'a> JoinGuard<'a, T> { /// Panics on the child thread are propagated by panicking the parent. #[stable(feature = "rust1", since = "1.0.0")] pub fn join(mut self) -> T { - match self.0.join() { + match self.inner.join() { Ok(res) => res, Err(_) => panic!("child thread {:?} panicked", self.thread()), } @@ -676,8 +676,8 @@ impl JoinGuard<'static, T> { #[deprecated(since = "1.0.0", reason = "use spawn instead")] #[unstable(feature = "std_misc")] pub fn detach(mut self) { - unsafe { imp::detach(self.0.native) }; - self.0.joined = true; // avoid joining in the destructor + unsafe { imp::detach(self.inner.native) }; + self.inner.joined = true; // avoid joining in the destructor } } @@ -685,8 +685,8 @@ impl JoinGuard<'static, T> { #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T: Send + 'a> Drop for JoinGuard<'a, T> { fn drop(&mut self) { - if !self.0.joined { - unsafe { imp::join(self.0.native) }; + if !self.inner.joined { + unsafe { imp::join(self.inner.native) }; } } } diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs index 6cd96769ed2..304f370a199 100644 --- a/src/libterm/lib.rs +++ b/src/libterm/lib.rs @@ -59,6 +59,7 @@ #![feature(rustc_private)] #![feature(staged_api)] #![feature(unicode)] +#![feature(std_misc)] #![feature(env)] #![cfg_attr(windows, feature(libc))] diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 32ba410224e..62bf95d3b7b 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -75,7 +75,7 @@ use std::iter::repeat; use std::num::{Float, Int}; use std::env; use std::sync::mpsc::{channel, Sender}; -use std::thread::{self, Thread}; +use std::thread; use std::thunk::{Thunk, Invoke}; use std::time::Duration; @@ -895,7 +895,7 @@ pub fn run_test(opts: &TestOpts, cfg = cfg.stderr(box stderr as Box); } - let result_guard = cfg.scoped(move || { testfn.invoke(()) }); + let result_guard = cfg.spawn(move || { testfn.invoke(()) }).unwrap(); let stdout = reader.read_to_end().unwrap().into_iter().collect(); let test_result = calc_result(&desc, result_guard.join()); monitor_ch.send((desc.clone(), test_result, stdout)).unwrap(); diff --git a/src/test/compile-fail/issue-8460-const.rs b/src/test/compile-fail/issue-8460-const.rs index 4e44b4dcdce..b6d371e4b11 100644 --- a/src/test/compile-fail/issue-8460-const.rs +++ b/src/test/compile-fail/issue-8460-const.rs @@ -12,44 +12,44 @@ use std::{int, i8, i16, i32, i64}; use std::thread; fn main() { - assert!(thread::spawn(move|| int::MIN / -1).join().is_err()); + assert!(thread::spawn(move|| { int::MIN / -1; }).join().is_err()); //~^ ERROR attempted to divide with overflow in a constant expression - assert!(thread::spawn(move|| i8::MIN / -1).join().is_err()); + assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err()); //~^ ERROR attempted to divide with overflow in a constant expression - assert!(thread::spawn(move|| i16::MIN / -1).join().is_err()); + assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err()); //~^ ERROR attempted to divide with overflow in a constant expression - assert!(thread::spawn(move|| i32::MIN / -1).join().is_err()); + assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err()); //~^ ERROR attempted to divide with overflow in a constant expression - assert!(thread::spawn(move|| i64::MIN / -1).join().is_err()); + assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err()); //~^ ERROR attempted to divide with overflow in a constant expression - assert!(thread::spawn(move|| 1is / 0).join().is_err()); + assert!(thread::spawn(move|| { 1is / 0; }).join().is_err()); //~^ ERROR attempted to divide by zero in a constant expression - assert!(thread::spawn(move|| 1i8 / 0).join().is_err()); + assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err()); //~^ ERROR attempted to divide by zero in a constant expression - assert!(thread::spawn(move|| 1i16 / 0).join().is_err()); + assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err()); //~^ ERROR attempted to divide by zero in a constant expression - assert!(thread::spawn(move|| 1i32 / 0).join().is_err()); + assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err()); //~^ ERROR attempted to divide by zero in a constant expression - assert!(thread::spawn(move|| 1i64 / 0).join().is_err()); + assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err()); //~^ ERROR attempted to divide by zero in a constant expression - assert!(thread::spawn(move|| int::MIN % -1).join().is_err()); + assert!(thread::spawn(move|| { int::MIN % -1; }).join().is_err()); //~^ ERROR attempted remainder with overflow in a constant expression - assert!(thread::spawn(move|| i8::MIN % -1).join().is_err()); + assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err()); //~^ ERROR attempted remainder with overflow in a constant expression - assert!(thread::spawn(move|| i16::MIN % -1).join().is_err()); + assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err()); //~^ ERROR attempted remainder with overflow in a constant expression - assert!(thread::spawn(move|| i32::MIN % -1).join().is_err()); + assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err()); //~^ ERROR attempted remainder with overflow in a constant expression - assert!(thread::spawn(move|| i64::MIN % -1).join().is_err()); + assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err()); //~^ ERROR attempted remainder with overflow in a constant expression - assert!(thread::spawn(move|| 1is % 0).join().is_err()); + assert!(thread::spawn(move|| { 1is % 0; }).join().is_err()); //~^ ERROR attempted remainder with a divisor of zero in a constant expression - assert!(thread::spawn(move|| 1i8 % 0).join().is_err()); + assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err()); //~^ ERROR attempted remainder with a divisor of zero in a constant expression - assert!(thread::spawn(move|| 1i16 % 0).join().is_err()); + assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err()); //~^ ERROR attempted remainder with a divisor of zero in a constant expression - assert!(thread::spawn(move|| 1i32 % 0).join().is_err()); + assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err()); //~^ ERROR attempted remainder with a divisor of zero in a constant expression - assert!(thread::spawn(move|| 1i64 % 0).join().is_err()); + assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err()); //~^ ERROR attempted remainder with a divisor of zero in a constant expression } diff --git a/src/test/compile-fail/lint-uppercase-variables.rs b/src/test/compile-fail/lint-uppercase-variables.rs index b68d9dc4645..a4f46cbd187 100644 --- a/src/test/compile-fail/lint-uppercase-variables.rs +++ b/src/test/compile-fail/lint-uppercase-variables.rs @@ -13,9 +13,6 @@ #![allow(dead_code)] #![deny(non_snake_case)] -use std::old_io::File; -use std::old_io::IoError; - mod foo { pub enum Foo { Foo } } @@ -36,6 +33,7 @@ fn main() { Foo => {} //~^ ERROR variable `Foo` should have a snake case name such as `foo` //~^^ WARN `Foo` is named the same as one of the variants of the type `foo::Foo` +//~^^^ WARN unused variable: `Foo` } test(1); diff --git a/src/test/run-fail/panic-task-name-none.rs b/src/test/run-fail/panic-task-name-none.rs index 40a881852f5..3a5ac5a1009 100644 --- a/src/test/run-fail/panic-task-name-none.rs +++ b/src/test/run-fail/panic-task-name-none.rs @@ -13,9 +13,8 @@ use std::thread; fn main() { - let r: Result = thread::spawn(move|| { + let r: Result<(),_> = thread::spawn(move|| { panic!("test"); - 1 }).join(); assert!(r.is_ok()); } diff --git a/src/test/run-fail/panic-task-name-owned.rs b/src/test/run-fail/panic-task-name-owned.rs index d48d282c9eb..8cab9e05f96 100644 --- a/src/test/run-fail/panic-task-name-owned.rs +++ b/src/test/run-fail/panic-task-name-owned.rs @@ -13,9 +13,9 @@ use std::thread::Builder; fn main() { - let r: Result = Builder::new().name("owned name".to_string()).scoped(move|| { + let r: () = Builder::new().name("owned name".to_string()).scoped(move|| { panic!("test"); - 1 - }).join(); - assert!(r.is_ok()); + () + }).unwrap().join(); + panic!(); } diff --git a/src/test/run-pass/cleanup-rvalue-temp-during-incomplete-alloc.rs b/src/test/run-pass/cleanup-rvalue-temp-during-incomplete-alloc.rs index edb3d72483b..96ae7e3d336 100644 --- a/src/test/run-pass/cleanup-rvalue-temp-during-incomplete-alloc.rs +++ b/src/test/run-pass/cleanup-rvalue-temp-during-incomplete-alloc.rs @@ -27,7 +27,7 @@ #![allow(unknown_features)] #![feature(box_syntax)] -use std::thread::Thread; +use std::thread; enum Conzabble { Bickwick(Foo) @@ -48,5 +48,5 @@ pub fn fails() { } pub fn main() { - Thread::scoped(fails).join(); + thread::spawn(fails).join(); } diff --git a/src/test/run-pass/issue-12684.rs b/src/test/run-pass/issue-12684.rs index 38731b8c8da..e66b5d21e17 100644 --- a/src/test/run-pass/issue-12684.rs +++ b/src/test/run-pass/issue-12684.rs @@ -9,10 +9,10 @@ // except according to those terms. use std::time::Duration; -use std::thread::Thread; +use std::thread; fn main() { - Thread::scoped(move|| customtask()).join().ok().unwrap(); + thread::spawn(move|| customtask()).join().ok().unwrap(); } fn customtask() { diff --git a/src/test/run-pass/issue-16560.rs b/src/test/run-pass/issue-16560.rs index ca40b2fe4c7..9448e605937 100644 --- a/src/test/run-pass/issue-16560.rs +++ b/src/test/run-pass/issue-16560.rs @@ -10,7 +10,7 @@ #![feature(unboxed_closures)] -use std::thread::Thread; +use std::thread; use std::mem; fn main() { @@ -20,7 +20,7 @@ fn main() { // Check that both closures are capturing by value assert_eq!(1, mem::size_of_val(&closure)); - Thread::scoped(move|| { + thread::spawn(move|| { let ok = closure; }).join().ok().unwrap(); } diff --git a/src/test/run-pass/issue-16671.rs b/src/test/run-pass/issue-16671.rs index 124b0205fae..0e42f2593f2 100644 --- a/src/test/run-pass/issue-16671.rs +++ b/src/test/run-pass/issue-16671.rs @@ -18,11 +18,11 @@ // A var moved into a proc, that has a mutable loan path should // not trigger a misleading unused_mut warning. -use std::thread::Thread; +use std::thread; pub fn main() { let mut stdin = std::old_io::stdin(); - Thread::spawn(move|| { + thread::spawn(move|| { let _ = stdin.read_to_end(); }); } diff --git a/src/test/run-pass/issue-4446.rs b/src/test/run-pass/issue-4446.rs index ec4cd02e9fd..b40a726a2c3 100644 --- a/src/test/run-pass/issue-4446.rs +++ b/src/test/run-pass/issue-4446.rs @@ -10,14 +10,14 @@ use std::old_io::println; use std::sync::mpsc::channel; -use std::thread::Thread; +use std::thread; pub fn main() { let (tx, rx) = channel(); tx.send("hello, world").unwrap(); - Thread::scoped(move|| { + thread::spawn(move|| { println(rx.recv().unwrap()); }).join().ok().unwrap(); } diff --git a/src/test/run-pass/issue-4448.rs b/src/test/run-pass/issue-4448.rs index a19bfca721a..ef30f9182ba 100644 --- a/src/test/run-pass/issue-4448.rs +++ b/src/test/run-pass/issue-4448.rs @@ -9,12 +9,12 @@ // except according to those terms. use std::sync::mpsc::channel; -use std::thread::Thread; +use std::thread; pub fn main() { let (tx, rx) = channel::<&'static str>(); - let t = Thread::scoped(move|| { + let t = thread::spawn(move|| { assert_eq!(rx.recv().unwrap(), "hello, world"); }); diff --git a/src/test/run-pass/issue-8460.rs b/src/test/run-pass/issue-8460.rs index 4b9ed44c7cd..72a1ec436f3 100644 --- a/src/test/run-pass/issue-8460.rs +++ b/src/test/run-pass/issue-8460.rs @@ -9,31 +9,31 @@ // except according to those terms. use std::num::Int; -use std::thread::Thread; +use std::thread; // Avoid using constants, which would trigger compile-time errors. fn min_val() -> T { Int::min_value() } fn zero() -> T { Int::zero() } fn main() { - assert!(Thread::scoped(move|| min_val::() / -1).join().is_err()); - assert!(Thread::scoped(move|| min_val::() / -1).join().is_err()); - assert!(Thread::scoped(move|| min_val::() / -1).join().is_err()); - assert!(Thread::scoped(move|| min_val::() / -1).join().is_err()); - assert!(Thread::scoped(move|| min_val::() / -1).join().is_err()); - assert!(Thread::scoped(move|| 1is / zero()).join().is_err()); - assert!(Thread::scoped(move|| 1i8 / zero()).join().is_err()); - assert!(Thread::scoped(move|| 1i16 / zero()).join().is_err()); - assert!(Thread::scoped(move|| 1i32 / zero()).join().is_err()); - assert!(Thread::scoped(move|| 1i64 / zero()).join().is_err()); - assert!(Thread::scoped(move|| min_val::() % -1).join().is_err()); - assert!(Thread::scoped(move|| min_val::() % -1).join().is_err()); - assert!(Thread::scoped(move|| min_val::() % -1).join().is_err()); - assert!(Thread::scoped(move|| min_val::() % -1).join().is_err()); - assert!(Thread::scoped(move|| min_val::() % -1).join().is_err()); - assert!(Thread::scoped(move|| 1is % zero()).join().is_err()); - assert!(Thread::scoped(move|| 1i8 % zero()).join().is_err()); - assert!(Thread::scoped(move|| 1i16 % zero()).join().is_err()); - assert!(Thread::scoped(move|| 1i32 % zero()).join().is_err()); - assert!(Thread::scoped(move|| 1i64 % zero()).join().is_err()); + assert!(thread::spawn(move|| { min_val::() / -1; }).join().is_err()); + assert!(thread::spawn(move|| { min_val::() / -1; }).join().is_err()); + assert!(thread::spawn(move|| { min_val::() / -1; }).join().is_err()); + assert!(thread::spawn(move|| { min_val::() / -1; }).join().is_err()); + assert!(thread::spawn(move|| { min_val::() / -1; }).join().is_err()); + assert!(thread::spawn(move|| { 1is / zero(); }).join().is_err()); + assert!(thread::spawn(move|| { 1i8 / zero(); }).join().is_err()); + assert!(thread::spawn(move|| { 1i16 / zero(); }).join().is_err()); + assert!(thread::spawn(move|| { 1i32 / zero(); }).join().is_err()); + assert!(thread::spawn(move|| { 1i64 / zero(); }).join().is_err()); + assert!(thread::spawn(move|| { min_val::() % -1; }).join().is_err()); + assert!(thread::spawn(move|| { min_val::() % -1; }).join().is_err()); + assert!(thread::spawn(move|| { min_val::() % -1; }).join().is_err()); + assert!(thread::spawn(move|| { min_val::() % -1; }).join().is_err()); + assert!(thread::spawn(move|| { min_val::() % -1; }).join().is_err()); + assert!(thread::spawn(move|| { 1is % zero(); }).join().is_err()); + assert!(thread::spawn(move|| { 1i8 % zero(); }).join().is_err()); + assert!(thread::spawn(move|| { 1i16 % zero(); }).join().is_err()); + assert!(thread::spawn(move|| { 1i32 % zero(); }).join().is_err()); + assert!(thread::spawn(move|| { 1i64 % zero(); }).join().is_err()); } diff --git a/src/test/run-pass/logging-only-prints-once.rs b/src/test/run-pass/logging-only-prints-once.rs index 644efe20ded..b03c4b5ff47 100644 --- a/src/test/run-pass/logging-only-prints-once.rs +++ b/src/test/run-pass/logging-only-prints-once.rs @@ -13,7 +13,7 @@ use std::cell::Cell; use std::fmt; -use std::thread::Thread; +use std::thread; struct Foo(Cell); @@ -27,7 +27,7 @@ impl fmt::Debug for Foo { } pub fn main() { - Thread::scoped(move|| { + thread::spawn(move|| { let mut f = Foo(Cell::new(0)); println!("{:?}", f); let Foo(ref mut f) = f; diff --git a/src/test/run-pass/no-landing-pads.rs b/src/test/run-pass/no-landing-pads.rs index c90c6ce87f0..5ce32e4fe2c 100644 --- a/src/test/run-pass/no-landing-pads.rs +++ b/src/test/run-pass/no-landing-pads.rs @@ -10,7 +10,7 @@ // compile-flags: -Z no-landing-pads -use std::thread::Thread; +use std::thread; static mut HIT: bool = false; @@ -23,7 +23,7 @@ impl Drop for A { } fn main() { - Thread::scoped(move|| -> () { + thread::spawn(move|| -> () { let _a = A; panic!(); }).join().err().unwrap(); 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 3cc01b967ce..6da15b97aca 100644 --- a/src/test/run-pass/panic-in-dtor-drops-fields.rs +++ b/src/test/run-pass/panic-in-dtor-drops-fields.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::thread::Thread; +use std::thread; static mut dropped: bool = false; @@ -33,7 +33,7 @@ impl Drop for B { } pub fn main() { - let ret = Thread::scoped(move|| { + let ret = thread::spawn(move|| { let _a = A { b: B { foo: 3 } }; }).join(); assert!(ret.is_err()); 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 6c9707103b9..523b7528103 100644 --- a/src/test/run-pass/sendfn-spawn-with-fn-arg.rs +++ b/src/test/run-pass/sendfn-spawn-with-fn-arg.rs @@ -11,7 +11,7 @@ #![allow(unknown_features)] #![feature(box_syntax)] -use std::thread::Thread; +use std::thread; pub fn main() { test05(); } @@ -25,7 +25,7 @@ fn test05() { println!("{}", *three + n); // will copy x into the closure assert_eq!(*three, 3); }; - Thread::scoped(move|| { + thread::spawn(move|| { test05_start(fn_to_send); }).join().ok().unwrap(); } diff --git a/src/test/run-pass/sepcomp-unwind.rs b/src/test/run-pass/sepcomp-unwind.rs index f68dea04a08..21c5a6fc83a 100644 --- a/src/test/run-pass/sepcomp-unwind.rs +++ b/src/test/run-pass/sepcomp-unwind.rs @@ -19,7 +19,7 @@ // In any case, this test should let us know if enabling parallel codegen ever // breaks unwinding. -use std::thread::Thread; +use std::thread; fn pad() -> uint { 0 } @@ -36,5 +36,5 @@ mod b { } fn main() { - Thread::scoped(move|| { ::b::g() }).join().err().unwrap(); + thread::spawn(move|| { ::b::g() }).join().err().unwrap(); } diff --git a/src/test/run-pass/slice-panic-1.rs b/src/test/run-pass/slice-panic-1.rs index b2e3d83ca9b..639ffd56002 100644 --- a/src/test/run-pass/slice-panic-1.rs +++ b/src/test/run-pass/slice-panic-1.rs @@ -10,7 +10,7 @@ // Test that if a slicing expr[..] fails, the correct cleanups happen. -use std::thread::Thread; +use std::thread; struct Foo; @@ -26,6 +26,6 @@ fn foo() { } fn main() { - let _ = Thread::scoped(move|| foo()).join(); + let _ = thread::spawn(move|| foo()).join(); 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 dea45e63ab0..4a2038175d2 100644 --- a/src/test/run-pass/slice-panic-2.rs +++ b/src/test/run-pass/slice-panic-2.rs @@ -10,7 +10,7 @@ // Test that if a slicing expr[..] fails, the correct cleanups happen. -use std::thread::Thread; +use std::thread; struct Foo; @@ -30,6 +30,6 @@ fn foo() { } fn main() { - let _ = Thread::scoped(move|| foo()).join(); + let _ = thread::spawn(move|| foo()).join(); unsafe { assert!(DTOR_COUNT == 2); } } diff --git a/src/test/run-pass/spawn-types.rs b/src/test/run-pass/spawn-types.rs index eaad2abe8f7..bf2f03b3e6d 100644 --- a/src/test/run-pass/spawn-types.rs +++ b/src/test/run-pass/spawn-types.rs @@ -14,7 +14,7 @@ Arnold. */ -use std::thread::Thread; +use std::thread; use std::sync::mpsc::{channel, Sender}; type ctx = Sender; @@ -25,6 +25,6 @@ fn iotask(_tx: &ctx, ip: String) { pub fn main() { let (tx, _rx) = channel::(); - let t = Thread::scoped(move|| iotask(&tx, "localhost".to_string()) ); + let t = thread::spawn(move|| iotask(&tx, "localhost".to_string()) ); t.join().ok().unwrap(); } diff --git a/src/test/run-pass/spawn.rs b/src/test/run-pass/spawn.rs index 8f937afa6b9..90b47f4986b 100644 --- a/src/test/run-pass/spawn.rs +++ b/src/test/run-pass/spawn.rs @@ -8,10 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::thread::Thread; +use std::thread; pub fn main() { - Thread::scoped(move|| child(10)).join().ok().unwrap(); + thread::spawn(move|| child(10)).join().ok().unwrap(); } 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 75104a4ddef..91edb5fd9c1 100644 --- a/src/test/run-pass/spawn2.rs +++ b/src/test/run-pass/spawn2.rs @@ -8,10 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::thread::Thread; +use std::thread; pub fn main() { - let t = Thread::scoped(move|| child((10, 20, 30, 40, 50, 60, 70, 80, 90)) ); + let t = thread::spawn(move|| child((10, 20, 30, 40, 50, 60, 70, 80, 90)) ); t.join().ok().unwrap(); } diff --git a/src/test/run-pass/task-stderr.rs b/src/test/run-pass/task-stderr.rs index 5994b24dfdc..1c263b19dd1 100644 --- a/src/test/run-pass/task-stderr.rs +++ b/src/test/run-pass/task-stderr.rs @@ -20,9 +20,10 @@ fn main() { let mut reader = ChanReader::new(rx); let stderr = ChanWriter::new(tx); - let res = thread::Builder::new().stderr(box stderr as Box).scoped(move|| -> () { + let res = thread::Builder::new().stderr(box stderr as Box) + .spawn(move|| -> () { panic!("Hello, world!") - }).join(); + }).unwrap().join(); assert!(res.is_err()); let output = reader.read_to_string().unwrap(); diff --git a/src/test/run-pass/tempfile.rs b/src/test/run-pass/tempfile.rs index 4df1ff14810..053df3a57f3 100644 --- a/src/test/run-pass/tempfile.rs +++ b/src/test/run-pass/tempfile.rs @@ -23,7 +23,7 @@ use std::old_io::{fs, TempDir}; use std::old_io; use std::os; use std::sync::mpsc::channel; -use std::thread::Thread; +use std::thread; fn test_tempdir() { let path = { @@ -42,7 +42,7 @@ fn test_rm_tempdir() { tx.send(tmp.path().clone()).unwrap(); panic!("panic to unwind past `tmp`"); }; - let _ = Thread::scoped(f).join(); + thread::spawn(f).join(); let path = rx.recv().unwrap(); assert!(!path.exists()); @@ -52,7 +52,7 @@ fn test_rm_tempdir() { let _tmp = tmp; panic!("panic to unwind past `tmp`"); }; - let _ = Thread::scoped(f).join(); + thread::spawn(f).join(); assert!(!path.exists()); let path; @@ -61,7 +61,7 @@ fn test_rm_tempdir() { TempDir::new("test_rm_tempdir").unwrap() }; // FIXME(#16640) `: TempDir` annotation shouldn't be necessary - let tmp: TempDir = Thread::scoped(f).join().ok().expect("test_rm_tmdir"); + let tmp: TempDir = thread::scoped(f).join(); path = tmp.path().clone(); assert!(path.exists()); } @@ -85,7 +85,7 @@ fn test_rm_tempdir_close() { tmp.close(); panic!("panic when unwinding past `tmp`"); }; - let _ = Thread::scoped(f).join(); + thread::spawn(f).join(); let path = rx.recv().unwrap(); assert!(!path.exists()); @@ -96,7 +96,7 @@ fn test_rm_tempdir_close() { tmp.close(); panic!("panic when unwinding past `tmp`"); }; - let _ = Thread::scoped(f).join(); + thread::spawn(f).join(); assert!(!path.exists()); let path; @@ -105,7 +105,7 @@ fn test_rm_tempdir_close() { TempDir::new("test_rm_tempdir").unwrap() }; // FIXME(#16640) `: TempDir` annotation shouldn't be necessary - let tmp: TempDir = Thread::scoped(f).join().ok().expect("test_rm_tmdir"); + let tmp: TempDir = thread::scoped(f).join(); path = tmp.path().clone(); assert!(path.exists()); tmp.close(); @@ -179,7 +179,7 @@ pub fn test_rmdir_recursive_ok() { } pub fn dont_double_panic() { - let r: Result<(), _> = Thread::scoped(move|| { + let r: Result<(), _> = thread::spawn(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 185edb02cca..bef9efa9eb6 100644 --- a/src/test/run-pass/terminate-in-initializer.rs +++ b/src/test/run-pass/terminate-in-initializer.rs @@ -12,7 +12,7 @@ // Issue #787 // Don't try to clean up uninitialized locals -use std::thread::Thread; +use std::thread; fn test_break() { loop { let _x: Box = break; } } @@ -22,13 +22,13 @@ fn test_ret() { let _x: Box = return; } fn test_panic() { fn f() { let _x: Box = panic!(); } - Thread::scoped(move|| f() ).join().err().unwrap(); + thread::spawn(move|| f() ).join().err().unwrap(); } fn test_panic_indirect() { fn f() -> ! { panic!(); } fn g() { let _x: Box = f(); } - Thread::scoped(move|| g() ).join().err().unwrap(); + thread::spawn(move|| g() ).join().err().unwrap(); } pub fn main() { -- cgit 1.4.1-3-g733a5