Description
This has an accepted ACP, but I'm going to file a separate issue here since I was having issues implementing it and don't want to forget about it. (Like I have for the past year.)
Essentially, the primary issue is the way we go about specializing PartialOrd
for slices, which is not symmetric with the way we go about specializing PartialEq
for slices.
Right now, PartialEq<[U]> for [T]
relies on a corresponding SlicePartialEq<U> for [T]
, and there's no issue.
However, because Ord
doesn't have a generic parameter, SlicePartialOrd
also doesn't, and this means that we can't actually specialize PartialOrd<[U]> for [T]
. And I don't really know how to fix things without breaking the existing optimizations in the standard library, which is why I haven't touched this yet.
All the relevant code is in library/core/src/slice/cmp.rs
:
impl<T, U> PartialEq<[U]> for [T]
where
T: PartialEq<U>,
{
fn eq(&self, other: &[U]) -> bool {
SlicePartialEq::equal(self, other)
}
fn ne(&self, other: &[U]) -> bool {
SlicePartialEq::not_equal(self, other)
}
}
trait SlicePartialEq<B> {
fn equal(&self, other: &[B]) -> bool;
fn not_equal(&self, other: &[B]) -> bool {
!self.equal(other)
}
}
impl<T: PartialOrd> PartialOrd for [T] {
fn partial_cmp(&self, other: &[T]) -> Option<Ordering> {
SlicePartialOrd::partial_compare(self, other)
}
}
trait SlicePartialOrd: Sized {
fn partial_compare(left: &[Self], right: &[Self]) -> Option<Ordering>;
}
The main issue is this impl here:
trait AlwaysApplicableOrd: SliceOrd + Ord {}
impl<A: AlwaysApplicableOrd> SlicePartialOrd for A {
fn partial_compare(left: &[A], right: &[A]) -> Option<Ordering> {
Some(SliceOrd::compare(left, right))
}
}
Which essentially requires that SlicePartialOrd
not have a generic parameter, since SliceOrd
and Ord
don't.