Bug 4675 – [tdpl] Eponymous Template should hide internal names

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
Other
OS
Windows
Creation time
2010-08-18T13:19:00Z
Last change time
2012-01-24T15:06:38Z
Keywords
patch
Assigned to
nobody
Creator
andrej.mitrovich

Comments

Comment #0 by andrej.mitrovich — 2010-08-18T13:19:16Z
Code: import std.stdio; void main() { } template isNumeric(T) { enum bool test1 = is(T : long); // should be hidden enum bool test2 = is(T : real); // should be hidden enum bool isNumeric = test1 || test2; } unittest { static assert(isNumeric!(int).test1); // should be an error writeln(isNumeric!(int).test1); // should be an error, but writes true writeln(isNumeric!(int).test2); // should be an error, but writes true } According to TDPL, calling isNumeric!(T) is rewritten by the compiler to isNumeric!(T).isNumeric, therefore hiding access to any other names.
Comment #1 by torarin — 2010-08-20T17:26:26Z
I ran into trouble with this example as well, but this time because what should work, doesn't: import std.stdio; template isNumeric(T) { enum bool test1 = is(T : long); enum bool test2 = is(T : real); enum bool isNumeric = test1 || test2; } void main() { bool a = isNumeric!int; } Fails with: test.d(12): Error: expression isNumeric!(int) is void and has no value. I was surprised to find that the language reference actually contradicts TDPL here: "Implicit Template Properties If a template has exactly one member in it, and the name of that member is the same as the template name, that member is assumed to be referred to in a template instantiation." (In reply to comment #0) > > According to TDPL, calling isNumeric!(T) is rewritten by the compiler to > isNumeric!(T).isNumeric, therefore hiding access to any other names.
Comment #2 by andrej.mitrovich — 2010-08-20T17:35:05Z
There are more cases of contradiction, but I think this has to do with some of the spec not being updated. In other cases some features are simply not yet implemented.. My guess is that this feature should be implemented like it states in TDPL. Otherwise for any non-trivial templates you would have to write code like: isNumeric!(int).isNumeric
Comment #3 by torarin — 2010-08-20T17:54:25Z
Yes. std.traits deals with it by doing private template hasRawAliasing(T...) { enum hasRawAliasing = hasRawPointerImpl!(RepresentationTypeTuple!(T)).result; }
Comment #4 by bearophile_hugs — 2010-08-27T16:26:55Z
Time ago some people have proposed to allow "private" for that purpose: template isNumeric(T) { private enum bool test1 = is(T : long); private enum bool test2 = is(T : real); enum bool isNumeric = test1 || test2; } This is good because the person that reads the code doesn't need to remember the rule that test1 and test2 become invisible if isNumeric is defined inside isNumeric(). So I think this is a more tidy solution to the problem. On the other hand you want all names to be private but the one that is eponymous, so the solution in TDPL is shorter (and probably acceptable still).
Comment #5 by k.hara.pg — 2011-12-31T05:39:13Z
https://github.com/D-Programming-Language/dmd/pull/590 Eponymous member always hides other members (do not consider access attributes).
Comment #6 by bugzilla — 2012-01-15T19:17:09Z
Comment #7 by code — 2012-01-22T01:37:35Z
*** Issue 2640 has been marked as a duplicate of this issue. ***
Comment #8 by verylonglogin.reg — 2012-01-24T15:06:38Z
Still doesn't work in most real-life (Phobos) cases. Filled Issue 7363.