Skip to content

Commit

Permalink
improved the error message by insert_boxed (issue bevyengine#13646) (…
Browse files Browse the repository at this point in the history
…again) (bevyengine#13706)

previously I worked on fixing issue bevyengine#13646, back when the error message
did not include the type at all.
But that error message had room for improvement, so I included the
feedback of @alice-i-cecile and @MrGVSV.
The error message will now read `the given key (of type
bevy_reflect::tests::Foo) does not support hashing` or 'the given key
(of type bevy_reflect::DynamicStruct) does not support hashing' in case
of a dynamic struct that represents a hashable struct

i also added a new unit test for this new behaviour
(`reflect_map_no_hash_dynamic`).
Fixes bevyengine#13646 (again)

---------

Co-authored-by: Alice Cecile <[email protected]>
Co-authored-by: Gino Valente <[email protected]>
  • Loading branch information
3 people authored Jun 7, 2024
1 parent b17292f commit d45bcfd
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 7 deletions.
44 changes: 43 additions & 1 deletion crates/bevy_reflect/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,7 @@ mod tests {
any::TypeId,
borrow::Cow,
fmt::{Debug, Formatter},
hash::Hash,
marker::PhantomData,
};

Expand Down Expand Up @@ -756,19 +757,60 @@ mod tests {
}

#[test]
#[should_panic(expected = "the given key bevy_reflect::tests::Foo does not support hashing")]
#[should_panic(
expected = "the given key of type `bevy_reflect::tests::Foo` does not support hashing"
)]
fn reflect_map_no_hash() {
#[derive(Reflect)]
struct Foo {
a: u32,
}

let foo = Foo { a: 1 };
assert!(foo.reflect_hash().is_none());

let mut map = DynamicMap::default();
map.insert(foo, 10u32);
}

#[test]
#[should_panic(
expected = "the dynamic type `bevy_reflect::DynamicStruct` (representing `bevy_reflect::tests::Foo`) does not support hashing"
)]
fn reflect_map_no_hash_dynamic_representing() {
#[derive(Reflect, Hash)]
#[reflect(Hash)]
struct Foo {
a: u32,
}

let foo = Foo { a: 1 };
assert!(foo.reflect_hash().is_some());
let dynamic = foo.clone_dynamic();

let mut map = DynamicMap::default();
map.insert(dynamic, 11u32);
}

#[test]
#[should_panic(
expected = "the dynamic type `bevy_reflect::DynamicStruct` does not support hashing"
)]
fn reflect_map_no_hash_dynamic() {
#[derive(Reflect, Hash)]
#[reflect(Hash)]
struct Foo {
a: u32,
}

let mut dynamic = DynamicStruct::default();
dynamic.insert("a", 4u32);
assert!(dynamic.reflect_hash().is_none());

let mut map = DynamicMap::default();
map.insert(dynamic, 11u32);
}

#[test]
fn reflect_ignore() {
#[derive(Reflect)]
Expand Down
26 changes: 20 additions & 6 deletions crates/bevy_reflect/src/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,12 +197,26 @@ impl MapInfo {
#[macro_export]
macro_rules! hash_error {
( $key:expr ) => {{
let type_name = match (*$key).get_represented_type_info() {
None => "Unknown",
Some(s) => s.type_path(),
};
format!("the given key {} does not support hashing", type_name).as_str()
}};
let type_path = (*$key).reflect_type_path();
if !$key.is_dynamic() {
format!(
"the given key of type `{}` does not support hashing",
type_path
)
} else {
match (*$key).get_represented_type_info() {
// Handle dynamic types that do not represent a type (i.e a plain `DynamicStruct`):
None => format!("the dynamic type `{}` does not support hashing", type_path),
// Handle dynamic types that do represent a type (i.e. a `DynamicStruct` proxying `Foo`):
Some(s) => format!(
"the dynamic type `{}` (representing `{}`) does not support hashing",
type_path,
s.type_path()
),
}
}
.as_str()
}}
}

/// An ordered mapping between reflected values.
Expand Down

0 comments on commit d45bcfd

Please sign in to comment.