https://issues.dlang.org/show_bug.cgi?id=23907
--- Comment #2 from Bolpat <qs.il.paperi...@gmail.com> --- > I would argue that this is intended behavior and if the opposite occurs for > other traits then that is the bug. I strongly disagree. If you were right, that would mean that you cannot e.g. create a serialization library that can serialize private data members. A module could reasonably pass a private symbol as an argument to an `alias` parameter of a template imported from another module. That template should be able to do its job, regardless whether the symbol is private. > Which ones? * `getProtection` for a trivial one. * `getOverloads` allows accessing private overloads in a private aggregate * `hasMember` and `allMembers` returns/lists private members * `hasCopyConstructor` does not fail if the argument is an alias to a private struct I didn’t check all of them, just a sample. > I tried `getMember` and that doesn't bypass private. I have no idea what you tried, but in my tests, it does. Here is what I tried (suitable for run.dlang.io): ```d --- a.d #line 3 "a.d" private struct _S { private int x; private void f() @safe {} private static int f(int x) @safe pure => x; } // only way to access anything in this module: alias S = _S; --- playground.d #line 16 "playground.d" import a; void main() { S s; static foreach (ov; __traits(getOverloads, s, "f")) { static if (is(typeof(ov(0)))) { ov(0); } } static assert(__traits(hasMember, S, "f")); static assert(__traits(hasMember, s, "f")); static assert(!__traits(compiles, s.x = 2 )); // x is private __traits(getMember, s, "x") = 2; static assert(!__traits(compiles, assert(s.x == 2) )); // x is private assert(__traits(getMember, s, "x") == 2); static assert(__traits(getProtection, S) == "private"); static assert(__traits(getProtection, __traits(getMember, s, "x")) == "private"); } ``` --