[Issue 8557] AA error with string[string][]

d-bugmail at puremagic.com d-bugmail at puremagic.com
Wed Nov 27 23:20:33 PST 2013


https://d.puremagic.com/issues/show_bug.cgi?id=8557



--- Comment #13 from Kenji Hara <k.hara.pg at gmail.com> 2013-11-27 23:20:26 PST ---
This issue contains one compiler implementation bug and two enhancements.

----

In a variable definition which has explicit type declaration, the 'target' type
should be applied to the initializer recursively.

void testBugs()
{
    {
        int[ ] da = [1:2, 3];   // OK
        int[3] sa = [1:2, 3];   // OK
        int[int] aa = [0:3];    // OK
    }
    {
        int[ ][int] daa = [0:[1:2, 3]]; // NG, but should be OK
        int[3][int] saa = [0:[1:2, 3]]; // NG, but should be OK
        int[int][int] aaa = [0:[0:3]];  // NG, but should be OK
    }
}

This is a compiler implementation bug.

----

In current D grammar, ArrayInitializer can optionally have index (==AA key)
part,

  http://dlang.org/declaration#ArrayInitializer
  ArrayInitializer:
      [ ]
      [ ArrayMemberInitializations ]

  ArrayMemberInitializations:
      ArrayMemberInitialization
      ArrayMemberInitialization ,
      ArrayMemberInitialization , ArrayMemberInitializations

  ArrayMemberInitialization:
      NonVoidInitializer
      AssignExpression : NonVoidInitializer

Let's classify the pattern of array initializer.

1. Bare array initializer
    eg. [1, 2, 3]
2. Sparse array initializer
    eg. [1:2, 3, 0:1], ["1":"a", "b"]
    (gap is not an issue)
3. Indexed array initializer
    eg. [1:1, 2:2, 3:3], ["1":"a", "2":"b"]

Sparse version is only allowed for dynamic/static array initializing, because
AA initializing needs key for each elements.

void testInitializer1()
{
    // Bare array literal
    {
        int[]    a = [1, 2, 3];
        int[3]   b = [1, 2, 3];
      static assert(!is(typeof({
        int[int] c = [1, 2, 3]; // need key for each element
      })));
    }

    // Sparse array initializer is allowed only for (s)array.
    {
        int[]    a = [1:2, 3, 0:1];
        int[3]   b = [1:2, 3, 0:1];
      static assert(!is(typeof({
        int[int] c = [1:2, 3, 0:1]; // need key for each element
      })));
    }

    // Indexed array initializer
    {
        int[]    a = [1:2, 2:3, 0:1];
        int[3]   b = [1:2, 2:3, 0:1];
        int[int] c = [1:2, 2:3, 0:1];
    }
}

However, the index part in ArrayInitializer should be AssignExp,
so sparse array initializer cannot be appeared in index part.

void testInitializer2()
{
    // value is array (== indexed array initializer)
    {
        int[][int]  a = [0:[2, 3]];
        int[][]     b = [0:[2, 3]];
        int[2][int] c = [0:[2, 3]];
        int[2][]    d = [0:[2, 3]];
    }

    // value has gap (== sparse array initializer)
    {
        int[][int]  a = [0:[1:2, 3]];
        int[][]     b = [0:[1:2, 3]];
        int[3][int] c = [0:[1:2, 3]];
        int[3][]    d = [0:[1:2, 3]];
    }

    // value is AA (== indexed array initializer)
    {
        int[int][int] a = [0:[0:3]];
        int[][int]    b = [0:[0:3]];
        int[1][int]   c = [0:[0:3]];
        int[int][]    d = [0:[0:3]];
        int[int][1]   e = [0:[0:3]];
    }

    // key is array (== array literal expression == AssignExp)
    {
        int[int[]]  a = [[2, 3]:0];
        int[int[2]] b = [[2, 3]:0];
    }

    // key is AA (currently not supported in grammar)
    {
        int[int[int]] a = [[0:0]:0];
      //int[int[]]    b = [[0:0]:0];    // [0:0] is not AssignExp
      //int[int[1]]   c = [[0:0]:0];    // [0:0] is not AssignExp
    }

    // key has gap (currently not supported in grammar)
    {
      //int[int[]]  a = [[1:2, 3]:0];
      //int[int[3]] b = [[1:2, 3]:0];
    }
}

If we change the grammar as follows, the commented out lines in
testInitializer2 will be accepted properly.

ArrayMemberInitialization:
    NonVoidInitializer
    Initializer : NonVoidInitializer   <---!

It is the first enhancement request.

----

Type inference is in completely different situation.
At first, compiler tries to translate initializer to expression. Then,
- if it is impossible, inference fails.
- otherwise, pick up the type of converted expression.

An important point is, currently compiler does not convert sparse array
initializer to corresponding array literal expression.

void testInference()
{
    // bare array initializer to array literal
    {
        auto a = [1, 2, 3];
        static assert(is(typeof(a) == int[]));
    }

    // sparse array initializer to array literal
    // (gap is not important)
    {
      //auto a = [1:2, 3, 0:1];
      //static assert(is(typeof(a) == int[]));

      //auto a = [1:2, 3];
      //static assert(is(typeof(a) == int[]));
    }

    // indexed array literal to associative array literal
    {
        auto a = [1:2, 2:3, 0:1];
        static assert(is(typeof(a) == int[int]));
    }
}

Supporting it is the second enhancement request.

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


More information about the Digitalmars-d-bugs mailing list