Skip to content

Commit

Permalink
bevy_reflect: Update internal docs regarding anonymous function type …
Browse files Browse the repository at this point in the history
…names (bevyengine#14666)

# Objective

As pointed out by @SkiFire13 on
[Discord](https://discord.com/channels/691052431525675048/1002362493634629796/1270624366119485441),
I was incorrect in bevyengine#14641 regarding the type name of anonymous
functions. I had stated that they will return something like `fn(i32,
i32) -> i32`, but this is wrong. They actually behave like closures
(despite not technically being closures) and return something more like
`foo::bar::{{closure}}`.

This isn't a major issue because the reasoning behind bevyengine#14641 still
stands. However, the internal documentation should probably be updated
so future contributors don't believe the lies I left behind.

## Solution

Updated the internal documentation for `create_info` to reflect the
actual type name of an anonymous function.

In that same module, I also added a test for function pointers and
updated all tests to include sanity checks for the `std::any::type_name`
of each category of callable.

## Testing

You can test locally by running:

```
cargo test --package bevy_reflect
```
  • Loading branch information
MrGVSV authored Aug 8, 2024
1 parent 3f47273 commit aeef1c0
Showing 1 changed file with 45 additions and 4 deletions.
49 changes: 45 additions & 4 deletions crates/bevy_reflect/src/func/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,9 +342,9 @@ all_tuples!(impl_typed_function, 0, 15, Arg, arg);
///
/// | Category | `type_name` | `FunctionInfo::name` |
/// | ------------------ | ----------------------- | ----------------------- |
/// | Named function | `foo::bar::baz` | `Some("foo::bar::baz")` |
/// | Named function | `foo::bar::baz` | `Some("foo::bar::baz")` |
/// | Closure | `foo::bar::{{closure}}` | `None` |
/// | Anonymous function | `fn() -> String` | `None` |
/// | Anonymous function | `foo::bar::{{closure}}` | `None` |
/// | Function pointer | `fn() -> String` | `None` |
///
/// [`type_name`]: std::any::type_name
Expand All @@ -368,6 +368,12 @@ mod tests {
a + b
}

// Sanity check:
assert_eq!(
std::any::type_name_of_val(&add),
"bevy_reflect::func::info::tests::should_create_function_info::add"
);

let info = add.get_function_info();
assert_eq!(
info.name().unwrap(),
Expand All @@ -379,9 +385,36 @@ mod tests {
assert_eq!(info.return_info().type_path(), "i32");
}

#[test]
fn should_create_function_pointer_info() {
fn add(a: i32, b: i32) -> i32 {
a + b
}

let add = add as fn(i32, i32) -> i32;

// Sanity check:
assert_eq!(std::any::type_name_of_val(&add), "fn(i32, i32) -> i32");

let info = add.get_function_info();
assert!(info.name().is_none());
assert_eq!(info.arg_count(), 2);
assert_eq!(info.args()[0].type_path(), "i32");
assert_eq!(info.args()[1].type_path(), "i32");
assert_eq!(info.return_info().type_path(), "i32");
}

#[test]
fn should_create_anonymous_function_info() {
let info = (|a: i32, b: i32| a + b).get_function_info();
let add = |a: i32, b: i32| a + b;

// Sanity check:
assert_eq!(
std::any::type_name_of_val(&add),
"bevy_reflect::func::info::tests::should_create_anonymous_function_info::{{closure}}"
);

let info = add.get_function_info();
assert!(info.name().is_none());
assert_eq!(info.arg_count(), 2);
assert_eq!(info.args()[0].type_path(), "i32");
Expand All @@ -392,7 +425,15 @@ mod tests {
#[test]
fn should_create_closure_info() {
let mut total = 0;
let info = (|a: i32, b: i32| total = a + b).get_function_info();
let add = |a: i32, b: i32| total = a + b;

// Sanity check:
assert_eq!(
std::any::type_name_of_val(&add),
"bevy_reflect::func::info::tests::should_create_closure_info::{{closure}}"
);

let info = add.get_function_info();
assert!(info.name().is_none());
assert_eq!(info.arg_count(), 2);
assert_eq!(info.args()[0].type_path(), "i32");
Expand Down

0 comments on commit aeef1c0

Please sign in to comment.