@@ -249,7 +249,7 @@ use core::mem::{self, align_of, align_of_val, forget, size_of_val};
249249use core:: ops:: { CoerceUnsized , Deref , DispatchFromDyn , Receiver } ;
250250use core:: pin:: Pin ;
251251use core:: ptr:: { self , NonNull } ;
252- use core:: slice:: { self , from_raw_parts_mut} ;
252+ use core:: slice:: from_raw_parts_mut;
253253
254254use crate :: alloc:: { box_free, handle_alloc_error, AllocInit , AllocRef , Global , Layout } ;
255255use crate :: string:: String ;
@@ -1221,6 +1221,12 @@ impl<T: ?Sized + PartialEq> RcEqIdent<T> for Rc<T> {
12211221 }
12221222}
12231223
1224+ // Hack to allow specializing on `Eq` even though `Eq` has a method.
1225+ #[ rustc_unsafe_specialization_marker]
1226+ pub ( crate ) trait MarkerEq : PartialEq < Self > { }
1227+
1228+ impl < T : Eq > MarkerEq for T { }
1229+
12241230/// We're doing this specialization here, and not as a more general optimization on `&T`, because it
12251231/// would otherwise add a cost to all equality checks on refs. We assume that `Rc`s are used to
12261232/// store large values, that are slow to clone, but also heavy to check for equality, causing this
@@ -1229,7 +1235,7 @@ impl<T: ?Sized + PartialEq> RcEqIdent<T> for Rc<T> {
12291235///
12301236/// We can only do this when `T: Eq` as a `PartialEq` might be deliberately irreflexive.
12311237#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1232- impl < T : ?Sized + Eq > RcEqIdent < T > for Rc < T > {
1238+ impl < T : ?Sized + MarkerEq > RcEqIdent < T > for Rc < T > {
12331239 #[ inline]
12341240 fn eq ( & self , other : & Rc < T > ) -> bool {
12351241 Rc :: ptr_eq ( self , other) || * * self == * * other
@@ -1548,25 +1554,25 @@ impl<T> iter::FromIterator<T> for Rc<[T]> {
15481554 /// # assert_eq!(&*evens, &*(0..10).collect::<Vec<_>>());
15491555 /// ```
15501556 fn from_iter < I : iter:: IntoIterator < Item = T > > ( iter : I ) -> Self {
1551- RcFromIter :: from_iter ( iter. into_iter ( ) )
1557+ ToRcSlice :: to_rc_slice ( iter. into_iter ( ) )
15521558 }
15531559}
15541560
15551561/// Specialization trait used for collecting into `Rc<[T]>`.
1556- trait RcFromIter < T , I > {
1557- fn from_iter ( iter : I ) -> Self ;
1562+ trait ToRcSlice < T > : Iterator < Item = T > + Sized {
1563+ fn to_rc_slice ( self ) -> Rc < [ T ] > ;
15581564}
15591565
1560- impl < T , I : Iterator < Item = T > > RcFromIter < T , I > for Rc < [ T ] > {
1561- default fn from_iter ( iter : I ) -> Self {
1562- iter . collect :: < Vec < T > > ( ) . into ( )
1566+ impl < T , I : Iterator < Item = T > > ToRcSlice < T > for I {
1567+ default fn to_rc_slice ( self ) -> Rc < [ T ] > {
1568+ self . collect :: < Vec < T > > ( ) . into ( )
15631569 }
15641570}
15651571
1566- impl < T , I : iter:: TrustedLen < Item = T > > RcFromIter < T , I > for Rc < [ T ] > {
1567- default fn from_iter ( iter : I ) -> Self {
1572+ impl < T , I : iter:: TrustedLen < Item = T > > ToRcSlice < T > for I {
1573+ fn to_rc_slice ( self ) -> Rc < [ T ] > {
15681574 // This is the case for a `TrustedLen` iterator.
1569- let ( low, high) = iter . size_hint ( ) ;
1575+ let ( low, high) = self . size_hint ( ) ;
15701576 if let Some ( high) = high {
15711577 debug_assert_eq ! (
15721578 low,
@@ -1577,29 +1583,15 @@ impl<T, I: iter::TrustedLen<Item = T>> RcFromIter<T, I> for Rc<[T]> {
15771583
15781584 unsafe {
15791585 // SAFETY: We need to ensure that the iterator has an exact length and we have.
1580- Rc :: from_iter_exact ( iter , low)
1586+ Rc :: from_iter_exact ( self , low)
15811587 }
15821588 } else {
15831589 // Fall back to normal implementation.
1584- iter . collect :: < Vec < T > > ( ) . into ( )
1590+ self . collect :: < Vec < T > > ( ) . into ( )
15851591 }
15861592 }
15871593}
15881594
1589- impl < ' a , T : ' a + Clone > RcFromIter < & ' a T , slice:: Iter < ' a , T > > for Rc < [ T ] > {
1590- fn from_iter ( iter : slice:: Iter < ' a , T > ) -> Self {
1591- // Delegate to `impl<T: Clone> From<&[T]> for Rc<[T]>`.
1592- //
1593- // In the case that `T: Copy`, we get to use `ptr::copy_nonoverlapping`
1594- // which is even more performant.
1595- //
1596- // In the fall-back case we have `T: Clone`. This is still better
1597- // than the `TrustedLen` implementation as slices have a known length
1598- // and so we get to avoid calling `size_hint` and avoid the branching.
1599- iter. as_slice ( ) . into ( )
1600- }
1601- }
1602-
16031595/// `Weak` is a version of [`Rc`] that holds a non-owning reference to the
16041596/// managed allocation. The allocation is accessed by calling [`upgrade`] on the `Weak`
16051597/// pointer, which returns an [`Option`]`<`[`Rc`]`<T>>`.
0 commit comments