mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-28 20:16:58 +03:00
liballoc: implement From for Box, Rc, Arc
Sometimes when writing generic code you want to abstract over
owning/pointer type so that calling code isn't restricted by one
concrete owning/pointer type. This commit makes possible such code:
```
fn i_will_work_with_arc<T: Into<Arc<MyTy>>>(t: T) {
let the_arc = t.into();
// Do something
}
i_will_work_with_arc(MyTy::new());
i_will_work_with_arc(Box::new(MyTy::new()));
let arc_that_i_already_have = Arc::new(MyTy::new());
i_will_work_with_arc(arc_that_i_already_have);
```
Please note that this patch doesn't work with DSTs.
This commit is contained in:
@@ -84,6 +84,7 @@
|
||||
use core::marker::Unsize;
|
||||
use core::hash::{Hash, Hasher};
|
||||
use core::{usize, isize};
|
||||
use core::convert::From;
|
||||
use heap::deallocate;
|
||||
|
||||
const MAX_REFCOUNT: usize = (isize::MAX) as usize;
|
||||
@@ -894,8 +895,23 @@ fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.6.0")]
|
||||
impl<T> From<T> for Arc<T> {
|
||||
fn from(t: T) -> Self {
|
||||
Arc::new(t)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.6.0")]
|
||||
impl<T> From<Box<T>> for Arc<T> {
|
||||
fn from(t: Box<T>) -> Self {
|
||||
Arc::new(*t)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::boxed::Box;
|
||||
use std::clone::Clone;
|
||||
use std::sync::mpsc::channel;
|
||||
use std::mem::drop;
|
||||
@@ -908,6 +924,7 @@ mod tests {
|
||||
use std::vec::Vec;
|
||||
use super::{Arc, Weak};
|
||||
use std::sync::Mutex;
|
||||
use std::convert::From;
|
||||
|
||||
struct Canary(*mut atomic::AtomicUsize);
|
||||
|
||||
@@ -1137,6 +1154,20 @@ fn test_unsized() {
|
||||
drop(x);
|
||||
assert!(y.upgrade().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_owned() {
|
||||
let foo = 123;
|
||||
let foo_arc = Arc::from(foo);
|
||||
assert!(123 == *foo_arc);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_box() {
|
||||
let foo_box = Box::new(123);
|
||||
let foo_arc = Arc::from(foo_box);
|
||||
assert!(123 == *foo_arc);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> borrow::Borrow<T> for Arc<T> {
|
||||
|
||||
@@ -67,6 +67,7 @@
|
||||
use core::ops::{Placer, Boxed, Place, InPlace, BoxPlace};
|
||||
use core::ptr::{self, Unique};
|
||||
use core::raw::TraitObject;
|
||||
use core::convert::From;
|
||||
|
||||
/// A value that represents the heap. This is the default place that the `box`
|
||||
/// keyword allocates into when no place is supplied.
|
||||
@@ -375,6 +376,13 @@ fn hash<H: hash::Hasher>(&self, state: &mut H) {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.6.0")]
|
||||
impl<T> From<T> for Box<T> {
|
||||
fn from(t: T) -> Self {
|
||||
Box::new(t)
|
||||
}
|
||||
}
|
||||
|
||||
impl Box<Any> {
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
@@ -165,6 +165,7 @@
|
||||
use core::mem::{self, align_of_val, size_of_val, forget};
|
||||
use core::ops::{CoerceUnsized, Deref};
|
||||
use core::ptr::{self, Shared};
|
||||
use core::convert::From;
|
||||
|
||||
use heap::deallocate;
|
||||
|
||||
@@ -698,6 +699,20 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.6.0")]
|
||||
impl<T> From<T> for Rc<T> {
|
||||
fn from(t: T) -> Self {
|
||||
Rc::new(t)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.6.0")]
|
||||
impl<T> From<Box<T>> for Rc<T> {
|
||||
fn from(t: Box<T>) -> Self {
|
||||
Rc::new(*t)
|
||||
}
|
||||
}
|
||||
|
||||
/// A weak version of `Rc<T>`.
|
||||
///
|
||||
/// Weak references do not count when determining if the inner value should be
|
||||
@@ -903,6 +918,7 @@ mod tests {
|
||||
use std::result::Result::{Err, Ok};
|
||||
use std::mem::drop;
|
||||
use std::clone::Clone;
|
||||
use std::convert::From;
|
||||
|
||||
#[test]
|
||||
fn test_clone() {
|
||||
@@ -1105,6 +1121,20 @@ fn test_unsized() {
|
||||
let foo: Rc<[i32]> = Rc::new([1, 2, 3]);
|
||||
assert_eq!(foo, foo.clone());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_owned() {
|
||||
let foo = 123;
|
||||
let foo_rc = Rc::from(foo);
|
||||
assert!(123 == *foo_rc);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_box() {
|
||||
let foo_box = Box::new(123);
|
||||
let foo_rc = Rc::from(foo_box);
|
||||
assert!(123 == *foo_rc);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> borrow::Borrow<T> for Rc<T> {
|
||||
|
||||
Reference in New Issue
Block a user