What we might need are float types with typestate.
Something like F64<CheckAtRuntime, NoNaNs, NoInfs, NoSignedZeroes, AllowReciprocal, AllowContraction, Reassociate, OtherFast> (these are LLVM’s flags for floating point operations, except for Reassociate split out of OtherFast).
Ord would be implemented only for NoNaNs = True. Checks in debug mode only unless CheckAtRuntime is True (unsafe code already can’t rely on Ord behavior).
Developers would use this by defining a type alias with the desired options. Would need to add an “as” trait to the compiler, a “pragma” allowing to choose the type to assign to constants, and preferably keyword-based parameters for generics.
Anyway, another possible solution for sort is to define sort on “SemiOrd”, which would be a new trait inheriting from PartialOrd that adds an “is_comparable” method and guarantees that the order is a total order on elements where “is_comparable” is true, while the other elements are not comparable with anything (obviously in the float case is_comparable would be !is_nan).
This allows to trivially implement a fast sort respecting the partial order by first placing all incomparable elements at the end, and then sorting the rest as normal using a comparator based on PartialOrd with unwrap.
(without such a guarantee it would still be possible to implement a sort, but it would take n^2 time on a slice with all nans since it needs to do all pairwise comparisons in case a pair is comparable, which is unacceptable)