I have a function that takes a mutable reference to any iterator over given Item
s. The function can usually consume the items one-by-one, but occasionally has to perform lookahead. The item retrieved like this will sometimes be consumed, but sometimes has to be "prepended" back to the iterator (using e.g. a Chain
), over which this function must then recurse.
However, the execution crashes at runtime while resolving trait requirements:
error[E0275]: overflow evaluating the requirement `std::iter::Chain<std::vec::IntoIter<std::string::String>, &mut std::iter::Chain<std::vec::IntoIter<std::string::String>, &mut std::iter::Chain<std::vec::IntoIter<std::string::String>, &mut std::iter::Chain<std::vec::IntoIter<std::string::String>, &mut std::iter::Chain<std::vec::IntoIter<std::string::String>, &mut std::iter::Chain<std::vec::IntoIter<std::string::String>, &mut std::iter::Chain<std::vec::IntoIter<std::string::String>, &mut std::iter::Chain<std::vec::IntoIter<std::string::String>, &mut std::iter::Chain<std::vec::IntoIter<std::string::String>, &mut std::iter::Chain<std::vec::IntoIter<std::string::String>, ...
The minimal code is (the condition here expresses that unlimited recursion depth cannot be reached):
fn foo<I: Iterator<Item = String>>(it: &mut I) -> String {
if *(&1) == 1 {
String::new()
} else {
foo(&mut vec![String::new()].into_iter().chain(it))
}
}
fn main() {
let mut it = vec!["Hello".to_string(), "World!".to_string()].into_iter();
println!["{:?}", foo(&mut it)];
}
Changing the function to accept a trait object resolves the problem, but I'm not keen on using dynamic dispatch for this simple situation.
Do I have to restructure the code, use trait objects, or is there another solution to stop the checker from recursing indefinitely?
I'm using Rust 1.44.1 on x86_64-apple-darwin
, but it crashes under nightly too.