Skip to content

Implementing default with default - recursion #8609

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
mikatpt opened this issue Mar 30, 2022 · 2 comments
Open

Implementing default with default - recursion #8609

mikatpt opened this issue Mar 30, 2022 · 2 comments

Comments

@mikatpt
Copy link

mikatpt commented Mar 30, 2022

Description

Hey, this is probably a pretty silly feature request, but this tripped me up way more than it should have.

Normally, if you try to implement Default and use ..Default::default(), it'll give you the following warning:
recursive call site [unconditional_recursion].

However, if you add any function call, this will no longer happen.

pub struct Test {
    pub a: String,
    pub b: i32,
}

impl Default for Test {
    fn default() -> Self {
        let test = "test".to_string();
        Self {
            a: test,
            ..Default::default() // No compiler warning!
        }
    }
}

In retrospect, this is exceptionally obvious. But my intuitive thought when I was writing that line was that the remaining fields would be implemented with Default, not that it would refer to the struct itself. Rust Analyzer even suggests using it... not that that's any excuse either, but I lost a lot of time to this particular footgun 😞

Related issue: #103

Version

No response

Additional Labels

No response

@kraktus
Copy link
Contributor

kraktus commented Sep 24, 2022

Running the snippet on playground, the compiler fires a warning. Note that this is rustc warning, not a clippy one.

@thehappycheese
Copy link

Just blew my toes off with the same "stack overflow";

@kraktus I don't see any warning in the terminal... perhaps it would appear if I recompiled from scratch?

use bevy::{prelude::*, audio::{PlaybackMode, Volume}};
use bevy_turborand::prelude::*;

#[derive(Component)]
pub struct FootStepSounds {
    pub last_position     : Vec3,
    pub movement_distance : f32,
    pub stride_length     : f32,
    pub elapsed_time      : f32,
    pub stride_time       : f32,
    pub sound_assets      : Vec<Handle<AudioSource>>,
}

impl Default for FootStepSounds {
    fn default() -> Self {
        Self {
            stride_length     : 20.0,
            stride_time       : 0.3,
            // elapsed_time      : 0.0,
            // movement_distance : 0.0,
            // last_position     : Vec3::ZERO,
            // sound_assets      : vec![],
            ..default() // <-- stack overflow
        }
    }
}

Like @mikatpt I also think it seems like a perfectly reasonable thing to try, but obvious why it cant work. Hopefully there is like a ..super_default() or a ..partial_default() in the future :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants