www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 3231] New: Function declared to return a type with its same name doesn't compile

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

           Summary: Function declared to return a type with its same name
                    doesn't compile
           Product: D
           Version: 2.032
          Platform: All
        OS/Version: All
            Status: NEW
          Keywords: rejects-valid
          Severity: blocker
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: tim.matthews7 gmail.com


class Bar
{
}

class Foo
{
    Bar Bar(); //declare a func without the implementation
}

void main()
{
}

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






The error reported:

test.d(11): Error: function test.Foo.Bar is used as a type

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






Sorry I shouldn't have rushed this but it if I provide the implementation it
makes no difference. Are we meant to be allowed a function with the same name
as its return type or is this a bug?

class Bar
{
}

class Foo
{
    Bar Bar()
    {
        return null;
    } 
}

void main()
{
}

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


Jarrett Billingsley <jarrett.billingsley gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |jarrett.billingsley gmail.c
                   |                            |om
         Resolution|                            |INVALID





2009-08-06 17:22:42 PDT ---
Name lookup in D is simple: it starts with the scope in which the name is used,
and moves outward until it finds a symbol of that name, regardless of how the
symbol is used.  The function 'Bar' is inserted into Foo's namespace before its
return type is resolved.  When the return type is resolved, it finds the
function Bar() itself instead of the class Bar at module scope, and you get an
error.

Marking this as invalid unless it can be proven otherwise.

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


BCS <shro8822 vandals.uidaho.edu> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |shro8822 vandals.uidaho.edu





---
I also think this is invalid.

As a work around:

class Bar
{
}

class Foo
{
    .Bar Bar()   // note '.' to start from global scope
    {
        return null;
    } 
}

void main()
{
}

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


Cristi Vlasceanu <cristian zerobugs.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |cristian zerobugs.org





21:43:34 PDT ---
The bug was filed as a blocker for the .net implementation because there are
cases like this System.Text.RegularExpressions that has a static Match
Match(System.String, System.String) method.

I think that marking the bug as invalid because of a limitation in the
implementation is ridiculous.

