rust-lang / hashbrown

Rust port of Google's SwissTable hash map
https://rust-lang.github.io/hashbrown
Apache License 2.0
2.44k stars 288 forks source link

Hashbrown fails to compile if 0.14.x and 0.15.x are in the same project, only one with the nightly feature #564

Open orlp opened 1 month ago

orlp commented 1 month ago

If a project (most likely indirectly through dependencies) depends on both version 0.14.x and 0.15.x of hashbrown, and only one of the two dependencies has the nightly feature flag set, the project will fail to compile due to using the allocator_api without enabling the unstable feature for it:

error[E0658]: use of unstable library feature 'allocator_api'
    --> /Users/orlp/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.14.5/src/raw/mod.rs:4329:23
     |
4329 |                 alloc.deallocate(ptr, layout);
     |                       ^^^^^^^^^^
     |
     = note: see issue #32838 <https://github.com/rust-lang/rust/issues/32838> for more information
     = help: add `#![feature(allocator_api)]` to the crate attributes to enable
     = note: this compiler was built on 2024-10-02; consider upgrading it if it is out of date

This can be reproduced by making a clean new project and adding the following two lines to Cargo.toml:

hashbrown_14 = { package = "hashbrown", version = "=0.14.5", features = [] }
hashbrown_15 = { package = "hashbrown", version = "=0.15.0", features = ["nightly"] }

If it's just one of the two the project compiles fine, regardless of the nightly feature flag. If neither or both have the nightly feature flag everything compiles fine as well. However if one has the nightly feature flag and the other does not, the project doesn't compile.

orlp commented 1 month ago

The problem appears to be that allocator-api2's recommended usage is inherently flawed:

Your library MAY provide a feature that will enable "allocator-api2/nightly". When this feature is enabled, your library MUST enable unstable #![feature(allocator_api)] or it may not compile. If feature is not provided, your library may not be compatible with the rest of the users and cause compilation errors on nightly channel when some other crate enables "allocator-api2/nightly" feature.

Feature unification makes the requirement "When this feature is enabled your library MUST enable unstable #![feature(allocator_api)] or it may not compile" fundamentally impossible to fulfill.

Amanieu commented 1 month ago

I'm not sure there's anything actionable we can do on hashbrown's side...

cuviper commented 1 month ago

allocator-api2/nightly re-exports from alloc, but hashbrown/nightly is already using alloc directly -- so I think there's no reason to forward the nightly feature at all. That will mean its Allocator won't match that from allocator-api2 (without nightly), but really, it's already a breaking change that these features change the types in public API.