@@ -537,9 +537,7 @@ impl<T> WrapperTypeDecode for Box<T> {
537537 } else {
538538
539539 // SAFETY: Layout has a non-zero size so calling this is safe.
540- let ptr: * mut u8 = unsafe {
541- crate :: alloc:: alloc:: alloc ( layout)
542- } ;
540+ let ptr = unsafe { crate :: alloc:: alloc:: alloc ( layout) } ;
543541
544542 if ptr. is_null ( ) {
545543 crate :: alloc:: alloc:: handle_alloc_error ( layout) ;
@@ -554,25 +552,43 @@ impl<T> WrapperTypeDecode for Box<T> {
554552 //
555553 // Constructing a `Box` from `NonNull::dangling` is also always safe as long
556554 // as the underlying type is zero-sized.
557- let mut boxed: Box < MaybeUninit < T > > = unsafe { Box :: from_raw ( ptr) } ;
558-
555+ let mut boxed = unsafe { Box :: from_raw ( ptr) } ;
559556 T :: decode_into ( input, & mut boxed) ?;
560557
561558 // Decoding succeeded, so let's get rid of `MaybeUninit`.
562559 //
563560 // TODO: Use `Box::assume_init` once that's stable.
564- let ptr: * mut MaybeUninit < T > = Box :: into_raw ( boxed) ;
561+ let ptr = Box :: into_raw ( boxed) ;
565562 let ptr: * mut T = ptr. cast ( ) ;
566563
567564 // SAFETY: `MaybeUninit` doesn't affect the memory layout, so casting the pointer back
568565 // into a `Box` is safe.
569- let boxed: Box < T > = unsafe { Box :: from_raw ( ptr) } ;
566+ let boxed = unsafe { Box :: from_raw ( ptr) } ;
570567
571568 input. ascend_ref ( ) ;
572569 Ok ( boxed)
573570 }
574571}
575572
573+ impl < T : Decode > Decode for Box < [ T ] > {
574+ fn decode < I : Input > ( input : & mut I ) -> Result < Self , Error > {
575+ Ok ( Vec :: decode ( input) ?. into_boxed_slice ( ) )
576+ }
577+ }
578+
579+ impl Decode for Box < str > {
580+ fn decode < I : Input > ( input : & mut I ) -> Result < Self , Error > {
581+ // Guaranteed to create a Vec with capacity == len
582+ let vec = Vec :: from ( Box :: < [ u8 ] > :: decode ( input) ?) ;
583+ // Guaranteed not to reallocate the vec, only transmute to String
584+ let str = String :: from_utf8 ( vec) . map_err ( |_| "Invalid utf8 sequence" ) ?;
585+
586+ // At this point we have String with capacity == len,
587+ // therefore String::into_boxed_str will not reallocate
588+ Ok ( str. into_boxed_str ( ) )
589+ }
590+ }
591+
576592impl < T > WrapperTypeDecode for Rc < T > {
577593 type Wrapped = T ;
578594
@@ -1612,6 +1628,28 @@ mod tests {
16121628 assert_eq ! ( ( x, y) , Decode :: decode( & mut & encoded[ ..] ) . unwrap( ) ) ;
16131629 }
16141630
1631+ #[ test]
1632+ fn boxed_str_works ( ) {
1633+ let s = "Hello world" . to_owned ( ) ;
1634+ let b = s. clone ( ) . into_boxed_str ( ) ;
1635+
1636+ let encoded = b. encode ( ) ;
1637+ assert_eq ! ( s. encode( ) , encoded) ;
1638+
1639+ assert_eq ! ( * b, * Box :: <str >:: decode( & mut & encoded[ ..] ) . unwrap( ) ) ;
1640+ }
1641+
1642+ #[ test]
1643+ fn boxed_slice_works ( ) {
1644+ let v = vec ! [ 1u32 , 2 , 3 , 4 , 5 , 6 ] ;
1645+ let b = v. clone ( ) . into_boxed_slice ( ) ;
1646+
1647+ let encoded = b. encode ( ) ;
1648+ assert_eq ! ( v. encode( ) , encoded) ;
1649+
1650+ assert_eq ! ( * b, * Box :: <[ u32 ] >:: decode( & mut & b. encode( ) [ ..] ) . unwrap( ) ) ;
1651+ }
1652+
16151653 #[ test]
16161654 fn cow_works ( ) {
16171655 let x = & [ 1u32 , 2 , 3 , 4 , 5 , 6 ] [ ..] ;
0 commit comments