@@ -239,7 +239,7 @@ use core::ops::CoerceUnsized;
239239use core:: ptr:: { self , Shared } ;
240240use core:: convert:: From ;
241241
242- use heap:: deallocate;
242+ use heap:: { allocate , deallocate, box_free } ;
243243use raw_vec:: RawVec ;
244244
245245struct RcBox < T : ?Sized > {
@@ -248,7 +248,6 @@ struct RcBox<T: ?Sized> {
248248 value : T ,
249249}
250250
251-
252251/// A single-threaded reference-counting pointer.
253252///
254253/// See the [module-level documentation](./index.html) for more details.
@@ -438,6 +437,38 @@ impl Rc<str> {
438437 }
439438}
440439
440+ impl < T > Rc < [ T ] > {
441+ /// Constructs a new `Rc<[T]>` from a `Box<[T]>`.
442+ #[ doc( hidden) ]
443+ #[ unstable( feature = "rustc_private" ,
444+ reason = "for internal use in rustc" ,
445+ issue = "0" ) ]
446+ pub fn __from_array ( value : Box < [ T ] > ) -> Rc < [ T ] > {
447+ unsafe {
448+ let ptr: * mut RcBox < [ T ] > =
449+ mem:: transmute ( [ mem:: align_of :: < RcBox < [ T ; 1 ] > > ( ) , value. len ( ) ] ) ;
450+ // FIXME(custom-DST): creating this invalid &[T] is dubiously defined,
451+ // we should have a better way of getting the size/align
452+ // of a DST from its unsized part.
453+ let ptr = allocate ( size_of_val ( & * ptr) , align_of_val ( & * ptr) ) ;
454+ let ptr: * mut RcBox < [ T ] > = mem:: transmute ( [ ptr as usize , value. len ( ) ] ) ;
455+
456+ // Initialize the new RcBox.
457+ ptr:: write ( & mut ( * ptr) . strong , Cell :: new ( 1 ) ) ;
458+ ptr:: write ( & mut ( * ptr) . weak , Cell :: new ( 1 ) ) ;
459+ ptr:: copy_nonoverlapping (
460+ value. as_ptr ( ) ,
461+ & mut ( * ptr) . value as * mut [ T ] as * mut T ,
462+ value. len ( ) ) ;
463+
464+ // Free the original allocation without freeing its (moved) contents.
465+ box_free ( Box :: into_raw ( value) ) ;
466+
467+ Rc { ptr : Shared :: new ( ptr as * const _ ) }
468+ }
469+ }
470+ }
471+
441472impl < T : ?Sized > Rc < T > {
442473 /// Creates a new [`Weak`][weak] pointer to this value.
443474 ///
0 commit comments