www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 4302] New: compiler errors using startsWith in CTFE

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

           Summary: compiler errors using startsWith in CTFE
           Product: D
           Version: D2
          Platform: Other
        OS/Version: Windows
            Status: NEW
          Keywords: rejects-valid
          Severity: regression
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: r.sagitario gmx.de



PDT ---
the following code fails with dmd 2.047:

import std.algorithm;

const bool var = startsWith("ab", "a");

dmd output:

c:\l\dmd2\windows\bin\..\..\src\phobos\std\functional.d(176): Error: static
assert  "Bad binary function q{a == b}. You need to use a valid D expression
using symbols a of type dchar and b of type string."
c:\l\dmd2\windows\bin\..\..\src\phobos\std\functional.d(179):       
instantiated from here: Body!(dchar,string)
c:\l\dmd2\windows\bin\..\..\src\phobos\std\algorithm.d(1983):       
instantiated from here: result!(dchar,string)

the error disappears if you remove the "const".

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




PDT ---
I've tried to untangle the startsWith code, and here's the minimal test case I
could come up with so far:

///////////////////////
template binaryFunImpl(bool b)
{
       template Body()
       {
           static assert(b);
           alias bool BodyType;
       }
       alias Body!().BodyType  ReturnType;  // line 9
}

uint startsWith(A)(A a) if (is(binaryFunImpl!(true ).ReturnType)) { return 1; }
uint startsWith(A)(A a) if (is(binaryFunImpl!(false).ReturnType)) { return 0; }
 // line 13

const uint var = startsWith(1);
///////////////////////
dmd produces:

test.d(6): Error: static assert  (b) is false
test.d(9):        instantiated from here: Body!()
test.d(13):        instantiated from here: binaryFunImpl!(false)

The error does not show up if var is not const. Also, dmd 2.032 to 2.045 do not
produce this error (2.046 fails), so it seems a compiler regression being
triggered with the new implementation of startsWith.

This is what happens:

while deducing a template match,
- a template instance of binaryFunImpl!false is created to evaluate
is(binaryFunImpl!(false).ReturnType)
- the template instance is added as a member to the module (template.c(3779))
- semantic analysis fails, so the respective startsWith alternative is rejected
- compiler attempts to compile added binaryFunImpl!false and fails

maybe, the template instance should be removed from the module member list at
template.c(3975)

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


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Version|D2                          |D1 & D2
            Summary|Regression(2.046): compiler |Regression(2.046, 1.061):
                   |errors using startsWith in  |compiler errors using
                   |CTFE                        |startsWith in CTFE



Reduced test case shows it doesn't require template constraints, and applies to
D1 as well. Passes on D1.060, fails on D1.061.
-----
template fail4302() {
    static assert(0);
}
template bug4302() {
   alias fail4302!() bad;
}
static if (is(bug4302!())) {}
--------
// And this case broke one of my early attempts to fix it

template tough4302()
{
  template bar()
  { 
     template far()
     {
         static assert(0);
     }
     alias far!() par;
  }
  static if (is(bar!())) {}
}

alias tough4302!() tougher;

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


Don <clugdbug yahoo.com.au> changed:

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



The cause of the regression was this line at the end of
TemplateInstance::semantic()
around line 3980:

        if (global.gag)
        {   // Try to reset things so we can try again later to instantiate it
            tempdecl->instances.remove(tempdecl_instance_idx);
+            semanticRun = 0;
+            inst = NULL;
        }
This code was added in svn 477, to fix bug 4042. 
BUT... removing those lines, bug 4042 still passes, and the test suite still



not reset for a later attempt, if the instantiation was made from inside a
static if. You only get chance at a static if.
Note that template constraints set the SCOPEstaticif flag.

// template.c, line 3982.

        if (global.gag)
        {   // Try to reset things so we can try again later to instantiate it
            tempdecl->instances.remove(tempdecl_instance_idx);
+         if (!(sc->flags & SCOPEstaticif))
+         {
            semanticRun = 0;
            inst = NULL;
+         }
    }

Thirdly, it is in fact possible that what we're seeing is a consequence of
bug4269, ie is a bug in is(). If so, then this patch is just a temporary
workaround until that deeper bug is fixed.

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




PDT ---

 The cause of the regression was this line at the end of
 TemplateInstance::semantic()
 around line 3980:
 
         if (global.gag)
         {   // Try to reset things so we can try again later to instantiate it
             tempdecl->instances.remove(tempdecl_instance_idx);
 +            semanticRun = 0;
 +            inst = NULL;
         }
The template is also added to the member list of the importing scope/module (lines 3752+). I guess this should be undone aswell. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 21 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4302




PDT ---
Or maybe even simpler: it's probably not necessary to add the template as a
member to the module if it is instantiated in a "static if" or similar.

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





 Or maybe even simpler: it's probably not necessary to add the template as a
 member to the module if it is instantiated in a "static if" or similar.
I think you're right. Maybe it should not be added, if it is only instantiated in an "is" expression (rather using "static if" as the criterion). But that might make compile times blow out, if an is() occurs in a loop. That may be the root cause of bug 4269 and bug 3996, as well. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 22 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4302




PDT ---
It seems to me that the module member list is not searched when looking for
existing template instantations, but templdecl->instances. The failed template
instance is currently removed from that array, so it should do no extra harm to
remove it from the member list aswell.

issue 4269 does not deal with templates, so it will not change with a fix to
this bug. It's kind of the reverse problem: the declaration exists in the
member list, but is not revisited after causing an error once.

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


Walter Bright <bugzilla digitalmars.com> changed:

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



00:26:49 PDT ---
http://www.dsource.org/projects/dmd/changeset/632

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


klickverbot <code klickverbot.at> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |code klickverbot.at



---
This turned out to be an incomplete fix since this situation can not only occur
in static ifs, see bug 6602.

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