Skip to content

Commit 99093b7

Browse files
committed
Auto merge of #29580 - alexbool:smart-pointer-conversion, r=alexcrichton
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: ```rust 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. Also to mention, I made those impls stable, and I don't know whether they should be actually stable from the beginning. Please tell me if this should be feature-gated.
2 parents 3042fed + 67c07d4 commit 99093b7

File tree

3 files changed

+40
-0
lines changed

3 files changed

+40
-0
lines changed

src/liballoc/arc.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ use core::ptr::{self, Shared};
8787
use core::marker::Unsize;
8888
use core::hash::{Hash, Hasher};
8989
use core::{usize, isize};
90+
use core::convert::From;
9091
use heap::deallocate;
9192

9293
const MAX_REFCOUNT: usize = (isize::MAX) as usize;
@@ -896,6 +897,13 @@ impl<T: ?Sized + Hash> Hash for Arc<T> {
896897
}
897898
}
898899

900+
#[stable(feature = "from_for_ptrs", since = "1.6.0")]
901+
impl<T> From<T> for Arc<T> {
902+
fn from(t: T) -> Self {
903+
Arc::new(t)
904+
}
905+
}
906+
899907
#[cfg(test)]
900908
mod tests {
901909
use std::clone::Clone;
@@ -910,6 +918,7 @@ mod tests {
910918
use std::vec::Vec;
911919
use super::{Arc, Weak};
912920
use std::sync::Mutex;
921+
use std::convert::From;
913922

914923
struct Canary(*mut atomic::AtomicUsize);
915924

@@ -1139,6 +1148,13 @@ mod tests {
11391148
drop(x);
11401149
assert!(y.upgrade().is_none());
11411150
}
1151+
1152+
#[test]
1153+
fn test_from_owned() {
1154+
let foo = 123;
1155+
let foo_arc = Arc::from(foo);
1156+
assert!(123 == *foo_arc);
1157+
}
11421158
}
11431159

11441160
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.
@@ -373,6 +374,13 @@ impl<T: ?Sized + Hash> Hash for Box<T> {
373374
}
374375
}
375376

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

src/liballoc/rc.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ use core::ops::Deref;
169169
#[cfg(not(stage0))]
170170
use core::ops::CoerceUnsized;
171171
use core::ptr::{self, Shared};
172+
use core::convert::From;
172173

173174
use heap::deallocate;
174175

@@ -701,6 +702,13 @@ impl<T> fmt::Pointer for Rc<T> {
701702
}
702703
}
703704

705+
#[stable(feature = "from_for_ptrs", since = "1.6.0")]
706+
impl<T> From<T> for Rc<T> {
707+
fn from(t: T) -> Self {
708+
Rc::new(t)
709+
}
710+
}
711+
704712
/// A weak version of `Rc<T>`.
705713
///
706714
/// Weak references do not count when determining if the inner value should be
@@ -906,6 +914,7 @@ mod tests {
906914
use std::result::Result::{Err, Ok};
907915
use std::mem::drop;
908916
use std::clone::Clone;
917+
use std::convert::From;
909918

910919
#[test]
911920
fn test_clone() {
@@ -1108,6 +1117,13 @@ mod tests {
11081117
let foo: Rc<[i32]> = Rc::new([1, 2, 3]);
11091118
assert_eq!(foo, foo.clone());
11101119
}
1120+
1121+
#[test]
1122+
fn test_from_owned() {
1123+
let foo = 123;
1124+
let foo_rc = Rc::from(foo);
1125+
assert!(123 == *foo_rc);
1126+
}
11111127
}
11121128

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

0 commit comments

Comments
 (0)