What is the borrow checker complaining about(mut early return)?

I'm writing a hashmap for fun and ran into an interesting problem

pub fn entry(&mut self, key: K) -> Entry<'_, K, V> {
        let bucket_idx = self.bucket(&key);
        if let Some(entry) = self.buckets[bucket_idx]
            .iter_mut()
            .find(|(k, _)| k == &key)
            {
                // OccEntry takes a &'a mut (K, V)
                return Entry::Occupied( OccEntry { entry } );
            };
        // takes the key: K and bucket: &'a mut Vec<(K, V)>
        Entry::Vacant( VacEntry { key, bucket: &mut self.buckets[bucket_idx], } )
    }

I then spent an hour trying to recreate it in the playground... I can't I'm sure it's me but I do not understand why this is ok but not hash-map's entry fn.

fn test(&mut self, key: char) -> Either<'_> {
    self.take_ref();
    
    if let Some(s) = self.little.iter_mut().find(|c| *c == &key) {
        return Either::A( Other((s, 0)) );
    };
    Either::B( Example( &mut self.all ))
}

Thanks all!!

(Might be wrong, don't have much to go on.)
Your test uses two fields little and all compiler can give exclusive borrow to both independently.
entry on the other hand gives the exclusive borrow to buckets and when you early return that lasts for the remainder of the function; Second attempt to access field then gets rejected by borrow checker.

This is a limitation of nll, and will be fixed in the next borrow checker polonius.

I wondered about polonius, so the current BC is limited because it can not read the meaning of an early return and sees the mut borrow as lasting the entire function? It also does not distinguish between fields on a struct because unless otherwise annotated the borrow applies to the entire struct?

// this lifetime will always limit every field
fn do_stuff(&'all self) ...

Yes

I'm not sure about this, I don't think this is true, but I may be wrong.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.