Thread overview
[Issue 3131] New: better type resolve
Jul 03, 2009
davidl@126.com
Jul 03, 2009
david
Jul 03, 2009
david
Jul 04, 2009
Derek Parnell
Dec 21, 2012
Andrej Mitrovic
July 03, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3131

           Summary: better type resolve
           Product: D
           Version: 2.028
          Platform: Other
        OS/Version: Windows
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: davidl@126.com


class c{
}

c c;
c = new c;

Jarrett mentioned that it doesn't compile in bug 3125.

This can alleviate the pain of porting C# code.
I patched this in my own box when I tried to port some C# code.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
July 03, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3131


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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jarrett.billingsley@gmail.c
                   |                            |om




--- Comment #1 from Jarrett Billingsley <jarrett.billingsley@gmail.com>  2009-07-03 08:42:11 PDT ---
No.  This is working as intended.  What you're doing here is shadowing the global 'c' with a local 'c'.  Symbol lookup in D is simple: it looks in enclosing scopes until it finds a symbol of the given name, no matter how you're using that name.  If you're porting code from another language, you're going to have to expect some translation work.  And besides, what's so difficult about "c c = new c;", or better yet, _not doing it in the first place_?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
July 03, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3131


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

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|normal                      |enhancement




-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
July 03, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3131





--- Comment #2 from david <davidl@126.com>  2009-07-03 16:33:30 PDT ---
(In reply to comment #1)
> No.  This is working as intended.  What you're doing here is shadowing the global 'c' with a local 'c'.  Symbol lookup in D is simple: it looks in enclosing scopes until it finds a symbol of the given name, no matter how you're using that name.  If you're porting code from another language, you're going to have to expect some translation work.  And besides, what's so difficult about "c c = new c;", or better yet, _not doing it in the first place_?

c c = new c; <-- this is the only 1 case that trigger this issue. Sometimes you can have

class ClassType1
{
}

class ClassType2
{
  ClassType1 ClassType1;
  void func(ClassType1 t){} // this ClassType1 is clearly referring to the type
of "ClassType1"
}

And it's not hard to make this work. I see no reason to ignore this one.

My own dmd gets several other features patched. So it's somewhat troublesome to isolate the patch to this particular bug.

The idea is pretty simple, when you try to tell the user the error, firstly try to resolve the type upper scope

A roughly patch:

Type *TypeIdentifier::semantic(Loc loc, Scope *sc)
{
    Type *t;
    Expression *e;
    Dsymbol *s;
+++    bool tried = false;
+++    Scope *sce = sc -> enclosing;

    //printf("TypeIdentifier::semantic(%s)\n", toChars());
    resolve(loc, sc, &e, &t, &s);
+++ L1:
    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
    {
+++            if ( sce != NULL)
+++            {
+++                resolve(loc, sce, &e, &t, &s);
+++                sce = sce -> enclosing;
+++                goto L1;
+++            }

#ifdef DEBUG
    if (!global.gag)
        printf("1: ");
#endif
    if (s)
    {
        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;
}

You see, it's simple. I think it should be enhanced.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
July 03, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3131





--- Comment #3 from david <davidl@126.com>  2009-07-03 16:43:39 PDT ---
Umm, this time I review the patch, that bool tried is some legacy way to solve the issue. It didn't work correctly if it requires to resolve the symbol in upper-upper scope. I changed it to the current one, but the bool tried left forgotten.

I won't try to hack the compiler, if hacking it is relatively simple, the issue is hard to bypass. The original C# code uses duplication name of var and type everywhere.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
July 03, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3131





--- Comment #4 from Jarrett Billingsley <jarrett.billingsley@gmail.com>  2009-07-03 16:59:11 PDT ---
(In reply to comment #2)

> Sometimes you can have
> 
> class ClassType1
> {
> }
> 
> class ClassType2
> {
>   ClassType1 ClassType1;
>   void func(ClassType1 t){} // this ClassType1 is clearly referring to the type
> of "ClassType1"
> }
> 
> And it's not hard to make this work. I see no reason to ignore this one.

I do.  It's stupid and pointless.  Just name your local variable _something else_.

> You see, it's simple. I think it should be enhanced.

Just because it's simple doesn't mean it should be done.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
July 04, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3131


Derek Parnell <ddparnell@bigpond.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ddparnell@bigpond.com




--- Comment #5 from Derek Parnell <ddparnell@bigpond.com>  2009-07-03 20:33:36 PDT ---
Regardless of whether it is a good idea or not, I see a related problem in that there is a bit of apparent inconsistency.

Look at this program ...

// ------------
struct X
{
}
struct Y
{
    X X;   // Disallowed
}
void main()
{
    X X;   // Allowed.
}
// ------------

Either both instances should be disallowed or both allowed, IMO.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
July 04, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3131





--- Comment #6 from Jarrett Billingsley <jarrett.billingsley@gmail.com>  2009-07-03 21:43:33 PDT ---
(In reply to comment #5)
> Regardless of whether it is a good idea or not, I see a related problem in that there is a bit of apparent inconsistency.
> 
> Look at this program ...
> 
> // ------------
> struct X
> {
> }
> struct Y
> {
>     X X;   // Disallowed
> }
> void main()
> {
>     X X;   // Allowed.
> }
> // ------------
> 
> Either both instances should be disallowed or both allowed, IMO.

I would say they should both be allowed.  The declaration of the struct member should happen semantically after the type lookup, just like with the variable.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 21, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=3131


Andrej Mitrovic <andrej.mitrovich@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrej.mitrovich@gmail.com


--- Comment #7 from Andrej Mitrovic <andrej.mitrovich@gmail.com> 2012-12-21 10:46:48 PST ---
(In reply to comment #6)
> I would say they should both be allowed.  The declaration of the struct member should happen semantically after the type lookup, just like with the variable.

This kind of code is just asking for trouble.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------