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 | ||||
|         .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(); | ||||
|     punctuated_generic_idents.extend(lifetimeless_generics.iter().map(|g| match g { | ||||
|         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
 | ||||
|         // <EventReader<'static, 'static, T> as SystemParam>::State
 | ||||
|         const _: () = { | ||||
|             impl<'w, 's, #punctuated_generics> #path::system::SystemParam for #struct_name #ty_generics #where_clause { | ||||
|                 type State = State<'w, 's, #punctuated_generic_idents>; | ||||
|             impl #impl_generics #path::system::SystemParam for #struct_name #ty_generics #where_clause { | ||||
|                 type State = FetchState<'static, 'static, #punctuated_generic_idents>; | ||||
|             } | ||||
| 
 | ||||
|             #[doc(hidden)] | ||||
|             type State<'w, 's, #punctuated_generics_no_bounds> = FetchState< | ||||
|                 (#(<#tuple_types as #path::system::SystemParam>::State,)*), | ||||
|                 #punctuated_generic_idents | ||||
|             >; | ||||
| 
 | ||||
|             #[doc(hidden)] | ||||
|             #state_struct_visibility struct FetchState <TSystemParamState, #punctuated_generics> { | ||||
|                 state: TSystemParamState, | ||||
|                 marker: std::marker::PhantomData<fn()->(#punctuated_type_generic_idents)> | ||||
|             #state_struct_visibility struct FetchState <'w, 's, #(#lifetimeless_generics,)*> { | ||||
|                 state: (#(<#tuple_types as #path::system::SystemParam>::State,)*), | ||||
|                 marker: std::marker::PhantomData<( | ||||
|                     <#path::prelude::Query<'w, 's, ()> as #path::system::SystemParam>::State, | ||||
|                     #(fn() -> #ignored_field_types,)* | ||||
|                 )>, | ||||
|             } | ||||
| 
 | ||||
|             unsafe impl<'__w, '__s, #punctuated_generics> #path::system::SystemParamState for | ||||
|                 State<'__w, '__s, #punctuated_generic_idents> | ||||
|             unsafe impl<#punctuated_generics> #path::system::SystemParamState for | ||||
|                 FetchState<'static, 'static, #punctuated_generic_idents> | ||||
|             #where_clause { | ||||
|                 type Item<'w, 's> = #struct_name #ty_generics; | ||||
| 
 | ||||
|  | ||||
| @ -1809,4 +1809,10 @@ mod tests { | ||||
|         Res<'w, R>, | ||||
|         Local<'s, L>, | ||||
|     ); | ||||
| 
 | ||||
|     #[derive(Resource)] | ||||
|     struct PrivateResource; | ||||
| 
 | ||||
|     #[derive(SystemParam)] | ||||
|     pub struct EncapsulatedParam<'w>(Res<'w, PrivateResource>); | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 JoJoJet
						JoJoJet