Skip to content
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

Stack overflow with struct update syntax #91012

Closed
crisidev opened this issue Nov 18, 2021 · 3 comments
Closed

Stack overflow with struct update syntax #91012

crisidev opened this issue Nov 18, 2021 · 3 comments
Labels
C-bug Category: This is a bug.

Comments

@crisidev
Copy link

This problem happens when using Struct update syntax with Default implementation (https://doc.rust-lang.org/book/ch05-01-defining-structs.html#creating-instances-from-other-instances-with-struct-update-syntax).

I have found this bug in a more complicated piece of code, but I was able to create a simpler reproduction.

#[derive(Debug)]
pub struct Router<B> {
    routes: Vec<(B, i32)>,
}

impl<B> Default for Router<B>
where
    B: Send + 'static,
{
    fn default() -> Self {
        Self::new()
    }
}

impl<B> Router<B>
where
    B: Send + 'static,
{
    pub fn new() -> Self {
        Self {
            ..Default::default()
        }
    }
}

fn main() {
    let r: Router<String> = Router::new();
    println!("Hello, world!");
}

I expected this to just print "Hello, world!", but instead it panics with a stack overflow:

    Finished dev [unoptimized + debuginfo] target(s) in 0.00s
     Running `target/debug/repro`

thread 'main' has overflowed its stack
fatal runtime error: stack overflow
zsh: abort      RUST_BACKTRACE=1 cargo run

Changing the Struct update syntax to explicit parameters resolves the issue:

    pub fn new() -> Self {
        Self {
            routes: Default::default()
        }
    }
    Finished dev [unoptimized + debuginfo] target(s) in 0.82s
     Running `target/debug/repro`
Hello, world!

Meta

The issue is reproducible with both stable and nightly compilers and adding RUST_BACKTRACE=1 or RUST_BACKTRACE=full does not produce a stack trace.

The reproduction runs also on playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=e5dd848f3af5f5f2b1f13c1d70163f5b

@robojumper
Copy link
Contributor

Router::<_>::new and <Router<_> as Default>::default are mutually recursive. #57965 tracks detecting unconditional recursion across function calls, which would at least emit a compiler warning in this case.

@inquisitivecrystal
Copy link
Contributor

Thanks for the report! Since this appears not to actually be a problem with rustc, and there's already an issue tracking the diagnostic, I'm going to close this issue. Anyone should feel free to reopen if there's something I'm missing.

@crisidev
Copy link
Author

Of course! I'll keep a close eye to the diagnostic issue. Thanks for the help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

3 participants