-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Specialisation of Iterator methods for Range #42534
Conversation
This commit is a result of the libs team's discussion of rust-lang#33417 and how it affects integral types. The conclusion was that the motivation for converting integral types, working in a cross-platform code that uses platform-specific integer types, was different enough from the intent of `TryFrom` that it doesn't make sense to unify the paths. As a result this is a proposal for the alternative version of the API which purely works with integral types. An unstable `Cast` trait is added as the implementation detail of this API, and otherwise with this you should be able to call `i32::cast(0u8)` at will. The intention is then to call this in platform-specific contexts like: // Convert from C to Rust let a: c_int = ...; let b: u32 = u32::cast(a)?; // Convert from Rust to C let a: u32 = ...; let b: c_int = <c_int>::cast(a)?; Everything here is unstable for now, but the intention is that this will stabilize sooner than `TryFrom`.
r? @BurntSushi (rust_highfive has picked a reviewer for you, use r? to override) |
For anybody triaging this: I will not bother fixing the test failures until the |
I believe this also Fixes #41477 (by deleting it) |
src/libcore/iter/range.rs
Outdated
|
||
#[inline] | ||
fn count(self) -> usize { | ||
usize::MAX |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this, like last
, also panic? Returning a value here is neither of the behaviours (panic or diverge) possible from this today.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As the Iterator
implementation for RangeFrom
in fundamentally broken at the moment (#25708), I don't think it's a good idea to override count
, nth
and last
just yet. At least the default impls match what happens when you repeatedly call .next()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@scottmcm the documentation of Iterator::count
says:
The method does no guarding against overflows, so counting elements of an iterator with more than usize::MAX elements either produces the wrong result or panics. If debug assertions are enabled, a panic is guaranteed.
so yes, it should panic, as you say.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ollie27 I’m fairly confident that nth
maintains the same behaviour as the current next
by being ever-so-slightly broken around the last value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well with debug assertions disabled (0u8..).nth(1000)
returns Some(232)
and by the looks of it your version will always panic
. Ideally it would return None
. I guess adding panic
s in cases where the behaviour isn't properly defined isn't too bad but I'd like to see this implementation properly fixed.
@@ -1090,26 +1090,92 @@ fn test_range_step() { | |||
#![allow(deprecated)] | |||
|
|||
assert_eq!((0..20).step_by(5).collect::<Vec<isize>>(), [0, 5, 10, 15]); | |||
assert_eq!((20..0).step_by(-5).collect::<Vec<isize>>(), [20, 15, 10, 5]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be worth rephrasing these in terms of rev
? Like, for this one,
assert_eq!((1..21).rev().step_by(5).collect::<Vec<isize>>(), [20, 15, 10, 5]);
Is the new StepBy on (x..y) intervals efficient? Because this is the most common use case, and it's a quite common one. |
#![feature(iterator_step_by)]
pub fn foo(x: ::std::ops::Range<i32>) -> i32 {
let mut sum = 0;
for a in x.step_by(3) {
sum += a;
}
return sum;
} results in this being generated:
so it does use the new |
@nagisa your code gives me:
Compiling with the latest Nightly (given by rustup show):
|
@leonardo-m because it would still be using the DeprecatedStepBy on nightly. Replace |
Thank you @nagisa, adding a "mut" it works. I have this test code:
Compiling with: It gives:
The new step_by isn't acceptable, I think. |
☔ The latest upstream changes (presumably #42644) made this pull request unmergeable. Please resolve the merge conflicts. |
Friendly ping to keep this on your radar @nagisa. |
🕸 Closing PR due to inactivity to keep our backlog clean. Feel free to reopen. 🕸 |
I use step_by often in my code, and now my code has many: warning: use of deprecated item: replaced by So the situation isn't in a stable state. |
This is based onto #42456. Should not be merged before that lands.
This also removes the StepBy deprecated in previous cycle.