@@ -183,30 +183,40 @@ impl<A: Ord> SliceOrd for A {
183
183
}
184
184
}
185
185
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))`.
187
193
#[ rustc_specialization_trait]
188
- unsafe trait UnsignedByte { }
194
+ unsafe trait UnsignedBytewiseOrd { }
189
195
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 { }
195
201
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 {
198
205
#[ inline]
199
206
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.
201
209
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.
203
212
let len = if left. len ( ) < right. len ( ) { left. len ( ) } else { right. len ( ) } ;
204
213
let left = left. as_ptr ( ) . cast ( ) ;
205
214
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.
210
220
let mut order = unsafe { compare_bytes ( left, right, len) as isize } ;
211
221
if order == 0 {
212
222
order = diff;
0 commit comments