Is it alright to assume that the following assertions always hold? I assume the internal representation of std::cmp::Ordering is an implementation detail that could change any time?
fn main() {
assert!((7.cmp(&9) as i32) < 0);
assert_eq!(7.cmp(&9) as i32, -1);
}
... The enum has a #[repr(i8)] attribute and the overall type is stable.
That means you can rely on Ordering::Less being -1, Ordering::Equal being 0, and Ordering::Greater being 1. Furthermore, the i8 representation means the behaviour when casting to i32 or other types is also well-specified and not going to change.
The as i32 behaviour is visible to safe code on stable, so I think you're fine to assume it'll stay that way.
I wouldn't write any code that depends on the repr(i8), though. reprs aren't necessarily part of the public API, the same way that size_of isn't necessarily stable.
That said, why not just do
assert_eq!(7.cmp(&9), Ordering::Less);
instead?
EDIT (much, much later): While my general statement above is still correct, cmp::Ordering had an explicit libs-api FCP to make it part of the ABI, so you can absolutely rely on -1/0/+1 as i8 for that specific enum.
That's surprising. If they don't want people to make any assumptions about the type's layout, you would think they'd leave it as repr(Rust) and not provide any values for each enum variant
But if you're really worried about assembly-peeking, you might want to add a cmp_bytes_unchecked_raw that returns a c_int, since normalizing to -1, 0, 1 for the enum adds some cost, compared to just returning the c_int from the memcmp I assume it's using internally.
This one definitely doesn't follow, because as i32 still works without the repr, so they might add the custom discriminants to enable that without intending to say anything about the layout.
It depends if they want to use it as an implementation detail for unsafe code elsewhere in the library.
Update on the missing optimization: C++ has the same problem (https://clang.godbolt.org/z/57jqWxbxe), so it's not rust's fault, and thus here's the bug on LLVM if you're curious to follow along