Skip to content

VecDeque's Hash::hash implementation is incorrect #80303

Closed
@SvetlinZarev

Description

@SvetlinZarev

VecDeque's hashcode changes after rotation. In the following example, the VecDeque should be in its original ordering, yet it produces a different hashcode.

I've also opened rust-lang/hashbrown#218 but I was advised to open a new issue here.

I tried this code:

use ahash::AHasher;
use std::collections::VecDeque;
use std::hash::{Hash, Hasher};

fn hash(x: &impl Hash) -> u64 {
    let mut hasher = AHasher::default();
    Hash::hash(x, &mut hasher);
    hasher.finish()
}

fn main() {
    let deque: VecDeque<i32> = (0..10).collect();

    let mut deque2 = deque.clone();
    deque2.rotate_left(5);
    deque2.rotate_left(5);

    assert_eq!(deque, deque2);
    assert_eq!(hash(&deque), hash(&deque2)); // fails!
}

I expected to see this happen:
The hashcode should not change and the example should terminate successfully

Instead, this happened:
The hashcode is different and the application panics.

Meta

Yes, the bug exists in beta and nightly.

rustc --version --verbose:

rustc 1.48.0 (7eac88abb 2020-11-16)
binary: rustc
commit-hash: 7eac88abb2e57e752f3302f02be5f3ce3d7adfb4
commit-date: 2020-11-16
host: x86_64-unknown-linux-gnu
release: 1.48.0
LLVM version: 11.0

The issue is caused by an ambiguity in the Hash::hash_slice() contract - it's not clear whether the hashcode should be sensitive to the slice's length. The default hasher is not sensitive, while ahash is.

Metadata

Metadata

Assignees

Labels

A-collectionsArea: `std::collections`C-bugCategory: This is a bug.P-mediumMedium priorityT-libsRelevant to the library team, which will review and decide on the PR/issue.T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions