3

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 Answer 1

5

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.

Sign up to request clarification or add additional context in comments.

5 Comments

Hm. Interesting interaction. Thanks for clear explanation. But anyway, IMO, compiler shouldn't let me do this sort of stuff
@Cherrionella It's not the compiler's job to keep you from making logic errors or solve the halting problem. :)
@DK.: well, many forms of unbounded recursion which cannot possibly be what you wanted are trivial to detect, and one could easily form a case for the compiler complaining of such things.
@ChrisMorgan: I didn't want to get bogged down in the comments section on the subject; I agree that detecting almost certainly incorrect behaviour in lints is a good thing, but I think expecting or relying on a language to detect all such mistakes is just begging for trouble.
@Cherrionella I've submitted an issue to rust-clippy, which I believe is more suited for this kind of thing than the rust compiler. If you are on nightly, consider yourself invited to try it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.