Lifetime issues with mutable borrow in a loop
⚓ Rust 📅 2026-01-01 👤 surdeus 👁️ 1I'm working on refactoring code from owned data to borrowed data, and I've hit a lifetime issue with mutable borrows in a loop. The working version (with owned data) compiles fine, but the borrowed version fails.
The Problem:
I have a trait method that takes a mutable scratch space and returns an iterator. When the iterator borrows from the scratch space, I can't call this method multiple times in a loop:
fn ref_records<'point, 'scratch, ScratchT: ScratchSpaceRegistry>(
&'point self,
scratch: &'scratch mut ScratchT,
) -> RefIterResult<'point> // Returns Result<Box<dyn Iterator<Item = RefRecord<'point>> + Send + 'point>, String>
where
'scratch: 'point;
When I try to call this in a loop:
for point in data {
let records = point.ref_records(scratch)?;
Self::handle_point_ref(point, records, &mut inserter).await?;
}
Compiler Error:
cannot borrow `*scratch` as mutable more than once at a time
`*scratch` was mutably borrowed here in the previous iteration of the loop
The Working Version (for comparison):
This version works fine because the iterator doesn't borrow from scratch:
fn records<'point, 'scratch, ScratchT: ScratchSpaceRegistry>(
&'point mut self,
scratch: &'scratch mut ScratchT,
) -> OwnedIterResult // Returns Result<Box<dyn Iterator<Item = Record> + Send>, String>
where
'scratch: 'point;
The returned iterator contains owned Record values with no lifetime parameters, so the borrow of scratch ends immediately.
My Question:
Is there a way to express that the mutable borrow of scratch should only last as long as needed for deserialization, even though the returned iterator lives for 'point? Or is this a fundamental limitation where I need to restructure my API? If I need API restructuring, what would be a good way to handle this ?
The full code is available here: Rust Playground
I've tried various lifetime annotations but can't find a way to tell the compiler that scratch is only borrowed temporarily during iterator construction, not for the iterator's entire lifetime.
7 posts - 3 participants
🏷️ Rust_feed