@@ -183,30 +183,40 @@ impl<A: Ord> SliceOrd for A {
183183 }
184184}
185185
186- // The type should be treated as an unsigned byte for comparisons.
186+ /// Marks that a type should be treated as an unsigned byte for comparisons.
187+ ///
188+ /// # Safety
189+ /// * The type must be readable as an `u8`, meaning it has to have the same
190+ /// layout as `u8` and always be initialized.
191+ /// * For every `x` and `y` of this type, `Ord(x, y)` must return the same
192+ /// value as `Ord::cmp(transmute::<_, u8>(x), transmute::<_, u8>(y))`.
187193#[ rustc_specialization_trait]
188- unsafe trait UnsignedByte { }
194+ unsafe trait UnsignedBytewiseOrd { }
189195
190- unsafe impl UnsignedByte for bool { }
191- unsafe impl UnsignedByte for u8 { }
192- unsafe impl UnsignedByte for NonZero < u8 > { }
193- unsafe impl UnsignedByte for Option < NonZero < u8 > > { }
194- unsafe impl UnsignedByte for ascii:: Char { }
196+ unsafe impl UnsignedBytewiseOrd for bool { }
197+ unsafe impl UnsignedBytewiseOrd for u8 { }
198+ unsafe impl UnsignedBytewiseOrd for NonZero < u8 > { }
199+ unsafe impl UnsignedBytewiseOrd for Option < NonZero < u8 > > { }
200+ unsafe impl UnsignedBytewiseOrd for ascii:: Char { }
195201
196- // `compare_bytes` compares a sequence of unsigned bytes lexicographically.
197- impl < A : Ord + UnsignedByte > SliceOrd for A {
202+ // `compare_bytes` compares a sequence of unsigned bytes lexicographically, so
203+ // use it if the requirements for `UnsignedBytewiseOrd` are fulfilled.
204+ impl < A : Ord + UnsignedBytewiseOrd > SliceOrd for A {
198205 #[ inline]
199206 fn compare ( left : & [ Self ] , right : & [ Self ] ) -> Ordering {
200- // Since the length of a slice is always less than or equal to isize::MAX, this never underflows.
207+ // Since the length of a slice is always less than or equal to
208+ // isize::MAX, this never underflows.
201209 let diff = left. len ( ) as isize - right. len ( ) as isize ;
202- // This comparison gets optimized away (on x86_64 and ARM) because the subtraction updates flags.
210+ // This comparison gets optimized away (on x86_64 and ARM) because the
211+ // subtraction updates flags.
203212 let len = if left. len ( ) < right. len ( ) { left. len ( ) } else { right. len ( ) } ;
204213 let left = left. as_ptr ( ) . cast ( ) ;
205214 let right = right. as_ptr ( ) . cast ( ) ;
206- // SAFETY: `left` and `right` are references and are thus guaranteed to be valid.
207- // `UnsignedByte` is only implemented for types that are valid u8s. We use the
208- // minimum of both lengths which guarantees that both regions are valid for reads
209- // in that interval.
215+ // SAFETY: `left` and `right` are references and are thus guaranteed to
216+ // be valid. `UnsignedBytewiseOrd` is only implemented for types that
217+ // are valid u8s and can be compared the same way. We use the minimum
218+ // of both lengths which guarantees that both regions are valid for
219+ // reads in that interval.
210220 let mut order = unsafe { compare_bytes ( left, right, len) as isize } ;
211221 if order == 0 {
212222 order = diff;
0 commit comments