This PR replaces type sets and the type parameters on SyncEditorBundle in order to simplify the API around registering types and to make compiler errors more readible. Previously, the errors produced when a registered component/resource didn't implement the correct trait were largely incomprehensible due to the complexity of the generated types:
With these changes, the compiler is able to more directly point to the line that registers the component/resource and point out exactly which trait isn't implemented:
error[E0277]: the trait bound `MyResource: amethyst::specs::Component` is not satisfied
--> src\lib.rs:59:19
|
25 | .tap(|bundle| sync_components!(bundle, MyComponent, MyResource))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `amethyst::specs::Component` is not implemented for `MyResource`
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
Internally, this change replaces the clever type-level lists that were being used to construct the lists of registered types with an alternate solution based on trait objects and type erasure. While this solution is regrettably not as runtime efficient as the former solution (in that it requires allocations and dynamic dispatch), it drastically simplifies the code and improves the ergonomics of compiler errors dramatically for users.
This PR replaces type sets and the type parameters on
SyncEditorBundle
in order to simplify the API around registering types and to make compiler errors more readible. Previously, the errors produced when a registered component/resource didn't implement the correct trait were largely incomprehensible due to the complexity of the generated types:With these changes, the compiler is able to more directly point to the line that registers the component/resource and point out exactly which trait isn't implemented:
Internally, this change replaces the clever type-level lists that were being used to construct the lists of registered types with an alternate solution based on trait objects and type erasure. While this solution is regrettably not as runtime efficient as the former solution (in that it requires allocations and dynamic dispatch), it drastically simplifies the code and improves the ergonomics of compiler errors dramatically for users.