@@ -173,13 +173,20 @@ impl<Param: SystemParam> SystemState<Param> {
173
173
///
174
174
/// let system = my_system_function.system();
175
175
/// ```
176
- pub trait IntoSystem < Params , SystemType : System > {
176
+ // This trait has to be generic because we have potentially overlapping impls, in particular
177
+ // because Rust thinks a type could impl multiple different `FnMut` combinations
178
+ // even though none can currently
179
+ pub trait IntoSystem < In , Out , Params > {
180
+ type System : System < In = In , Out = Out > ;
177
181
/// Turns this value into its corresponding [`System`].
178
- fn system ( self ) -> SystemType ;
182
+ fn system ( self ) -> Self :: System ;
179
183
}
180
184
185
+ pub struct AlreadyWasSystem ;
186
+
181
187
// Systems implicitly implement IntoSystem
182
- impl < Sys : System > IntoSystem < ( ) , Sys > for Sys {
188
+ impl < In , Out , Sys : System < In = In , Out = Out > > IntoSystem < In , Out , AlreadyWasSystem > for Sys {
189
+ type System = Sys ;
183
190
fn system ( self ) -> Sys {
184
191
self
185
192
}
@@ -256,16 +263,18 @@ impl<In, Out, Param: SystemParam, Marker, F> FunctionSystem<In, Out, Param, Mark
256
263
self
257
264
}
258
265
}
266
+ pub struct IsFunctionSystem ;
259
267
260
- impl < In , Out , Param , Marker , F > IntoSystem < Param , FunctionSystem < In , Out , Param , Marker , F > > for F
268
+ impl < In , Out , Param , Marker , F > IntoSystem < In , Out , ( IsFunctionSystem , Param , Marker ) > for F
261
269
where
262
270
In : ' static ,
263
271
Out : ' static ,
264
272
Param : SystemParam + ' static ,
265
273
Marker : ' static ,
266
274
F : SystemParamFunction < In , Out , Param , Marker > + Send + Sync + ' static ,
267
275
{
268
- fn system ( self ) -> FunctionSystem < In , Out , Param , Marker , F > {
276
+ type System = FunctionSystem < In , Out , Param , Marker , F > ;
277
+ fn system ( self ) -> Self :: System {
269
278
FunctionSystem {
270
279
func : self ,
271
280
param_state : None ,
@@ -376,30 +385,47 @@ pub trait SystemParamFunction<In, Out, Param: SystemParam, Marker>: Send + Sync
376
385
macro_rules! impl_system_function {
377
386
( $( $param: ident) ,* ) => {
378
387
#[ allow( non_snake_case) ]
379
- impl <Out , Func , $( $param: SystemParam ) ,* > SystemParamFunction <( ) , Out , ( $( $param, ) * ) , ( ) > for Func
388
+ impl <Out , Func : Send + Sync + ' static , $( $param: SystemParam ) ,* > SystemParamFunction <( ) , Out , ( $( $param, ) * ) , ( ) > for Func
380
389
where
381
- Func :
390
+ for < ' a> & ' a mut Func :
382
391
FnMut ( $( $param) ,* ) -> Out +
383
- FnMut ( $( <<$param as SystemParam >:: Fetch as SystemParamFetch >:: Item ) ,* ) -> Out + Send + Sync + ' static , Out : ' static
392
+ FnMut ( $( <<$param as SystemParam >:: Fetch as SystemParamFetch >:: Item ) ,* ) -> Out , Out : ' static
384
393
{
385
394
#[ inline]
386
395
unsafe fn run( & mut self , _input: ( ) , state: & mut <( $( $param, ) * ) as SystemParam >:: Fetch , system_meta: & SystemMeta , world: & World , change_tick: u32 ) -> Out {
396
+ // Yes, this is strange, but rustc fails to compile this impl
397
+ // without using this function.
398
+ #[ allow( clippy:: too_many_arguments) ]
399
+ fn call_inner<Out , $( $param, ) * >(
400
+ mut f: impl FnMut ( $( $param, ) * ) ->Out ,
401
+ $( $param: $param, ) *
402
+ ) ->Out {
403
+ f( $( $param, ) * )
404
+ }
387
405
let ( $( $param, ) * ) = <<( $( $param, ) * ) as SystemParam >:: Fetch as SystemParamFetch >:: get_param( state, system_meta, world, change_tick) ;
388
- self ( $( $param) ,* )
406
+ call_inner ( self , $( $param) ,* )
389
407
}
390
408
}
391
409
392
410
#[ allow( non_snake_case) ]
393
- impl <Input , Out , Func , $( $param: SystemParam ) ,* > SystemParamFunction <Input , Out , ( $( $param, ) * ) , InputMarker > for Func
411
+ impl <Input , Out , Func : Send + Sync + ' static , $( $param: SystemParam ) ,* > SystemParamFunction <Input , Out , ( $( $param, ) * ) , InputMarker > for Func
394
412
where
395
- Func :
413
+ for < ' a> & ' a mut Func :
396
414
FnMut ( In <Input >, $( $param) ,* ) -> Out +
397
- FnMut ( In <Input >, $( <<$param as SystemParam >:: Fetch as SystemParamFetch >:: Item ) ,* ) -> Out + Send + Sync + ' static , Out : ' static
415
+ FnMut ( In <Input >, $( <<$param as SystemParam >:: Fetch as SystemParamFetch >:: Item ) ,* ) -> Out , Out : ' static
398
416
{
399
417
#[ inline]
400
418
unsafe fn run( & mut self , input: Input , state: & mut <( $( $param, ) * ) as SystemParam >:: Fetch , system_meta: & SystemMeta , world: & World , change_tick: u32 ) -> Out {
419
+ #[ allow( clippy:: too_many_arguments) ]
420
+ fn call_inner<Input , Out , $( $param, ) * >(
421
+ mut f: impl FnMut ( In <Input >, $( $param, ) * ) ->Out ,
422
+ input: In <Input >,
423
+ $( $param: $param, ) *
424
+ ) ->Out {
425
+ f( input, $( $param, ) * )
426
+ }
401
427
let ( $( $param, ) * ) = <<( $( $param, ) * ) as SystemParam >:: Fetch as SystemParamFetch >:: get_param( state, system_meta, world, change_tick) ;
402
- self ( In ( input) , $( $param) ,* )
428
+ call_inner ( self , In ( input) , $( $param) ,* )
403
429
}
404
430
}
405
431
} ;
0 commit comments