Skip to content

std: Stabilize a number of small APIs #27370

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 31, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 11 additions & 12 deletions src/libcore/hash/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,7 @@ pub trait Hash {
fn hash<H: Hasher>(&self, state: &mut H);

/// Feeds a slice of this type into the state provided.
#[unstable(feature = "hash_slice",
reason = "module was recently redesigned")]
#[stable(feature = "hash_slice", since = "1.3.0")]
fn hash_slice<H: Hasher>(data: &[Self], state: &mut H) where Self: Sized {
for piece in data {
piece.hash(state);
Expand All @@ -111,29 +110,29 @@ pub trait Hasher {

/// Write a single `u8` into this hasher
#[inline]
#[unstable(feature = "hasher_write", reason = "module was recently redesigned")]
#[stable(feature = "hasher_write", since = "1.3.0")]
fn write_u8(&mut self, i: u8) { self.write(&[i]) }
/// Write a single `u16` into this hasher.
#[inline]
#[unstable(feature = "hasher_write", reason = "module was recently redesigned")]
#[stable(feature = "hasher_write", since = "1.3.0")]
fn write_u16(&mut self, i: u16) {
self.write(&unsafe { mem::transmute::<_, [u8; 2]>(i) })
}
/// Write a single `u32` into this hasher.
#[inline]
#[unstable(feature = "hasher_write", reason = "module was recently redesigned")]
#[stable(feature = "hasher_write", since = "1.3.0")]
fn write_u32(&mut self, i: u32) {
self.write(&unsafe { mem::transmute::<_, [u8; 4]>(i) })
}
/// Write a single `u64` into this hasher.
#[inline]
#[unstable(feature = "hasher_write", reason = "module was recently redesigned")]
#[stable(feature = "hasher_write", since = "1.3.0")]
fn write_u64(&mut self, i: u64) {
self.write(&unsafe { mem::transmute::<_, [u8; 8]>(i) })
}
/// Write a single `usize` into this hasher.
#[inline]
#[unstable(feature = "hasher_write", reason = "module was recently redesigned")]
#[stable(feature = "hasher_write", since = "1.3.0")]
fn write_usize(&mut self, i: usize) {
if cfg!(target_pointer_width = "32") {
self.write_u32(i as u32)
Expand All @@ -144,23 +143,23 @@ pub trait Hasher {

/// Write a single `i8` into this hasher.
#[inline]
#[unstable(feature = "hasher_write", reason = "module was recently redesigned")]
#[stable(feature = "hasher_write", since = "1.3.0")]
fn write_i8(&mut self, i: i8) { self.write_u8(i as u8) }
/// Write a single `i16` into this hasher.
#[inline]
#[unstable(feature = "hasher_write", reason = "module was recently redesigned")]
#[stable(feature = "hasher_write", since = "1.3.0")]
fn write_i16(&mut self, i: i16) { self.write_u16(i as u16) }
/// Write a single `i32` into this hasher.
#[inline]
#[unstable(feature = "hasher_write", reason = "module was recently redesigned")]
#[stable(feature = "hasher_write", since = "1.3.0")]
fn write_i32(&mut self, i: i32) { self.write_u32(i as u32) }
/// Write a single `i64` into this hasher.
#[inline]
#[unstable(feature = "hasher_write", reason = "module was recently redesigned")]
#[stable(feature = "hasher_write", since = "1.3.0")]
fn write_i64(&mut self, i: i64) { self.write_u64(i as u64) }
/// Write a single `isize` into this hasher.
#[inline]
#[unstable(feature = "hasher_write", reason = "module was recently redesigned")]
#[stable(feature = "hasher_write", since = "1.3.0")]
fn write_isize(&mut self, i: isize) { self.write_usize(i as usize) }
}

Expand Down
102 changes: 93 additions & 9 deletions src/libstd/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ impl Error for string::FromUtf16Error {
// copied from any.rs
impl Error + 'static {
/// Returns true if the boxed type is the same as `T`
#[unstable(feature = "error_downcast", reason = "recently added")]
#[stable(feature = "error_downcast", since = "1.3.0")]
#[inline]
pub fn is<T: Error + 'static>(&self) -> bool {
// Get TypeId of the type this function is instantiated with
Expand All @@ -183,7 +183,7 @@ impl Error + 'static {

/// Returns some reference to the boxed value if it is of type `T`, or
/// `None` if it isn't.
#[unstable(feature = "error_downcast", reason = "recently added")]
#[stable(feature = "error_downcast", since = "1.3.0")]
#[inline]
pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
if self.is::<T>() {
Expand All @@ -201,7 +201,7 @@ impl Error + 'static {

/// Returns some mutable reference to the boxed value if it is of type `T`, or
/// `None` if it isn't.
#[unstable(feature = "error_downcast", reason = "recently added")]
#[stable(feature = "error_downcast", since = "1.3.0")]
#[inline]
pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
if self.is::<T>() {
Expand All @@ -220,21 +220,44 @@ impl Error + 'static {

impl Error + 'static + Send {
/// Forwards to the method defined on the type `Any`.
#[unstable(feature = "error_downcast", reason = "recently added")]
#[stable(feature = "error_downcast", since = "1.3.0")]
#[inline]
pub fn is<T: Error + 'static>(&self) -> bool {
<Error + 'static>::is::<T>(self)
}

/// Forwards to the method defined on the type `Any`.
#[unstable(feature = "error_downcast", reason = "recently added")]
#[stable(feature = "error_downcast", since = "1.3.0")]
#[inline]
pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
<Error + 'static>::downcast_ref::<T>(self)
}

/// Forwards to the method defined on the type `Any`.
#[unstable(feature = "error_downcast", reason = "recently added")]
#[stable(feature = "error_downcast", since = "1.3.0")]
#[inline]
pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
<Error + 'static>::downcast_mut::<T>(self)
}
}

impl Error + 'static + Send + Sync {
/// Forwards to the method defined on the type `Any`.
#[stable(feature = "error_downcast", since = "1.3.0")]
#[inline]
pub fn is<T: Error + 'static>(&self) -> bool {
<Error + 'static>::is::<T>(self)
}

/// Forwards to the method defined on the type `Any`.
#[stable(feature = "error_downcast", since = "1.3.0")]
#[inline]
pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
<Error + 'static>::downcast_ref::<T>(self)
}

/// Forwards to the method defined on the type `Any`.
#[stable(feature = "error_downcast", since = "1.3.0")]
#[inline]
pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
<Error + 'static>::downcast_mut::<T>(self)
Expand All @@ -243,7 +266,7 @@ impl Error + 'static + Send {

impl Error {
#[inline]
#[unstable(feature = "error_downcast", reason = "recently added")]
#[stable(feature = "error_downcast", since = "1.3.0")]
/// Attempt to downcast the box to a concrete type.
pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<Error>> {
if self.is::<T>() {
Expand All @@ -264,13 +287,74 @@ impl Error {

impl Error + Send {
#[inline]
#[unstable(feature = "error_downcast", reason = "recently added")]
#[stable(feature = "error_downcast", since = "1.3.0")]
/// Attempt to downcast the box to a concrete type.
pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<Error + Send>> {
pub fn downcast<T: Error + 'static>(self: Box<Self>)
-> Result<Box<T>, Box<Error + Send>> {
let err: Box<Error> = self;
<Error>::downcast(err).map_err(|s| unsafe {
// reapply the Send marker
transmute::<Box<Error>, Box<Error + Send>>(s)
})
}
}

impl Error + Send + Sync {
#[inline]
#[stable(feature = "error_downcast", since = "1.3.0")]
/// Attempt to downcast the box to a concrete type.
pub fn downcast<T: Error + 'static>(self: Box<Self>)
-> Result<Box<T>, Box<Self>> {
let err: Box<Error> = self;
<Error>::downcast(err).map_err(|s| unsafe {
// reapply the Send+Sync marker
transmute::<Box<Error>, Box<Error + Send + Sync>>(s)
})
}
}

#[cfg(test)]
mod tests {
use prelude::v1::*;
use super::Error;
use fmt;

#[derive(Debug, PartialEq)]
struct A;
#[derive(Debug, PartialEq)]
struct B;

impl fmt::Display for A {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "A")
}
}
impl fmt::Display for B {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "B")
}
}

impl Error for A {
fn description(&self) -> &str { "A-desc" }
}
impl Error for B {
fn description(&self) -> &str { "A-desc" }
}

#[test]
fn downcasting() {
let mut a = A;
let mut a = &mut a as &mut (Error + 'static);
assert_eq!(a.downcast_ref::<A>(), Some(&A));
assert_eq!(a.downcast_ref::<B>(), None);
assert_eq!(a.downcast_mut::<A>(), Some(&mut A));
assert_eq!(a.downcast_mut::<B>(), None);

let a: Box<Error> = Box::new(A);
match a.downcast::<B>() {
Ok(..) => panic!("expected error"),
Err(e) => assert_eq!(*e.downcast::<A>().unwrap(), A),
}
}
}
15 changes: 6 additions & 9 deletions src/libstd/io/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,7 @@ impl Error {
///
/// If this `Error` was constructed via `new` then this function will
/// return `Some`, otherwise it will return `None`.
#[unstable(feature = "io_error_inner",
reason = "recently added and requires UFCS to downcast")]
#[stable(feature = "io_error_inner", since = "1.3.0")]
pub fn get_ref(&self) -> Option<&(error::Error+Send+Sync+'static)> {
match self.repr {
Repr::Os(..) => None,
Expand All @@ -233,8 +232,7 @@ impl Error {
///
/// If this `Error` was constructed via `new` then this function will
/// return `Some`, otherwise it will return `None`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add a note to the docs for these methods about the need to call via UFCS - it confused the hell out of me for a while when I was writing tests for them.

EDIT: Ah, looks like it works now from the tests, nvm.

#[unstable(feature = "io_error_inner",
reason = "recently added and requires UFCS to downcast")]
#[stable(feature = "io_error_inner", since = "1.3.0")]
pub fn get_mut(&mut self) -> Option<&mut (error::Error+Send+Sync+'static)> {
match self.repr {
Repr::Os(..) => None,
Expand All @@ -246,8 +244,7 @@ impl Error {
///
/// If this `Error` was constructed via `new` then this function will
/// return `Some`, otherwise it will return `None`.
#[unstable(feature = "io_error_inner",
reason = "recently added and requires UFCS to downcast")]
#[stable(feature = "io_error_inner", since = "1.3.0")]
pub fn into_inner(self) -> Option<Box<error::Error+Send+Sync>> {
match self.repr {
Repr::Os(..) => None,
Expand Down Expand Up @@ -349,10 +346,10 @@ mod test {
// we have to call all of these UFCS style right now since method
// resolution won't implicitly drop the Send+Sync bounds
let mut err = Error::new(ErrorKind::Other, TestError);
assert!(error::Error::is::<TestError>(err.get_ref().unwrap()));
assert!(err.get_ref().unwrap().is::<TestError>());
assert_eq!("asdf", err.get_ref().unwrap().description());
assert!(error::Error::is::<TestError>(err.get_mut().unwrap()));
assert!(err.get_mut().unwrap().is::<TestError>());
let extracted = err.into_inner().unwrap();
error::Error::downcast::<TestError>(extracted).unwrap();
extracted.downcast::<TestError>().unwrap();
}
}
2 changes: 1 addition & 1 deletion src/libstd/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ impl Child {
}

/// Returns the OS-assigned process identifier associated with this child.
#[unstable(feature = "process_id", reason = "api recently added")]
#[stable(feature = "process_id", since = "1.3.0")]
pub fn id(&self) -> u32 {
self.handle.id()
}
Expand Down