-
Notifications
You must be signed in to change notification settings - Fork 13.1k
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
Forgetting .iter() in for loop causes confusing type error message #8649
Comments
I think the only way to completely fix the strangeness of these errors would be to implement for loops in the compiler beyond just a transformation on the AST. We would also need that to fix issue #8372, and possibly to support both an |
This is pretty bad, and should probably be fixed for 1.0 |
A hacky fix is to have a global function like
and call that from the generated function. It'd give an improved |
We should do something here for 1.0, if only the hack niko suggested. |
I think there's a better hack (just one call, more of a noop, relevant name): { // in for loop expansion:
let iter = ::std::iter::assert_iter(&mut rhs);
...
}
// in std::iter
pub fn assert_iter<'a, T, I: Iterator<T>>(iter: &'a mut I) -> &'a mut I {iter} An |
Adding more code to the macro is going to cause further problems at |
Let's not overstate: s/cause further problems/"mildly lenghten compile times"/ |
@nikomatsakis: I don't think we can ignore performance without optimizations enabled, because LLVM doesn't offer support for debugging while optimizing like GCC (-Og, -fvar-tracking-assignments). A demanding interactive application could easily become unusable without optimizations... It should just be done properly instead of adding more hacks. Every hack we add makes it less likely that it's going to be written properly any time soon. Giving sane error messages and not bloating the code are important. |
@thestinger Here are my thoughts:
In my ideal world, we would build up some infrastructure for doing this sort of rewriting. I know that some (e.g. @pcwalton) have their doubts about the utility of this. However, if we were careful we could reduce the Rust language to a truly small set of operations. This would have the further benefit that this would be quite close to a language that we can formalize and prove sound etc etc. |
@thestinger I guess what I mean is, I'd rather live with the current hack, especially if we can improve end-user experience, then invest effort writing custom code for |
@nikomatsakis: I think it's important that it doesn't unnecessarily borrow an lvalue for the loop body though. I don't really see how this can be done without it being part of the compiler. You should be able to use the iterator within a for loop using the iterator. for x in xs.iter() {
if cond(x) {
xs.next(); // skip the next value
}
foo(x);
} |
@thestinger I guess you mean |
@thestinger I thought you currently couldn't write that code anyway, since it is pretty much the exact example motivating issue #8372 ? (Or are you just providing this as a separate argument for why iterator support should be integrated into the compiler rather than left as a preprocessor expansion?) |
@pnkfelix: I'm providing it as an example for why integrating it into the compiler would be nice. If we can have a branch doing this in the expansion, then it doesn't matter. |
Closed by #15809 |
add [`manual_find`] lint for function return case part of the implementation discussed in rust-lang#7143 changelog: add [`manual_find`] lint for function return case
I accidentally wrote:
where
foo
returns a vector. The error:was not exactly useful. The problem was that I left out the
.iter()
afterfoo()
. But my first instinct would be to look for where I'm callingnext()
, and I'm not calling it explicitly.The text was updated successfully, but these errors were encountered: