@@ -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,43 @@ 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) ;
561
+ let ptr = Box :: into_raw ( boxed) ;
565
562
let ptr: * mut T = ptr. cast ( ) ;
566
563
567
564
// SAFETY: `MaybeUninit` doesn't affect the memory layout, so casting the pointer back
568
565
// into a `Box` is safe.
569
- let boxed: Box < T > = unsafe { Box :: from_raw ( ptr) } ;
566
+ let boxed = unsafe { Box :: from_raw ( ptr) } ;
570
567
571
568
input. ascend_ref ( ) ;
572
569
Ok ( boxed)
573
570
}
574
571
}
575
572
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
+
576
592
impl < T > WrapperTypeDecode for Rc < T > {
577
593
type Wrapped = T ;
578
594
@@ -1612,6 +1628,28 @@ mod tests {
1612
1628
assert_eq ! ( ( x, y) , Decode :: decode( & mut & encoded[ ..] ) . unwrap( ) ) ;
1613
1629
}
1614
1630
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
+
1615
1653
#[ test]
1616
1654
fn cow_works ( ) {
1617
1655
let x = & [ 1u32 , 2 , 3 , 4 , 5 , 6 ] [ ..] ;
0 commit comments