You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Bit of an edge case that it might be useful to correct: During the expansion of the Reflect derive macro on a struct that uses a higher-kinded type directly as one of its field types, the macro expands to some rather ambiguous bounds:
#[derive(bevy::reflect::Reflect)]pubstructSingleLineDisplayState{#[reflect(ignore)]transform:for<'a> fn(&'a str) -> &'a str,}fnget_type_registration<T: bevy::reflect::GetTypeRegistration>(){}fncaller(){get_type_registration::<SingleLineDisplayState>();// error occurs here}// auto-generated by derive(Reflect) on SingleLineDisplayState, shown here for example purposesimpl bevy::reflect::GetTypeRegistrationforSingleLineDisplayStatewherefor<'a>fn(&'a str) -> &'a str:Any + Send + Sync,{
...
}
What went wrong
Unfortunately, rustc does not interpret this as where (for<'a> fn(&'a str) -> &'a str): Any (a higher-kinded bound of for<'a> fn(&'a str) -> &'a str), as is intended, but instead where for<'a> (fn(&'a str) -> &'a str): Any (a for<'a>-bound predicate of the non-higher-kinded type fn(&'a str) -> &'a str). This then causes the compiler to be unable to prove that SingleLineDisplayState does in fact implement GetTypeRegistration, leading to a compilation failure with the rather unhelpful error message "error: higher-ranked lifetime error".
Additional information
The issue arises when attempting to pass SingleLineDisplayState to any generic parameter that expects its type to implement GetTypeRegistration, as seen in the example above.
This is a simple grammar problem, as merely wrapping the type in parentheses in the struct definition resolves the ambiguity and fixes the problem. Perhaps Reflect could be augmented to place parentheses around the trait bounds it outputs, to prevent this ambiguity?
The text was updated successfully, but these errors were encountered:
I should note that the issue can be resolved on the caller's end by doing anything that would resolve the ambiguity, even if the resolution is implicit - for example, wrapping the HKT in an identity macro that simply takes tokens and returns them straight back to the code unchanged will solve the issue, as will merely wrapping it in parentheses. However, it would be very beneficial if Bevy itself accounted for the issue, as this solution is rather obscure (and results in a spurious unused_parens lint if you wrap it in parentheses.)
Bevy version
0.10.1
System information
Rustc version: 1.69.0 (84c898d65 2023-04-16)
Cargo version: 1.69.0 (6e9a83356 2023-04-12)
Platform: amd64 Windows 11 22H2 (OS Build 22621.1702)
The bug report
Bit of an edge case that it might be useful to correct: During the expansion of the
Reflect
derive macro on a struct that uses a higher-kinded type directly as one of its field types, the macro expands to some rather ambiguous bounds:What went wrong
Unfortunately, rustc does not interpret this as
where (for<'a> fn(&'a str) -> &'a str): Any
(a higher-kinded bound offor<'a> fn(&'a str) -> &'a str
), as is intended, but insteadwhere for<'a> (fn(&'a str) -> &'a str): Any
(afor<'a>
-bound predicate of the non-higher-kinded typefn(&'a str) -> &'a str
). This then causes the compiler to be unable to prove thatSingleLineDisplayState
does in fact implementGetTypeRegistration
, leading to a compilation failure with the rather unhelpful error message "error: higher-ranked lifetime error
".Additional information
The issue arises when attempting to pass
SingleLineDisplayState
to any generic parameter that expects its type to implementGetTypeRegistration
, as seen in the example above.This is a simple grammar problem, as merely wrapping the type in parentheses in the struct definition resolves the ambiguity and fixes the problem. Perhaps
Reflect
could be augmented to place parentheses around the trait bounds it outputs, to prevent this ambiguity?The text was updated successfully, but these errors were encountered: