Hello,
This is my first post in this forum. I just hit this problem in a personal project and I was wondering if the situation could be improved. Consider the type:
#[derive(Debug, Default)]
struct A {
name: Option<String>,
age: Option<u32>,
}
It's common to do a partial initialization of an instance of the type by using the ..
shorthand (snippet 1):
fn main() {
let a = A {
name: Some("name".to_string()),
..Default::default()
};
println!("{:?}", a);
}
However, if we consider the following struct instead:
#[derive(Debug)]
struct A {
name: Option<String>,
age: Option<u32>,
}
And try to perform the same operation, but when implementing the Default
trait (snippet 2):
impl Default for A {
fn default() -> A {
A {
name: Some("name".to_string()),
..Default::default()
}
}
}
rustc 1.81 yields --it's printing a warning, but I think a better solution might be feasible--:
❯ cargo run --quiet
warning: function cannot return without recursing
--> src/main.rs:8:5
|
8 | fn default() -> A {
| ^^^^^^^^^^^^^^^^^ cannot return without recursing
...
11 | ..Default::default()
| ------------------ recursive call site
|
= help: a `loop` may express intention better if this is on purpose
= note: `#[warn(unconditional_recursion)]` on by default
warning: fields `name` and `age` are never read
--> src/main.rs:3:5
|
2 | struct A {
| - fields in this struct
3 | name: Option<String>,
| ^^^^
4 | age: Option<u32>,
| ^^^
|
= note: `A` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
= note: `#[warn(dead_code)]` on by default
thread 'main' has overflowed its stack
fatal runtime error: stack overflow
Aborted (core dumped)
Leaving aside the warning and the stack overflow error reported by rustc, my question is about the semantics of this operation. Couldn't (snippet 2) desugar into:
impl Default for A {
fn default() -> A {
A {
name: Some("name".to_string()),
age: Default::default(),
}
}
}
What do you think about this? Is there anything blocking this option? I'd be happy to look into this more in detail.
This has been reported in other places such as Use Default::default syntax sugar maybe cause stack overflow · Issue #94930 · rust-lang/rust · GitHub or Print warning when Default::default calls itself · Issue #90513 · rust-lang/rust · GitHub, but I think assuming (snippet 1) is the expected behavior, I think (snippet 2) would also be desired. The idea behind the '..' syntactic sugar is that it calls to Default::default()
on the rest of fields not specifically set by the user.
Thank you!