Allow SystemParams with private fields (#7056)
# Objective - Fix #4200 Currently, `#[derive(SystemParam)]` publicly exposes each field type, which makes it impossible to encapsulate private fields. ## Solution Previously, the fields were leaked because they were used as an input generic type to the macro-generated `SystemParam::State` struct. That type has been changed to store its state in a field with a specific type, instead of a generic type. --- ## Changelog - Fixed a bug that caused `#[derive(SystemParam)]` to leak the types of private fields.
This commit is contained in:
parent
9ff111e24c
commit
8ca3d0462c
@ -411,7 +411,7 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let (_impl_generics, ty_generics, where_clause) = generics.split_for_impl();
|
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
|
||||||
|
|
||||||
let lifetimeless_generics: Vec<_> = generics
|
let lifetimeless_generics: Vec<_> = generics
|
||||||
.params
|
.params
|
||||||
@ -441,12 +441,6 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut punctuated_type_generic_idents = Punctuated::<_, Token![,]>::new();
|
|
||||||
punctuated_type_generic_idents.extend(lifetimeless_generics.iter().filter_map(|g| match g {
|
|
||||||
GenericParam::Type(g) => Some(&g.ident),
|
|
||||||
_ => None,
|
|
||||||
}));
|
|
||||||
|
|
||||||
let mut punctuated_generic_idents = Punctuated::<_, Token![,]>::new();
|
let mut punctuated_generic_idents = Punctuated::<_, Token![,]>::new();
|
||||||
punctuated_generic_idents.extend(lifetimeless_generics.iter().map(|g| match g {
|
punctuated_generic_idents.extend(lifetimeless_generics.iter().map(|g| match g {
|
||||||
GenericParam::Type(g) => &g.ident,
|
GenericParam::Type(g) => &g.ident,
|
||||||
@ -485,24 +479,21 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream {
|
|||||||
// The struct can still be accessed via SystemParam::State, e.g. EventReaderState can be accessed via
|
// The struct can still be accessed via SystemParam::State, e.g. EventReaderState can be accessed via
|
||||||
// <EventReader<'static, 'static, T> as SystemParam>::State
|
// <EventReader<'static, 'static, T> as SystemParam>::State
|
||||||
const _: () = {
|
const _: () = {
|
||||||
impl<'w, 's, #punctuated_generics> #path::system::SystemParam for #struct_name #ty_generics #where_clause {
|
impl #impl_generics #path::system::SystemParam for #struct_name #ty_generics #where_clause {
|
||||||
type State = State<'w, 's, #punctuated_generic_idents>;
|
type State = FetchState<'static, 'static, #punctuated_generic_idents>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
type State<'w, 's, #punctuated_generics_no_bounds> = FetchState<
|
#state_struct_visibility struct FetchState <'w, 's, #(#lifetimeless_generics,)*> {
|
||||||
(#(<#tuple_types as #path::system::SystemParam>::State,)*),
|
state: (#(<#tuple_types as #path::system::SystemParam>::State,)*),
|
||||||
#punctuated_generic_idents
|
marker: std::marker::PhantomData<(
|
||||||
>;
|
<#path::prelude::Query<'w, 's, ()> as #path::system::SystemParam>::State,
|
||||||
|
#(fn() -> #ignored_field_types,)*
|
||||||
#[doc(hidden)]
|
)>,
|
||||||
#state_struct_visibility struct FetchState <TSystemParamState, #punctuated_generics> {
|
|
||||||
state: TSystemParamState,
|
|
||||||
marker: std::marker::PhantomData<fn()->(#punctuated_type_generic_idents)>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<'__w, '__s, #punctuated_generics> #path::system::SystemParamState for
|
unsafe impl<#punctuated_generics> #path::system::SystemParamState for
|
||||||
State<'__w, '__s, #punctuated_generic_idents>
|
FetchState<'static, 'static, #punctuated_generic_idents>
|
||||||
#where_clause {
|
#where_clause {
|
||||||
type Item<'w, 's> = #struct_name #ty_generics;
|
type Item<'w, 's> = #struct_name #ty_generics;
|
||||||
|
|
||||||
|
|||||||
@ -1809,4 +1809,10 @@ mod tests {
|
|||||||
Res<'w, R>,
|
Res<'w, R>,
|
||||||
Local<'s, L>,
|
Local<'s, L>,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#[derive(Resource)]
|
||||||
|
struct PrivateResource;
|
||||||
|
|
||||||
|
#[derive(SystemParam)]
|
||||||
|
pub struct EncapsulatedParam<'w>(Res<'w, PrivateResource>);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user