Implementing Default on nested structures causes a stack overflow

628 views Asked by At

I found an unusual behavior of std::default. If you create a nested structure with default setters and try to create the highest level struct with default parameters, it causes a stack overflow.

This code compiles, but when you try to run it throws thread '<main>' has overflowed its stack:

use std::default;

pub struct A {
    x: i32
}

impl Default for A {
    fn default() -> A {
        A { ..Default::default() }
    }
}

fn main() {
    let test = A { ..Default::default() };
}

But if you set the defaults of inherited by props, it works:

use std::default;

pub struct A {
    x: i32
}

impl Default for A {
    fn default() -> A {
        A { x: 0 }
    }
}

fn main() {
    let test = A { ..Default::default() };
}

Is this a known issue and should I post it to the Rust issue tracker? My compiler version is rustc 1.2.0-nightly (0250ff9a5 2015-06-17).

1

There are 1 answers

5
DK. On BEST ANSWER

Of course it causes a stack overflow.

To make this clearer, let's change the example a little:

pub struct A {
    x: i32,
    y: i32,
}

impl Default for A {
    fn default() -> A {
        A { x: 1, ..Default::default() }
    }
}

When you say A { ..Default::default() }, you are not saying "create me an A and execute Default::default() for each field". This means that the implementation of default is not equivalent to:

A { x: 1, y: Default::default() }

It is, in fact, this:

let temp: A = Default::default();
temp.x = 1;
temp

So yes, it causes a stack overflow: you've defined the default value of A in terms of itself.