The fix (which I am applying to the my source tree at
http://dnet.codeplex.com/) is very simple: continue the look up in enclosing
scope.

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






2009-08-06 22:22:05 PDT ---

 The bug was filed as a blocker for the .net implementation because there are
 cases like this System.Text.RegularExpressions that has a static Match
 Match(System.String, System.String) method.
 
 I think that marking the bug as invalid because of a limitation in the
 implementation is ridiculous.
It's not a limitation in the implementation, it's how the language is defined. their "inspiration" - allows for multiple symbols of the same name to be distinguished based on how they're used. D does not. If you have a disagreement, it's with the spec, not the implementation. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 06 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3231






---

 The bug was filed as a blocker for the .net implementation because there are
 cases like this System.Text.RegularExpressions that has a static Match
 Match(System.String, System.String) method.
 
 I think that marking the bug as invalid because of a limitation in the
 implementation is ridiculous.
 
 The fix (which I am applying to the my source tree at
 http://dnet.codeplex.com/) is very simple: continue the look up in enclosing
 scope.
class Foo { class Bar { } Bar Bar() { return new Bar(); } } There is no need to alter the compiler, just require fully qualified names. Heck, for imports of other CLR code via meta-data, that isn't even needed as IIRC assemblies alway use fully qualified names internally. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 07 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3231






21:28:56 PDT ---
 BCS
That case is indeed illegal, AND handled correctly by my fix.

You can try it out either by downloading the dnet compiler, or by applying the
change to DMD, here's the full code:

Type *TypeIdentifier::semantic(Loc loc, Scope *sc)
{
    Type *t;
    Expression *e;
    Dsymbol *s;

    //printf("TypeIdentifier::semantic(%s)\n", toChars());
    resolve(loc, sc, &e, &t, &s);
    if (t)
    {
    //printf("\tit's a type %d, %s, %s\n", t->ty, t->toChars(), t->deco);

    if (t->ty == Ttypedef)
    {   TypeTypedef *tt = (TypeTypedef *)t;

        if (tt->sym->sem == 1)
        error(loc, "circular reference of typedef %s", tt->toChars());
    }
    t = t->addMod(mod);
    }
    else
    {
#ifdef DEBUG
    if (!global.gag)
        printf("1: ");
#endif
    if (s)
    {
#if TARGET_NET
            //http://d.puremagic.com/issues/show_bug.cgi?id=3231
        if (sc->enclosing)
             return semantic(loc, sc->enclosing);
#endif
        s->error(loc, "is used as a type");
        //halt();
    }
    else
        error(loc, "%s is used as a type", toChars());
    t = tvoid;
    }
    //t->print();
    return t;
}

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


Stewart Gordon <smjg iname.com> changed:

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






 I think that marking the bug as invalid because of a limitation in the
 implementation is ridiculous.
AIUI this isn't a limitation in the implementation, but a characteristic of how D is designed.
 The fix (which I am applying to the my source tree at
 http://dnet.codeplex.com/) is very simple: continue the look up in enclosing
 scope.
Better beware of hijacking vulnerabilities. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 08 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3231






13:25:53 PDT ---


 I think that marking the bug as invalid because of a limitation in the
 implementation is ridiculous.
AIUI this isn't a limitation in the implementation, but a characteristic of how D is designed.
 The fix (which I am applying to the my source tree at
 http://dnet.codeplex.com/) is very simple: continue the look up in enclosing
 scope.
Better beware of hijacking vulnerabilities.
This is possibly valid, do you have an example that drives your point? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 08 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3231






---


 Better beware of hijacking vulnerabilities.
This is possibly valid, do you have an example that drives your point?
I'm not sure if there are any in this particular instance, but it's something to be careful of whenever you try to resolve a symbol to a different scope depending on how it's being used. It may be the case that the worst that can happen here is that the class-level function conflicts with an opCall on the module-level class. While no call of the form Bar(...) is happening here, I can see it getting confusing if one does occur.... -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 08 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3231






---
Adding the dot is so trivial and takes no time at all. I do believe that this
is indeed a bug anyway explanation of such:

This code will not compile:

class A
{
    void func();
    func getFunc()
    {
        return null;
    }
}
void main()
{
}


You cannot return a 'func' as it is not a type. 'func' is actually an instance
of 'delegate' so it should have been declared as that.


class A
{
    void func();
    void getFunc()
    {
        new func();
    }
}
void main()
{
}

Here 'getFunc' is declared as void but it doesn't compile either because this
time I am trying to new a 'func' which causes a compile error again because
'func' is not a type but an instance of delegate.

Whenever a peice of D code contains 2 identifiers next to each other like so:

AB XY

It can only mean either XY is an instance (whether that be value, ref, of
function returning) and AB is a type. Likewise I can't 'new' everything either.

The bug is simply that dmdfe wasn't attempting to find a type or instance with
the particular name but it was satisfied with the first symbol it found.

If this indeed hard to fixup now (and I would rather Walter focus on more
important issues) then adding a couple of dots is something I wouldn't mind to
do either (it would require a few bytes of code)

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


Stewart Gordon <smjg iname.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |spec





---
I think comment 3 pretty much covers it, but is this stated in the spec?

FTR here are two closely related examples that fail:

----- overload_scope_1.d -----
void func(int i) {}

class C {
    static {
        void func() {}
        void func(string s) {}
        void test() {
            func();
            func(42); // line 9
            func("test");
        }
    }
}
----------
overload_scope_1.d(9): Error: function overload_scope_1.C.func () does not
match parameter types (int)
overload_scope_1.d(9): Error: cannot implicitly convert expression (42) of type
int to immutable(char)[]
overload_scope_1.d(9): Error: cannot cast int to immutable(char)[]

----- overload_scope_2.d -----
import overload_scope_2a;
import overload_scope_2b;

Qwert yuiop;
----- overload_scope_2a.d -----
alias string Qwert;
----- overload_scope_2b.d -----
void Qwert() {}
----------
overload_scope_2.d(4): Error: overload_scope_2a.Qwert at overload_scope_2a.d(1)
conflicts with overload_scope_2b.Qwert at overload_scope_2b.d(1)
----------

(DMD 2.031 Win; messages essentially the same in DMD 1.046.)

These cases show that it's down to two things:
- overload sets apply only between imported modules, not between scoping levels
- in any case, they apply only between function overloads, not between
arbitrarily mixed entity types

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






---

  BCS
 That case is indeed illegal, AND handled correctly by my fix.
 
Given that you are willing to redefine the language I have to ask; What is correctly? Assuming you are allowing it: Even if you can make D handle the case, unless you can point at another .NET language (one that MS supports) that supports having both a function and a type with the same name in the same scope, I think it would be a bad idea to let D.NET do this. use F12 on the reused name? Adding this requires changing the specification of the D language and maybe even the whole .NET system. I would be uncomfortable with any change at all and would I wouldn't actively oppose a change that allows for both a member and a type in a class to have the same name. Assuming you are disallowing it: You are adding nothing to the language. Using fully qualified names (or .identifier) gets the same end effect. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 09 2009
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3231






---

 
 Better beware of hijacking vulnerabilities.
class Foo {} class Bar { int Foo(){} // this would become a conflict with only an arbitrary resolution. alias Foo Baz; } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 09 2009