Testcase:
```
import std.traits;
import std.stdio;
void main() {
static struct S { @disable this(this); }
writeln(hasMember!(S, "__postblit")); // expected: false
writeln(hasElaborateCopyConstructor!S); // expected: false
}
```
The program prints twice "true", instead of "false".
Note that `hasElaborateCopyConstructor` does a `hasMember!(S, "__postblit")` check, so that's the root cause of the problem.
Comment #1 by razvan.nitu1305 — 2018-03-19T11:41:27Z
Well, the struct defines the member, it's just that it is disabled. One might argue that the output is correct and the programmer needs to check if the member is disabled or not
Comment #2 by razvan.nitu1305 — 2018-03-19T11:43:17Z
What I'm saying is that the output of hasMember is correct, but the output of hasElaborateCopyConstructor most certainly isn't, but, in my opinion, the fix should be in phobos, not in dmd.
Comment #3 by andrei — 2018-03-19T16:40:35Z
Question applies to all functions. Consider:
import std.stdio;
import std.traits;
struct A { @disable void fun(); }
void main()
{
writeln(hasMember!(A, "fun")); // expected: false
}
This prints true.
Comment #4 by andrei — 2018-03-19T16:43:10Z
The problem with hasElaborateCopyConstructor is the binary expectation:
* is that true? Then there's work involved to copy the object
* is that false? Then the object can be copied with memcpy
This does not account for the disabled case. So I'm not sure what to do here aside from defining a different trait e.g. hasDisabledCopyConstructor.
(In reply to johanengelen from comment #5)
>
> Currently, adding `@disable this(this)` to a struct that normally wouldn't
> have a postblit, actually makes the compiler emit a postblit function
Interestingly without @disable, no postblit is emitted when just a declaration is given:
```
struct S {
int i;
@disable this(this); // will emit S.__aggrPostblit() function
}
```
without @disable:
```
struct S {
int i;
this(this); // will _not_ emit S.__aggrPostblit() function
}
```
Comment #7 by robert.schadek — 2024-12-13T18:57:55Z