-
-
Notifications
You must be signed in to change notification settings - Fork 3.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SystemParamBuilder - Enable type inference of closure parameter when building dynamic systems #14820
SystemParamBuilder - Enable type inference of closure parameter when building dynamic systems #14820
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good to see that there's a test and excellent internal docs, thank you.
pub fn build_system<Marker, F: SystemParamFunction<Marker, Param = Param>>( | ||
/// This method signature allows any system function, but the compiler will not perform type inference on closure parameters. | ||
/// You can use [`SystemState::build_system()`] or [`SystemState::build_system_with_input()`] to get type inference on parameters. | ||
pub fn build_any_system<Marker, F: SystemParamFunction<Marker, Param = Param>>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we're implementing build_system
for a FnMut<Param1, Param2, ...>
which calls build_any_system
, which is implemented for SystemParamFunction
and SystemParamFunction
is implemented for all FnMut<Param1, Param2...>
I get your overall logic to add type inference, but would there be a way to get rid of SystemParamFunction
altogether and just use macros everywhere to deal directly with FnMut<Param1, Param2...>
?
It seems weird to have this extra indirection.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SystemParamFunction
is the existing trait that powers FunctionSystem
. So I can't get rid of that!
I agree it's weird, but given that we need a SystemParamFunction
to make a system, I think this is the simplest way to make parameter type inference work in the current rust compiler.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like someone like @SkiFire13 would have a better opinion than mine
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that getting rid of SystemParamFunction
is likely not an option, as it power all the other system trait machinery. The duplicated FnMut
bounds on these methods do feel a bit unfortunate given that SystemParamFunction
's impl
s already have them (and twice!). However I don't think you can avoid them, as closure type inference is very finicky and requires a direct FnMut
bound on the function that the closure is passed to, which in this case is build_system
. So in the end:
SystemParamFunction
is needed for the existing system machinery (e.g.App::add_systems
)- the
FnMut
bounds here are needed because closure inference won't look at them if they are anywhere else
Oh BTW, before I merge this, do you want to try the |
I'm happy to try it! I don't expect it to work, though. I think that only works for trait impls, and this is a bunch of impl blocks. How do I test that? Just running |
Regardless, I'll merge this in as-is once merge conflicts are resolved :) |
…ilder-type-inference
You can build the docs with This should do the trick: RUSTFLAGS='--cfg docsrs_dep' RUSTDOCFLAGS='--cfg=docsrs' cargo +nightly doc If you don't want to remember the correct incantation there's a handy |
Let me know if you want to experiment more, or if I should merge this as is. If I don't hear back I'll merge this on Monday :) |
Nope, putting the attribute on the
so I don't think it will work for this. (And the reason I had trouble before is that I forgot how to set environment variables in PowerShell :).) I can make it work for |
Objective
When building a system from
SystemParamBuilder
s and defining the system as a closure, the compiler should be able to infer the parameter types from the builder types.Solution
Create methods for each arity that take an argument that implements both
SystemParamFunction
as well asFnMut(SystemParamItem<P>,...)
. The explicitFnMut
constraint will allow the compiler to infer the necessary higher-ranked lifetimes along with the parameter types.I wanted to show that this was possible, but I can't tell whether it's worth the complexity. It requires a separate method for each arity, which pollutes the docs a bit:

Example