Description
Bevy version
0.8.1
The issue
I stumbled upon a situation where when I spawned my player bundle the program would segfault with a stack overflow. With gdb I discovered that this occurred in the default
function. The problem might be obvious to some:
#[derive(Bundle)]
pub struct PlayerBundle {
player: Player,
#[bundle]
sprite: SpriteBundle,
rigid_body: RigidBody,
collider: Collider,
}
impl Default for PlayerBundle {
fn default() -> Self {
Self {
sprite: SpriteBundle {
sprite: Sprite {
custom_size: Some(Vec2::new(24.0, 24.0)),
..default()
},
..default()
},
..default()
}
}
}
Namely, the default
function is recursive and non terminating (I wrongly assumed that ..default()
calls upon the Default trait of each respective field). This is quite problematic which is why in a non bevy project like this sandboxed example:
struct DefaultOne {
v: u32,
}
impl Default for DefaultOne {
fn default() -> Self {
Self { v: 1 }
}
}
struct DefaultFour {
v: u32,
}
impl Default for DefaultFour {
fn default() -> Self {
Self { v: 5 }
}
}
struct Pair {
x: DefaultOne,
y: DefaultFour,
}
impl Default for Pair {
fn default() -> Self {
Self {
x: DefaultOne { v: 42 },
..Default::default()
}
}
}
rust analyzer produces a big fat warning about possible non termination. However, somehow when using the ..default()
syntax made available in the bevy prelude, rust analyzer is blind to the issue and lets you write a nasty bug like this. It would be good to research if it is possible to make sure that in the bevy case this warning is still emitted.