Option::Some and Some in bsn! creates compile error
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 16h
- Merged PRs (30d)
- 171
Description
## Bevy version and features
0.19 and main
I tested on main so that #24876 was applied, as this issue had a similar smell to #24775.
## What you did
I was having difficulty instantiating a Sprite with a TextureAtlas inside of a bsn! block. My setup was a bit complicated because I was using a custom asset loader to load TextureAtlasLayout assets from config files and relying on templates to go from String => Handle.
I created a simpler reproducer that uses images since there is a built-in loader for Image assets. However - the real use case I care about is using a template to load a TextureAtlasLayout.
```rust
use bevy::asset::HandleTemplate;
use bevy::ecs::template::OptionTemplate;
use bevy::prelude::*;
#[derive(Clone, Default, FromTemplate)]
pub struct Wrapper {
#[template(HandleTemplate)]
pub image: Handle,
}
// Show that nestled structs are not the problem.
#[derive(Clone, Component, Default, FromTemplate)]
struct DoDirect {
#[template(WrapperTemplate)]
pub child: Wrapper,
}
// Show that options / enums are the problem.
#[derive(Clone, Component, Default, FromTemplate)]
struct DoOption {
#[template(OptionTemplate)]
pub child: Option,
}
...
commands.spawn_scene(bsn! {
DoDirect {
child: Wrapper {image: "foo.png"},
}
DoOption {
child: Option::Some(Wrapper {image: "bar.png"}),
}
});
...
```
## What went wrong
There are compile errors for the bsn! block:
```
error[E0277]: the trait bound `bevy::bevy_asset::Handle: From<&str>` is not satisfied
...
error[E0277]: the trait bound `WrapperTemplate: From` is not satisfied
```
cargo expand produces this:
```rust
// DoDirect works
let __value = _scene
.get_or_insert_template::<
::Template,
>(_context);
::bevy::scene::macro_utils::touch_type::();
__value.child.image = "foo.png".into();
// DoOption does not
let __value = _scene
.get_or_insert_template::<
::Template,
>(_context);
__value
.child = (Option::Some(
(Wrapper {
image: "bar.png".into(), // This is clearly wrong and causes the compile error
})
.into(),
))
.into();
```
Note I've been using Option::Some(...). If I just use Some(...) instead I get:
```
error[E0573]: expected type, found variant `Some`
...
error[E0609]: no field `0` on type `OptionTemplate`
```
```rust
let __value = _scene
.get_or_insert_template::<
::Template,
>(_context);
::bevy::scene::macro_utils::touch_type::();
::bevy::scene::macro_utils::touch_type::();
__value.child.0.image = "bar.png".into();
```
This seems closer to correct but is still broken - the assignment target is the correct type, but the generated code is trying to assign to it as if it's a tuple rather than an enum.
Contributor guide
Research direction
Start with the bsn! reproducer and inspect the FromTemplate, OptionTemplate, and scene macro expansion described in the issue. Verify how Option::Some(...) and Some(...) are expanded, then confirm done when both forms compile with nested template values and preserve the intended Option enum assignment.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- game-dev, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100