Skip to content

Commit

Permalink
Auto merge of #34778 - GuillaumeGomez:rollup, r=GuillaumeGomez
Browse files Browse the repository at this point in the history
Rollup of 7 pull requests

- Successful merges: #34736, #34737, #34740, #34742, #34749, #34750, #34770
- Failed merges: #33951
  • Loading branch information
bors authored Jul 12, 2016
2 parents 5c69a4f + 23d5f56 commit 31e9ed5
Show file tree
Hide file tree
Showing 7 changed files with 357 additions and 19 deletions.
4 changes: 2 additions & 2 deletions src/doc/book/closures.md
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ could annotate it on the function declaration:

```rust,ignore
fn call_with_ref<'a, F>(some_closure:F) -> i32
where F: Fn(&'a 32) -> i32 {
where F: Fn(&'a i32) -> i32 {
```

However this presents a problem with in our case. When you specify the explicit
Expand All @@ -350,7 +350,7 @@ of the closure we can use Higher-Ranked Trait Bounds with the `for<...>` syntax:

```ignore
fn call_with_ref<F>(some_closure:F) -> i32
where F: for<'a> Fn(&'a 32) -> i32 {
where F: for<'a> Fn(&'a i32) -> i32 {
```

This lets the Rust compiler find the minimum lifetime to invoke our closure and
Expand Down
4 changes: 3 additions & 1 deletion src/doc/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -2633,7 +2633,7 @@ comma:

