www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 2006] New: Appending empty array using ~= doesn't work

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

           Summary: Appending empty array using ~= doesn't work
           Product: D
           Version: 2.012
          Platform: PC
        OS/Version: Windows
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla digitalmars.com
        ReportedBy: bartosz relisoft.com


I have an empty array of arrays of string aas. I append to it an empty array of
string. The result should be an array aas of length one. 

string [][] aas = [];
aas ~= cast (string []) [];
writefln ("%d", aas.length);
aas = aas ~ cast (string []) [];
writefln ("%d", aas.length);

It works correctly when using assignment and concatenation, but id doesn't when
using the combined operator ~=. In the latter case, the length of array remains
zero.


-- 
Apr 18 2008
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2006





------- Comment #1 from wbaxter gmail.com  2008-04-18 14:46 -------
That's funny I was just about to file this one myself a couple of days ago, BUT
then I decided that it probably isn't really a bug.

[] could be an empty array of any type.  So the compiler is interpreting it as
an empty string[][], not an empty string[].  You have a T[], you concat an
empty T[],  your original array isn't supposed to change.

I will agree it's not the most useful of behaviors, and the doc could certainly
be clearer about what will happen in such a case, but I don't think its
actually a bug.  It's just the compiler interpreting [] in a not-so-useful
manner.  If you type a literal "~= []" in the code then clearly you want
something to happen.

The workaround is to use "~= [[]]" instead.


-- 
Apr 18 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2006


smjg iname.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |smjg iname.com
           Keywords|                            |wrong-code




