Why can we not use __traits across protection?

Alex AJ at gmail.com
Wed Apr 3 00:57:31 UTC 2019


On Tuesday, 2 April 2019 at 15:50:29 UTC, drug wrote:
> On 02.04.2019 17:56, Alex wrote:
>> Module X:
>> 
>> class x
>> {
>>     private int x;
>> }
>> 
>> Module Y:
>> 
>> import X;
>> 
>> moduleName!(x.x);
>> 
>> or
>> 
>> __traits(getProtection, x.x);
>> 
>> Deprecation: `X.x.x.x` is not visible from module `Y`
>> Error: class `X.x.x` member `x` is not accessible
>> 
>> My use case is a little more complicated but I have two issues.
>> 
>> 
>> 1: I have to import the module even though the type passed is 
>> valid(I'm using templates which are passed the type with a 
>> module import and I'd expect the module import to be "passed" 
>> along with the type so that I don't have to import it to use 
>> __traits or reflection.
>> 
>> 2. If a member is protected then __traits and others fails. 
>> This makes absolutely no sense. Protection is used for run 
>> time, not compile time. What is strange is private methods 
>> give a deprecation warning but private fields give a 
>> deprecation error.
>> 
>> 
>
> Yes, it's known issue. I've spent rather much time to manage 
> this. I do something like 
> https://github.com/drug007/asdf/blob/the_last_changes/source/asdf/serialization.d#L3008 (this branch is not merged upstream yet)


private template isPublic(alias aggregate, string member)
{
	static if (!is(Identity!(__traits(getMember, aggregate, 
member))) &&
		       __traits(compiles, { auto s = __traits(getProtection, 
__traits(getMember, aggregate, member)); }))
			enum isPublic = !__traits(getProtection, __traits(getMember, 
aggregate, member)).privateOrPackage;
	else
		enum isPublic = false;
}

How does that work to get around the problem? It seems all it 
does is return false if it fails and so assumes it to be 
private...

but this doesn't work in other traits that fail.


More information about the Digitalmars-d mailing list