There are several forms of struct expressions. A _struct expression_
consists of the [path](#paths) of a [struct item](#structs), followed by
a brace-enclosed list of one or more comma-separated name-value pairs,
a brace-enclosed list of zero or more comma-separated name-value pairs,
providing the field values of a new instance of the struct. A field name
can be any identifier, and is separated from its value expression by a colon.
The location denoted by a struct field is mutable if and only if the
Expand All @@ -2652,10 +2652,12 @@ The following are examples of struct expressions:

```
# struct Point { x: f64, y: f64 }
# struct NothingInMe { }
# struct TuplePoint(f64, f64);
# mod game { pub struct User<'a> { pub name: &'a str, pub age: u32, pub score: usize } }
# struct Cookie; fn some_fn<T>(t: T) {}
Point {x: 10.0, y: 20.0};
NothingInMe {};
TuplePoint(10.0, 20.0);
let u = game::User {name: "Joe", age: 35, score: 100_000};
some_fn::<Cookie>(Cookie);
Expand Down
49 changes: 46 additions & 3 deletions src/liballoc/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,14 @@ impl<T: ?Sized> Box<T> {
/// This function is unsafe because improper use may lead to
/// memory problems. For example, a double-free may occur if the
/// function is called twice on the same raw pointer.
///
/// # Examples
///
/// ```
/// let x = Box::new(5);
/// let ptr = Box::into_raw(x);
/// let x = unsafe { Box::from_raw(ptr) };
/// ```
#[stable(feature = "box_raw", since = "1.4.0")]
#[inline]
pub unsafe fn from_raw(raw: *mut T) -> Self {
Expand All @@ -266,9 +274,8 @@ impl<T: ?Sized> Box<T> {
/// # Examples
///
/// ```
/// let seventeen = Box::new(17);
/// let raw = Box::into_raw(seventeen);
/// let boxed_again = unsafe { Box::from_raw(raw) };
/// let x = Box::new(5);
/// let ptr = Box::into_raw(x);
/// ```
#[stable(feature = "box_raw", since = "1.4.0")]
#[inline]
Expand Down Expand Up @@ -399,6 +406,24 @@ impl Box<Any> {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
/// Attempt to downcast the box to a concrete type.
///
/// # Examples
///
/// ```
/// use std::any::Any;
///
/// fn print_if_string(value: Box<Any>) {
/// if let Ok(string) = value.downcast::<String>() {
/// println!("String ({}): {}", string.len(), string);
/// }
/// }
///
/// fn main() {
/// let my_string = "Hello World".to_string();
/// print_if_string(Box::new(my_string));
/// print_if_string(Box::new(0i8));
/// }
/// ```
pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<Any>> {
if self.is::<T>() {
unsafe {
Expand All @@ -419,6 +444,24 @@ impl Box<Any + Send> {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
/// Attempt to downcast the box to a concrete type.
///
/// # Examples
///
/// ```
/// use std::any::Any;
///
/// fn print_if_string(value: Box<Any + Send>) {
/// if let Ok(string) = value.downcast::<String>() {
/// println!("String ({}): {}", string.len(), string);
/// }
/// }
///
/// fn main() {
/// let my_string = "Hello World".to_string();
/// print_if_string(Box::new(my_string));
/// print_if_string(Box::new(0i8));
/// }
/// ```
pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<Any + Send>> {
<Box<Any>>::downcast(self).map_err(|s| unsafe {
// reapply the Send marker
Expand Down
160 changes: 158 additions & 2 deletions src/libcore/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,23 @@ use marker::{Reflect, Sized};
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Any: Reflect + 'static {
/// Gets the `TypeId` of `self`.
///
/// # Examples
///
/// ```
/// #![feature(get_type_id)]
///
/// use std::any::{Any, TypeId};
///
/// fn is_string(s: &Any) -> bool {
/// TypeId::of::<String>() == s.get_type_id()
/// }
///
/// fn main() {
/// assert_eq!(is_string(&0), false);
/// assert_eq!(is_string(&"cookie monster".to_owned()), true);
/// }
/// ```
#[unstable(feature = "get_type_id",
reason = "this method will likely be replaced by an associated static",
issue = "27745")]
Expand Down Expand Up @@ -125,7 +142,26 @@ impl fmt::Debug for Any + Send {
}

impl Any {
/// Returns true if the boxed type is the same as `T`
/// Returns true if the boxed type is the same as `T`.
///
/// # Examples
///
/// ```
/// use std::any::Any;
///
/// fn is_string(s: &Any) {
/// if s.is::<String>() {
/// println!("It's a string!");
/// } else {
/// println!("Not a string...");
/// }
/// }
///
/// fn main() {
/// is_string(&0);
/// is_string(&"cookie monster".to_owned());
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn is<T: Any>(&self) -> bool {
Expand All @@ -141,6 +177,25 @@ impl Any {

/// Returns some reference to the boxed value if it is of type `T`, or
/// `None` if it isn't.
///
/// # Examples
///
/// ```
/// use std::any::Any;
///
/// fn print_if_string(s: &Any) {
/// if let Some(string) = s.downcast_ref::<String>() {
/// println!("It's a string({}): '{}'", string.len(), string);
/// } else {
/// println!("Not a string...");
/// }
/// }
///
/// fn main() {
/// print_if_string(&0);
/// print_if_string(&"cookie monster".to_owned());
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
Expand All @@ -159,6 +214,29 @@ impl Any {

/// Returns some mutable reference to the boxed value if it is of type `T`, or
/// `None` if it isn't.
///
/// # Examples
///
/// ```
/// use std::any::Any;
///
/// fn modify_if_u32(s: &mut Any) {
/// if let Some(num) = s.downcast_mut::<u32>() {
/// *num = 42;
/// }
/// }
///
/// fn main() {
/// let mut x = 10u32;
/// let mut s = "starlord".to_owned();
///
/// modify_if_u32(&mut x);
/// modify_if_u32(&mut s);
///
/// assert_eq!(x, 42);
/// assert_eq!(&s, "starlord");
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
Expand All @@ -178,20 +256,81 @@ impl Any {

impl Any+Send {
/// Forwards to the method defined on the type `Any`.
///
/// # Examples
///
/// ```
/// use std::any::Any;
///
/// fn is_string(s: &(Any + Send)) {
/// if s.is::<String>() {
/// println!("It's a string!");
/// } else {
/// println!("Not a string...");
/// }
/// }
///
/// fn main() {
/// is_string(&0);
/// is_string(&"cookie monster".to_owned());
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn is<T: Any>(&self) -> bool {
Any::is::<T>(self)
}

/// Forwards to the method defined on the type `Any`.
///
/// # Examples
///
/// ```
/// use std::any::Any;
///
/// fn print_if_string(s: &(Any + Send)) {
/// if let Some(string) = s.downcast_ref::<String>() {
/// println!("It's a string({}): '{}'", string.len(), string);
/// } else {
/// println!("Not a string...");
/// }
/// }
///
/// fn main() {
/// print_if_string(&0);
/// print_if_string(&"cookie monster".to_owned());
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
Any::downcast_ref::<T>(self)
}

/// Forwards to the method defined on the type `Any`.
///
/// # Examples
///
/// ```
/// use std::any::Any;
///
/// fn modify_if_u32(s: &mut (Any+ Send)) {
/// if let Some(num) = s.downcast_mut::<u32>() {
/// *num = 42;
/// }
/// }
///
/// fn main() {
/// let mut x = 10u32;
/// let mut s = "starlord".to_owned();
///
/// modify_if_u32(&mut x);
/// modify_if_u32(&mut s);
///
/// assert_eq!(x, 42);
/// assert_eq!(&s, "starlord");
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
Expand Down Expand Up @@ -220,7 +359,24 @@ pub struct TypeId {

impl TypeId {
/// Returns the `TypeId` of the type this generic function has been
/// instantiated with
/// instantiated with.
///
/// # Examples
///
/// ```
/// #![feature(get_type_id)]
///
/// use std::any::{Any, TypeId};
///
/// fn is_string(s: &Any) -> bool {
/// TypeId::of::<String>() == s.get_type_id()
/// }
///
/// fn main() {
/// assert_eq!(is_string(&0), false);
/// assert_eq!(is_string(&"cookie monster".to_owned()), true);
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn of<T: ?Sized + Reflect + 'static>() -> TypeId {
TypeId {
Expand Down
Loading

0 comments on commit 31e9ed5

Please sign in to comment.