------- Comment #2 from smjg iname.com  2008-11-21 15:08 -------
(In reply to comment #1)
 [] could be an empty array of any type.  So the compiler is interpreting it as
 an empty string[][], not an empty string[].  You have a T[], you concat an
 empty T[],  your original array isn't supposed to change.
But it has been explicitly cast to a string[]. How can a CastExpression be of any type other than that to which it is cast? --
Nov 21 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2006





------- Comment #3 from wbaxter gmail.com  2008-12-22 19:34 -------
I just got bitten by this again.

float[][] arr;
arr ~= [1.0]; // ok, adds a new element (an array of length 1).
arr ~= []; // not ok, does nothing. :-(

The last line there does nothing, apparently because the compiler interprets it
to be an array of array that's empty, which is the least useful interpretation.
 So I find it unexpected that the compiler interprets it this way.  Once
again... even though I already ran into it once.  I just forgot because it
seems so silly for the compiler to choose the interpretation that it does.

At the very least I'd like the compiler to generate an error saying it doesn't
know how to interpret 'arr ~= []'.


-- 
Dec 22 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2006


clugdbug yahoo.com.au changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Version|2.012                       |1.028




------- Comment #4 from clugdbug yahoo.com.au  2009-02-19 07:06 -------
Applies equally to D1.


-- 
Feb 19 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2006


Denis Derman <denis.spir gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |denis.spir gmail.com


--- Comment #5 from Denis Derman <denis.spir gmail.com> 2011-01-28 06:39:21 PST
---
(In reply to comment #3)
 I just got bitten by this again.
 
 float[][] arr;
 arr ~= [1.0]; // ok, adds a new element (an array of length 1).
 arr ~= []; // not ok, does nothing. :-(
 
 The last line there does nothing, apparently because the compiler interprets it
 to be an array of array that's empty, which is the least useful interpretation.
  So I find it unexpected that the compiler interprets it this way.  Once
 again... even though I already ran into it once.  I just forgot because it
 seems so silly for the compiler to choose the interpretation that it does.
 
 At the very least I'd like the compiler to generate an error saying it doesn't
 know how to interpret 'arr ~= []'.
Yes, ambiguity that is bug-prone, because both interpretations can run, must yield compiler error. Denis -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 28 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2006



--- Comment #6 from Stewart Gordon <smjg iname.com> 2011-10-01 13:13:23 PDT ---
(In reply to comment #5)
 (In reply to comment #3)
 At the very least I'd like the compiler to generate an error saying it doesn't
 know how to interpret 'arr ~= []'.
Yes, ambiguity that is bug-prone, because both interpretations can run, must yield compiler error.
Yes, an uncast [] is ambiguous. But the original bug report isn't about that, but about aas ~= cast (string []) []; which is completely unambiguous. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 01 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2006


yebblies <yebblies gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull
            Summary|Empty array literals with   |Empty array literals with
                   |explicit type implicitly    |explicit type implicitly
                   |convert to anything         |convert to any array type


--- Comment #7 from yebblies <yebblies gmail.com> 2012-02-03 22:16:00 EST ---
https://github.com/D-Programming-Language/dmd/pull/691

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


Stewart Gordon <smjg iname.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|Empty array literals with   |Appending empty array using
                   |explicit type implicitly    |~= cast(T[]) [] doesn't
                   |convert to any array type   |work


--- Comment #8 from Stewart Gordon <smjg iname.com> 2012-02-03 17:10:48 PST ---
The recent change to the summary line is wrong.

If they merely implicitly converted to any array type, the original code would
behave correctly, because the semantic analyser always attempts an exact match
before an implicit conversion match.  Clearly something else is going on.

(DMD 2.057 Win32)
----- bz2006.d -----
import std.stdio;

pragma(msg, typeof(cast(string[]) []));

void main() {
    string[][] aas = [];
    aas ~= cast(string[]) [];
    writefln("%d", aas.length);
    aas ~= (string[]).init;
    writefln("%d", aas.length);
    aas = aas ~ cast(string[]) [];
    writefln("%d", aas.length);

    auto empty = cast(string[]) [];
    pragma(msg, typeof(empty));
    aas ~= empty;
    writefln("%d", aas.length);
}
----------
C:\Users\Stewart\Documents\Programming\D\Tests\bugs>dmd bz2006.d
string[]
string[]

C:\Users\Stewart\Documents\Programming\D\Tests\bugs>bz2006
0
1
2
3
----------

Going by this, the problem seems to occur only with this specific
representation of an empty array, and only when it is applied directly to ~=
and not passed through a variable.

So it isn't an implicit conversion problem.  It would seem that DMD
special-cases this form, but this special-casing is broken.

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


yebblies <yebblies gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|Appending empty array using |Empty array literals with
                   |~= cast(T[]) [] doesn't     |explicit type implicitly
                   |work                        |convert to any array type


--- Comment #9 from yebblies <yebblies gmail.com> 2012-02-04 13:10:58 EST ---
No, you're wrong.  I just wrote a patch to fix this bug, I think I know where
the problem was and what I had to change to fix it.

eg.
struct S {}

void main()
{
        int[] x = cast(S[])[];
}

It has nothing to do with appending, but the fact that for T[][] the compiler
has to choose to append an empty array as a T[] or a T[][], and it does this by
checking implicit conversions, which pass incorrectly.

Please at least read the patch before deciding you know what the problem is.

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



--- Comment #10 from Stewart Gordon <smjg iname.com> 2012-02-04 06:15:31 PST ---
(In reply to comment #9)
 It has nothing to do with appending, but the fact that for T[][] the compiler
 has to choose to append an empty array as a T[] or a T[][], and it does this by
 checking implicit conversions, which pass incorrectly.
cast(T[]) [] is a T[], simple as that. So the bug is that, in this situation, for some perverted reason an implicit conversion match is chosen over an exact match. Removing the implicit conversions stops this bug from biting, but I can imagine there being other places where it might still be an issue. I'm finding it puzzling that changing a method in ArrayLiteralExp would alter the implicit conversions of a CastExpression. But if it works, so be it. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 04 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2006



--- Comment #11 from yebblies <yebblies gmail.com> 2012-02-05 01:29:46 EST ---
(In reply to comment #10)
 cast(T[]) [] is a T[], simple as that.  So the bug is that, in this situation,
 for some perverted reason an implicit conversion match is chosen over an exact
 match.  Removing the implicit conversions stops this bug from biting, but I can
 imagine there being other places where it might still be an issue.
 
 I'm finding it puzzling that changing a method in ArrayLiteralExp would alter
 the implicit conversions of a CastExpression.  But if it works, so be it.
Yes and no. In CatAssignExp::semantic, the compiler calls implicitConvTo on e2 (the array literal) to see if it can convert to T[][]. ArrayLiteralExp::implicitConvTo returns a match level, and unless it returns MATCHnomatch the compiler essentially rewrites the expression as (e1 ~= cast(typeof(e1))e2). All that works fine, the problem is in ArrayLiteralExp::implicitConvTo. An array literal can implicitly convert to a type if the type is an array, and each element converts to the type's element type. ArrayLiteralExp::implicitConvTo does that with something like the following (simplified): { level = assume perfect match foreach(element) if conversion match is worse than level level = this match } Which results in the assumption never being corrected if the literal has zero elements, which makes sense because an untyped empty array literal converts to anything. This breaks down if the array literal has been set an explicit type, which is what my patch fixes. The way it's all done is actually quite clever, but it takes a bit of work to understand. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 04 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2006



--- Comment #12 from github-bugzilla puremagic.com 2012-07-19 00:14:06 PDT ---
Commits pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/82700b3d2cf466cd69f57491a759a14e101467ac
Issue 2006 - Empty array literals with explicit type implicitly convert to
anything

ArrayLiteralExp::implicitConvTo defaults to MATCHexact, and when there are no
parameters it is never corrected.

https://github.com/D-Programming-Language/dmd/commit/9268d6fb1bedf9d931eadb5adf4067698b0d1e19
Merge pull request #691 from yebblies/issue2006

Issue 2006 - Empty array literals with explicit type implicitly convert to any
array type

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


yebblies <yebblies gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Version|D1 & D2                     |D1


--- Comment #13 from yebblies <yebblies gmail.com> 2012-07-20 01:06:50 EST ---
Fixed for D2 only.

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



--- Comment #14 from Kenji Hara <k.hara.pg gmail.com> 2012-07-19 09:13:24 PDT
---
Pull request for D1:
https://github.com/D-Programming-Language/dmd/pull/1056

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



--- Comment #15 from Kenji Hara <k.hara.pg gmail.com> 2012-07-20 23:34:03 PDT
---
Fixed for D1:
https://github.com/9rnsr/dmd/commit/d7a1b1cbb7bceaee00ffb6733bd1d267dd069550

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


Kenji Hara <k.hara.pg gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |FIXED


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