While it's in the same genre as this question, I feel my particular case is a little more surprising. Apologies if it has been asked about before, and I couldn't find it.
Here is a contrived reproducer. My original code is the same structure as this, but does a different type conversion and split point calculation (making the unwrap()s unnecessary):
let places: Vec<String> = {
let mut places: Vec<_> = vec!["Hamptons", "Hollywood", "Costa Rica"];
let non_h_places = places.iter().position(|item| item.chars().next().unwrap() != 'H').unwrap();
places.drain(non_h_places..).try_fold::<Vec<_>, _, anyhow::Result<Vec<_>>>(Vec::new(), |mut vec, s| {
vec.push(s.to_string());
Ok(vec)
})?
};
Written this way, the compiler complains that the inner places does not live long enough.
In general, I understand why: the Drain iterator mutably borrows the collection without owning it, and the TryFold iterator on it consumes that. The compiler wants to aggressively clean up the collection at that point, hence the error.
The solution (which is even suggested the compiler iteslf, good work on the diagonstic messages!) is to add a temporary binding. What that really does, IIRC, is implicitly require a longer lifetime on the iterator -- because the TryFold is required to complete so its output value can live past the end of the statement. Thus, the collection is not dropped until after the last statement in the block.
In this case, however, the collection created by the TryFold is the return value of the block. I would expect the compiler to extend the lifetime it in a similar way, since it is "bound" to the stack slot reserved for the return, which will be put into an outer scope.
But this doesn't happen, apparently. Instead, I need to create a temporary just to return it immediately:
let vec = places.drain(non_h_places..).try_fold::<Vec<_>, _, anyhow::Result<Vec<_>>>(Vec::new(), |mut vec, s| {
vec.push(s.to_string());
Ok(vec)
})?;
vec
This is not specific to inline blocks, either. Turning it into a stand-alone function has the same problem.
This behavior seems rather silly to me. What do the compiler experts think? Is this worth filing a (minor) GH issue, in the hopes it could be fixed without regressing borrow checking in most cases?