3 ms·
> Did you know that Option<T> implements IntoIterator yielding 0/1 elements, and you can then call Iterator::flatten to make that be 0/n elements if T: IntoIter
by RcouF1uZ4gsC 4y ago
> Did you know that Option<T> implements IntoIterator yielding 0/1 elements, and you can then call Iterator::flatten to make that be 0/n elements if T: IntoIterator?
I thought this was so cool, being able to treat Option like a 0/1 collection.
- pornel 4y agoPersonally I dislike this (Result has it too), because it gives bizarre errors if you forget to unwrap a result: let collection = get_stuff(); for item in collection { } This can unexpectedly give you one item of iterable `Result` instead of items of the collection if `get_stuff()` returns a `Result<Vec>` or `Option<Vec>`. Such mistake won't make it to production thanks to strict type checking, but it manifests in surprising and misleading error messages that the `item` doesn't have methods you expect it to have, rather than pointing to the true cause of `get_stuff()` not having error handled.
- tialaramex 4y agoI can't say I've ever run into this, but it sounds like you have. You might find there's a common pattern which distinguishes this mistake from typical scenarios where you did something else wrong and the compiler can use that to provide more helpful errors in this case. Seems like, we do for x in Result-or-Option<T> and T is IntoIterator, and then we treat x as if it is the thing T was an iterator for, rather than T. That's detectable. So, worth taking some examples of code where you did this, and writing up a report that the compilers team can look at. If you've got some idea what you're doing you might well even find Rust's error reporting code readable enough to dive in and try some fixes yourself.
- Arnavion 4y agoI've seen users come asking for help about it on IRC a bunch of times, so it's probably a pretty common typo, at least among beginners. In retrospect it might've been better if there was an explicit conversion to the (Into)Iterator type instead of being impled on Option/Result itself. https://www.arnavion.dev/blog/2020-04-07-rust-the-unfortunate-bits/#result-option-intoiterator https://www.arnavion.dev/blog/2020-04-07-rust-the-unfortunat...
- 3836293648 4y agoI've never run into this because I always write out my `.iter()`s and `.into_iter()`, but this is why I don't think loops should accept `IntoIterator` types, just actual `Iterator`s so you're forced to type it out
- tialaramex 4y agoThis just adds verbosity - there's a blanket implementation of IntoIterator on Iterator so people would just learn to write for x in y.into_iter() and presumably curse 3836293648 who made them do this extra typing for no purpose. It doesn't, as you seem to imply fix the parent's problem, because both the container they thought they were getting, and the Option or Result they were actually getting, implement IntoIterator so they'll call into_iter() on it.
- afdbcreid 4y agoThere is a warn-by-default Clippy lint for that: `clippy::for_loops_over_fallibles`. However, being an `IntoIterator` is important for things like flattening and other iterator adapters.
- estebank 4y agoCould you file a ticket? rustc is not above inspecting the types at play and special casing Option and Result handling to check for the consequences of iterating on them should be doable.