www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - D1: Overloading across modules

reply "Nick Sabalausky" <a a.a> writes:
In D1, is there any reason I should be getting an error on this?:

// module A:
enum FooA { fooA };
void bar(FooA x) {}

// module B:
import A;
enum FooB { fooB };
void bar(FooB x) {}

bar(FooB.fooB); // Error: A.bar conflicts with B.bar

Is overloading across modules not allowed? Is overloading on two different 
enum types not allowed? Is it a DMD bug? Or does this all work fine and I 
probably just have some other problem elsewhere? 
Mar 23 2010
next sibling parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Nick Sabalausky wrote:
 In D1, is there any reason I should be getting an error on this?:

 // module A:
 enum FooA { fooA };
 void bar(FooA x) {}
 
 // module B:
 import A;
 enum FooB { fooB };

alias A.bar bar;
 void bar(FooB x) {}
 
 bar(FooB.fooB); // Error: A.bar conflicts with B.bar
 
 Is overloading across modules not allowed? Is overloading on two different 
 enum types not allowed? Is it a DMD bug? Or does this all work fine and I 
 probably just have some other problem elsewhere? 

The compiler assumes that, unless you specifically tell it otherwise, symbols pulled in from another module conflict with local ones. This might also work: import A : bar;
Mar 23 2010
next sibling parent Ellery Newcomer <ellery-newcomer utulsa.edu> writes:
On 03/23/2010 05:42 AM, Daniel Keep wrote:
 Nick Sabalausky wrote:
 In D1, is there any reason I should be getting an error on this?:

 // module A:
 enum FooA { fooA };
 void bar(FooA x) {}

 // module B:
 import A;
 enum FooB { fooB };

alias A.bar bar;
 void bar(FooB x) {}

 bar(FooB.fooB); // Error: A.bar conflicts with B.bar

 Is overloading across modules not allowed? Is overloading on two different
 enum types not allowed? Is it a DMD bug? Or does this all work fine and I
 probably just have some other problem elsewhere?

The compiler assumes that, unless you specifically tell it otherwise, symbols pulled in from another module conflict with local ones. This might also work: import A : bar;

What about // module A: enum FooA{ fooA }; void bar(FooA x){} // module B: import A; mixin(` enum FooB{ fooB }; void bar(FooB x){} `); bar(FooB.fooB); It doesn't seem to work the same as when enum FooB et al are normal code. It's been giving me grief lately.
Mar 23 2010
prev sibling parent "Nick Sabalausky" <a a.a> writes:
"Daniel Keep" <daniel.keep.lists gmail.com> wrote in message 
news:hoa5v4$1bai$1 digitalmars.com...
 Nick Sabalausky wrote:
 In D1, is there any reason I should be getting an error on this?:

 // module A:
 enum FooA { fooA };
 void bar(FooA x) {}

 // module B:
 import A;
 enum FooB { fooB };

alias A.bar bar;

Hmm, unfortunately (I just realized) my exact case is more like this: // module A: enum FooA { fooA }; void bar(FooA x) {} // module B: import A; enum FooB { fooB }; void bar(FooB x) {} // module C: import A; import B; bar(FooB.fooB); // Error: A.bar conflicts with B.bar Turns out that putting the alias in module B doesn't fix the problem, I have to put aliases to both "bar"s in module C.
 void bar(FooB x) {}

 bar(FooB.fooB); // Error: A.bar conflicts with B.bar

 Is overloading across modules not allowed? Is overloading on two 
 different
 enum types not allowed? Is it a DMD bug? Or does this all work fine and I
 probably just have some other problem elsewhere?

The compiler assumes that, unless you specifically tell it otherwise, symbols pulled in from another module conflict with local ones.

I *really* hope that's changed in D2 (is it?), because that's completely breaking a utility I have. Specifically, I have a CTFE function "genEnum" that generates code (to be mixed in) which creates an enum along with an enumToString function (I realize Phobos2 has something similar to that, but Phobos1/Tango don't). The library that this is in also actually uses "genEnum", so any client code (or any other part of the same library) that wants to make use of genEnum has to jump through that alias contortion anywhere an enumToString is actually used. I could change it to "{name of enum}ToString", but I'd really rather not have to do it that way (although I am doing it that way for the "stringToEnum" function since I obviously can't overload on return type). I was starting to think maybe I could try doing a function template like "enumToString!(enumTypeHere)(enumTypeHere.foo);", (which would perhaps be a better solution anyway) but without D2's template constraints I'm not sure how I'd be able to pull that off.
Mar 23 2010
prev sibling parent reply BCS <none anon.com> writes:
Hello Nick,

 Is overloading across modules not allowed? Is overloading on two
 different enum types not allowed? Is it a DMD bug? Or does this all
 work fine and I probably just have some other problem elsewhere?

IIRC, this is done so that importing a module will never alter what function a call binds to. By forcing an error, the program gets a prompt to deal with it. -- ... <IXOYE><
Mar 23 2010
parent "Nick Sabalausky" <a a.a> writes:
"BCS" <none anon.com> wrote in message 
news:a6268ff119c68cc98a14e065cd6 news.digitalmars.com...
 Hello Nick,

 Is overloading across modules not allowed? Is overloading on two
 different enum types not allowed? Is it a DMD bug? Or does this all
 work fine and I probably just have some other problem elsewhere?

IIRC, this is done so that importing a module will never alter what function a call binds to. By forcing an error, the program gets a prompt to deal with it.

But isn't it going a lot farther than it needs to? I mean, if you have a function call "bar(e)" where "e" is of type "SomeEnum", then what other function "X bar( /+whatever+/ )" could possibly be made that would hijack the call without violating the ordinary intra-module overloading rules that already exist? I'm not aware of anything that can be implicitly converted to an enum. Instead of having a rule "two functions from different modules conflict if they have the same name", shouldn't it really be "two functions from different modules conflict if they have the same name *and* implicit conversion rules make it possible for a call to one to be hijacked by the other"? I'd also like to know, does all this still apply to D2 as well? Or has it been fixed there? .... Oh shit....I just realized, thanks to that obnoxious "Enums are implicity convertable to their base type" rule (A rule which I already hate for blatantly breaking strong-typing), one can do this: // Module Foo: enum Foo { foo } // module A: import Foo; void bar(Foo x){} // module B version 1: import Foo; void bar(int x){} bar(Foo.foo); // Stupid crap that should never be allowed in the first place // module B version 2: import Foo; import A; // <- This line added void bar(int x){} bar(Foo.foo); // Now that conflict error *cough* "helps". I think I'm going to merge this discussion with bearophile's "Enum equality test" and bring it over to the "digitalmars.D" ng.
Mar 23 2010