D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 2028 - Can't create template class in module of same name
Summary: Can't create template class in module of same name
Status: RESOLVED INVALID
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: x86 Linux
: P2 normal
Assignee: No Owner
URL:
Keywords: spec
Depends on:
Blocks:
 
Reported: 2008-04-24 15:04 UTC by Jerry Quinn
Modified: 2015-06-09 01:14 UTC (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Jerry Quinn 2008-04-24 15:04:27 UTC
I'm not sure this is a bug or a language limitation, but it feels like a bug...

I have 2 modules:

a.d:
class a(T) {}

b.d:
import a;
class b {
  a!(int) x;
}

When I try to compile this, I get the following error:

~/dmd/bin/dmd -c a.d b.d
b.d(4): template instance a is not a template declaration, it is a import
b.d(4): Error: a!(int) is used as a type
b.d(4): variable b.b.x voids have no value

Why can't I do this?
Comment 1 Russ Lewis 2008-04-24 15:47:14 UTC
I don't know whether to call this a bug or a language design issue, but I know the workaround: specify the full name

Use
    a.a
instead of
    a
Comment 2 Bill Baxter 2008-04-24 17:04:17 UTC
(In reply to comment #1)
> I don't know whether to call this a bug or a language design issue, but I know
> the workaround: specify the full name
> 
> Use
>     a.a
> instead of
>     a
> 

I think this can also be avoided by having the module in a package.  Then DMD seems not to get confused.  I've not totally understood the specifics, it seems modules and other symbols conflict in ways that package names don't.

So I think if you put a.d into an 'a' directory, make it's module statement be "module a.a;" then do 

import a.a;

then you won't get the conflict.  Can anyone confirm this?  Don't have time at the moment...

Comment 3 Bill Baxter 2008-04-24 18:23:56 UTC
(In reply to comment #2)
> (In reply to comment #1)
> > I don't know whether to call this a bug or a language design issue, but I know
> > the workaround: specify the full name
> > 
> > Use
> >     a.a
> > instead of
> >     a
> > 
> 
> I think this can also be avoided by having the module in a package.  Then DMD
> seems not to get confused.  I've not totally understood the specifics, it seems
> modules and other symbols conflict in ways that package names don't.
> 
> So I think if you put a.d into an 'a' directory, make it's module statement be
> "module a.a;" then do 
> 
> import a.a;
> 
> then you won't get the conflict.  Can anyone confirm this?  Don't have time at
> the moment...
> 

Jarrett Billingsley wrote:
>That wouldn't work either, since the top-level name is also a.  It's that 
modules and packages have a higher precedence than the symbols within them. 

Ah, ok.  So I guess when I've gotten rid of such problems in the past by putting the offending module in a package, it worked because I named the package something that didn't conflict.

But this still does point out the issue with namespace pollution that arises when using top-level, no-package modules.  Seems like that should be a general rule of thumb for D programming -- "Effective D": Rule #1: always put your classes in a package.

Comment 4 Jerry Quinn 2012-01-13 21:38:36 UTC
Any thoughts?  This bug is almost 4 years old and still present.
Comment 5 Jonathan M Davis 2012-01-13 22:00:37 UTC
I'm not sure if this is a bug or not. Given that it would work if a.a weren't a template, that would tend to indicate that it's a bug, but I don't know. The problem probably is tied into the fact that a.a doesn't really exist until it's instantiated.

Regardless, this is one of a long list of bugs which has been sitting around for a long time without being looked at. The increased community involvement with dmd has helped substantially in getting bugs fixed, but there are still plenty of them like this sitting around. There is talk of putting greater focus on older bugs (e.g. addressing the 10 oldest bugs in bugzill each release) which may finally ameliorate the problem though.
Comment 6 Walter Bright 2012-01-22 01:35:54 UTC
The error you get is expected.

The statement:

    import a;

introduces the name 'a' into the current scope, where 'a' is a module name. Names in the current scope are always searched before names in imported scopes. Hence, the 'a' module name is found before 'a' the template.

a.a works because module 'a' is found, and then 'a' is looked up in the scope of module 'a'.

This is how it is designed to work.