@@ -238,12 +238,13 @@ use core::cmp::Ordering;
238
238
use core:: fmt;
239
239
use core:: hash:: { Hash , Hasher } ;
240
240
use core:: intrinsics:: abort;
241
+ use core:: iter;
241
242
use core:: marker:: { self , Unpin , Unsize , PhantomData } ;
242
243
use core:: mem:: { self , align_of, align_of_val, forget, size_of_val} ;
243
244
use core:: ops:: { Deref , Receiver , CoerceUnsized , DispatchFromDyn } ;
244
245
use core:: pin:: Pin ;
245
246
use core:: ptr:: { self , NonNull } ;
246
- use core:: slice:: from_raw_parts_mut;
247
+ use core:: slice:: { self , from_raw_parts_mut} ;
247
248
use core:: convert:: From ;
248
249
use core:: usize;
249
250
@@ -698,21 +699,29 @@ impl Rc<dyn Any> {
698
699
}
699
700
700
701
impl < T : ?Sized > Rc < T > {
701
- // Allocates an `RcBox<T>` with sufficient space for an unsized value
702
- unsafe fn allocate_for_ptr ( ptr : * const T ) -> * mut RcBox < T > {
703
- // Calculate layout using the given value.
702
+ // Allocates an `RcBox<T>` with sufficient space for
703
+ // an unsized value where the value has the layout provided.
704
+ //
705
+ // The function `mem_to_rcbox` is called with the data pointer
706
+ // and must return back a (potentially fat)-pointer for the `RcBox<T>`.
707
+ unsafe fn allocate_for_unsized (
708
+ value_layout : Layout ,
709
+ mem_to_rcbox : impl FnOnce ( * mut u8 ) -> * mut RcBox < T >
710
+ ) -> * mut RcBox < T > {
711
+ // Calculate layout using the given value layout.
704
712
// Previously, layout was calculated on the expression
705
713
// `&*(ptr as *const RcBox<T>)`, but this created a misaligned
706
714
// reference (see #54908).
707
715
let layout = Layout :: new :: < RcBox < ( ) > > ( )
708
- . extend ( Layout :: for_value ( & * ptr ) ) . unwrap ( ) . 0
716
+ . extend ( value_layout ) . unwrap ( ) . 0
709
717
. pad_to_align ( ) . unwrap ( ) ;
710
718
719
+ // Allocate for the layout.
711
720
let mem = Global . alloc ( layout)
712
721
. unwrap_or_else ( |_| handle_alloc_error ( layout) ) ;
713
722
714
723
// Initialize the RcBox
715
- let inner = set_data_ptr ( ptr as * mut T , mem. as_ptr ( ) as * mut u8 ) as * mut RcBox < T > ;
724
+ let inner = mem_to_rcbox ( mem. as_ptr ( ) ) ;
716
725
debug_assert_eq ! ( Layout :: for_value( & * inner) , layout) ;
717
726
718
727
ptr:: write ( & mut ( * inner) . strong , Cell :: new ( 1 ) ) ;
@@ -721,6 +730,15 @@ impl<T: ?Sized> Rc<T> {
721
730
inner
722
731
}
723
732
733
+ // Allocates an `RcBox<T>` with sufficient space for an unsized value
734
+ unsafe fn allocate_for_ptr ( ptr : * const T ) -> * mut RcBox < T > {
735
+ // Allocate for the `RcBox<T>` using the given value.
736
+ Self :: allocate_for_unsized (
737
+ Layout :: for_value ( & * ptr) ,
738
+ |mem| set_data_ptr ( ptr as * mut T , mem) as * mut RcBox < T > ,
739
+ )
740
+ }
741
+
724
742
fn from_box ( v : Box < T > ) -> Rc < T > {
725
743
unsafe {
726
744
let box_unique = Box :: into_unique ( v) ;
@@ -743,6 +761,32 @@ impl<T: ?Sized> Rc<T> {
743
761
}
744
762
}
745
763
764
+ impl < T > Rc < [ T ] > {
765
+ // Allocates an `RcBox<[T]>` with the given length.
766
+ unsafe fn allocate_for_slice ( len : usize ) -> * mut RcBox < [ T ] > {
767
+ // FIXME(#60667): Deduplicate.
768
+ fn slice_from_raw_parts_mut < T > ( data : * mut T , len : usize ) -> * mut [ T ] {
769
+ #[ repr( C ) ]
770
+ union Repr < T > {
771
+ rust_mut : * mut [ T ] ,
772
+ raw : FatPtr < T > ,
773
+ }
774
+
775
+ #[ repr( C ) ]
776
+ struct FatPtr < T > {
777
+ data : * const T ,
778
+ len : usize ,
779
+ }
780
+ unsafe { Repr { raw : FatPtr { data, len } } . rust_mut }
781
+ }
782
+
783
+ Self :: allocate_for_unsized (
784
+ Layout :: array :: < T > ( len) . unwrap ( ) ,
785
+ |mem| slice_from_raw_parts_mut ( mem as * mut T , len) as * mut RcBox < [ T ] > ,
786
+ )
787
+ }
788
+ }
789
+
746
790
// Sets the data pointer of a `?Sized` raw pointer.
747
791
//
748
792
// For a slice/trait object, this sets the `data` field and leaves the rest
@@ -757,8 +801,7 @@ impl<T> Rc<[T]> {
757
801
//
758
802
// Unsafe because the caller must either take ownership or bind `T: Copy`
759
803
unsafe fn copy_from_slice ( v : & [ T ] ) -> Rc < [ T ] > {
760
- let v_ptr = v as * const [ T ] ;
761
- let ptr = Self :: allocate_for_ptr ( v_ptr) ;
804
+ let ptr = Self :: allocate_for_slice ( v. len ( ) ) ;
762
805
763
806
ptr:: copy_nonoverlapping (
764
807
v. as_ptr ( ) ,
@@ -767,15 +810,11 @@ impl<T> Rc<[T]> {
767
810
768
811
Self :: from_ptr ( ptr)
769
812
}
770
- }
771
813
772
- trait RcFromSlice < T > {
773
- fn from_slice ( slice : & [ T ] ) -> Self ;
774
- }
775
-
776
- impl < T : Clone > RcFromSlice < T > for Rc < [ T ] > {
777
- #[ inline]
778
- default fn from_slice ( v : & [ T ] ) -> Self {
814
+ /// Constructs an `Rc<[T]>` from an iterator known to be of a certain size.
815
+ ///
816
+ /// Behavior is undefined should the size be wrong.
817
+ unsafe fn from_iter_exact ( iter : impl iter:: Iterator < Item = T > , len : usize ) -> Rc < [ T ] > {
779
818
// Panic guard while cloning T elements.
780
819
// In the event of a panic, elements that have been written
781
820
// into the new RcBox will be dropped, then the memory freed.
@@ -797,32 +836,42 @@ impl<T: Clone> RcFromSlice<T> for Rc<[T]> {
797
836
}
798
837
}
799
838
800
- unsafe {
801
- let v_ptr = v as * const [ T ] ;
802
- let ptr = Self :: allocate_for_ptr ( v_ptr) ;
839
+ let ptr = Self :: allocate_for_slice ( len) ;
803
840
804
- let mem = ptr as * mut _ as * mut u8 ;
805
- let layout = Layout :: for_value ( & * ptr) ;
841
+ let mem = ptr as * mut _ as * mut u8 ;
842
+ let layout = Layout :: for_value ( & * ptr) ;
806
843
807
- // Pointer to first element
808
- let elems = & mut ( * ptr) . value as * mut [ T ] as * mut T ;
844
+ // Pointer to first element
845
+ let elems = & mut ( * ptr) . value as * mut [ T ] as * mut T ;
809
846
810
- let mut guard = Guard {
811
- mem : NonNull :: new_unchecked ( mem) ,
812
- elems : elems,
813
- layout : layout,
814
- n_elems : 0 ,
815
- } ;
847
+ let mut guard = Guard {
848
+ mem : NonNull :: new_unchecked ( mem) ,
849
+ elems,
850
+ layout,
851
+ n_elems : 0 ,
852
+ } ;
816
853
817
- for ( i, item) in v . iter ( ) . enumerate ( ) {
818
- ptr:: write ( elems. add ( i) , item. clone ( ) ) ;
819
- guard. n_elems += 1 ;
820
- }
854
+ for ( i, item) in iter. enumerate ( ) {
855
+ ptr:: write ( elems. add ( i) , item) ;
856
+ guard. n_elems += 1 ;
857
+ }
821
858
822
- // All clear. Forget the guard so it doesn't free the new RcBox.
823
- forget ( guard) ;
859
+ // All clear. Forget the guard so it doesn't free the new RcBox.
860
+ forget ( guard) ;
824
861
825
- Self :: from_ptr ( ptr)
862
+ Self :: from_ptr ( ptr)
863
+ }
864
+ }
865
+
866
+ trait RcFromSlice < T > {
867
+ fn from_slice ( slice : & [ T ] ) -> Self ;
868
+ }
869
+
870
+ impl < T : Clone > RcFromSlice < T > for Rc < [ T ] > {
871
+ #[ inline]
872
+ default fn from_slice ( v : & [ T ] ) -> Self {
873
+ unsafe {
874
+ Self :: from_iter_exact ( v. iter ( ) . cloned ( ) , v. len ( ) )
826
875
}
827
876
}
828
877
}
@@ -1221,9 +1270,88 @@ impl<T> From<Vec<T>> for Rc<[T]> {
1221
1270
}
1222
1271
1223
1272
#[ stable( feature = "shared_from_iter" , since = "1.37.0" ) ]
1224
- impl < T > core:: iter:: FromIterator < T > for Rc < [ T ] > {
1225
- fn from_iter < I : IntoIterator < Item = T > > ( iter : I ) -> Self {
1226
- iter. into_iter ( ) . collect :: < Vec < T > > ( ) . into ( )
1273
+ impl < T > iter:: FromIterator < T > for Rc < [ T ] > {
1274
+ /// Takes each element in the `Iterator` and collects it into an `Rc<[T]>`.
1275
+ ///
1276
+ /// # Performance characteristics
1277
+ ///
1278
+ /// ## The general case
1279
+ ///
1280
+ /// In the general case, collecting into `Rc<[T]>` is done by first
1281
+ /// collecting into a `Vec<T>`. That is, when writing the following:
1282
+ ///
1283
+ /// ```rust
1284
+ /// # use std::rc::Rc;
1285
+ /// let evens: Rc<[u8]> = (0..10).filter(|&x| x % 2 == 0).collect();
1286
+ /// # assert_eq!(&*evens, &[0, 2, 4, 6, 8]);
1287
+ /// ```
1288
+ ///
1289
+ /// this behaves as if we wrote:
1290
+ ///
1291
+ /// ```rust
1292
+ /// # use std::rc::Rc;
1293
+ /// let evens: Rc<[u8]> = (0..10).filter(|&x| x % 2 == 0)
1294
+ /// .collect::<Vec<_>>() // The first set of allocations happens here.
1295
+ /// .into(); // A second allocation for `Rc<[T]>` happens here.
1296
+ /// # assert_eq!(&*evens, &[0, 2, 4, 6, 8]);
1297
+ /// ```
1298
+ ///
1299
+ /// This will allocate as many times as needed for constructing the `Vec<T>`
1300
+ /// and then it will allocate once for turning the `Vec<T>` into the `Rc<[T]>`.
1301
+ ///
1302
+ /// ## Iterators of known length
1303
+ ///
1304
+ /// When your `Iterator` implements `TrustedLen` and is of an exact size,
1305
+ /// a single allocation will be made for the `Rc<[T]>`. For example:
1306
+ ///
1307
+ /// ```rust
1308
+ /// # use std::rc::Rc;
1309
+ /// let evens: Rc<[u8]> = (0..10).collect(); // Just a single allocation happens here.
1310
+ /// # assert_eq!(&*evens, &*(0..10).collect::<Vec<_>>());
1311
+ /// ```
1312
+ fn from_iter < I : iter:: IntoIterator < Item = T > > ( iter : I ) -> Self {
1313
+ RcFromIter :: from_iter ( iter. into_iter ( ) )
1314
+ }
1315
+ }
1316
+
1317
+ /// Specialization trait used for collecting into `Rc<[T]>`.
1318
+ trait RcFromIter < T , I > {
1319
+ fn from_iter ( iter : I ) -> Self ;
1320
+ }
1321
+
1322
+ impl < T , I : Iterator < Item = T > > RcFromIter < T , I > for Rc < [ T ] > {
1323
+ default fn from_iter ( iter : I ) -> Self {
1324
+ iter. collect :: < Vec < T > > ( ) . into ( )
1325
+ }
1326
+ }
1327
+
1328
+ impl < T , I : iter:: TrustedLen < Item = T > > RcFromIter < T , I > for Rc < [ T ] > {
1329
+ default fn from_iter ( iter : I ) -> Self {
1330
+ // This is the case for a `TrustedLen` iterator.
1331
+ let ( low, high) = iter. size_hint ( ) ;
1332
+ if let Some ( high) = high {
1333
+ debug_assert_eq ! (
1334
+ low, high,
1335
+ "TrustedLen iterator's size hint is not exact: {:?}" ,
1336
+ ( low, high)
1337
+ ) ;
1338
+
1339
+ unsafe {
1340
+ // SAFETY: We need to ensure that the iterator has an exact length and we have.
1341
+ Rc :: from_iter_exact ( iter, low)
1342
+ }
1343
+ } else {
1344
+ // Fall back to normal implementation.
1345
+ iter. collect :: < Vec < T > > ( ) . into ( )
1346
+ }
1347
+ }
1348
+ }
1349
+
1350
+ impl < ' a , T : ' a + Clone > RcFromIter < & ' a T , slice:: Iter < ' a , T > > for Rc < [ T ] > {
1351
+ fn from_iter ( iter : slice:: Iter < ' a , T > ) -> Self {
1352
+ // Delegate to `impl<T: Clone> From<&[T]> for Rc<[T]>`
1353
+ // which will use `ptr::copy_nonoverlapping`.
1354
+ iter. as_slice ( ) . into ( )
1227
1355
}
1228
1356
}
1229
1357
0 commit comments