www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 7989] New: isInputRange and isForwardRange declare unused variables

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

           Summary: isInputRange and isForwardRange declare unused
                    variables
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Phobos
        AssignedTo: nobody puremagic.com
        ReportedBy: smjg iname.com
            Blocks: 3960



http://dlang.org/function.html
"It is an error to declare a local variable that is never referred to. Dead
variables, like anachronistic dead code, are just a source of confusion for
maintenance programmers."

However, as Timon Gehr has pointed out on digitalmars.D.learn,
std.range.isInputRange breaks this rule, and I've discovered that
isForwardRange does too.

template isInputRange(R)
{
    enum bool isInputRange = is(typeof(
    {
        R r = void;       // can define a range object
        if (r.empty) {}   // can test for empty
        r.popFront();     // can invoke popFront()
        auto h = r.front; // can get the front of the range
    }));
}

template isForwardRange(R)
{
    enum bool isForwardRange = isInputRange!R && is(typeof(
    {
        R r1 = void;
        R r2 = r1.save; // can call "save" against a range object
    }));
}

h and r2 are unused variables.  These templates only work at the moment because
of issue 3960.  Fixing that issue would at the moment cause these templates to
always evaluate to false, since the declarations of h and r2 are illegal
because the variables are never referred to.

Possible solutions:

-        auto h = r.front; // can get the front of the range
+        cast(void) r.front; // can get the front of the range

-        R r2 = r1.save; // can call "save" against a range object
+        static assert(is(typeof(r1.save) : R));

If issue 3960 is dealt with by removing the statement from the spec instead,
there is still some support for a warning about it, so it would be still worth
dealing with this in order to avoid such a warning.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 26 2012
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7989


Steven Schveighoffer <schveiguy yahoo.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |schveiguy yahoo.com



07:17:50 PDT ---


 -        auto h = r.front; // can get the front of the range
 +        cast(void) r.front; // can get the front of the range
front should return a value, returning void is not acceptable, but this would pass your code. I think this might work better: static assert(is(typeof(r.front) != void)); It may also be required that front can be used to initialize a variable (I think there may be some cases where a non-void value cannot be used this way, but I'm not sure). How do you test for this, and then 'use' the variable later when you have no idea how it can be used? I suppose you could pass it to a function template? This kind of requirement is going to be problematic, possibly in a lot of places. It might make sense to define some more helper enums for this, like isNonVoidInitializer or something like that. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 26 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7989





 It may also be required that front can be used to initialize a variable (I
 think there may be some cases where a non-void value cannot be used this way,
 but I'm not sure).  How do you test for this, and then 'use' the variable later
 when you have no idea how it can be used?  I suppose you could pass it to a
 function template?
Maybe auto h = r.front; static assert(is(typeof(h))); (I've assumed here that using a variable in a static assert or IsExpression passes as referencing it.) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 26 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7989





 I suppose you could pass it to a function template?
I've just figured that would work as well. Define void nop(T...)(T t) {} then this could be used to (a) require that something is of a non-void type (b) require that something is implicitly convertible to a given type (c) reference an otherwise unreferenced variable, thus suppress the unused variable error/warning so the lines I suggested would become nop(r.front); nop!(R)(r1.save); -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 26 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7989


Jonathan M Davis <jmdavisProg gmx.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jmdavisProg gmx.com



PDT ---
I'd say that this is a very argument for why the compiler _shouldn't_ complain
about unused variables at all.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 26 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7989





 I'd say that this is a very argument for why the compiler _shouldn't_ complain
 about unused variables at all.
What are you referring to as "this" exactly? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 26 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7989




PDT ---
 What are you referring to as "this" exactly?
This bug report. The fact that isInputRange and isForwardRange rely on declaring variables which aren't used being legal. It would be really annoying for unused local variables to be illegal when dealing with template constraint stuff like isInputRange and isForwardRange. Code would have to be needlessly contorted to deal with that fact, and you wouldn't ever get a good error about why the result of the template was false, because it would be part of a template constraint. IHMO, the very issue that this bug report brings up highlights a good reason why unused local variables should continue to be ignored by the compiler. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 26 2012
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7989




This discussion is relevant to both this and issue 3960, so I'm continuing it
on digitalmars.D.learn under the existing "Docs: Section on local variables"
thread.

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