Skip to content

Commit

Permalink
Add [f32]::sort_floats and [f64]::sort_floats
Browse files Browse the repository at this point in the history
It's inconvenient to sort a slice or Vec of floats, compared to sorting
integers. To simplify numeric code, add a convenience method to `[f32]`
and `[f64]` to sort them using `sort_unstable_by` with `total_cmp`.

Add lang items slice_f32 and slice_f64 to handle the two new impl
blocks.
  • Loading branch information
joshtriplett committed Jan 29, 2022
1 parent 21b4a9c commit 37ad800
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 4 deletions.
2 changes: 2 additions & 0 deletions compiler/rustc_hir/src/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ language_item_table! {
Str, sym::str, str_impl, Target::Impl, GenericRequirement::None;
Array, sym::array, array_impl, Target::Impl, GenericRequirement::None;
Slice, sym::slice, slice_impl, Target::Impl, GenericRequirement::None;
SliceF32, sym::slice_f32, slice_f32_impl, Target::Impl, GenericRequirement::None;
SliceF64, sym::slice_f64, slice_f64_impl, Target::Impl, GenericRequirement::None;
SliceU8, sym::slice_u8, slice_u8_impl, Target::Impl, GenericRequirement::None;
StrAlloc, sym::str_alloc, str_alloc_impl, Target::Impl, GenericRequirement::None;
SliceAlloc, sym::slice_alloc, slice_alloc_impl, Target::Impl, GenericRequirement::None;
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1295,6 +1295,8 @@ symbols! {
skip,
slice,
slice_alloc,
slice_f32,
slice_f64,
slice_len_fn,
slice_patterns,
slice_u8,
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_typeck/src/check/method/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
ty::Slice(_) => {
for lang_def_id in [
lang_items.slice_impl(),
lang_items.slice_f32_impl(),
lang_items.slice_f64_impl(),
lang_items.slice_u8_impl(),
lang_items.slice_alloc_impl(),
lang_items.slice_u8_alloc_impl(),
Expand Down
22 changes: 22 additions & 0 deletions compiler/rustc_typeck/src/coherence/inherent_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,28 @@ impl<'tcx> ItemLikeVisitor<'_> for InherentCollect<'tcx> {
assoc_items,
);
}
ty::Slice(slice_item) if slice_item == self.tcx.types.f32 => {
self.check_primitive_impl(
item.def_id,
lang_items.slice_f32_impl(),
None,
"slice_f32",
"[f32]",
item.span,
assoc_items,
);
}
ty::Slice(slice_item) if slice_item == self.tcx.types.f64 => {
self.check_primitive_impl(
item.def_id,
lang_items.slice_f64_impl(),
None,
"slice_f64",
"[f64]",
item.span,
assoc_items,
);
}
ty::Slice(_) => {
self.check_primitive_impl(
item.def_id,
Expand Down
2 changes: 2 additions & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@
#![feature(variant_count)]
#![feature(const_array_from_ref)]
#![feature(const_slice_from_ref)]
// Library features:
#![feature(total_cmp)]
//
// Language features:
#![feature(abi_unadjusted)]
Expand Down
62 changes: 62 additions & 0 deletions library/core/src/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3983,6 +3983,68 @@ impl<T> [T] {
}
}

#[cfg(not(bootstrap))]
#[cfg(not(test))]
#[lang = "slice_f32"]
impl [f32] {
/// Sorts the slice of floats.
///
/// This sort is in-place (i.e. does not allocate), *O*(*n* \* log(*n*)) worst-case, and uses
/// the ordering defined by [`f32::total_cmp`].
///
/// # Current implementation
///
/// This uses the same sorting algorithm as [`sort_unstable_by`](slice::sort_unstable_by).
///
/// # Examples
///
/// ```
/// #![feature(sort_floats)]
/// let mut v = [2.6, -5e-8, f32::NAN, 8.29, f32::INFINITY, -1.0, 0.0, -f32::INFINITY, -0.0];
///
/// v.sort_floats();
/// let sorted = [-f32::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f32::INFINITY, f32::NAN];
/// assert_eq!(&v[..8], &sorted[..8]);
/// assert!(v[8].is_nan());
/// ```
#[unstable(feature = "sort_floats", issue = "93396")]
#[inline]
pub fn sort_floats(&mut self) {
self.sort_unstable_by(f32::total_cmp);
}
}

#[cfg(not(bootstrap))]
#[cfg(not(test))]
#[lang = "slice_f64"]
impl [f64] {
/// Sorts the slice of floats.
///
/// This sort is in-place (i.e. does not allocate), *O*(*n* \* log(*n*)) worst-case, and uses
/// the ordering defined by [`f64::total_cmp`].
///
/// # Current implementation
///
/// This uses the same sorting algorithm as [`sort_unstable_by`](slice::sort_unstable_by).
///
/// # Examples
///
/// ```
/// #![feature(sort_floats)]
/// let mut v = [2.6, -5e-8, f64::NAN, 8.29, f64::INFINITY, -1.0, 0.0, -f64::INFINITY, -0.0];
///
/// v.sort_floats();
/// let sorted = [-f64::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f64::INFINITY, f64::NAN];
/// assert_eq!(&v[..8], &sorted[..8]);
/// assert!(v[8].is_nan());
/// ```
#[unstable(feature = "sort_floats", issue = "93396")]
#[inline]
pub fn sort_floats(&mut self) {
self.sort_unstable_by(f64::total_cmp);
}
}

trait CloneFromSpec<T> {
fn spec_clone_from(&mut self, src: &[T]);
}
Expand Down
10 changes: 6 additions & 4 deletions src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1648,18 +1648,18 @@ impl PrimitiveType {
}
}

crate fn impls(&self, tcx: TyCtxt<'_>) -> &'static ArrayVec<DefId, 4> {
crate fn impls(&self, tcx: TyCtxt<'_>) -> &'static ArrayVec<DefId, 6> {
Self::all_impls(tcx).get(self).expect("missing impl for primitive type")
}

crate fn all_impls(tcx: TyCtxt<'_>) -> &'static FxHashMap<PrimitiveType, ArrayVec<DefId, 4>> {
static CELL: OnceCell<FxHashMap<PrimitiveType, ArrayVec<DefId, 4>>> = OnceCell::new();
crate fn all_impls(tcx: TyCtxt<'_>) -> &'static FxHashMap<PrimitiveType, ArrayVec<DefId, 6>> {
static CELL: OnceCell<FxHashMap<PrimitiveType, ArrayVec<DefId, 6>>> = OnceCell::new();

CELL.get_or_init(move || {
use self::PrimitiveType::*;

let single = |a: Option<DefId>| a.into_iter().collect();
let both = |a: Option<DefId>, b: Option<DefId>| -> ArrayVec<_, 4> {
let both = |a: Option<DefId>, b: Option<DefId>| -> ArrayVec<_, 6> {
a.into_iter().chain(b).collect()
};

Expand All @@ -1686,6 +1686,8 @@ impl PrimitiveType {
lang_items
.slice_impl()
.into_iter()
.chain(lang_items.slice_f32_impl())
.chain(lang_items.slice_f64_impl())
.chain(lang_items.slice_u8_impl())
.chain(lang_items.slice_alloc_impl())
.chain(lang_items.slice_u8_alloc_impl())
Expand Down

0 comments on commit 37ad800

Please sign in to comment.