diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2016-04-07 10:42:53 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2016-04-11 08:57:53 -0700 |
| commit | 552eda70d33cead1398adfecce1a75e7a61e3daf (patch) | |
| tree | 7562570d4bedab441ff8196a5a66585b9af2d55b /src/libstd | |
| parent | 8694b4ffe9b223c351e50c10bd8ea4e23af58baa (diff) | |
| download | rust-552eda70d33cead1398adfecce1a75e7a61e3daf.tar.gz rust-552eda70d33cead1398adfecce1a75e7a61e3daf.zip | |
std: Stabilize APIs for the 1.9 release
This commit applies all stabilizations, renamings, and deprecations that the library team has decided on for the upcoming 1.9 release. All tracking issues have gone through a cycle-long "final comment period" and the specific APIs stabilized/deprecated are: Stable * `std::panic` * `std::panic::catch_unwind` (renamed from `recover`) * `std::panic::resume_unwind` (renamed from `propagate`) * `std::panic::AssertUnwindSafe` (renamed from `AssertRecoverSafe`) * `std::panic::UnwindSafe` (renamed from `RecoverSafe`) * `str::is_char_boundary` * `<*const T>::as_ref` * `<*mut T>::as_ref` * `<*mut T>::as_mut` * `AsciiExt::make_ascii_uppercase` * `AsciiExt::make_ascii_lowercase` * `char::decode_utf16` * `char::DecodeUtf16` * `char::DecodeUtf16Error` * `char::DecodeUtf16Error::unpaired_surrogate` * `BTreeSet::take` * `BTreeSet::replace` * `BTreeSet::get` * `HashSet::take` * `HashSet::replace` * `HashSet::get` * `OsString::with_capacity` * `OsString::clear` * `OsString::capacity` * `OsString::reserve` * `OsString::reserve_exact` * `OsStr::is_empty` * `OsStr::len` * `std::os::unix::thread` * `RawPthread` * `JoinHandleExt` * `JoinHandleExt::as_pthread_t` * `JoinHandleExt::into_pthread_t` * `HashSet::hasher` * `HashMap::hasher` * `CommandExt::exec` * `File::try_clone` * `SocketAddr::set_ip` * `SocketAddr::set_port` * `SocketAddrV4::set_ip` * `SocketAddrV4::set_port` * `SocketAddrV6::set_ip` * `SocketAddrV6::set_port` * `SocketAddrV6::set_flowinfo` * `SocketAddrV6::set_scope_id` * `<[T]>::copy_from_slice` * `ptr::read_volatile` * `ptr::write_volatile` * The `#[deprecated]` attribute * `OpenOptions::create_new` Deprecated * `std::raw::Slice` - use raw parts of `slice` module instead * `std::raw::Repr` - use raw parts of `slice` module instead * `str::char_range_at` - use slicing plus `chars()` plus `len_utf8` * `str::char_range_at_reverse` - use slicing plus `chars().rev()` plus `len_utf8` * `str::char_at` - use slicing plus `chars()` * `str::char_at_reverse` - use slicing plus `chars().rev()` * `str::slice_shift_char` - use `chars()` plus `Chars::as_str` * `CommandExt::session_leader` - use `before_exec` instead. Closes #27719 cc #27751 (deprecating the `Slice` bits) Closes #27754 Closes #27780 Closes #27809 Closes #27811 Closes #27830 Closes #28050 Closes #29453 Closes #29791 Closes #29935 Closes #30014 Closes #30752 Closes #31262 cc #31398 (still need to deal with `before_exec`) Closes #31405 Closes #31572 Closes #31755 Closes #31756
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/ascii.rs | 8 | ||||
| -rw-r--r-- | src/libstd/collections/hash/map.rs | 3 | ||||
| -rw-r--r-- | src/libstd/collections/hash/set.rs | 9 | ||||
| -rw-r--r-- | src/libstd/error.rs | 11 | ||||
| -rw-r--r-- | src/libstd/ffi/os_str.rs | 52 | ||||
| -rw-r--r-- | src/libstd/fs.rs | 7 | ||||
| -rw-r--r-- | src/libstd/io/mod.rs | 2 | ||||
| -rw-r--r-- | src/libstd/lib.rs | 2 | ||||
| -rw-r--r-- | src/libstd/net/addr.rs | 48 | ||||
| -rw-r--r-- | src/libstd/panic.rs | 222 | ||||
| -rw-r--r-- | src/libstd/rt.rs | 2 | ||||
| -rw-r--r-- | src/libstd/sync/once.rs | 6 | ||||
| -rw-r--r-- | src/libstd/sys/common/backtrace.rs | 2 | ||||
| -rw-r--r-- | src/libstd/sys/common/wtf8.rs | 5 | ||||
| -rw-r--r-- | src/libstd/sys/unix/ext/mod.rs | 4 | ||||
| -rw-r--r-- | src/libstd/sys/unix/ext/process.rs | 4 | ||||
| -rw-r--r-- | src/libstd/sys/unix/ext/thread.rs | 14 | ||||
| -rw-r--r-- | src/libstd/sys/windows/ext/thread.rs | 4 |
18 files changed, 259 insertions, 146 deletions
diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs index 3ae3cf8504e..0db91034eb5 100644 --- a/src/libstd/ascii.rs +++ b/src/libstd/ascii.rs @@ -128,8 +128,6 @@ pub trait AsciiExt { /// # Examples /// /// ``` - /// #![feature(ascii)] - /// /// use std::ascii::AsciiExt; /// /// let mut ascii = 'a'; @@ -138,7 +136,7 @@ pub trait AsciiExt { /// /// assert_eq!('A', ascii); /// ``` - #[unstable(feature = "ascii", issue = "27809")] + #[stable(feature = "ascii", since = "1.9.0")] fn make_ascii_uppercase(&mut self); /// Converts this type to its ASCII lower case equivalent in-place. @@ -148,8 +146,6 @@ pub trait AsciiExt { /// # Examples /// /// ``` - /// #![feature(ascii)] - /// /// use std::ascii::AsciiExt; /// /// let mut ascii = 'A'; @@ -158,7 +154,7 @@ pub trait AsciiExt { /// /// assert_eq!('a', ascii); /// ``` - #[unstable(feature = "ascii", issue = "27809")] + #[stable(feature = "ascii", since = "1.9.0")] fn make_ascii_lowercase(&mut self); } diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 234042ab011..c20270e8306 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -620,8 +620,7 @@ impl<K, V, S> HashMap<K, V, S> } /// Returns a reference to the map's hasher. - #[unstable(feature = "hashmap_public_hasher", reason = "don't want to make insta-stable", - issue = "31262")] + #[stable(feature = "hashmap_public_hasher", since = "1.9.0")] pub fn hasher(&self) -> &S { &self.hash_builder } diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index 954adf313be..b353a4c1ba1 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -194,8 +194,7 @@ impl<T, S> HashSet<T, S> } /// Returns a reference to the set's hasher. - #[unstable(feature = "hashmap_public_hasher", reason = "don't want to make insta-stable", - issue = "31262")] + #[stable(feature = "hashmap_public_hasher", since = "1.9.0")] pub fn hasher(&self) -> &S { self.map.hasher() } @@ -459,7 +458,7 @@ impl<T, S> HashSet<T, S> /// The value may be any borrowed form of the set's value type, but /// `Hash` and `Eq` on the borrowed form *must* match those for /// the value type. - #[unstable(feature = "set_recovery", issue = "28050")] + #[stable(feature = "set_recovery", since = "1.9.0")] pub fn get<Q: ?Sized>(&self, value: &Q) -> Option<&T> where T: Borrow<Q>, Q: Hash + Eq { @@ -556,7 +555,7 @@ impl<T, S> HashSet<T, S> /// Adds a value to the set, replacing the existing value, if any, that is equal to the given /// one. Returns the replaced value. - #[unstable(feature = "set_recovery", issue = "28050")] + #[stable(feature = "set_recovery", since = "1.9.0")] pub fn replace(&mut self, value: T) -> Option<T> { Recover::replace(&mut self.map, value) } @@ -591,7 +590,7 @@ impl<T, S> HashSet<T, S> /// The value may be any borrowed form of the set's value type, but /// `Hash` and `Eq` on the borrowed form *must* match those for /// the value type. - #[unstable(feature = "set_recovery", issue = "28050")] + #[stable(feature = "set_recovery", since = "1.9.0")] pub fn take<Q: ?Sized>(&mut self, value: &Q) -> Option<T> where T: Borrow<Q>, Q: Hash + Eq { diff --git a/src/libstd/error.rs b/src/libstd/error.rs index 660948b0acc..35cd4a5ec52 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -49,13 +49,11 @@ use any::TypeId; use boxed::Box; -use convert::From; +use char; use fmt::{self, Debug, Display}; use marker::{Send, Sync, Reflect}; use mem::transmute; use num; -use option::Option::{self, Some, None}; -use result::Result::{self, Ok, Err}; use raw::TraitObject; use str; use string::{self, String}; @@ -189,6 +187,13 @@ impl Error for string::ParseError { } } +#[stable(feature = "decode_utf16", since = "1.9.0")] +impl Error for char::DecodeUtf16Error { + fn description(&self) -> &str { + "unpaired surrogate found" + } +} + #[stable(feature = "box_error", since = "1.7.0")] impl<T: Error> Error for Box<T> { fn description(&self) -> &str { diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index de840457a01..0d29e62485a 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -86,13 +86,14 @@ impl OsString { self.inner.push_slice(&s.as_ref().inner) } - /// Creates a new `OsString` with the given capacity. The string will be - /// able to hold exactly `capacity` bytes without reallocating. If - /// `capacity` is 0, the string will not allocate. + /// Creates a new `OsString` with the given capacity. + /// + /// The string will be able to hold exactly `capacity` lenth units of other + /// OS strings without reallocating. If `capacity` is 0, the string will not + /// allocate. /// /// See main `OsString` documentation information about encoding. - #[unstable(feature = "osstring_simple_functions", - reason = "recently added", issue = "29453")] + #[stable(feature = "osstring_simple_functions", since = "1.9.0")] pub fn with_capacity(capacity: usize) -> OsString { OsString { inner: Buf::with_capacity(capacity) @@ -100,40 +101,36 @@ impl OsString { } /// Truncates the `OsString` to zero length. - #[unstable(feature = "osstring_simple_functions", - reason = "recently added", issue = "29453")] + #[stable(feature = "osstring_simple_functions", since = "1.9.0")] pub fn clear(&mut self) { self.inner.clear() } - /// Returns the number of bytes this `OsString` can hold without - /// reallocating. + /// Returns the capacity this `OsString` can hold without reallocating. /// /// See `OsString` introduction for information about encoding. - #[unstable(feature = "osstring_simple_functions", - reason = "recently added", issue = "29453")] + #[stable(feature = "osstring_simple_functions", since = "1.9.0")] pub fn capacity(&self) -> usize { self.inner.capacity() } - /// Reserves capacity for at least `additional` more bytes to be inserted - /// in the given `OsString`. The collection may reserve more space to avoid - /// frequent reallocations. - #[unstable(feature = "osstring_simple_functions", - reason = "recently added", issue = "29453")] + /// Reserves capacity for at least `additional` more capacity to be inserted + /// in the given `OsString`. + /// + /// The collection may reserve more space to avoid frequent reallocations. + #[stable(feature = "osstring_simple_functions", since = "1.9.0")] pub fn reserve(&mut self, additional: usize) { self.inner.reserve(additional) } - /// Reserves the minimum capacity for exactly `additional` more bytes to be - /// inserted in the given `OsString`. Does nothing if the capacity is + /// Reserves the minimum capacity for exactly `additional` more capacity to + /// be inserted in the given `OsString`. Does nothing if the capacity is /// already sufficient. /// /// Note that the allocator may give the collection more space than it /// requests. Therefore capacity can not be relied upon to be precisely /// minimal. Prefer reserve if future insertions are expected. - #[unstable(feature = "osstring_simple_functions", - reason = "recently added", issue = "29453")] + #[stable(feature = "osstring_simple_functions", since = "1.9.0")] pub fn reserve_exact(&mut self, additional: usize) { self.inner.reserve_exact(additional) } @@ -286,17 +283,20 @@ impl OsStr { } /// Checks whether the `OsStr` is empty. - #[unstable(feature = "osstring_simple_functions", - reason = "recently added", issue = "29453")] + #[stable(feature = "osstring_simple_functions", since = "1.9.0")] pub fn is_empty(&self) -> bool { self.inner.inner.is_empty() } - /// Returns the number of bytes in this `OsStr`. + /// Returns the length of this `OsStr`. + /// + /// Note that this does **not** return the number of bytes in this string + /// as, for example, OS strings on Windows are encoded as a list of `u16` + /// rather than a list of bytes. This number is simply useful for passing to + /// other methods like `OsString::with_capacity` to avoid reallocations. /// - /// See `OsStr` introduction for information about encoding. - #[unstable(feature = "osstring_simple_functions", - reason = "recently added", issue = "29453")] + /// See `OsStr` introduction for more information about encoding. + #[stable(feature = "osstring_simple_functions", since = "1.9.0")] pub fn len(&self) -> usize { self.inner.inner.len() } diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index c4d6cb33365..f5a51e97427 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -302,7 +302,7 @@ impl File { /// The returned `File` is a reference to the same state that this object /// references. Both handles will read and write with the same cursor /// position. - #[unstable(feature = "file_try_clone", reason = "newly added", issue = "31405")] + #[stable(feature = "file_try_clone", since = "1.9.0")] pub fn try_clone(&self) -> io::Result<File> { Ok(File { inner: self.inner.duplicate()? @@ -523,16 +523,13 @@ impl OpenOptions { /// # Examples /// /// ```no_run - /// #![feature(expand_open_options)] /// use std::fs::OpenOptions; /// /// let file = OpenOptions::new().write(true) /// .create_new(true) /// .open("foo.txt"); /// ``` - #[unstable(feature = "expand_open_options", - reason = "recently added", - issue = "30014")] + #[stable(feature = "expand_open_options2", since = "1.9.0")] pub fn create_new(&mut self, create_new: bool) -> &mut OpenOptions { self.0.create_new(create_new); self } diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index bcce8ee6abf..6dd7273c17f 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -1596,7 +1596,7 @@ impl<R: Read> Iterator for Chars<R> { } } Some(match str::from_utf8(&buf[..width]).ok() { - Some(s) => Ok(s.char_at(0)), + Some(s) => Ok(s.chars().next().unwrap()), None => Err(CharsError::NotUtf8), }) } diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 8dcac514172..e14a31453d3 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -222,10 +222,8 @@ #![feature(collections)] #![feature(collections_bound)] #![feature(const_fn)] -#![feature(copy_from_slice)] #![feature(core_float)] #![feature(core_intrinsics)] -#![feature(decode_utf16)] #![feature(dropck_parametricity)] #![feature(float_extras)] #![feature(float_from_str_radix)] diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index a915872d8ac..d510339f1c5 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -68,7 +68,7 @@ impl SocketAddr { } /// Change the IP address associated with this socket address. - #[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")] + #[stable(feature = "sockaddr_setters", since = "1.9.0")] pub fn set_ip(&mut self, new_ip: IpAddr) { // `match (*self, new_ip)` would have us mutate a copy of self only to throw it away. match (self, new_ip) { @@ -88,7 +88,7 @@ impl SocketAddr { } /// Change the port number associated with this socket address. - #[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")] + #[stable(feature = "sockaddr_setters", since = "1.9.0")] pub fn set_port(&mut self, new_port: u16) { match *self { SocketAddr::V4(ref mut a) => a.set_port(new_port), @@ -120,16 +120,22 @@ impl SocketAddrV4 { } /// Change the IP address associated with this socket address. - #[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")] - pub fn set_ip(&mut self, new_ip: Ipv4Addr) { self.inner.sin_addr = *new_ip.as_inner() } + #[stable(feature = "sockaddr_setters", since = "1.9.0")] + pub fn set_ip(&mut self, new_ip: Ipv4Addr) { + self.inner.sin_addr = *new_ip.as_inner() + } /// Returns the port number associated with this socket address. #[stable(feature = "rust1", since = "1.0.0")] - pub fn port(&self) -> u16 { ntoh(self.inner.sin_port) } + pub fn port(&self) -> u16 { + ntoh(self.inner.sin_port) + } /// Change the port number associated with this socket address. - #[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")] - pub fn set_port(&mut self, new_port: u16) { self.inner.sin_port = hton(new_port) } + #[stable(feature = "sockaddr_setters", since = "1.9.0")] + pub fn set_port(&mut self, new_port: u16) { + self.inner.sin_port = hton(new_port); + } } impl SocketAddrV6 { @@ -159,24 +165,32 @@ impl SocketAddrV6 { } /// Change the IP address associated with this socket address. - #[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")] - pub fn set_ip(&mut self, new_ip: Ipv6Addr) { self.inner.sin6_addr = *new_ip.as_inner() } + #[stable(feature = "sockaddr_setters", since = "1.9.0")] + pub fn set_ip(&mut self, new_ip: Ipv6Addr) { + self.inner.sin6_addr = *new_ip.as_inner() + } /// Returns the port number associated with this socket address. #[stable(feature = "rust1", since = "1.0.0")] - pub fn port(&self) -> u16 { ntoh(self.inner.sin6_port) } + pub fn port(&self) -> u16 { + ntoh(self.inner.sin6_port) + } /// Change the port number associated with this socket address. - #[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")] - pub fn set_port(&mut self, new_port: u16) { self.inner.sin6_port = hton(new_port) } + #[stable(feature = "sockaddr_setters", since = "1.9.0")] + pub fn set_port(&mut self, new_port: u16) { + self.inner.sin6_port = hton(new_port); + } /// Returns the flow information associated with this address, /// corresponding to the `sin6_flowinfo` field in C. #[stable(feature = "rust1", since = "1.0.0")] - pub fn flowinfo(&self) -> u32 { self.inner.sin6_flowinfo } + pub fn flowinfo(&self) -> u32 { + self.inner.sin6_flowinfo + } /// Change the flow information associated with this socket address. - #[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")] + #[stable(feature = "sockaddr_setters", since = "1.9.0")] pub fn set_flowinfo(&mut self, new_flowinfo: u32) { self.inner.sin6_flowinfo = new_flowinfo; } @@ -184,10 +198,12 @@ impl SocketAddrV6 { /// Returns the scope ID associated with this address, /// corresponding to the `sin6_scope_id` field in C. #[stable(feature = "rust1", since = "1.0.0")] - pub fn scope_id(&self) -> u32 { self.inner.sin6_scope_id } + pub fn scope_id(&self) -> u32 { + self.inner.sin6_scope_id + } /// Change the scope ID associated with this socket address. - #[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")] + #[stable(feature = "sockaddr_setters", since = "1.9.0")] pub fn set_scope_id(&mut self, new_scope_id: u32) { self.inner.sin6_scope_id = new_scope_id; } diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs index 4462ce24dce..16401c4527f 100644 --- a/src/libstd/panic.rs +++ b/src/libstd/panic.rs @@ -10,8 +10,7 @@ //! Panic support in the standard library -#![unstable(feature = "std_panic", reason = "awaiting feedback", - issue = "27719")] +#![stable(feature = "std_panic", since = "1.9.0")] use any::Any; use boxed::Box; @@ -23,6 +22,7 @@ use sync::{Arc, Mutex, RwLock}; use sys_common::unwind; use thread::Result; +#[unstable(feature = "panic_handler", issue = "30449")] pub use panicking::{take_hook, set_hook, PanicInfo, Location}; /// @@ -92,7 +92,7 @@ pub fn take_handler() -> Box<Fn(&PanicInfo) + 'static + Sync + Send> { /// "speed bump" to alert users of `recover` that broken invariants may be /// witnessed and may need to be accounted for. /// -/// ## Who implements `RecoverSafe`? +/// ## Who implements `UnwindSafe`? /// /// Types such as `&mut T` and `&RefCell<T>` are examples which are **not** /// recover safe. The general idea is that any mutable state which can be shared @@ -104,7 +104,7 @@ pub fn take_handler() -> Box<Fn(&PanicInfo) + 'static + Sync + Send> { /// poisoning by default. They still allow witnessing a broken invariant, but /// they already provide their own "speed bumps" to do so. /// -/// ## When should `RecoverSafe` be used? +/// ## When should `UnwindSafe` be used? /// /// Is not intended that most types or functions need to worry about this trait. /// It is only used as a bound on the `recover` function and as mentioned above, @@ -112,10 +112,18 @@ pub fn take_handler() -> Box<Fn(&PanicInfo) + 'static + Sync + Send> { /// wrapper struct in this module can be used to force this trait to be /// implemented for any closed over variables passed to the `recover` function /// (more on this below). -#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")] +#[stable(feature = "catch_unwind", since = "1.9.0")] #[rustc_on_unimplemented = "the type {Self} may not be safely transferred \ across a recover boundary"] +pub trait UnwindSafe {} + +/// Deprecated, renamed to UnwindSafe +#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")] +#[rustc_deprecated(reason = "renamed to `UnwindSafe`", since = "1.9.0")] pub trait RecoverSafe {} +#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")] +#[allow(deprecated)] +impl<T: UnwindSafe> RecoverSafe for T {} /// A marker trait representing types where a shared reference is considered /// recover safe. @@ -124,12 +132,12 @@ pub trait RecoverSafe {} /// interior mutability. /// /// This is a "helper marker trait" used to provide impl blocks for the -/// `RecoverSafe` trait, for more information see that documentation. -#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")] +/// `UnwindSafe` trait, for more information see that documentation. +#[stable(feature = "catch_unwind", since = "1.9.0")] #[rustc_on_unimplemented = "the type {Self} contains interior mutability \ and a reference may not be safely transferrable \ across a recover boundary"] -pub trait RefRecoverSafe {} +pub trait RefUnwindSafe {} /// A simple wrapper around a type to assert that it is panic safe. /// @@ -143,90 +151,141 @@ pub trait RefRecoverSafe {} /// /// # Examples /// -/// One way to use `AssertRecoverSafe` is to assert that the entire closure +/// One way to use `AssertUnwindSafe` is to assert that the entire closure /// itself is recover safe, bypassing all checks for all variables: /// /// ``` -/// #![feature(recover, std_panic)] -/// -/// use std::panic::{self, AssertRecoverSafe}; +/// use std::panic::{self, AssertUnwindSafe}; /// /// let mut variable = 4; /// /// // This code will not compile because the closure captures `&mut variable` /// // which is not considered panic safe by default. /// -/// // panic::recover(|| { +/// // panic::catch_unwind(|| { /// // variable += 3; /// // }); /// -/// // This, however, will compile due to the `AssertRecoverSafe` wrapper -/// let result = panic::recover(AssertRecoverSafe(|| { +/// // This, however, will compile due to the `AssertUnwindSafe` wrapper +/// let result = panic::catch_unwind(AssertUnwindSafe(|| { /// variable += 3; /// })); /// // ... /// ``` /// /// Wrapping the entire closure amounts to a blanket assertion that all captured -/// variables are recover safe. This has the downside that if new captures are -/// added in the future, they will also be considered recover safe. Therefore, +/// variables are unwind safe. This has the downside that if new captures are +/// added in the future, they will also be considered unwind safe. Therefore, /// you may prefer to just wrap individual captures, as shown below. This is /// more annotation, but it ensures that if a new capture is added which is not -/// recover safe, you will get a compilation error at that time, which will +/// unwind safe, you will get a compilation error at that time, which will /// allow you to consider whether that new capture in fact represent a bug or /// not. /// /// ``` -/// #![feature(recover, std_panic)] -/// -/// use std::panic::{self, AssertRecoverSafe}; +/// use std::panic::{self, AssertUnwindSafe}; /// /// let mut variable = 4; /// let other_capture = 3; /// /// let result = { -/// let mut wrapper = AssertRecoverSafe(&mut variable); -/// panic::recover(move || { +/// let mut wrapper = AssertUnwindSafe(&mut variable); +/// panic::catch_unwind(move || { /// **wrapper += other_capture; /// }) /// }; /// // ... /// ``` -#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")] +#[stable(feature = "catch_unwind", since = "1.9.0")] +pub struct AssertUnwindSafe<T>( + #[stable(feature = "catch_unwind", since = "1.9.0")] + pub T +); + +/// Deprecated, renamed to `AssertUnwindSafe` +#[unstable(feature = "recover", issue = "27719")] +#[rustc_deprecated(reason = "renamed to `AssertUnwindSafe`", since = "1.9.0")] pub struct AssertRecoverSafe<T>(pub T); -// Implementations of the `RecoverSafe` trait: +// Implementations of the `UnwindSafe` trait: // -// * By default everything is recover safe -// * pointers T contains mutability of some form are not recover safe +// * By default everything is unwind safe +// * pointers T contains mutability of some form are not unwind safe // * Unique, an owning pointer, lifts an implementation -// * Types like Mutex/RwLock which are explicilty poisoned are recover safe -// * Our custom AssertRecoverSafe wrapper is indeed recover safe -impl RecoverSafe for .. {} -impl<'a, T: ?Sized> !RecoverSafe for &'a mut T {} -impl<'a, T: RefRecoverSafe + ?Sized> RecoverSafe for &'a T {} -impl<T: RefRecoverSafe + ?Sized> RecoverSafe for *const T {} -impl<T: RefRecoverSafe + ?Sized> RecoverSafe for *mut T {} -impl<T: RecoverSafe> RecoverSafe for Unique<T> {} -impl<T: RefRecoverSafe + ?Sized> RecoverSafe for Shared<T> {} -impl<T: ?Sized> RecoverSafe for Mutex<T> {} -impl<T: ?Sized> RecoverSafe for RwLock<T> {} -impl<T> RecoverSafe for AssertRecoverSafe<T> {} +// * Types like Mutex/RwLock which are explicilty poisoned are unwind safe +// * Our custom AssertUnwindSafe wrapper is indeed unwind safe +#[stable(feature = "catch_unwind", since = "1.9.0")] +impl UnwindSafe for .. {} +#[stable(feature = "catch_unwind", since = "1.9.0")] +impl<'a, T: ?Sized> !UnwindSafe for &'a mut T {} +#[stable(feature = "catch_unwind", since = "1.9.0")] +impl<'a, T: RefUnwindSafe + ?Sized> UnwindSafe for &'a T {} +#[stable(feature = "catch_unwind", since = "1.9.0")] +impl<T: RefUnwindSafe + ?Sized> UnwindSafe for *const T {} +#[stable(feature = "catch_unwind", since = "1.9.0")] +impl<T: RefUnwindSafe + ?Sized> UnwindSafe for *mut T {} +#[stable(feature = "catch_unwind", since = "1.9.0")] +impl<T: UnwindSafe> UnwindSafe for Unique<T> {} +#[stable(feature = "catch_unwind", since = "1.9.0")] +impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Shared<T> {} +#[stable(feature = "catch_unwind", since = "1.9.0")] +impl<T: ?Sized> UnwindSafe for Mutex<T> {} +#[stable(feature = "catch_unwind", since = "1.9.0")] +impl<T: ?Sized> UnwindSafe for RwLock<T> {} +#[stable(feature = "catch_unwind", since = "1.9.0")] +impl<T> UnwindSafe for AssertUnwindSafe<T> {} +#[unstable(feature = "recover", issue = "27719")] +#[allow(deprecated)] +impl<T> UnwindSafe for AssertRecoverSafe<T> {} // not covered via the Shared impl above b/c the inner contents use // Cell/AtomicUsize, but the usage here is recover safe so we can lift the // impl up one level to Arc/Rc itself -impl<T: RefRecoverSafe + ?Sized> RecoverSafe for Rc<T> {} -impl<T: RefRecoverSafe + ?Sized> RecoverSafe for Arc<T> {} +#[stable(feature = "catch_unwind", since = "1.9.0")] +impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Rc<T> {} +#[stable(feature = "catch_unwind", since = "1.9.0")] +impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Arc<T> {} // Pretty simple implementations for the `RefRecoverSafe` marker trait, // basically just saying that this is a marker trait and `UnsafeCell` is the // only thing which doesn't implement it (which then transitively applies to // everything else). -impl RefRecoverSafe for .. {} -impl<T: ?Sized> !RefRecoverSafe for UnsafeCell<T> {} -impl<T> RefRecoverSafe for AssertRecoverSafe<T> {} +#[stable(feature = "catch_unwind", since = "1.9.0")] +impl RefUnwindSafe for .. {} +#[stable(feature = "catch_unwind", since = "1.9.0")] +impl<T: ?Sized> !RefUnwindSafe for UnsafeCell<T> {} +#[stable(feature = "catch_unwind", since = "1.9.0")] +impl<T> RefUnwindSafe for AssertUnwindSafe<T> {} +#[unstable(feature = "recover", issue = "27719")] +#[allow(deprecated)] +impl<T> RefUnwindSafe for AssertRecoverSafe<T> {} + +#[stable(feature = "catch_unwind", since = "1.9.0")] +impl<T> Deref for AssertUnwindSafe<T> { + type Target = T; + + fn deref(&self) -> &T { + &self.0 + } +} + +#[stable(feature = "catch_unwind", since = "1.9.0")] +impl<T> DerefMut for AssertUnwindSafe<T> { + fn deref_mut(&mut self) -> &mut T { + &mut self.0 + } +} +#[stable(feature = "catch_unwind", since = "1.9.0")] +impl<R, F: FnOnce() -> R> FnOnce<()> for AssertUnwindSafe<F> { + type Output = R; + + extern "rust-call" fn call_once(self, _args: ()) -> R { + (self.0)() + } +} + +#[allow(deprecated)] impl<T> AssertRecoverSafe<T> { /// Creates a new `AssertRecoverSafe` wrapper around the provided type. #[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")] @@ -245,6 +304,8 @@ impl<T> AssertRecoverSafe<T> { } } +#[unstable(feature = "recover", issue = "27719")] +#[allow(deprecated)] impl<T> Deref for AssertRecoverSafe<T> { type Target = T; @@ -253,12 +314,16 @@ impl<T> Deref for AssertRecoverSafe<T> { } } +#[unstable(feature = "recover", issue = "27719")] +#[allow(deprecated)] impl<T> DerefMut for AssertRecoverSafe<T> { fn deref_mut(&mut self) -> &mut T { &mut self.0 } } +#[unstable(feature = "recover", issue = "27719")] +#[allow(deprecated)] impl<R, F: FnOnce() -> R> FnOnce<()> for AssertRecoverSafe<F> { type Output = R; @@ -267,7 +332,7 @@ impl<R, F: FnOnce() -> R> FnOnce<()> for AssertRecoverSafe<F> { } } -/// Invokes a closure, capturing the cause of panic if one occurs. +/// Invokes a closure, capturing the cause of an unwinding panic if one occurs. /// /// This function will return `Ok` with the closure's result if the closure /// does not panic, and will return `Err(cause)` if the closure panics. The @@ -280,38 +345,44 @@ impl<R, F: FnOnce() -> R> FnOnce<()> for AssertRecoverSafe<F> { /// /// It is **not** recommended to use this function for a general try/catch /// mechanism. The `Result` type is more appropriate to use for functions that -/// can fail on a regular basis. -/// -/// The closure provided is required to adhere to the `RecoverSafe` to ensure -/// that all captured variables are safe to cross this recover boundary. The -/// purpose of this bound is to encode the concept of [exception safety][rfc] in -/// the type system. Most usage of this function should not need to worry about -/// this bound as programs are naturally panic safe without `unsafe` code. If it -/// becomes a problem the associated `AssertRecoverSafe` wrapper type in this +/// can fail on a regular basis. Additionally, this function is not guaranteed +/// to catch all panics, see the "Notes" sectino below. +/// +/// The closure provided is required to adhere to the `UnwindSafe` to ensure +/// that all captured variables are safe to cross this boundary. The purpose of +/// this bound is to encode the concept of [exception safety][rfc] in the type +/// system. Most usage of this function should not need to worry about this +/// bound as programs are naturally panic safe without `unsafe` code. If it +/// becomes a problem the associated `AssertUnwindSafe` wrapper type in this /// module can be used to quickly assert that the usage here is indeed exception /// safe. /// /// [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1236-stabilize-catch-panic.md /// +/// # Notes +/// +/// Note that this function **may not catch all panics** in Rust. A panic in +/// Rust is not always implemented via unwinding, but can be implemented by +/// aborting the process as well. This function *only* catches unwinding panics, +/// not those that abort the process. +/// /// # Examples /// /// ``` -/// #![feature(recover, std_panic)] -/// /// use std::panic; /// -/// let result = panic::recover(|| { +/// let result = panic::catch_unwind(|| { /// println!("hello!"); /// }); /// assert!(result.is_ok()); /// -/// let result = panic::recover(|| { +/// let result = panic::catch_unwind(|| { /// panic!("oh no!"); /// }); /// assert!(result.is_err()); /// ``` -#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")] -pub fn recover<F: FnOnce() -> R + RecoverSafe, R>(f: F) -> Result<R> { +#[stable(feature = "catch_unwind", since = "1.9.0")] +pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> { let mut result = None; unsafe { let result = &mut result; @@ -320,27 +391,46 @@ pub fn recover<F: FnOnce() -> R + RecoverSafe, R>(f: F) -> Result<R> { Ok(result.unwrap()) } +/// Deprecated, renamed to `catch_unwind` +#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")] +#[rustc_deprecated(reason = "renamed to `catch_unwind`", since = "1.9.0")] +pub fn recover<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> { + catch_unwind(f) +} + /// Triggers a panic without invoking the panic handler. /// -/// This is designed to be used in conjunction with `recover` to, for example, -/// carry a panic across a layer of C code. +/// This is designed to be used in conjunction with `catch_unwind` to, for +/// example, carry a panic across a layer of C code. +/// +/// # Notes +/// +/// Note that panics in Rust are not always implemented via unwinding, but they +/// may be implemented by aborting the process. If this function is called when +/// panics are implemented this way then this function will abort the process, +/// not trigger an unwind. /// /// # Examples /// /// ```should_panic -/// #![feature(std_panic, recover, panic_propagate)] -/// /// use std::panic; /// -/// let result = panic::recover(|| { +/// let result = panic::catch_unwind(|| { /// panic!("oh no!"); /// }); /// /// if let Err(err) = result { -/// panic::propagate(err); +/// panic::resume_unwind(err); /// } /// ``` +#[stable(feature = "resume_unwind", since = "1.9.0")] +pub fn resume_unwind(payload: Box<Any + Send>) -> ! { + unwind::rust_panic(payload) +} + +/// Deprecated, use resume_unwind instead #[unstable(feature = "panic_propagate", reason = "awaiting feedback", issue = "30752")] +#[rustc_deprecated(reason = "renamed to `resume_unwind`", since = "1.9.0")] pub fn propagate(payload: Box<Any + Send>) -> ! { - unwind::rust_panic(payload) + resume_unwind(payload) } diff --git a/src/libstd/rt.rs b/src/libstd/rt.rs index fcd827e2a8b..83091c72c0d 100644 --- a/src/libstd/rt.rs +++ b/src/libstd/rt.rs @@ -60,7 +60,7 @@ fn lang_start(main: *const u8, argc: isize, argv: *const *const u8) -> isize { sys_common::args::init(argc, argv); // Let's run some code! - let res = panic::recover(mem::transmute::<_, fn()>(main)); + let res = panic::catch_unwind(mem::transmute::<_, fn()>(main)); sys_common::cleanup(); res.is_err() }; diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs index e673879d20d..e228d236a3c 100644 --- a/src/libstd/sync/once.rs +++ b/src/libstd/sync/once.rs @@ -425,13 +425,13 @@ mod tests { static O: Once = Once::new(); // poison the once - let t = panic::recover(|| { + let t = panic::catch_unwind(|| { O.call_once(|| panic!()); }); assert!(t.is_err()); // poisoning propagates - let t = panic::recover(|| { + let t = panic::catch_unwind(|| { O.call_once(|| {}); }); assert!(t.is_err()); @@ -453,7 +453,7 @@ mod tests { static O: Once = Once::new(); // poison the once - let t = panic::recover(|| { + let t = panic::catch_unwind(|| { O.call_once(|| panic!()); }); assert!(t.is_err()); diff --git a/src/libstd/sys/common/backtrace.rs b/src/libstd/sys/common/backtrace.rs index 24e1a82a593..6f185437e50 100644 --- a/src/libstd/sys/common/backtrace.rs +++ b/src/libstd/sys/common/backtrace.rs @@ -131,7 +131,7 @@ pub fn demangle(writer: &mut Write, s: &str) -> io::Result<()> { first = false; } let mut rest = inner; - while rest.char_at(0).is_numeric() { + while rest.chars().next().unwrap().is_numeric() { rest = &rest[1..]; } let i: usize = inner[.. (inner.len() - rest.len())].parse().unwrap(); diff --git a/src/libstd/sys/common/wtf8.rs b/src/libstd/sys/common/wtf8.rs index f64f835e198..55e485e5811 100644 --- a/src/libstd/sys/common/wtf8.rs +++ b/src/libstd/sys/common/wtf8.rs @@ -191,8 +191,11 @@ impl Wtf8Buf { match item { Ok(ch) => string.push_char(ch), Err(surrogate) => { + let surrogate = surrogate.unpaired_surrogate(); // Surrogates are known to be in the code point range. - let code_point = unsafe { CodePoint::from_u32_unchecked(surrogate as u32) }; + let code_point = unsafe { + CodePoint::from_u32_unchecked(surrogate as u32) + }; // Skip the WTF-8 concatenation check, // surrogate pairs are already decoded by decode_utf16 string.push_code_point_unchecked(code_point) diff --git a/src/libstd/sys/unix/ext/mod.rs b/src/libstd/sys/unix/ext/mod.rs index 4d8f12c2d7c..1be3d75d866 100644 --- a/src/libstd/sys/unix/ext/mod.rs +++ b/src/libstd/sys/unix/ext/mod.rs @@ -49,7 +49,9 @@ pub mod prelude { #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")] pub use super::fs::{PermissionsExt, OpenOptionsExt, MetadataExt, FileTypeExt}; #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")] - pub use super::fs::{DirEntryExt}; + pub use super::fs::DirEntryExt; + #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")] + pub use super::thread::JoinHandleExt; #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")] pub use super::process::{CommandExt, ExitStatusExt}; } diff --git a/src/libstd/sys/unix/ext/process.rs b/src/libstd/sys/unix/ext/process.rs index 8cc291d00ee..7f31cf9f3bf 100644 --- a/src/libstd/sys/unix/ext/process.rs +++ b/src/libstd/sys/unix/ext/process.rs @@ -45,6 +45,8 @@ pub trait CommandExt { /// (the daemon) in the same session. #[unstable(feature = "process_session_leader", reason = "recently added", issue = "27811")] + #[rustc_deprecated(reason = "use `before_exec` instead", + since = "1.9.0")] fn session_leader(&mut self, on: bool) -> &mut process::Command; /// Schedules a closure to be run just before the `exec` function is @@ -94,7 +96,7 @@ pub trait CommandExt { /// file descriptors may have changed. If a "transactional spawn" is /// required to gracefully handle errors it is recommended to use the /// cross-platform `spawn` instead. - #[unstable(feature = "process_exec", issue = "31398")] + #[stable(feature = "process_exec2", since = "1.9.0")] fn exec(&mut self) -> io::Error; } diff --git a/src/libstd/sys/unix/ext/thread.rs b/src/libstd/sys/unix/ext/thread.rs index c98e42faba7..fe2a48764dc 100644 --- a/src/libstd/sys/unix/ext/thread.rs +++ b/src/libstd/sys/unix/ext/thread.rs @@ -8,37 +8,41 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Unix-specific extensions to primitives in the `std::process` module. +//! Unix-specific extensions to primitives in the `std::thread` module. -#![unstable(feature = "thread_extensions", issue = "29791")] +#![stable(feature = "thread_extensions", since = "1.9.0")] #[allow(deprecated)] use os::unix::raw::pthread_t; use sys_common::{AsInner, IntoInner}; use thread::JoinHandle; -#[unstable(feature = "thread_extensions", issue = "29791")] +#[stable(feature = "thread_extensions", since = "1.9.0")] #[allow(deprecated)] pub type RawPthread = pthread_t; /// Unix-specific extensions to `std::thread::JoinHandle` -#[unstable(feature = "thread_extensions", issue = "29791")] +#[stable(feature = "thread_extensions", since = "1.9.0")] pub trait JoinHandleExt { /// Extracts the raw pthread_t without taking ownership + #[stable(feature = "thread_extensions", since = "1.9.0")] fn as_pthread_t(&self) -> RawPthread; + /// Consumes the thread, returning the raw pthread_t /// /// This function **transfers ownership** of the underlying pthread_t to /// the caller. Callers are then the unique owners of the pthread_t and /// must either detach or join the pthread_t once it's no longer needed. + #[stable(feature = "thread_extensions", since = "1.9.0")] fn into_pthread_t(self) -> RawPthread; } -#[unstable(feature = "thread_extensions", issue = "29791")] +#[stable(feature = "thread_extensions", since = "1.9.0")] impl<T> JoinHandleExt for JoinHandle<T> { fn as_pthread_t(&self) -> RawPthread { self.as_inner().id() as RawPthread } + fn into_pthread_t(self) -> RawPthread { self.into_inner().into_id() as RawPthread } diff --git a/src/libstd/sys/windows/ext/thread.rs b/src/libstd/sys/windows/ext/thread.rs index 3a07204b2bc..36b3a3d4bde 100644 --- a/src/libstd/sys/windows/ext/thread.rs +++ b/src/libstd/sys/windows/ext/thread.rs @@ -10,18 +10,20 @@ //! Extensions to `std::thread` for Windows. -#![unstable(feature = "thread_extensions", issue = "29791")] +#![stable(feature = "thread_extensions", since = "1.9.0")] use os::windows::io::{RawHandle, AsRawHandle, IntoRawHandle}; use thread; use sys_common::{AsInner, IntoInner}; +#[stable(feature = "thread_extensions", since = "1.9.0")] impl<T> AsRawHandle for thread::JoinHandle<T> { fn as_raw_handle(&self) -> RawHandle { self.as_inner().handle().raw() as *mut _ } } +#[stable(feature = "thread_extensions", since = "1.9.0")] impl<T> IntoRawHandle for thread::JoinHandle<T> { fn into_raw_handle(self) -> RawHandle { self.into_inner().into_handle().into_raw() as *mut _ |
