I find that it can be useful to think about Option as a single-or-no-element iterator in other contexts as well. I think even outside of the utility of using it in contexts that take IntoIterator, it definitely should be IntoIterator.
for element in option { do stuff } is still correct, it’s just that the loop only runs zero or one times, rather than zero or more times. It’s calling regex ? a repetition ({0,1}) in addition to + ({1,}) and * ({0,}).
If a syntactical form existed for IntoOption to specifically cater to the zero-or-one case, then I’d support a clippy lint to prefer that when both IntoIterator and IntoOption are available, but not a rustc lint. I think they already get optimized to the same end code anyway, it’s just a matter of rustc being able to assume the block is run a maximum of one time for type and borrow checking.
The problem I see with if value in option is that I expect that to mean if option == Some(value) (or if option.contains(value), not if let Some(value) = option. for always creates a name, if never does, let does irrefutable pattern matching assignment, and if let does conditional scoped refutable pattern matching assignment.
At a glance, what do you expect the following code to do?
let option = Some(10);
let value = 5;
if value in option {
println!("if : value = {}", value);
} else {
println!("else: value = {}", value);
}
for value in option {
println!("for : value = {}", value);
}
My intuition says else: value = 5/for : value = 10, because so far I’ve been trained that if cannot introduce new bindings. That’s also why I’m weakly against if option is Some(value) without getting some other benefit from it (which I think exists but I cannot recall at the moment).