www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 3254] New: Module member visibility depends on declaration order

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3254

           Summary: Module member visibility depends on declaration order
           Product: D
           Version: 1.030
          Platform: Other
        OS/Version: Windows
            Status: NEW
          Keywords: rejects-valid
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: snake.scaly gmail.com


The following code compiles:

--a.d---------
import b;
void main() {
  foo(0);
}
--------------

--b.d---------
void foo(int x) {}
private void foo(float x) {}
--------------

 dmd -c -o- a.d

But swap function declarations in b.d, and it breaks: --b.d--------- private void foo(float x) {} void foo(int x) {} --------------
 dmd -c -o- a.d

-- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 16 2009
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3254


Stewart Gordon <smjg iname.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |smjg iname.com
             Blocks|                            |340




--- Comment #1 from Stewart Gordon <smjg iname.com>  2009-08-17 16:19:16 PDT ---
(DMD 1.046 Windows)

If b.d is changed to
----------
private void foo(int x) {}
void foo(float x) {}
----------
then it doesn't compile either way round:
----------
bz3254a.d: Error: module bz3254a bz3254b.foo is private
bz3254a.d(3): Error: function bz3254b.foo is not accessible from bz3254a
----------
The first of these errors disappears if they're swapped over.

But I'm not sure whether this is meant to work or not.  Are function calls
meant to be matched over all overloads, or only those that are accessible?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Aug 17 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3254





--- Comment #2 from Sobirari Muhomori <maxmo pochta.ru>  2009-08-18 00:42:15
PDT ---
From bug 314
 Access protection is defined to happen after lookup and overload resolution.

attribute. Though I don't understand this scheme too. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 18 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3254





--- Comment #3 from Stewart Gordon <smjg iname.com>  2009-08-18 02:08:23 PDT ---
(In reply to comment #2)
 From bug 314
 Access protection is defined to happen after lookup and overload resolution.


Defined where in the spec?
 So the correct behavior seems to match foo(int) first, then look for its access
 attribute. Though I don't understand this scheme too.

Basically, all overloads of a function name are looked at, regardless of their protection attributes, in order to pick an overload. Then the call is validated on the protection attribute of the one that's been picked. My guess is that the point is to protect against accidental behaviour changes if some code is moved between modules. But maybe it's better to avoid having a private function and a public function with the same name in the same scope. But the current behaviour does seem to be overdoing it. If a module imports two modules each of which defines a symbol, but in one of them it's private, an import conflict is reported. It's been my view for a while that private symbols should not be imported at all. Maybe the best policy is to see whether _all_ overloads are private and, if so, the module will keep the symbol to itself; otherwise, invoke the the current behaviour. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 18 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3254





--- Comment #4 from Sobirari Muhomori <maxmo pochta.ru>  2009-08-20 00:03:27
PDT ---
(In reply to comment #3)
 My guess is that the point is to protect against accidental behaviour changes
 if some code is moved between modules.

change still can happen in the module the code moved to. If there was public foo(int), the module used to call it, then private foo(float) appears and the module silently starts to call it. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 20 2009
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3254





--- Comment #5 from Sergey Gromov <snake.scaly gmail.com>  2009-08-20 06:27:26
PDT ---
 From bug 314
 Access protection is defined to happen after lookup and
 overload resolution.



That was Walter's comment. This exact comment made me experiment with module-level protection attributes and led to this bug report. Well, I think the "overload before protection" rule has its merit for classes. Class methods *hide* methods of the same name in base classes to protect from overload set hijacking. It probably would be confusing if hiding rules worked differently depending on whether your function is in the same module with the class or not. But module members cannot hide anything. Any name collision is an error, and any conflict resolution is explicit. Therefore I think overload resolution should be changed for modules, too. Consider: module a; class A {} void foo(A a) {} module b; class B {} void foo(B b) {} module c; import a, b; private alias a.foo foo; private alias b.foo foo; void bar() { foo(new A); foo(new B); } So far so good. But now: module d; import a, c; void baz() { foo(new A); // error ?!! } a.foo conflicts with c.foo ? But I don't know about c.foo. There is no documentation for c.foo. There is no c.foo. Still, this phantom messes up overloading. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 20 2009