Commit Graph

20 Commits

Author SHA1 Message Date
Zachary Harrold
bf765e61b5
Add no_std support to bevy_reflect (#16256)
# Objective

- Contributes to #15460

## Solution

- Added `std` feature (enabled by default)

## Testing

- CI
- `cargo check -p bevy_reflect --no-default-features --target
"x86_64-unknown-none"`
- UEFI demo application runs with this branch of `bevy_reflect`,
allowing `derive(Reflect)`

## Notes

- The [`spin`](https://crates.io/crates/spin) crate has been included to
provide `RwLock` and `Once` (as an alternative to `OnceLock`) when the
`std` feature is not enabled. Another alternative may be more desirable,
please provide feedback if you have a strong opinion here!
- Certain items (`Box`, `String`, `ToString`) provided by `alloc` have
been added to `__macro_exports` as a way to avoid `alloc` vs `std`
namespacing. I'm personally quite annoyed that we can't rely on `alloc`
as a crate name in `std` environments within macros. I'd love an
alternative to my approach here, but I suspect it's the least-bad
option.
- I would've liked to have an `alloc` feature (for allocation-free
`bevy_reflect`), unfortunately, `erased_serde` unconditionally requires
access to `Box`. Maybe one day we could design around this, but for now
it just means `bevy_reflect` requires `alloc`.

---------

Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-12-05 21:15:21 +00:00
Zachary Harrold
3cc1527e9e
Remove thiserror from bevy_reflect (#15766)
# Objective

- Contributes to #15460

## Solution

- Removed `thiserror` from `bevy_reflect`
2024-10-09 14:25:41 +00:00
Zachary Harrold
d70595b667
Add core and alloc over std Lints (#15281)
# Objective

- Fixes #6370
- Closes #6581

## Solution

- Added the following lints to the workspace:
  - `std_instead_of_core`
  - `std_instead_of_alloc`
  - `alloc_instead_of_core`
- Used `cargo +nightly fmt` with [item level use
formatting](https://rust-lang.github.io/rustfmt/?version=v1.6.0&search=#Item%5C%3A)
to split all `use` statements into single items.
- Used `cargo clippy --workspace --all-targets --all-features --fix
--allow-dirty` to _attempt_ to resolve the new linting issues, and
intervened where the lint was unable to resolve the issue automatically
(usually due to needing an `extern crate alloc;` statement in a crate
root).
- Manually removed certain uses of `std` where negative feature gating
prevented `--all-features` from finding the offending uses.
- Used `cargo +nightly fmt` with [crate level use
formatting](https://rust-lang.github.io/rustfmt/?version=v1.6.0&search=#Crate%5C%3A)
to re-merge all `use` statements matching Bevy's previous styling.
- Manually fixed cases where the `fmt` tool could not re-merge `use`
statements due to conditional compilation attributes.

## Testing

- Ran CI locally

## Migration Guide

The MSRV is now 1.81. Please update to this version or higher.

## Notes

- This is a _massive_ change to try and push through, which is why I've
outlined the semi-automatic steps I used to create this PR, in case this
fails and someone else tries again in the future.
- Making this change has no impact on user code, but does mean Bevy
contributors will be warned to use `core` and `alloc` instead of `std`
where possible.
- This lint is a critical first step towards investigating `no_std`
options for Bevy.

---------

Co-authored-by: François Mockers <francois.mockers@vleue.com>
2024-09-27 00:59:59 +00:00
Clar Fon
efda7f3f9c
Simpler lint fixes: makes ci lints work but disables a lint for now (#15376)
Takes the first two commits from #15375 and adds suggestions from this
comment:
https://github.com/bevyengine/bevy/pull/15375#issuecomment-2366968300

See #15375 for more reasoning/motivation.

## Rebasing (rerunning)

```rust
git switch simpler-lint-fixes
git reset --hard main
cargo fmt --all -- --unstable-features --config normalize_comments=true,imports_granularity=Crate
cargo fmt --all
git add --update
git commit --message "rustfmt"
cargo clippy --workspace --all-targets --all-features --fix
cargo fmt --all -- --unstable-features --config normalize_comments=true,imports_granularity=Crate
cargo fmt --all
git add --update
git commit --message "clippy"
git cherry-pick e6c0b94f6795222310fb812fa5c4512661fc7887
```
2024-09-24 11:42:59 +00:00
VitalyR
661ab1ab41
Fix warnings triggered by elided_named_lifetimes lint (#15328)
# Objective

Eliminate some warnings introduced by the new rust lint
[elided_named_lifetimes](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/builtin/static.ELIDED_NAMED_LIFETIMES.html),
fix #15326.

## Solution

- Add or remove lifetime markers to not trigger the lint.

## Testing

- When the lint comes to stable, the CI will fail and this PR could fix
that.
2024-09-20 19:17:33 +00:00
Cole Varner
cf55e6cb22
ParsedPath::try_from<&str> (#15180)
# Objective

- implements ParsedPath::try_from<&str>
- resolves #14438

## Testing

- Added unit test for ParsedPath::try_from<&str>

Note: I don't claim to be an expert on lifetimes! That said I think it
makes sense that the error shares a lifetime with input string as deeper
down it is used to construct it.
2024-09-13 17:37:09 +00:00
Gino Valente
245d03a78a
bevy_reflect: Update on_unimplemented attributes (#15110)
# Objective

Some of the new compile error messages are a little unclear (at least to
me). For example:

```
error[E0277]: `tests::foo::Bar` can not be created through reflection
   --> crates/bevy_reflect/src/lib.rs:679:18
    |
679 |         #[derive(Reflect)]
    |                  ^^^^^^^ the trait `from_reflect::FromReflect` is not implemented for `tests::foo::Bar`
    |
    = note: consider annotating `tests::foo::Bar` with `#[derive(Reflect)]` or `#[derive(FromReflect)]`
```

While the annotation makes it clear that `FromReflect` is missing, it's
not very clear from the main error message.

My IDE lists errors with only their message immediately present:

<p align="center">
<img width="700" alt="Image of said IDE listing errors with only their
message immediately present. These errors are as follows:
\"`tests::foo::Bar` can not be created through reflection\", \"The trait
bound `tests::foo::Bar: RegisterForReflection` is not satisfied\", and
\"The trait bound `tests::foo::Bar: type_info::MaybeTyped` is not
satisfied\""
src="https://github.com/user-attachments/assets/42c24051-9e8e-4555-8477-51a9407446aa">
</p>

This makes it hard to tell at a glance why my code isn't compiling.

## Solution

Updated all `on_unimplemented` attributes in `bevy_reflect` to mention
the relevant trait—either the actual trait or the one users actually
need to implement—as well as a small snippet of what not implementing
them means.

For example, failing to implement `TypePath` now mentions missing a
`TypePath` implementation. And failing to implement `DynamicTypePath`
now also mentions missing a `TypePath` implementation, since that's the
actual trait users need to implement (i.e. they shouldn't implement
`DynamicTypePath` directly).

Lastly, I also added some missing `on_unimplemented` attributes for
`MaybeTyped` and `RegisterForReflection` (which you can see in the image
above).

Here's how this looks in my IDE now:

<p align="center">
<img width="700" alt="Similar image as before showing the errors listed
by the IDE. This time the errors read as follows: \"`tests::foo::Bar`
does not implement `FromReflect` so cannot be reified through
reflection\", \"`tests::foo::Bar` does not implement
`GetTypeRegistration` so cannot be registered for reflection\", and
\"`tests::foo::Bar` does not implement `Typed` so cannot provide static
type information\""
src="https://github.com/user-attachments/assets/f6f8501f-0450-4f78-b84f-00e7a18d0533">
</p>


## Testing

You can test by adding the following code and verifying the compile
errors are correct:

```rust
#[derive(Reflect)]
struct Foo(Bar);

struct Bar;
```
2024-09-09 16:26:17 +00:00
radiish
6ab8767d3b
reflect: implement the unique reflect rfc (#7207)
# Objective

- Implements the [Unique Reflect
RFC](https://github.com/nicopap/rfcs/blob/bevy-reflect-api/rfcs/56-better-reflect.md).

## Solution

- Implements the RFC.
- This implementation differs in some ways from the RFC:
- In the RFC, it was suggested `Reflect: Any` but `PartialReflect:
?Any`. During initial implementation I tried this, but we assume the
`PartialReflect: 'static` in a lot of places and the changes required
crept out of the scope of this PR.
- `PartialReflect::try_into_reflect` originally returned `Option<Box<dyn
Reflect>>` but i changed this to `Result<Box<dyn Reflect>, Box<dyn
PartialReflect>>` since the method takes by value and otherwise there
would be no way to recover the type. `as_full` and `as_full_mut` both
still return `Option<&(mut) dyn Reflect>`.

---

## Changelog

- Added `PartialReflect`.
- `Reflect` is now a subtrait of `PartialReflect`.
- Moved most methods on `Reflect` to the new `PartialReflect`.
- Added `PartialReflect::{as_partial_reflect, as_partial_reflect_mut,
into_partial_reflect}`.
- Added `PartialReflect::{try_as_reflect, try_as_reflect_mut,
try_into_reflect}`.
- Added `<dyn PartialReflect>::{try_downcast_ref, try_downcast_mut,
try_downcast, try_take}` supplementing the methods on `dyn Reflect`.

## Migration Guide

- Most instances of `dyn Reflect` should be changed to `dyn
PartialReflect` which is less restrictive, however trait bounds should
generally stay as `T: Reflect`.
- The new `PartialReflect::{as_partial_reflect, as_partial_reflect_mut,
into_partial_reflect, try_as_reflect, try_as_reflect_mut,
try_into_reflect}` methods as well as `Reflect::{as_reflect,
as_reflect_mut, into_reflect}` will need to be implemented for manual
implementors of `Reflect`.

## Future Work

- This PR is designed to be followed up by another "Unique Reflect Phase
2" that addresses the following points:
- Investigate making serialization revolve around `Reflect` instead of
`PartialReflect`.
- [Remove the `try_*` methods on `dyn PartialReflect` since they are
stop
gaps](https://github.com/bevyengine/bevy/pull/7207#discussion_r1083476050).
- Investigate usages like `ReflectComponent`. In the places they
currently use `PartialReflect`, should they be changed to use `Reflect`?
- Merging this opens the door to lots of reflection features we haven't
been able to implement.
- We could re-add [the `Reflectable`
trait](8e3488c880/crates/bevy_reflect/src/reflect.rs (L337-L342))
and make `FromReflect` a requirement to improve [`FromReflect`
ergonomics](https://github.com/bevyengine/rfcs/pull/59). This is
currently not possible because dynamic types cannot sensibly be
`FromReflect`.
  - Since this is an alternative to #5772, #5781 would be made cleaner.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
2024-08-12 17:01:41 +00:00
Alice Cecile
ec7b3490f6
Add on_unimplemented Diagnostics to Most Public Traits (#13347) (#13662)
# Objective

- #13414 did not have the intended effect.
- #13404 is still blocked

## Solution

- Re-adds #13347.

Co-authored-by: Zachary Harrold <zac@harrold.com.au>
Co-authored-by: Jamie Ridding <Themayu@users.noreply.github.com>
Co-authored-by: BD103 <59022059+BD103@users.noreply.github.com>
2024-06-04 00:31:34 +00:00
Alice Cecile
ee6dfd35c9
Revert "Add on_unimplemented Diagnostics to Most Public Traits" (#13413)
# Objective

- Rust 1.78 breaks all Android support, see
https://github.com/bevyengine/bevy/issues/13331
- We should not bump the MSRV to 1.78 until that's resolved in #13366.

## Solution

- Temporarily revert https://github.com/bevyengine/bevy/pull/13347

Co-authored-by: Alice Cecile <alice.i.cecil@gmail.com>
2024-05-17 17:00:43 +00:00
Zachary Harrold
11f0a2dcde
Add on_unimplemented Diagnostics to Most Public Traits (#13347)
# Objective

- Fixes #12377

## Solution

Added simple `#[diagnostic::on_unimplemented(...)]` attributes to some
critical public traits providing a more approachable initial error
message. Where appropriate, a `note` is added indicating that a `derive`
macro is available.

## Examples

<details>
<summary>Examples hidden for brevity</summary>

Below is a collection of examples showing the new error messages
produced by this change. In general, messages will start with a more
Bevy-centric error message (e.g., _`MyComponent` is not a `Component`_),
and a note directing the user to an available derive macro where
appropriate.

### Missing `#[derive(Resource)]`

<details>
<summary>Example Code</summary>

```rust
use bevy::prelude::*;

struct MyResource;

fn main() {
    App::new()
        .insert_resource(MyResource)
        .run();
}
```

</details>

<details>
<summary>Error Generated</summary>

```error
error[E0277]: `MyResource` is not a `Resource`
   --> examples/app/empty.rs:7:26
    |
7   |         .insert_resource(MyResource)
    |          --------------- ^^^^^^^^^^ invalid `Resource`
    |          |
    |          required by a bound introduced by this call
    |
    = help: the trait `Resource` is not implemented for `MyResource`       
    = note: consider annotating `MyResource` with `#[derive(Resource)]`    
    = help: the following other types implement trait `Resource`:
              AccessibilityRequested
              ManageAccessibilityUpdates
              bevy::bevy_a11y::Focus
              DiagnosticsStore
              FrameCount
              bevy::prelude::State<S>
              SystemInfo
              bevy::prelude::Axis<T>
            and 141 others
note: required by a bound in `bevy::prelude::App::insert_resource`
   --> C:\Users\Zac\Documents\GitHub\bevy\crates\bevy_app\src\app.rs:419:31
    |
419 |     pub fn insert_resource<R: Resource>(&mut self, resource: R) -> &mut Self {
    |                               ^^^^^^^^ required by this bound in `App::insert_resource`
```

</details>

### Putting A `QueryData` in a `QueryFilter` Slot

<details>
<summary>Example Code</summary>

```rust
use bevy::prelude::*;

#[derive(Component)]
struct A;

#[derive(Component)]
struct B;

fn my_system(_query: Query<&A, &B>) {}

fn main() {
    App::new()
        .add_systems(Update, my_system)
        .run();
}
```

</details>

<details>
<summary>Error Generated</summary>

```error
error[E0277]: `&B` is not a valid `Query` filter
   --> examples/app/empty.rs:9:22
    |
9   | fn my_system(_query: Query<&A, &B>) {}
    |                      ^^^^^^^^^^^^^ invalid `Query` filter
    |
    = help: the trait `QueryFilter` is not implemented for `&B`
    = help: the following other types implement trait `QueryFilter`:
              With<T>
              Without<T>
              bevy::prelude::Or<()>
              bevy::prelude::Or<(F0,)>
              bevy::prelude::Or<(F0, F1)>
              bevy::prelude::Or<(F0, F1, F2)>
              bevy::prelude::Or<(F0, F1, F2, F3)>
              bevy::prelude::Or<(F0, F1, F2, F3, F4)>
            and 28 others
note: required by a bound in `bevy::prelude::Query`
   --> C:\Users\Zac\Documents\GitHub\bevy\crates\bevy_ecs\src\system\query.rs:349:51
    |
349 | pub struct Query<'world, 'state, D: QueryData, F: QueryFilter = ()> {
    |                                                   ^^^^^^^^^^^ required by this bound in `Query`
```

</details>

### Missing `#[derive(Component)]`

<details>
<summary>Example Code</summary>

```rust
use bevy::prelude::*;

struct A;

fn my_system(mut commands: Commands) {
    commands.spawn(A);
}

fn main() {
    App::new()
        .add_systems(Startup, my_system)
        .run();
}
```

</details>

<details>
<summary>Error Generated</summary>

```error
error[E0277]: `A` is not a `Bundle`
   --> examples/app/empty.rs:6:20
    |
6   |     commands.spawn(A);
    |              ----- ^ invalid `Bundle`
    |              |
    |              required by a bound introduced by this call
    |
    = help: the trait `bevy::prelude::Component` is not implemented for `A`, which is required by `A: Bundle`
    = note: consider annotating `A` with `#[derive(Component)]` or `#[derive(Bundle)]`
    = help: the following other types implement trait `Bundle`:
              TransformBundle
              SceneBundle
              DynamicSceneBundle
              AudioSourceBundle<Source>
              SpriteBundle
              SpriteSheetBundle
              Text2dBundle
              MaterialMesh2dBundle<M>
            and 34 others
    = note: required for `A` to implement `Bundle`
note: required by a bound in `bevy::prelude::Commands::<'w, 's>::spawn`
   --> C:\Users\Zac\Documents\GitHub\bevy\crates\bevy_ecs\src\system\commands\mod.rs:243:21
    |
243 |     pub fn spawn<T: Bundle>(&mut self, bundle: T) -> EntityCommands {
    |                     ^^^^^^ required by this bound in `Commands::<'w, 's>::spawn`
```

</details>

### Missing `#[derive(Asset)]`

<details>
<summary>Example Code</summary>

```rust
use bevy::prelude::*;

struct A;

fn main() {
    App::new()
        .init_asset::<A>()
        .run();
}
```

</details>

<details>
<summary>Error Generated</summary>

```error
error[E0277]: `A` is not an `Asset`
   --> examples/app/empty.rs:7:23
    |
7   |         .init_asset::<A>()
    |          ----------   ^ invalid `Asset`
    |          |
    |          required by a bound introduced by this call
    |
    = help: the trait `Asset` is not implemented for `A`
    = note: consider annotating `A` with `#[derive(Asset)]`
    = help: the following other types implement trait `Asset`:
              Font
              AnimationGraph
              DynamicScene
              Scene
              AudioSource
              Pitch
              bevy::bevy_gltf::Gltf
              GltfNode
            and 17 others
note: required by a bound in `init_asset`
   --> C:\Users\Zac\Documents\GitHub\bevy\crates\bevy_asset\src\lib.rs:307:22
    |
307 |     fn init_asset<A: Asset>(&mut self) -> &mut Self;
    |                      ^^^^^ required by this bound in `AssetApp::init_asset`
```

</details>

### Mismatched Input and Output on System Piping

<details>
<summary>Example Code</summary>

```rust
use bevy::prelude::*;

fn producer() -> u32 {
    123
}

fn consumer(_: In<u16>) {}

fn main() {
    App::new()
        .add_systems(Update, producer.pipe(consumer))
        .run();
}
```

</details>

<details>
<summary>Error Generated</summary>

```error
error[E0277]: `fn(bevy::prelude::In<u16>) {consumer}` is not a valid system with input `u32` and output `_`
   --> examples/app/empty.rs:11:44
    |
11  |         .add_systems(Update, producer.pipe(consumer))
    |                                       ---- ^^^^^^^^ invalid system
    |                                       |
    |                                       required by a bound introduced by this call
    |
    = help: the trait `bevy::prelude::IntoSystem<u32, _, _>` is not implemented for fn item `fn(bevy::prelude::In<u16>) {consumer}`
    = note: expecting a system which consumes `u32` and produces `_`
note: required by a bound in `pipe`
   --> C:\Users\Zac\Documents\GitHub\bevy\crates\bevy_ecs\src\system\mod.rs:168:12
    |
166 |     fn pipe<B, Final, MarkerB>(self, system: B) -> PipeSystem<Self::System, B::System>
    |        ---- required by a bound in this associated function
167 |     where
168 |         B: IntoSystem<Out, Final, MarkerB>,
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `IntoSystem::pipe`
```

</details>

### Missing Reflection

<details>
<summary>Example Code</summary>

```rust
use bevy::prelude::*;

#[derive(Component)]
struct MyComponent;

fn main() {
    App::new()
        .register_type::<MyComponent>()
        .run();
}
```

</details>

<details>
<summary>Error Generated</summary>

```error
error[E0277]: `MyComponent` does not provide type registration information
   --> examples/app/empty.rs:8:26
    |
8   |         .register_type::<MyComponent>()
    |          -------------   ^^^^^^^^^^^ the trait `GetTypeRegistration` is not implemented for `MyComponent`
    |          |
    |          required by a bound introduced by this call
    |
    = note: consider annotating `MyComponent` with `#[derive(Reflect)]`
    = help: the following other types implement trait `GetTypeRegistration`:
              bool
              char
              isize
              i8
              i16
              i32
              i64
              i128
            and 443 others
note: required by a bound in `bevy::prelude::App::register_type`
   --> C:\Users\Zac\Documents\GitHub\bevy\crates\bevy_app\src\app.rs:619:29
    |
619 |     pub fn register_type<T: bevy_reflect::GetTypeRegistration>(&mut self) -> &mut Self {
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `App::register_type`
```

</details>

### Missing `#[derive(States)]` Implementation

<details>
<summary>Example Code</summary>

```rust
use bevy::prelude::*;

#[derive(Debug, Clone, Copy, Default, Eq, PartialEq, Hash)]
enum AppState {
    #[default]
    Menu,
    InGame {
        paused: bool,
        turbo: bool,
    },
}

fn main() {
    App::new()
        .init_state::<AppState>()
        .run();
}
```

</details>

<details>
<summary>Error Generated</summary>

```error
error[E0277]: the trait bound `AppState: FreelyMutableState` is not satisfied
   --> examples/app/empty.rs:15:23
    |
15  |         .init_state::<AppState>()
    |          ----------   ^^^^^^^^ the trait `FreelyMutableState` is not implemented for `AppState`
    |          |
    |          required by a bound introduced by this call
    |
    = note: consider annotating `AppState` with `#[derive(States)]`
note: required by a bound in `bevy::prelude::App::init_state`
   --> C:\Users\Zac\Documents\GitHub\bevy\crates\bevy_app\src\app.rs:282:26
    |
282 |     pub fn init_state<S: FreelyMutableState + FromWorld>(&mut self) -> &mut Self {
    |                          ^^^^^^^^^^^^^^^^^^ required by this bound in `App::init_state`
```

</details>

### Adding a `System` with Unhandled Output

<details>
<summary>Example Code</summary>

```rust
use bevy::prelude::*;

fn producer() -> u32 {
    123
}

fn main() {
    App::new()
        .add_systems(Update, consumer)
        .run();
}
```

</details>

<details>
<summary>Error Generated</summary>

```error
error[E0277]: `fn() -> u32 {producer}` does not describe a valid system configuration
   --> examples/app/empty.rs:9:30
    |
9   |         .add_systems(Update, producer)
    |          -----------         ^^^^^^^^ invalid system configuration
    |          |
    |          required by a bound introduced by this call
    |
    = help: the trait `IntoSystem<(), (), _>` is not implemented for fn item `fn() -> u32 {producer}`, which is required by `fn() -> u32 {producer}: IntoSystemConfigs<_>`
    = help: the following other types implement trait `IntoSystemConfigs<Marker>`:
              <Box<(dyn bevy::prelude::System<In = (), Out = ()> + 'static)> as IntoSystemConfigs<()>>
              <NodeConfigs<Box<(dyn bevy::prelude::System<In = (), Out = ()> + 'static)>> as IntoSystemConfigs<()>>
              <(S0,) as IntoSystemConfigs<(SystemConfigTupleMarker, P0)>>
              <(S0, S1) as IntoSystemConfigs<(SystemConfigTupleMarker, P0, P1)>>
              <(S0, S1, S2) as IntoSystemConfigs<(SystemConfigTupleMarker, P0, P1, P2)>>
              <(S0, S1, S2, S3) as IntoSystemConfigs<(SystemConfigTupleMarker, P0, P1, P2, P3)>>
              <(S0, S1, S2, S3, S4) as IntoSystemConfigs<(SystemConfigTupleMarker, P0, P1, P2, P3, P4)>>
              <(S0, S1, S2, S3, S4, S5) as IntoSystemConfigs<(SystemConfigTupleMarker, P0, P1, P2, P3, P4, P5)>>
            and 14 others
    = note: required for `fn() -> u32 {producer}` to implement `IntoSystemConfigs<_>`
note: required by a bound in `bevy::prelude::App::add_systems`
   --> C:\Users\Zac\Documents\GitHub\bevy\crates\bevy_app\src\app.rs:342:23
    |
339 |     pub fn add_systems<M>(
    |            ----------- required by a bound in this associated function
...
342 |         systems: impl IntoSystemConfigs<M>,
    |                       ^^^^^^^^^^^^^^^^^^^^ required by this bound in `App::add_systems`
```

</details>
</details>

## Testing

CI passed locally.

## Migration Guide

Upgrade to version 1.78 (or higher) of Rust.

## Future Work

- Currently, hints are not supported in this diagnostic. Ideally,
suggestions like _"consider using ..."_ would be in a hint rather than a
note, but that is the best option for now.
- System chaining and other `all_tuples!(...)`-based traits have bad
error messages due to the slightly different error message format.

---------

Co-authored-by: Jamie Ridding <Themayu@users.noreply.github.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: BD103 <59022059+BD103@users.noreply.github.com>
2024-05-17 00:49:05 +00:00
BD103
84363f2fab
Remove redundant imports (#12817)
# Objective

- There are several redundant imports in the tests and examples that are
not caught by CI because additional flags need to be passed.

## Solution

- Run `cargo check --workspace --tests` and `cargo check --workspace
--examples`, then fix all warnings.
- Add `test-check` to CI, which will be run in the check-compiles job.
This should catch future warnings for tests. Examples are already
checked, but I'm not yet sure why they weren't caught.

## Discussion

- Should the `--tests` and `--examples` flags be added to CI, so this is
caught in the future?
- If so, #12818 will need to be merged first. It was also a warning
raised by checking the examples, but I chose to split off into a
separate PR.

---------

Co-authored-by: François Mockers <francois.mockers@vleue.com>
2024-04-01 19:59:08 +00:00
Ame
9d67edc3a6
fix some typos (#12038)
# Objective

Split - containing only the fixed typos

-
https://github.com/bevyengine/bevy/pull/12036#pullrequestreview-1894738751


# Migration Guide
In `crates/bevy_mikktspace/src/generated.rs` 

```rs
// before
pub struct SGroup {
    pub iVertexRepresentitive: i32,
    ..
}

// after
pub struct SGroup {
    pub iVertexRepresentative: i32,
    ..
}
```

In `crates/bevy_core_pipeline/src/core_2d/mod.rs`

```rs
// before
Node2D::ConstrastAdaptiveSharpening

// after
Node2D::ContrastAdaptiveSharpening
```

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: James Liu <contact@jamessliu.com>
Co-authored-by: François <mockersf@gmail.com>
2024-02-22 18:55:22 +00:00
Doonv
054134fba2
Add ReflectKind (#11664)
# Objective

Fix https://github.com/bevyengine/bevy/issues/11657

## Solution

Add a `ReflectKind` enum, add `Reflect::reflect_kind` which returns a
`ReflectKind`, and add `kind` method implementions to `ReflectRef`,
`ReflectMut`, and `ReflectOwned`, which returns a `ReflectKind`.

I also changed `AccessError` to use this new struct instead of it's own
`TypeKind` struct.

---

## Changelog

- Added `ReflectKind`, an enumeration over the kinds of a reflected type
without its data.
- Added `Reflect::reflect_kind` (with default implementation)
- Added implementation for the `kind` method on `ReflectRef`,
`ReflectMut`, and `ReflectOwned` which gives their kind without any
information, as a `ReflectKind`
2024-02-07 00:36:23 +00:00
Tristan Guichaoua
694c06f3d0
Inverse missing_docs logic (#11676)
# Objective

Currently the `missing_docs` lint is allowed-by-default and enabled at
crate level when their documentations is complete (see #3492).
This PR proposes to inverse this logic by making `missing_docs`
warn-by-default and mark crates with imcomplete docs allowed.

## Solution

Makes `missing_docs` warn at workspace level and allowed at crate level
when the docs is imcomplete.
2024-02-03 21:40:55 +00:00
Doonv
b1a2d342af
Add the ability to manually create ParsedPaths (+ cleanup) (#11029)
# Objective

I'm working on a developer console plugin, and I wanted to get a
field/index of a struct/list/tuple. My command parser already parses
member expressions and all that, so I wanted to construct a `ParsedPath`
manually, but it's all private.

## Solution

Make the internals of `ParsedPath` public and add documentation for
everything, and I changed the boxed slice inside `ParsedPath` to a
vector for more flexibility.

I also did a bunch of code cleanup. Improving documentation, error
messages, code, type names, etc.

---

## Changelog

- Added the ability to manually create `ParsedPath`s from their
elements, without the need of string parsing.
- Improved `ReflectPath` error handling.

## Migration Guide

-  `bevy::reflect::AccessError` has been refactored.

That should be it I think, everything else that was changed was private
before this PR.

---------

Co-authored-by: Nicola Papale <nicopap@users.noreply.github.com>
2024-02-01 19:22:40 +00:00
Nicola Papale
365cf3114a
Make the reflect path parser utf-8-unaware (#9371)
# Objective

All delimiter symbols used by the path parser are ASCII, this means we
can entirely ignore UTF8 handling. This may improve performance.

## Solution

Instead of storing the path as an `&str` + the parser offset, and
reading the path using `&self.path[self.offset..]`, we store the parser
state in a `&[u8]`. This allows two optimizations:

1. Avoid UTF8 checking on `&self.path[self.offset..]`
2. Avoid any kind of bound checking, since the length of what is left to
read is stored in the `&[u8]`'s reference metadata, and is assumed valid
by the compiler.

This is a major improvement when comparing to the previous parser.

1. `access_following` and `next_token` now inline in `PathParser::next`
2. Benchmarking show a 20% performance increase (#9364)

Please note that while we ignore UTF-8 handling, **utf-8 is still
supported**. This is because we only handle "at the edges" what happens
exactly before and after a recognized `SYMBOL`. utf-8 is handled
transparently beyond that.
2023-08-25 23:12:25 +00:00
Nicola Papale
7083f0d593
Make it so ParsedPath can be passed to GetPath (#9373)
# Objective

- Unify the `ParsedPath` and `GetPath` APIs. They weirdly didn't play
well together.
- Make `ParsedPath` and `GetPath` API easier to use

## Solution

- Add the `ReflectPath` trait.
- `GetPath` methods now accept an `impl ReflectPath<'a>` instead of a
`&'a str`, this mean it also can accepts a `&ParsedPath`
- Make `GetPath: Reflect` and use default impl for `Reflect` types.
- Add `GetPath` and `ReflectPath` to the `bevy_reflect` prelude

---

## Changelog

- Add the `ReflectPath` trait.
- `GetPath` methods now accept an `impl ReflectPath<'a>` instead of a
`&'a str`, this mean it also can accept a `&ParsedPath`
- Make `GetPath: Reflect` and use default impl for `Reflect` types.
- Add `GetPath` and `ReflectPath` to the `bevy_reflect` prelude

## Migration Guide

`GetPath` now requires `Reflect`. This reduces a lot of boilerplate on
bevy's side. If you were implementing manually `GetPath` on your own
type, please get in touch!

`ParsedPath::element[_mut]` isn't an inherent method of `ParsedPath`,
you must now import `ReflectPath`. This is only relevant if you weren't
importing the bevy prelude.

```diff
-use bevy::reflect::ParsedPath;
+use bevy::reflect::{ParsedPath, ReflectPath};

 parsed_path.element(reflect_type).unwrap()
 parsed_path.element(reflect_type).unwrap()
2023-08-25 14:32:41 +00:00
Nicola Papale
10797d4f15
Refactor parsing in bevy_reflect path module (#9048)
# Objective

- Follow up to #8887
- The parsing code in `bevy_reflect/src/path/mod.rs` could also do with
some cleanup

## Solution

- Create the `parse.rs` module, move all parsing code to this module
- The parsing errors also now keep track of the whole parsed string, and
are much more fine-grained

### Detailed changes

- Move `PathParser` to `parse.rs` submodule
- Rename `token_to_access` to `access_following` (yep, goes from 132
lines to 16)
- Move parsing tests into the `parse.rs` file
2023-08-05 17:18:13 +00:00
Nicola Papale
08ea1d18ae
Refactor path module of bevy_reflect (#8887)
# Objective

- The `path` module was getting fairly large.
- The code in `AccessRef::read_element` and mut equivalent was very
complex and difficult to understand.
- The `ReflectPathError` had a lot of variants, and was difficult to
read.

## Solution

- Split the file in two, `access` now has its own module
- Rewrite the `read_element` methods, they were ~200 lines long, they
are now ~70 lines long — I didn't change any of the logic. It's really
just the same code, but error handling is separated.
- Split the `ReflectPathError` error
- Merge `AccessRef` and `Access`
- A few other changes that aim to reduce code complexity

### Fully detailed change list

- `Display` impl of `ParsedPath` now includes prefix dots — this allows
simplifying its implementation, and IMO `.path.to.field` is a better way
to express a "path" than `path.to.field` which could suggest we are
reading the `to` field of a variable named `path`
- Add a test to check that dot prefixes and other are correctly parsed —
Until now, no test contained a prefixing dot
- Merge `Access` and `AccessRef`, using a `Cow<'a, str>`. Generated code
seems to agree with this decision (`ParsedPath::parse` sheds 5% of
instructions)
- Remove `Access::as_ref` since there is no such thing as an `AccessRef`
anymore.
- Rename `AccessRef::to_owned` into `AccessRef::into_owned()` since it
takes ownership of `self` now.
- Add a `parse_static` that doesn't allocate new strings for named
fields!
- Add a section about path reflection in the `bevy_reflect` crate root
doc — I saw a few people that weren't aware of path reflection, so I
thought it was pertinent to add it to the root doc
- a lot of nits
- rename `index` to `offset` when it refers to offset in the path string
— There is no more confusion with the other kind of indices in this
context, also it's a common naming convention for parsing.
  - Make a dedicated enum for parsing errors
- rename the `read_element` methods to `element` — shorter, but also
`read_element_mut` was a fairly poor name
- The error values now not only contain the expected type but also the
actual type.
- Remove lifetimes that could be inferred from the `GetPath` trait
methods.

---

## Change log

- Added the `ParsedPath::parse_static` method, avoids allocating when
parsing `&'static str`.

## Migration Guide

If you were matching on the `Err(ReflectPathError)` value returned by
`GetPath` and `ParsedPath` methods, now only the parse-related errors
and the offset are publicly accessible. You can always use the
`fmt::Display` to get a clear error message, but if you need
programmatic access to the error types, please open an issue.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
2023-07-30 19:17:07 +00:00