bevy/crates/bevy_asset/src
Gino Valente 379b9e5cb6
bevy_reflect: Split #[reflect(where)] (#11597)
# Objective

Revert the changes to type parameter bounds introduced in #9046,
improves the `#[reflect(where)]` attribute (also from #9046), and adds
the ability to opt out of field bounds.

This is based on suggestions by @soqb and discussion on
[Discord](https://discord.com/channels/691052431525675048/1002362493634629796/1201227833826103427).

## Solution

Reverts the changes to type parameter bounds when deriving `Reflect`,
introduced in #9046. This was originally done as a means of fixing a
recursion issue (#8965). However, as @soqb pointed out, we could achieve
the same result by simply making an opt-out attribute instead of messing
with the type parameter bounds.

This PR has four main changes:
1. Reverts the type parameter bounds from #9046
2. Includes `TypePath` as a default bound for active fields
3. Changes `#reflect(where)]` to be strictly additive
4. Adds `#reflect(no_field_bounds)]` to opt out of field bounds

Change 1 means that, like before, type parameters only receive at most
the `TypePath` bound (if `#[reflect(type_path = false)]` is not present)
and active fields receive the `Reflect` or `FromReflect` bound. And with
Change 2, they will also receive `TypePath` (since it's indirectly
required by `Typed` to construct `NamedField` and `UnnamedField`
instances).

Change 3 was made to make room for Change 4. By splitting out the
responsibility of `#reflect(where)]`, we can use it with or without
`#reflect(no_field_bounds)]` for various use cases.

For example, if we hadn't done this, the following would have failed:

```rust
// Since we're not using `#reflect(no_field_bounds)]`, 
// `T::Assoc` is automatically given the required bounds
// of `FromReflect + TypePath`
#[derive(Reflect)]
#[reflect(where T::Assoc: OtherTrait)]
struct Foo<T: MyTrait> {
  value: T::Assoc,
}
```

This provides more flexibility to the user while still letting them add
or remove most trait bounds.

And to solve the original recursion issue, we can do:

```rust
#[derive(Reflect)]
#[reflect(no_field_bounds)] // <-- Added
struct Foo {
  foo: Vec<Foo>
}
```

#### Bounds

All in all, we now have four sets of trait bounds:
- `Self` gets the bounds `Any + Send + Sync`
- Type parameters get the bound `TypePath`. This can be opted out of
with `#[reflect(type_path = false)]`
- Active fields get the bounds `TypePath` and `FromReflect`/`Reflect`
bounds. This can be opted out of with `#reflect(no_field_bounds)]`
- Custom bounds can be added with `#[reflect(where)]`

---

## Changelog

- Revert some changes #9046
- `#reflect(where)]` is now strictly additive
- Added `#reflect(no_field_bounds)]` attribute to opt out of automatic
field trait bounds when deriving `Reflect`
- Made the `TypePath` requirement on fields when deriving `Reflect` more
explicit

## Migration Guide

> [!important]
> This PR shouldn't be a breaking change relative to the current version
of Bevy (v0.12). And since it removes the breaking parts of #9046, that
PR also won't need a migration guide.
2024-01-29 17:54:17 +00:00
..
io Fix documentation for AssetReader::is_directory function (#11538) 2024-01-26 13:55:36 +00:00
processor AssetSaver and AssetTransformer split (#11260) 2024-01-26 20:20:58 +00:00
server Add a getter for asset watching status on AssetServer (#11578) 2024-01-28 20:15:14 +00:00
assets.rs Remove TypeUuid (#11497) 2024-01-25 16:16:58 +00:00
event.rs Added AssetLoadFailedEvent, UntypedAssetLoadFailedEvent (#11369) 2024-01-17 21:12:00 +00:00
folder.rs Bevy Asset V2 (#8624) 2023-09-07 02:07:27 +00:00
handle.rs bevy_reflect: Split #[reflect(where)] (#11597) 2024-01-29 17:54:17 +00:00
id.rs bevy_reflect: Split #[reflect(where)] (#11597) 2024-01-29 17:54:17 +00:00
lib.rs AssetSaver and AssetTransformer split (#11260) 2024-01-26 20:20:58 +00:00
loader.rs AssetSaver and AssetTransformer split (#11260) 2024-01-26 20:20:58 +00:00
meta.rs Reorder impl to be the same as the trait (#11076) 2023-12-24 17:43:55 +00:00
path.rs AssetPath source parse fix (#11543) 2024-01-26 21:23:06 +00:00
reflect.rs Enable the unsafe_op_in_unsafe_fn lint (#11591) 2024-01-28 23:18:11 +00:00
saver.rs Make AssetLoader/Saver Error type bounds compatible with anyhow::Error (#10493) 2023-11-14 01:25:06 +00:00
transformer.rs AssetSaver and AssetTransformer split (#11260) 2024-01-26 20:20:58 +00:00