Skip to content

hash_map::OccupiedEntry::take leaves map in an inconsistent state #19292

Closed
@spernsteiner

Description

@spernsteiner

This code manipulates a HashMap using the new Entry API, checking for consistency after each step.

use std::collections::HashMap;
use std::collections::hash_map::Entry::{Vacant, Occupied};
use std::rand::Rng;

fn check(m: &HashMap<int, ()>) {
    for k in m.keys() {
        assert!(m.contains_key(k),
                "{} is in keys() but not in the map?", k);
    }
}

fn main() {
    let mut m = HashMap::new();
    let mut rng = std::rand::weak_rng();

    // Populate the map with some items.
    for _ in range(0u, 50) {
        let x = rng.gen_range(-10, 10);
        m.insert(x, ());
    }

    for i in range(0u, 1000) {
        let x = rng.gen_range(-10, 10);
        match m.entry(x) {
            Vacant(_) => {},
            Occupied(e) => {
                println!("{}: remove {}", i, x);
                e.take();
            },
        }

        check(&m);
    }
}

The assertion in check should never fail, but in my tests it does so reliably, almost always within the first 10 iterations of the second loop. When it does fail, the value of k is not one of the values previously removed during the loop (that is, keys is right to return this key, and contains_key is wrong to report it as absent).

I tested this with rustc 0.13.0-dev (377d7524a 2014-11-24 13:56:36 +0000) on 64-bit Linux.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions