Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
April 02, 2019 Why can we not use __traits across protection? | ||||
---|---|---|---|---|
| ||||
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. |
April 02, 2019 Re: Why can we not use __traits across protection? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alex | 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) |
April 03, 2019 Re: Why can we not use __traits across protection? | ||||
---|---|---|---|---|
| ||||
Posted in reply to drug | 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. |
April 03, 2019 Re: Why can we not use __traits across protection? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alex | On 03.04.2019 3:57, Alex wrote:
> On Tuesday, 2 April 2019 at 15:50:29 UTC, drug wrote:
>
>
> 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
Ok, my usecase is the following - I need to process all members of some aggregate. But using traits with not accessible members fails. So I use `isPublic` to filter out not accessible members and then use other traits to process accessible members.
|
April 03, 2019 Re: Why can we not use __traits across protection? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alex | On Tuesday, 2 April 2019 at 14:56:38 UTC, 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. __traits(getProtection, __traits(getMember, x, "x")) works. You just can't spell "x.x" anywhere. > > 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. I used to think this but it's not actually needed. > 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. See above. |
April 15, 2019 Re: Why can we not use __traits across protection? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Atila Neves | On 4/3/19 5:19 AM, Atila Neves wrote:
> On Tuesday, 2 April 2019 at 14:56:38 UTC, 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.
>
> __traits(getProtection, __traits(getMember, x, "x")) works. You just can't spell "x.x" anywhere.
>
So this is quite unintuitive. The compiler should realize here you are just checking protection, and forego the protection check on the expression. I.e. there should be a special exception to visibility checking inside __traits(getProtection, ...).
-Steve
|
April 15, 2019 Re: Why can we not use __traits across protection? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Monday, 15 April 2019 at 14:55:36 UTC, Steven Schveighoffer wrote:
> So this is quite unintuitive. The compiler should realize here you are just checking protection, and forego the protection check on the expression.
So there was a PR pulled last week that exempts getMember from protection checks, which solves this (finally!) and makes private filtering a user concern for the traits now.
That is kinda cool. I got used to it the way before but this will prolly be more convenient overall.
|
Copyright © 1999-2021 by the D Language Foundation