# Objective
I found a bug while working on #17871. When required components are
registered, ones that are more specific (smaller inheritance depth) are
preferred to others. So, if a ComponentA is already required, but it is
registered as required again, it will be updated if and only if the new
requirement has a smaller inheritance depth (is more specific). However,
this logic was not reflected in merging `RequriedComponents`s together.
Hence, for complicated requirement trees, the wrong initializer could be
used.
## Solution
Re-write merging to work by extending the collection via
`require_dynamic` instead of blindly combining the inner storage.
## Testing
I created this test to ensure this bug doesn't creep back in. This test
fails on main, but passes on this branch.
```rs
#[test]
fn required_components_inheritance_depth_bias() {
#[derive(Component, PartialEq, Eq, Clone, Copy, Debug)]
struct MyRequired(bool);
#[derive(Component, Default)]
#[require(MyRequired(|| MyRequired(false)))]
struct MiddleMan;
#[derive(Component, Default)]
#[require(MiddleMan)]
struct ConflictingRequire;
#[derive(Component, Default)]
#[require(MyRequired(|| MyRequired(true)))]
struct MyComponent;
let mut world = World::new();
let order_a = world
.spawn((ConflictingRequire, MyComponent))
.get::<MyRequired>()
.cloned();
let order_b = world
.spawn((MyComponent, ConflictingRequire))
.get::<MyRequired>()
.cloned();
assert_eq!(order_a, Some(MyRequired(true)));
assert_eq!(order_b, Some(MyRequired(true)));
}
```
Note that when the inheritance depth is 0 (Like if there were no middle
man above), the order of the components in the bundle still matters.
## Migration Guide
`RequiredComponents::register_dynamic` has been changed to
`RequiredComponents::register_dynamic_with`.
Old:
```rust
required_components.register_dynamic(
component_id,
component_constructor.clone(),
requirement_inheritance_depth,
);
```
New:
```rust
required_components.register_dynamic_with(
component_id,
requirement_inheritance_depth,
|| component_constructor.clone(),
);
```
This can prevent unnecessary cloning.
---------
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
Co-authored-by: Joona Aalto <jondolf.dev@gmail.com>