@@ -249,7 +249,7 @@ use core::mem::{self, align_of, align_of_val, forget, size_of_val};
249
249
use core:: ops:: { CoerceUnsized , Deref , DispatchFromDyn , Receiver } ;
250
250
use core:: pin:: Pin ;
251
251
use core:: ptr:: { self , NonNull } ;
252
- use core:: slice:: { self , from_raw_parts_mut} ;
252
+ use core:: slice:: from_raw_parts_mut;
253
253
254
254
use crate :: alloc:: { box_free, handle_alloc_error, AllocInit , AllocRef , Global , Layout } ;
255
255
use crate :: string:: String ;
@@ -1221,6 +1221,12 @@ impl<T: ?Sized + PartialEq> RcEqIdent<T> for Rc<T> {
1221
1221
}
1222
1222
}
1223
1223
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
+
1224
1230
/// We're doing this specialization here, and not as a more general optimization on `&T`, because it
1225
1231
/// would otherwise add a cost to all equality checks on refs. We assume that `Rc`s are used to
1226
1232
/// 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> {
1229
1235
///
1230
1236
/// We can only do this when `T: Eq` as a `PartialEq` might be deliberately irreflexive.
1231
1237
#[ 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 > {
1233
1239
#[ inline]
1234
1240
fn eq ( & self , other : & Rc < T > ) -> bool {
1235
1241
Rc :: ptr_eq ( self , other) || * * self == * * other
@@ -1548,25 +1554,25 @@ impl<T> iter::FromIterator<T> for Rc<[T]> {
1548
1554
/// # assert_eq!(&*evens, &*(0..10).collect::<Vec<_>>());
1549
1555
/// ```
1550
1556
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 ( ) )
1552
1558
}
1553
1559
}
1554
1560
1555
1561
/// 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 ] > ;
1558
1564
}
1559
1565
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 ( )
1563
1569
}
1564
1570
}
1565
1571
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 ] > {
1568
1574
// This is the case for a `TrustedLen` iterator.
1569
- let ( low, high) = iter . size_hint ( ) ;
1575
+ let ( low, high) = self . size_hint ( ) ;
1570
1576
if let Some ( high) = high {
1571
1577
debug_assert_eq ! (
1572
1578
low,
@@ -1577,29 +1583,15 @@ impl<T, I: iter::TrustedLen<Item = T>> RcFromIter<T, I> for Rc<[T]> {
1577
1583
1578
1584
unsafe {
1579
1585
// 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)
1581
1587
}
1582
1588
} else {
1583
1589
// Fall back to normal implementation.
1584
- iter . collect :: < Vec < T > > ( ) . into ( )
1590
+ self . collect :: < Vec < T > > ( ) . into ( )
1585
1591
}
1586
1592
}
1587
1593
}
1588
1594
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
-
1603
1595
/// `Weak` is a version of [`Rc`] that holds a non-owning reference to the
1604
1596
/// managed allocation. The allocation is accessed by calling [`upgrade`] on the `Weak`
1605
1597
/// pointer, which returns an [`Option`]`<`[`Rc`]`<T>>`.
0 commit comments