Skip to content

Commit 31e9a3c

Browse files
authored
bevy_reflect: Re-reflect hashbrown types (#18944)
# Objective Fixes #18943 ## Solution Reintroduces support for `hashbrown`'s `HashMap` and `HashSet` types. These were inadvertently removed when `bevy_platform` newtyped the `hashbrown` types. Since we removed our `hashbrown` dependency, I gated these impls behind a `hashbrown` feature. Not entirely sure if this is necessary since we enabled it for `bevy_reflect` through `bevy_platform` anyways. (Complex features still confuse me a bit so let me know if I can just remove it!) I also went ahead and preemptively implemented `TypePath` for `PassHash` while I was here. ## Testing You can test that it works by adding the following to a Bevy example based on this PR (you'll also need to include `hashbrown` of course): ```rust #[derive(Reflect)] struct Foo(hashbrown::HashMap<String, String>); ``` Then check it compiles with: ``` cargo check --example hello_world --no-default-features --features=bevy_reflect/hashbrown ```
1 parent 7f04906 commit 31e9a3c

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

crates/bevy_reflect/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ debug_stack = ["std"]
3333
## Adds reflection support to `glam` types.
3434
glam = ["dep:glam"]
3535

36+
## Adds reflection support to `hashbrown` types.
37+
hashbrown = ["dep:hashbrown"]
38+
3639
## Adds reflection support to `petgraph` types.
3740
petgraph = ["dep:petgraph", "std"]
3841

@@ -87,6 +90,7 @@ bevy_platform = { path = "../bevy_platform", version = "0.16.0-dev", default-fea
8790

8891
# used by bevy-utils, but it also needs reflect impls
8992
foldhash = { version = "0.1.3", default-features = false }
93+
hashbrown = { version = "0.15.1", optional = true, default-features = false }
9094

9195
# other
9296
erased-serde = { version = "0.4", default-features = false, features = [

crates/bevy_reflect/src/impls/std.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,19 @@ crate::func::macros::impl_function_traits!(::bevy_platform::collections::HashMap
10011001
>
10021002
);
10031003

1004+
#[cfg(feature = "hashbrown")]
1005+
impl_reflect_for_hashmap!(hashbrown::hash_map::HashMap<K, V, S>);
1006+
#[cfg(feature = "hashbrown")]
1007+
impl_type_path!(::hashbrown::hash_map::HashMap<K, V, S>);
1008+
#[cfg(all(feature = "functions", feature = "hashbrown"))]
1009+
crate::func::macros::impl_function_traits!(::hashbrown::hash_map::HashMap<K, V, S>;
1010+
<
1011+
K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash,
1012+
V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration,
1013+
S: TypePath + BuildHasher + Default + Send + Sync
1014+
>
1015+
);
1016+
10041017
macro_rules! impl_reflect_for_hashset {
10051018
($ty:path) => {
10061019
impl<V, S> Set for $ty
@@ -1208,6 +1221,7 @@ macro_rules! impl_reflect_for_hashset {
12081221

12091222
impl_type_path!(::bevy_platform::hash::NoOpHash);
12101223
impl_type_path!(::bevy_platform::hash::FixedHasher);
1224+
impl_type_path!(::bevy_platform::hash::PassHash);
12111225
impl_reflect_opaque!(::core::net::SocketAddr(
12121226
Clone,
12131227
Debug,
@@ -1239,6 +1253,18 @@ crate::func::macros::impl_function_traits!(::bevy_platform::collections::HashSet
12391253
>
12401254
);
12411255

1256+
#[cfg(feature = "hashbrown")]
1257+
impl_reflect_for_hashset!(::hashbrown::hash_set::HashSet<V,S>);
1258+
#[cfg(feature = "hashbrown")]
1259+
impl_type_path!(::hashbrown::hash_set::HashSet<V, S>);
1260+
#[cfg(all(feature = "functions", feature = "hashbrown"))]
1261+
crate::func::macros::impl_function_traits!(::hashbrown::hash_set::HashSet<V, S>;
1262+
<
1263+
V: Hash + Eq + FromReflect + TypePath + GetTypeRegistration,
1264+
S: TypePath + BuildHasher + Default + Send + Sync
1265+
>
1266+
);
1267+
12421268
impl<K, V> Map for ::alloc::collections::BTreeMap<K, V>
12431269
where
12441270
K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord,
@@ -2848,4 +2874,15 @@ mod tests {
28482874
let output = <&'static str as FromReflect>::from_reflect(&expected).unwrap();
28492875
assert_eq!(expected, output);
28502876
}
2877+
2878+
#[test]
2879+
fn should_reflect_hashmaps() {
2880+
assert_impl_all!(std::collections::HashMap<u32, f32>: Reflect);
2881+
assert_impl_all!(bevy_platform::collections::HashMap<u32, f32>: Reflect);
2882+
2883+
// We specify `foldhash::fast::RandomState` directly here since without the `default-hasher`
2884+
// feature, hashbrown uses an empty enum to force users to specify their own
2885+
#[cfg(feature = "hashbrown")]
2886+
assert_impl_all!(hashbrown::HashMap<u32, f32, foldhash::fast::RandomState>: Reflect);
2887+
}
28512888
}

0 commit comments

Comments
 (0)