Change:
} } <del> /// true if `borrow_location` can reach `use_location` by going through a loop and /// `use_location` is also inside of that loop fn is_use_in_later_iteration_of_loop( &self, borrow_location: Location, use_location: Location, ) -> bool { let back_edge = self.reach_through_backedge(borrow_location, use_location); back_edge.map_or(false, |back_edge| self.can_reach_head_of_loop(use_location, back_edge)) } /// Returns the outmost back edge if `from` location can reach `to` location passing through /// that back edge fn reach_through_backedge(&self, from: Location, to: Location) -> Option<Location> { let mut visited_locations = FxHashSet::default(); let mut pending_locations = VecDeque::new(); visited_locations.insert(from); pending_locations.push_back(from); debug!("reach_through_backedge: from={:?} to={:?}", from, to,); let mut outmost_back_edge = None; while let Some(location) = pending_locations.pop_front() { debug!( "reach_through_backedge: location={:?} outmost_back_edge={:?} pending_locations={:?} visited_locations={:?}", location, outmost_back_edge, pending_locations, visited_locations ); if location == to && outmost_back_edge.is_some() { // We've managed to reach the use location debug!("reach_through_backedge: found!"); return outmost_back_edge; } let block = &self.body.basic_blocks[location.block]; if location.statement_index < block.statements.len() { let successor = location.successor_within_block(); if visited_locations.insert(successor) { pending_locations.push_back(successor); } } else { pending_locations.extend( block .terminator() .successors() .map(|bb| Location { statement_index: 0, block: bb }) .filter(|s| visited_locations.insert(*s)) .map(|s| { if self.is_back_edge(location, s) { match outmost_back_edge { None => { outmost_back_edge = Some(location); } Some(back_edge) if location.dominates(back_edge, &self.dominators) => { outmost_back_edge = Some(location); } Some(_) => {} } } s }), ); } } None } /// true if `from` location can reach `loop_head` location and `loop_head` dominates all the /// intermediate nodes fn can_reach_head_of_loop(&self, from: Location, loop_head: Location) -> bool { self.find_loop_head_dfs(from, loop_head, &mut FxHashSet::default()) } fn find_loop_head_dfs( &self, from: Location, loop_head: Location, visited_locations: &mut FxHashSet<Location>, ) -> bool { visited_locations.insert(from); if from == loop_head { return true; } if loop_head.dominates(from, &self.dominators) { let block = &self.body.basic_blocks[from.block]; if from.statement_index < block.statements.len() { let successor = from.successor_within_block(); if !visited_locations.contains(&successor) && self.find_loop_head_dfs(successor, loop_head, visited_locations) { return true; } } else { for bb in block.terminator().successors() { let successor = Location { statement_index: 0, block: bb }; if !visited_locations.contains(&successor) && self.find_loop_head_dfs(successor, loop_head, visited_locations) { return true; } } } } false } /// True if an edge `source -> target` is a backedge -- in other words, if the target /// dominates the source. fn is_back_edge(&self, source: Location, target: Location) -> bool { target.dominates(source, &self.dominators) } </del> /// Determine how the borrow was later used. /// First span returned points to the location of the conflicting use /// Second span if `Some` is returned in the case of closures and points

Discussion:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. If you cannot produce a minimal reproduction case (something that would work in isolation), please provide the steps or even link to a repository that causes the problematic output to occur. --Given the following code: The current output is: It looks like the error is pointing to the wrong spot in the code and is quite misleading. Ideally the output should mention that is still mutably borrowed because it holds a reference to between loops. Or something, im not actually sure :P I have confirmed that this occurs in both the latest stable (1.62.1) and nightly () <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
With the proposed the output will be like this: