diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/utility.rs b/crates/bevy_reflect/bevy_reflect_derive/src/utility.rs index b8efa3f530e62..32549bd4af8e3 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/utility.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/utility.rs @@ -155,11 +155,16 @@ pub(crate) fn extend_where_clause( } else { quote!() }; + + // The nested parentheses here are required to properly scope HRTBs coming + // from field types to the type itself, as the compiler will scope them to + // the whole bound by default, resulting in a failure to prove trait + // adherence. generic_where_clause.extend(quote! { - #(#active_types: #active_trait_bounds,)* - #(#ignored_types: #ignored_trait_bounds,)* + #((#active_types): #active_trait_bounds,)* + #((#ignored_types): #ignored_trait_bounds,)* // Leave parameter bounds to the end for more sane error messages. - #(#parameter_types: #parameter_trait_bounds,)* + #((#parameter_types): #parameter_trait_bounds,)* }); generic_where_clause } diff --git a/crates/bevy_reflect/src/lib.rs b/crates/bevy_reflect/src/lib.rs index c00b91e626ff1..13221427960d9 100644 --- a/crates/bevy_reflect/src/lib.rs +++ b/crates/bevy_reflect/src/lib.rs @@ -1426,6 +1426,26 @@ mod tests { assert!(info.is::()); } + #[test] + fn should_permit_higher_ranked_lifetimes() { + #[derive(Reflect)] + struct TestStruct { + #[reflect(ignore)] + _hrl: for<'a> fn(&'a str) -> &'a str, + } + + impl Default for TestStruct { + fn default() -> Self { + TestStruct { + _hrl: |input| input, + } + } + } + + fn get_type_registration() {} + get_type_registration::(); + } + #[test] fn should_permit_valid_represented_type_for_dynamic() { let type_info = <[i32; 2] as Typed>::type_info();