Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make is_sorted[_by_key] require Ord instead of PartialOrd and remove Iterator::is_sorted_by_key #81382

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions compiler/rustc_typeck/src/astconv/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,13 +270,16 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
tcx,
arg,
param,
!args_iter.clone().is_sorted_by_key(|arg| match arg {
GenericArg::Lifetime(_) => ParamKindOrd::Lifetime,
GenericArg::Type(_) => ParamKindOrd::Type,
GenericArg::Const(_) => ParamKindOrd::Const {
unordered: tcx.features().const_generics,
},
}),
!args_iter
.clone()
.map(|arg| match arg {
GenericArg::Lifetime(_) => ParamKindOrd::Lifetime,
GenericArg::Type(_) => ParamKindOrd::Type,
GenericArg::Const(_) => ParamKindOrd::Const {
unordered: tcx.features().const_generics,
},
})
.is_sorted(),
Some(&format!(
"reorder the arguments: {}: `<{}>`",
param_types_present
Expand Down
44 changes: 6 additions & 38 deletions library/core/src/iter/traits/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3272,9 +3272,6 @@ pub trait Iterator {
/// That is, for each element `a` and its following element `b`, `a <= b` must hold. If the
/// iterator yields exactly zero or one element, `true` is returned.
///
/// Note that if `Self::Item` is only `PartialOrd`, but not `Ord`, the above definition
/// implies that this function returns `false` if any two consecutive items are not
/// comparable.
///
/// # Examples
///
Expand All @@ -3283,18 +3280,17 @@ pub trait Iterator {
///
/// assert!([1, 2, 2, 9].iter().is_sorted());
/// assert!(![1, 3, 2, 4].iter().is_sorted());
/// assert!([0].iter().is_sorted());
/// assert!(std::iter::once("ferris").is_sorted());
/// assert!(std::iter::empty::<i32>().is_sorted());
/// assert!(![0.0, 1.0, f32::NAN].iter().is_sorted());
/// ```
#[inline]
#[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
fn is_sorted(self) -> bool
where
Self: Sized,
Self::Item: PartialOrd,
Self::Item: Ord,
{
self.is_sorted_by(PartialOrd::partial_cmp)
self.is_sorted_by(|a, b| Some(a.cmp(b)))
}

/// Checks if the elements of this iterator are sorted using the given comparator function.
Expand All @@ -3308,9 +3304,9 @@ pub trait Iterator {
/// ```
/// #![feature(is_sorted)]
///
/// assert!([1, 2, 2, 9].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
/// assert!(![1, 3, 2, 4].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
/// assert!([0].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
/// assert!([8, 5, 4, 1].iter().is_sorted_by(|a, b| a.partial_cmp(b).map(|o| o.reverse())));
/// assert!(![1, 3, 2, 4].iter().is_sorted_by(|a, b| a.partial_cmp(b).map(|o| o.reverse())));
/// assert!(std::iter::once("ferris").is_sorted_by(|a, b| a.partial_cmp(b)));
/// assert!(std::iter::empty::<i32>().is_sorted_by(|a, b| a.partial_cmp(b)));
/// assert!(![0.0, 1.0, f32::NAN].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
/// ```
Expand All @@ -3337,34 +3333,6 @@ pub trait Iterator {
true
}

/// Checks if the elements of this iterator are sorted using the given key extraction
/// function.
///
/// Instead of comparing the iterator's elements directly, this function compares the keys of
/// the elements, as determined by `f`. Apart from that, it's equivalent to [`is_sorted`]; see
/// its documentation for more information.
///
/// [`is_sorted`]: Iterator::is_sorted
///
/// # Examples
///
/// ```
/// #![feature(is_sorted)]
///
/// assert!(["c", "bb", "aaa"].iter().is_sorted_by_key(|s| s.len()));
/// assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs()));
/// ```
#[inline]
#[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
fn is_sorted_by_key<F, K>(self, f: F) -> bool
where
Self: Sized,
F: FnMut(Self::Item) -> K,
K: PartialOrd,
{
self.map(f).is_sorted()
}

/// See [TrustedRandomAccess]
// The unusual name is to avoid name collisions in method resolution
// see #76479.
Expand Down
12 changes: 4 additions & 8 deletions library/core/src/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3322,9 +3322,6 @@ impl<T> [T] {
/// That is, for each element `a` and its following element `b`, `a <= b` must hold. If the
/// slice yields exactly zero or one element, `true` is returned.
///
/// Note that if `Self::Item` is only `PartialOrd`, but not `Ord`, the above definition
/// implies that this function returns `false` if any two consecutive items are not
/// comparable.
///
/// # Examples
///
Expand All @@ -3336,15 +3333,14 @@ impl<T> [T] {
/// assert!(![1, 3, 2, 4].is_sorted());
/// assert!([0].is_sorted());
/// assert!(empty.is_sorted());
/// assert!(![0.0, 1.0, f32::NAN].is_sorted());
/// ```
#[inline]
#[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
pub fn is_sorted(&self) -> bool
where
T: PartialOrd,
T: Ord,
{
self.is_sorted_by(|a, b| a.partial_cmp(b))
self.is_sorted_by(|a, b| Some(a.cmp(b)))
}

/// Checks if the elements of this slice are sorted using the given comparator function.
Expand Down Expand Up @@ -3383,9 +3379,9 @@ impl<T> [T] {
pub fn is_sorted_by_key<F, K>(&self, f: F) -> bool
where
F: FnMut(&T) -> K,
K: PartialOrd,
K: Ord,
{
self.iter().is_sorted_by_key(f)
self.iter().map(f).is_sorted()
}

/// Returns the index of the partition point according to the given predicate
Expand Down
3 changes: 0 additions & 3 deletions library/core/tests/iter/traits/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,11 +373,8 @@ fn test_is_sorted() {
assert!(![1, 3, 2].iter().is_sorted());
assert!([0].iter().is_sorted());
assert!(std::iter::empty::<i32>().is_sorted());
assert!(![0.0, 1.0, f32::NAN].iter().is_sorted());
assert!([-2, -1, 0, 3].iter().is_sorted());
assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs()));
assert!(!["c", "bb", "aaa"].iter().is_sorted());
assert!(["c", "bb", "aaa"].iter().is_sorted_by_key(|s| s.len()));
}

#[test]
Expand Down
1 change: 0 additions & 1 deletion library/core/tests/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2005,7 +2005,6 @@ fn test_is_sorted() {
assert!(![1, 3, 2].is_sorted());
assert!([0].is_sorted());
assert!(empty.is_sorted());
assert!(![0.0, 1.0, f32::NAN].is_sorted());
assert!([-2, -1, 0, 3].is_sorted());
assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
assert!(!["c", "bb", "aaa"].is_sorted());
Expand Down
2 changes: 0 additions & 2 deletions src/test/ui/feature-gates/feature-gate-is_sorted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ fn main() {
// Assert `Iterator` methods are unstable
assert!([1, 2, 2, 9].iter().is_sorted());
//~^ ERROR: use of unstable library feature 'is_sorted': new API
assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs()));
//~^ ERROR: use of unstable library feature 'is_sorted': new API

// Assert `[T]` methods are unstable
assert!([1, 2, 2, 9].is_sorted());
Expand Down
15 changes: 3 additions & 12 deletions src/test/ui/feature-gates/feature-gate-is_sorted.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,7 @@ LL | assert!([1, 2, 2, 9].iter().is_sorted());
= help: add `#![feature(is_sorted)]` to the crate attributes to enable

error[E0658]: use of unstable library feature 'is_sorted': new API
--> $DIR/feature-gate-is_sorted.rs:5:39
|
LL | assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs()));
| ^^^^^^^^^^^^^^^^
|
= note: see issue #53485 <https://github.com/rust-lang/rust/issues/53485> for more information
= help: add `#![feature(is_sorted)]` to the crate attributes to enable

error[E0658]: use of unstable library feature 'is_sorted': new API
--> $DIR/feature-gate-is_sorted.rs:9:26
--> $DIR/feature-gate-is_sorted.rs:7:26
|
LL | assert!([1, 2, 2, 9].is_sorted());
| ^^^^^^^^^
Expand All @@ -26,14 +17,14 @@ LL | assert!([1, 2, 2, 9].is_sorted());
= help: add `#![feature(is_sorted)]` to the crate attributes to enable

error[E0658]: use of unstable library feature 'is_sorted': new API
--> $DIR/feature-gate-is_sorted.rs:11:32
--> $DIR/feature-gate-is_sorted.rs:9:32
|
LL | assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
| ^^^^^^^^^^^^^^^^
|
= note: see issue #53485 <https://github.com/rust-lang/rust/issues/53485> for more information
= help: add `#![feature(is_sorted)]` to the crate attributes to enable

error: aborting due to 4 previous errors
error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0658`.