Skip to content

Commit fcc79f2

Browse files
committed
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.
1 parent a216e84 commit fcc79f2

File tree

3 files changed

+69
-0
lines changed

3 files changed

+69
-0
lines changed

src/liballoc/arc.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ use core::ptr::{self, Shared};
8484
use core::marker::Unsize;
8585
use core::hash::{Hash, Hasher};
8686
use core::{usize, isize};
87+
use core::convert::From;
8788
use heap::deallocate;
8889

8990
const MAX_REFCOUNT: usize = (isize::MAX) as usize;
@@ -894,8 +895,23 @@ impl<T: ?Sized + Hash> Hash for Arc<T> {
894895
}
895896
}
896897

898+
#[stable(feature = "rust1", since = "1.6.0")]
899+
impl<T> From<T> for Arc<T> {
900+
fn from(t: T) -> Self {
901+
Arc::new(t)
902+
}
903+
}
904+
905+
#[stable(feature = "rust1", since = "1.6.0")]
906+
impl<T> From<Box<T>> for Arc<T> {
907+
fn from(t: Box<T>) -> Self {
908+
Arc::new(*t)
909+
}
910+
}
911+
897912
#[cfg(test)]
898913
mod tests {
914+
use std::boxed::Box;
899915
use std::clone::Clone;
900916
use std::sync::mpsc::channel;
901917
use std::mem::drop;
@@ -908,6 +924,7 @@ mod tests {
908924
use std::vec::Vec;
909925
use super::{Arc, Weak};
910926
use std::sync::Mutex;
927+
use std::convert::From;
911928

912929
struct Canary(*mut atomic::AtomicUsize);
913930

@@ -1137,6 +1154,20 @@ mod tests {
11371154
drop(x);
11381155
assert!(y.upgrade().is_none());
11391156
}
1157+
1158+
#[test]
1159+
fn test_from_owned() {
1160+
let foo = 123;
1161+
let foo_arc = Arc::from(foo);
1162+
assert!(123 == *foo_arc);
1163+
}
1164+
1165+
#[test]
1166+
fn test_from_box() {
1167+
let foo_box = Box::new(123);
1168+
let foo_arc = Arc::from(foo_box);
1169+
assert!(123 == *foo_arc);
1170+
}
11401171
}
11411172

11421173
impl<T: ?Sized> borrow::Borrow<T> for Arc<T> {

src/liballoc/boxed.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ use core::ops::{CoerceUnsized, Deref, DerefMut};
6767
use core::ops::{Placer, Boxed, Place, InPlace, BoxPlace};
6868
use core::ptr::{self, Unique};
6969
use core::raw::TraitObject;
70+
use core::convert::From;
7071

7172
/// A value that represents the heap. This is the default place that the `box`
7273
/// keyword allocates into when no place is supplied.
@@ -375,6 +376,13 @@ impl<T: ?Sized + Hash> Hash for Box<T> {
375376
}
376377
}
377378

379+
#[stable(feature = "rust1", since = "1.6.0")]
380+
impl<T> From<T> for Box<T> {
381+
fn from(t: T) -> Self {
382+
Box::new(t)
383+
}
384+
}
385+
378386
impl Box<Any> {
379387
#[inline]
380388
#[stable(feature = "rust1", since = "1.0.0")]

src/liballoc/rc.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ use core::marker::{self, Unsize};
165165
use core::mem::{self, align_of_val, size_of_val, forget};
166166
use core::ops::{CoerceUnsized, Deref};
167167
use core::ptr::{self, Shared};
168+
use core::convert::From;
168169

169170
use heap::deallocate;
170171

@@ -698,6 +699,20 @@ impl<T> fmt::Pointer for Rc<T> {
698699
}
699700
}
700701

702+
#[stable(feature = "rust1", since = "1.6.0")]
703+
impl<T> From<T> for Rc<T> {
704+
fn from(t: T) -> Self {
705+
Rc::new(t)
706+
}
707+
}
708+
709+
#[stable(feature = "rust1", since = "1.6.0")]
710+
impl<T> From<Box<T>> for Rc<T> {
711+
fn from(t: Box<T>) -> Self {
712+
Rc::new(*t)
713+
}
714+
}
715+
701716
/// A weak version of `Rc<T>`.
702717
///
703718
/// Weak references do not count when determining if the inner value should be
@@ -903,6 +918,7 @@ mod tests {
903918
use std::result::Result::{Err, Ok};
904919
use std::mem::drop;
905920
use std::clone::Clone;
921+
use std::convert::From;
906922

907923
#[test]
908924
fn test_clone() {
@@ -1105,6 +1121,20 @@ mod tests {
11051121
let foo: Rc<[i32]> = Rc::new([1, 2, 3]);
11061122
assert_eq!(foo, foo.clone());
11071123
}
1124+
1125+
#[test]
1126+
fn test_from_owned() {
1127+
let foo = 123;
1128+
let foo_rc = Rc::from(foo);
1129+
assert!(123 == *foo_rc);
1130+
}
1131+
1132+
#[test]
1133+
fn test_from_box() {
1134+
let foo_box = Box::new(123);
1135+
let foo_rc = Rc::from(foo_box);
1136+
assert!(123 == *foo_rc);
1137+
}
11081138
}
11091139

11101140
impl<T: ?Sized> borrow::Borrow<T> for Rc<T> {

0 commit comments

Comments
 (0)