Skip to content

bevy_reflect: Optional generic info#24383

Draft
MrGVSV wants to merge 1 commit into
bevyengine:mainfrom
MrGVSV:mrgvsv/optional-generic-info
Draft

bevy_reflect: Optional generic info#24383
MrGVSV wants to merge 1 commit into
bevyengine:mainfrom
MrGVSV:mrgvsv/optional-generic-info

Conversation

@MrGVSV
Copy link
Copy Markdown
Member

@MrGVSV MrGVSV commented May 21, 2026

Objective

Resolves #24379

Solution

This PR does makes it so that TypeParamInfo and ConstParamInfo (and thus, GenericInfo) capture type information optionally. This allows us to still capture some details about a generic type even when #[reflect(type_path = false)] is used.

It essentially allows us to capture the following details in every case:

  • The generic parameter name (e.g. T)
  • The generic parameter default (e.g. const N: usize = 10 or T: Clone = String). Note that the type parameter case still needs to implement TypePath, but the type is known so we don't have to really worry about it in the impl's where clause.

And so the optional information becomes:

  • The generic parameter type. Note that this includes const parameters even though const parameters currently only support a known subset of types in Rust (all of which implies TypePath). We can change this if desired. I only didn't to prepare for a potential future where more types support being const parameters.

Note

This PR is open for debate. While it provides useful generic details to devs when a type opt-out of the TypePath auto-derive, it does come at the cost of wrapping all generic type info surfaces in Option. This means a generally worse developer experience in the most common cases in exchange for a small benefit in the least common cases.

I'd especially love to hear if anyone has experience with generic types that need to opt out of the TypePath derive and where this kind of type info would be useful.

Testing

Added some unit tests!


Showcase

Reflected types marked with #[reflect(type_path = false)] now capture basic generic information.

#[derive(Reflect)]
#[reflect(type_path = false)]
struct MyType<T: Default>(#[reflect(ignore)] T);

let generics = <MyType<u32>::type_info()
    .as_tuple_struct()
    .unwrap()
    .generics();

// BEFORE
assert_eq!(generics.len(), 0);

// AFTER
assert_eq!(generics.len(), 1);

let t = generics.get_named("T").unwrap();
assert_eq!(t.name(), "T");
assert!(!t.is_const());
// Note: Opting out of `TypePath` means we can't capture type information:
assert_eq!(t.ty(), None);

@MrGVSV MrGVSV added C-Usability A targeted quality-of-life change that makes Bevy easier to use A-Reflection Runtime information about types S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels May 21, 2026
@github-project-automation github-project-automation Bot moved this to Needs SME Triage in Reflection May 21, 2026
@MrGVSV MrGVSV moved this from Needs SME Triage to SME Triaged in Reflection May 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Reflection Runtime information about types C-Usability A targeted quality-of-life change that makes Bevy easier to use S-Needs-Review Needs reviewer attention (from anyone!) to move forward

Projects

Status: SME Triaged

Development

Successfully merging this pull request may close these issues.

Generic type info not captured when #[reflect(type_path = false]

1 participant