@@ -537,9 +537,7 @@ impl<T> WrapperTypeDecode for Box<T> {
537
537
} else {
538
538
539
539
// 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) } ;
543
541
544
542
if ptr. is_null ( ) {
545
543
crate :: alloc:: alloc:: handle_alloc_error ( layout) ;
@@ -554,25 +552,42 @@ impl<T> WrapperTypeDecode for Box<T> {
554
552
//
555
553
// Constructing a `Box` from `NonNull::dangling` is also always safe as long
556
554
// 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) } ;
559
556
T :: decode_into ( input, & mut boxed) ?;
560
557
561
558
// Decoding succeeded, so let's get rid of `MaybeUninit`.
562
559
//
563
560
// TODO: Use `Box::assume_init` once that's stable.
564
- let ptr: * mut MaybeUninit < T > = Box :: into_raw ( boxed) ;
565
- let ptr: * mut T = ptr. cast ( ) ;
561
+ let ptr: * mut T = Box :: into_raw ( boxed) . cast ( ) ;
566
562
567
563
// SAFETY: `MaybeUninit` doesn't affect the memory layout, so casting the pointer back
568
564
// into a `Box` is safe.
569
- let boxed: Box < T > = unsafe { Box :: from_raw ( ptr) } ;
565
+ let boxed = unsafe { Box :: from_raw ( ptr) } ;
570
566
571
567
input. ascend_ref ( ) ;
572
568
Ok ( boxed)
573
569
}
574
570
}
575
571
572
+ impl < T : Decode > Decode for Box < [ T ] > {
573
+ fn decode < I : Input > ( input : & mut I ) -> Result < Self , Error > {
574
+ Ok ( Vec :: decode ( input) ?. into_boxed_slice ( ) )
575
+ }
576
+ }
577
+
578
+ impl Decode for Box < str > {
579
+ fn decode < I : Input > ( input : & mut I ) -> Result < Self , Error > {
580
+ // Guaranteed to create a Vec with capacity == len
581
+ let vec = Vec :: from ( Box :: < [ u8 ] > :: decode ( input) ?) ;
582
+ // Guaranteed not to reallocate the vec, only transmute to String
583
+ let str = String :: from_utf8 ( vec) . map_err ( |_| "Invalid utf8 sequence" ) ?;
584
+
585
+ // At this point we have String with capacity == len,
586
+ // therefore String::into_boxed_str will not reallocate
587
+ Ok ( str. into_boxed_str ( ) )
588
+ }
589
+ }
590
+
576
591
impl < T > WrapperTypeDecode for Rc < T > {
577
592
type Wrapped = T ;
578
593
@@ -1612,6 +1627,28 @@ mod tests {
1612
1627
assert_eq ! ( ( x, y) , Decode :: decode( & mut & encoded[ ..] ) . unwrap( ) ) ;
1613
1628
}
1614
1629
1630
+ #[ test]
1631
+ fn boxed_str_works ( ) {
1632
+ let s = "Hello world" . to_owned ( ) ;
1633
+ let b = s. clone ( ) . into_boxed_str ( ) ;
1634
+
1635
+ let encoded = b. encode ( ) ;
1636
+ assert_eq ! ( s. encode( ) , encoded) ;
1637
+
1638
+ assert_eq ! ( * b, * Box :: <str >:: decode( & mut & encoded[ ..] ) . unwrap( ) ) ;
1639
+ }
1640
+
1641
+ #[ test]
1642
+ fn boxed_slice_works ( ) {
1643
+ let v = vec ! [ 1u32 , 2 , 3 , 4 , 5 , 6 ] ;
1644
+ let b = v. clone ( ) . into_boxed_slice ( ) ;
1645
+
1646
+ let encoded = b. encode ( ) ;
1647
+ assert_eq ! ( v. encode( ) , encoded) ;
1648
+
1649
+ assert_eq ! ( * b, * Box :: <[ u32 ] >:: decode( & mut & b. encode( ) [ ..] ) . unwrap( ) ) ;
1650
+ }
1651
+
1615
1652
#[ test]
1616
1653
fn cow_works ( ) {
1617
1654
let x = & [ 1u32 , 2 , 3 , 4 , 5 , 6 ] [ ..] ;
0 commit comments