You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Yeah that would be a breaking change (and not the kind that epochs enable). If we could remove the impl Iterator for Range<...>, we should do that and just replace it with an IntoIterator impl. Alas...
The choice of removing Copy impls instead of adjusted for loop desugaring or linting was made to prevent this problematic case:
letmut iter = 0..n;for i in iter {if i > 2{break;}}
iter.collect()
The above code triggers an unused_mut lint
Maybe in 2015 this looked like a dangerous thing to have, but I really feel like nowadays Rustaceans know that for loops capture by value (most will even know that it happens because of the implicit .into_iter() call).
I mean, if we are to be oblivious to .into_iter(), I don't see that much difference between the above code and:
letmut iter = &[0,1,2,3,4,5];for i in iter {if*i > 2{break;}}FromIterator::from_iter(iter)
Plus there are two ways to avoid using a mutable iterator as an iterable (IntoIter):
manually advance the iteration by explicitly calling .next().
For instance, with while let Some(x) = iterator.next()
feed the iterator by ref: for x in iterator.by_ref() or for x in &mut iterator, where both are very explicit and readable idioms.
In favor of Copy
Factoring out repeated ranges:
letmut s = 0;let range = 0 .. 10;println!("{}", s);for i in range {
s += i;println!("{}", s);}for i in range.rev(){// currently errors
s -= i;println!("{}", s);}
Storing Ranges in Copy structs
pubstructZipSubSlice{left:[u8;8],right:[u8;8],pubrange:Range<usize>,}implCopyforZipSubSlice{}// currently errors
Alternatives
Edition 2019: Iterator -> IntoIterator
Wait for the next edition to change impl<Idx : Step> Iterator for Range<Idx> { //... into impl<Idx : Copy> Copy for Range<Idx> {} impl <Idx : Step> IntoIterator for Range<Idx> { //...
Activity
sinkuu commentedon Mar 2, 2018
Definitely possible, but there is a reason why it is currently not.
#27186 (comment)
SoniEx2 commentedon Mar 3, 2018
Can't you implement iterator for &mut Range, and have Range itself be Copy?
It would solve the lint problem, altho it's a breaking change and also requires you to use "for x in &mut a..b" I guess...
hanna-kruppe commentedon Mar 3, 2018
Yeah that would be a breaking change (and not the kind that epochs enable). If we could remove the
impl Iterator for Range<...>, we should do that and just replace it with anIntoIteratorimpl. Alas...danielhenrymantilla commentedon Mar 31, 2019
Against
CopyThe above code triggers an
unused_mutlintMaybe in 2015 this looked like a dangerous thing to have, but I really feel like nowadays Rustaceans know that
forloops capture by value (most will even know that it happens because of the implicit.into_iter()call).I mean, if we are to be oblivious to
.into_iter(), I don't see that much difference between the above code and:Plus there are two ways to avoid using a mutable iterator as an iterable (
IntoIter):manually advance the iteration by explicitly calling
.next().while let Some(x) = iterator.next()feed the iterator by ref:
for x in iterator.by_ref()orfor x in &mut iterator, where both are very explicit and readable idioms.In favor of
CopyFactoring out repeated ranges:
Storing
Ranges inCopystructsAlternatives
Edition 2019:
Iterator->IntoIteratorWait for the next edition to change
impl<Idx : Step> Iterator for Range<Idx> { //...intoimpl<Idx : Copy> Copy for Range<Idx> {} impl <Idx : Step> IntoIterator for Range<Idx> { //...A secondary
CopyRangestruct instdwhich would be copy, and with
For instance, something along these lines:
Mark-Simulacrum commentedon Sep 1, 2019
Since we've consciously made this decision in the past I think a (small) RFC would be warranted. Closing.