When creating a structure that stores DST (for example, a raw slice), I can use the usual environment #[derive(Eq, PartialEq, Ord, PartialOrd)] to get implementations of this attribute by my type:
However, if I implement them manually, then the compiler will complain that my type does not implement Sized :
struct A([u8]); impl AsRef<[u8]> for A { fn as_ref(&self) -> &[u8] { &self.0 } } impl<S: AsRef<[u8]>> PartialEq<S> for A { fn eq(&self, other: &S) -> bool { self.0.eq(other.as_ref()) } } impl Eq for A { } impl<S: AsRef<[u8]>> PartialOrd<S> for A { fn partial_cmp(&self, other: &S) -> Option<Ordering> { let slice: &[u8] = &self.0; slice.partial_cmp(other.as_ref()) } } impl Ord for A { fn cmp(&self, other: &Self) -> Ordering { self.partial_cmp(&other).unwrap() } }
Compiler Result:
rustc 1.12.0 (3191fbae9 2016-09-23) error[E0277]: the trait bound `[u8]: std::marker::Sized` is not satisfied --> <anon>:20:6 | 20 | impl Eq for A { } | ^^ | = note: `[u8]` does not have a constant size known at compile-time = note: required because it appears within the type `A` = note: required because of the requirements on the impl of `std::cmp::PartialEq` for `A` = note: required by `std::cmp::Eq` error[E0277]: the trait bound `[u8]: std::marker::Sized` is not satisfied --> <anon>:29:6 | 29 | impl Ord for A { | ^^^ | = note: `[u8]` does not have a constant size known at compile-time = note: required because it appears within the type `A` = note: required because of the requirements on the impl of `std::cmp::PartialOrd` for `A` = note: required by `std::cmp::Ord`
If I create a variant of a type that has a fixed size (for example, turning it into a fixed size array), I can manually implement the traits without any problems.
struct B([u8; 5]); impl AsRef<[u8]> for B { fn as_ref(&self) -> &[u8] { &self.0 } } impl<S: AsRef<[u8]>> PartialEq<S> for B { fn eq(&self, other: &S) -> bool { self.0.eq(other.as_ref()) } } impl Eq for B { } impl<S: AsRef<[u8]>> PartialOrd<S> for B { fn partial_cmp(&self, other: &S) -> Option<Ordering> { let slice: &[u8] = &self.0; slice.partial_cmp(other.as_ref()) } } impl Ord for B { fn cmp(&self, other: &Self) -> Ordering { self.partial_cmp(&other).unwrap() } }
Here is a link to a playground showing the problem .
My question is: how to implement Ord and Eq in my custom DST so that I can take advantage of the fact that I can partial_cmp/eq any AsRef<[u8]> , but also use this to force the border to implement traits of Ord / Eq , like in struct B in my example?
traits rust
burtonageo
source share