This has been discussed ad nauseam, so I’m skipping rationale. Let’s just say that many users want this feature, especially those who need C++ interop. Here’s how it can be implemented in a non-problematic way.
A struct with a default constructor can only be instantiated by an implicit constructor call, following the same rules as a struct with a disabled default constructor.
struct S {
this() {
writeln("S.this()");
}
}
void main {
S s; // error
S t = S(); // ok (constructed by calling `S.this()`)
S u = void; // ok (not `@safe`)
S v = S.init; // ok (may be a logically incorrect object)
S[3] a; // error
S[3] b = [S(), S(), S()]; // ok
}
If any fields of an aggregate type are structs with default constructors, all constructors of this type must initialize them. If a default constructor is not defined, default construction is disabled.
struct S {
this() { writeln("S.this()"); }
}
struct T {
S s;
// implicit `@disable this();`
}
struct U {
S s;
this(int x) {} // error: `s` must be initialized
this() { s = S(); }
}
class C {
S s;
this(int x) {} // error: `s` must be initialized
this() { s = S(); }
}
void main {
T t1; // error: default construction is disabled
T t2 = T(); // ditto
U u = U(); // ok
C c = new C(); // ok
}
Destroy.