www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 3276] New: Mutual recursion broken in type templates

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

           Summary: Mutual recursion broken in type templates
           Product: D
           Version: 2.032
          Platform: x86
        OS/Version: Windows
            Status: NEW
          Severity: critical
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: bartosz relisoft.com


Created an attachment (id=442)
 --> (http://d.puremagic.com/issues/attachment.cgi?id=442)
bug example

Recursion in templates works, but mutual recursion doesn’t. I’m attaching
this
example—it can’t be reduced much further. Each part of it works separately,
but
once they start recursing into each other, I get the error:

small.d(3): Error: alias small.F!(void*).StripPtr recursive alias declaration

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


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |rejects-valid
                 CC|                            |clugdbug yahoo.com.au
            Summary|Mutual recursion broken in  |Recursion broken by alias
                   |type templates              |template parameter


--- Comment #1 from Don <clugdbug yahoo.com.au> 2010-05-12 12:35:28 PDT ---
Reduced test case shows it doesn't involve mutual recursion (original title was
"Mutual recursion broken in type templates")

template Bug3276(bool B) {
   static if (B)
      alias Bug3276!(false) Bug3276;
   else
       alias double Bug3276;
}

template Bug3276_b(alias W) {
    alias W!(true) Bug3276_b;
}

alias Bug3276_b!(Bug3276) Bug3276_c;

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 12 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3276


Shin Fujishiro <rsinfu gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |rsinfu gmail.com


--- Comment #2 from Shin Fujishiro <rsinfu gmail.com> 2010-11-02 22:09:58 PDT
---
The bug happens if a recursive template is instantiated via an alias:

  alias Bug3276 W;
  alias W!true w;

In template.c, the following if at the line 4304 tries to get the relevant
TemplateDeclaration for doing recursion:

TemplateDeclaration *TemplateInstance::findTemplateDeclaration(Scope *sc)
{
    ...
        TemplateInstance *ti;
        if (s->parent &&
            (ti = s->parent->isTemplateInstance()) != NULL)
        {
            if (
                (ti->name == id ||
                 ti->toAlias()->ident == id)    // <-- the cause
                &&
                ti->tempdecl)
    ...
}

Here 'this' refers to the recursive instantiation "Bug3276!(false)" and
id="Bug3276" is its identifier.  'ti' is the enclosing TemplateInstance (i.e.
"W!(true)").

The test sees if the identifier 'id' used in the instantiation
"Bug3276!(false)" is the same as the one of enclosing 'ti'.  But 'ti' was
instantiated with the aliased identifier (ti->name="W"), so the first condition
isn't met.

Then it tests the next condition: ti->toAlias()->ident.  It dives into the
following code in TemplateInstance::toAlias():

    if (aliasdecl)
    {
        return aliasdecl->toAlias();
    }

Here 'aliasdecl' is the "result" of the eponymous template "Bug3276!(true)",
and it's exactly the "alias Bug3276!(false)" analyzing now. 
AliasDeclaration::toAlias() does the follownig check:

    if (inSemantic)
    {   error("recursive alias declaration");
        aliassym = new TypedefDeclaration(loc, ident, Type::terror, NULL);
    }

Since it's in semantic, the compiler raises the error.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 02 2010
prev sibling next sibling parent reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3276


Shin Fujishiro <rsinfu gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |patch


--- Comment #3 from Shin Fujishiro <rsinfu gmail.com> 2010-11-02 22:11:39 PDT
---
Patch against dmd r737.

--- src/template.c
+++ src/template.c
   -4304,11 +4304,7    TemplateDeclaration
*TemplateInstance::findTemplateDeclaration(Scope *sc)
         if (s->parent &&
             (ti = s->parent->isTemplateInstance()) != NULL)
         {
-            if (
-                (ti->name == id ||
-                 ti->toAlias()->ident == id)
-                &&
-                ti->tempdecl)
+            if (ti->tempdecl && ti->tempdecl->ident == id)
             {
                 /* This is so that one can refer to the enclosing
                  * template, even if it has the same name as a member


Getting 'ti' for recognizing recursion is good; but the identifier should be
compared with the one of a TemplateDeclaration, not the TemplateInstance.  As
happened in the reported bug, ti->name is not always the appropriate identifier
for recursion check.

The patch removes ti->toAlias() for good.  TemplateInstance::toAlias() does
*not* resolve alias of itself; as seen in its implementation, it actually
returns the "result" of the template and makes no sense.  'id' has to be
compared with ti->tempdecl->ident.

The patch passed dmd, druntime and phobos tests.  It couldn't pass the broken
test (runnable/interpret.d) though.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 02 2010
parent Don <nospam nospam.com> writes:
d-bugmail puremagic.com wrote:
 http://d.puremagic.com/issues/show_bug.cgi?id=3276
 --- Comment #3 from Shin Fujishiro <rsinfu gmail.com> 2010-11-02 22:11:39 PDT
---

 The patch passed dmd, druntime and phobos tests.  It couldn't pass the broken
 test (runnable/interpret.d) though.

What do you mean, the broken test? It needs to pass, unless you have modified the file from the one in svn. (It fails on Linux with -O, but that is not part of the test).
Nov 03 2010
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3276


Walter Bright <bugzilla digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |bugzilla digitalmars.com
         Resolution|                            |FIXED


--- Comment #4 from Walter Bright <bugzilla digitalmars.com> 2010-12-05
23:00:13 PST ---
http://www.dsource.org/projects/dmd/changeset/784

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