Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upIntroduce the `IntoIterator` trait and reimplement for-loops to use it #20790
Conversation
rust-highfive
assigned
alexcrichton
Jan 9, 2015
This comment has been minimized.
This comment has been minimized.
|
(rust_highfive has picked a reviewer for you, use r? to override) |
This comment has been minimized.
This comment has been minimized.
|
Can we do this without expanding in the front end? |
This comment has been minimized.
This comment has been minimized.
|
@huonw @nikomatsakis was interested in an implementation that used the frontend (hence this prototype) |
This comment has been minimized.
This comment has been minimized.
|
Also, expanding to include |
This comment has been minimized.
This comment has been minimized.
|
(I think @aturon and @nikomatsakis mainly want to measure the size of the fallout and the change in ergonomics of these new for-loop semantics before commiting to it. This implementation is minimal work to measure that. We can come up with a better implementation if we decide to actually do this.) |
alexcrichton
reviewed
Jan 9, 2015
| @@ -273,7 +273,7 @@ impl<'a> Iterator for Recompositions<'a> { | |||
| loop { | |||
| match self.state { | |||
| Composing => { | |||
| for ch in self.iter { | |||
| while let Some(ch) = self.iter.next() { | |||
This comment has been minimized.
This comment has been minimized.
alexcrichton
Jan 9, 2015
Member
Could some loops like this be altered to:
for ch in self.iter.by_ref() { /* ... */ }That may avoid consuming the entire iterator.
This comment has been minimized.
This comment has been minimized.
alexcrichton
Jan 9, 2015
Member
Actually, if it helps in basically all cases, I wonder if we could spec it like this...
This comment has been minimized.
This comment has been minimized.
japaric
Jan 10, 2015
Author
Member
I had forgotten about by_ref()! I think we can use that instead of most (all?) the while lets.
Actually, if it helps in basically all cases, I wonder if we could spec it like this...
You mean using by_ref() in the for loop expansion?
japaric
force-pushed the
japaric:for-loops
branch
from
b7f577d
to
6f91e46
Jan 10, 2015
This comment has been minimized.
This comment has been minimized.
|
Updated to use the |
This comment has been minimized.
This comment has been minimized.
|
Some thoughts:
|
This comment has been minimized.
This comment has been minimized.
|
@japaric and @nikomatsakis As a fan of desugaring as much as possible I think this seems like a good idea. If error messages become a problem you could use a similar scheme to what they do with Pyret where you provide a tag (either in some table or directly on the AST) for which rewrite rule you used, and then utilize that information when reporting errors by re-sugaring it then pretty printing. I would be happy to help explore such a scheme if the error reporting suffers. |
japaric
force-pushed the
japaric:for-loops
branch
from
6f91e46
to
49fae39
Jan 12, 2015
This comment has been minimized.
This comment has been minimized.
|
Updated PR with @nikomatsakis suggestions ( I've collected some error messages from 3 cfail tests related to for-loops:
struct MyStruct {
x: isize,
y: isize,
}
impl MyStruct {
fn next(&mut self) -> Option<isize> {
Option::Some(self.x)
}
}
fn main() {
let mut bogus = MyStruct {
x: 1,
y: 2,
};
for x in bogus {
//~^ old-ERROR has type `MyStruct` which does not implement the `Iterator` trait
//~^^ new-ERROR the trait `iter::Iterator` is not implemented for the type `MyStruct`
}
}The error message changed its wording but the meaning is the same.
fn main() {
for
&1i8
//~^ old-ERROR refutable pattern in `for` loop binding
//~^^ new-ERROR non-exhaustive patterns: `Some(&_)` not covered
in [1i8].iter() {}
}The message is more obscure now.
fn main() {
let x = () + (); //~ ERROR binary operation
// this shouldn't have a flow-on error:
// japaric: and it doesn't with the either version of for loops
for _ in x {}
}Behavior remains the same. |
alexcrichton
reviewed
Jan 12, 2015
| @@ -65,6 +65,8 @@ | |||
| #![allow(unknown_features)] #![feature(int_uint)] | |||
| #![feature(on_unimplemented)] | |||
| #![deny(missing_docs)] | |||
| // SNAP 9e4e524 remove `allow(unused_mut)` after a snapshot | |||
| #![allow(unused_mut)] | |||
This comment has been minimized.
This comment has been minimized.
alexcrichton
Jan 12, 2015
Member
Now that we have cfg_attr, could this be #![cfg_attr(stage0, allow(unused_mut))]? Anything with the string "stage0" in it is a pretty easy flag for something to clean out when dealing with snapshots.
This comment has been minimized.
This comment has been minimized.
|
@japaric and I were talking on IRC. My feeling is that the error in this example: fn main() {
for
&1i8
//~^ old-ERROR refutable pattern in `for` loop binding
//~^^ new-ERROR non-exhaustive patterns: `Some(&_)` not covered
in [1i8].iter() {}
}is actually better. I doubt most "lay people" know what a "refutable pattern" is. (I personally have to work out from first principles which is "irrefutable" and which is "refutable".) But having a concrete counter example seems immediately understandable. It might be better still to combine the two messages:
|
This comment has been minimized.
This comment has been minimized.
|
@nikomatsakis I think introducing the |
japaric
referenced this pull request
Jan 16, 2015
Closed
Type inference works with method calls, but not with UFCS #21245
pnkfelix
referenced this pull request
Jan 23, 2015
Open
new scoping rules for safe dtors can yield spurious semi-colon or trailing unit expr #21114
japaric
force-pushed the
japaric:for-loops
branch
from
49fae39
to
2678d5a
Jan 23, 2015
japaric
changed the title
[proto][WIP] Introduce the `IntoIterator` trait and reimplement for-loops to use it
Introduce the `IntoIterator` trait and reimplement for-loops to use it
Jan 23, 2015
japaric
force-pushed the
japaric:for-loops
branch
from
2678d5a
to
f4bd701
Jan 23, 2015
This comment has been minimized.
This comment has been minimized.
|
This PR is ready! (passed re: error message on refutable patterns, I decide to reuse the old message/diagnostic code, we can customize it later if desired. |
This was referenced Jan 26, 2015
japaric
force-pushed the
japaric:for-loops
branch
from
f4bd701
to
522e902
Jan 26, 2015
This comment has been minimized.
This comment has been minimized.
|
rebased and added tests for issues that new for loops fix. Also fixed a recursive call that the new |
japaric
force-pushed the
japaric:for-loops
branch
from
522e902
to
d2d9270
Jan 26, 2015
This comment has been minimized.
This comment has been minimized.
|
Just a heads up, until #21637 gets fixed, we won't be able to use the fn concat<I: IntoIterator>(it: I) -> String where <I::Iter as Iterator>::Item: Str {
unimplemented!();
} |
alexcrichton
reviewed
Jan 27, 2015
| @@ -0,0 +1,7 @@ | |||
| std | |||
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
alexcrichton
added a commit
to alexcrichton/rust
that referenced
this pull request
Jan 30, 2015
This comment has been minimized.
This comment has been minimized.
bors
added a commit
that referenced
this pull request
Jan 30, 2015
This comment has been minimized.
This comment has been minimized.
|
@bors: retry |
This comment has been minimized.
This comment has been minimized.
bors
added a commit
that referenced
this pull request
Jan 31, 2015
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
|
@bors: retry |
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
|
@bors: retry |
This comment has been minimized.
This comment has been minimized.
bors
added a commit
that referenced
this pull request
Jan 31, 2015
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
|
@bors: retry |
This comment has been minimized.
This comment has been minimized.
bors
added a commit
that referenced
this pull request
Jan 31, 2015
alexcrichton
merged commit b9a9030
into
rust-lang:master
Jan 31, 2015
japaric
deleted the
japaric:for-loops
branch
Jan 31, 2015
This was referenced Jan 31, 2015
bors
added a commit
that referenced
this pull request
Feb 1, 2015
This comment has been minimized.
This comment has been minimized.
|
The RFC didn't mention this "mod std" business, and I'm a bit uncomfortable with it. Why not directly access the core crate? |
This comment has been minimized.
This comment has been minimized.
If you mean expanding to
You already have to use the |
aepsil0n
added a commit
to aepsil0n/rust-itertools
that referenced
this pull request
Feb 3, 2015
aepsil0n
referenced this pull request
Feb 3, 2015
Merged
Adapt code to the new semantics of the for-loop #13
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
alexchandel
commented
Feb 4, 2015
|
The relevant section of the Rust Reference ought to be updated to reflect this, cc @steveklabnik |
japaric commentedJan 9, 2015
As per RFC #235, you can now do:
[breaking-change]s
For loops now "consume" (move) the iterator, this breaks iterating over mutable references to iterators, and also breaks multiple iterations over the same iterator:
Both cases can be fixed using the
by_ref()adapter to create an iterator from the mutable reference:This PR also makes iterator non-implicitly copyable, as this was source of subtle bugs in the libraries. You can still use
clone()to explictly copy the iterator.Finally, since the for loops are implemented in the frontend and use global paths to
IntoIterator,IteratorandOptionvariants, users of thecorecrate will have to use add anstdmodule to the root of their crate to be able to use for loops:r? @nikomatsakis @aturon
cc #18424
closes #18045