Issue 16763 - Associative array literal inside array or AA literal doesn't work as initializer if variable type is known
Summary: Associative array literal inside array or AA literal doesn't work as initiali...
Status: NEW
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P2 critical
Assignee: No Owner
URL:
Keywords: accepts-invalid, pull, rejects-valid
Depends on:
Blocks:
 
Reported: 2016-11-24 17:28 UTC by Denis Shelomovskii
Modified: 2024-07-01 20:38 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Denis Shelomovskii 2016-11-24 17:28:05 UTC
This code should work:
---
void main()
{
    int[int][] a = [[1 : 2]]; // ok
    int[int][] b = [[0 : 2]]; // expression ([[1]]) of type int[][]
    int[int][int] c = [1 : [0 : 2]]; // expression ([1:[2]]) of type int[][int]
    int[int][int] d = [1 : [3 : 2]]; // Error: not an associative array initializer

    static assert(!__traits(compiles, { int[][] x = [[0 : 2]]; })); // fails
    static assert(!__traits(compiles, { int[][int] x = [1 : [0 : 2]]; })); // fails
}
---
bug.d(4): Error: cannot implicitly convert expression ([[2]]) of type int[][] to int[int][]
bug.d(5): Error: cannot implicitly convert expression ([1:[2]]) of type int[][int] to int[int][int]
bug.d(6): Error: not an associative array initializer
---

Workarounds are:
* not specify variable type (e.g. use `auto`) or
* initialize with identity function called over literal or
* initialize with default value and assign later.

Note:
Compiler behavior depends on actual constants used (0 or 1 as key) so it looks like something is terribly wrong (memory corruption or alike).
Comment 1 Denis Shelomovskii 2016-12-16 14:59:19 UTC
(In reply to Denis Shelomovskii from comment #0)
>     int[int][] b = [[0 : 2]]; // expression ([[1]]) of type int[][]

It was "expression ([[2]])" actually.

So, looks like if `ArrayInitializer.inferType` isn't called AA literals are treated as array literals with explicit indices (see Static Initialization of Statically Allocated Arrays [1]) like in this code:
---
import std.stdio;

void main()
{
    int[][] a = [[2: 6, 1: 345, 3: 78, 6: 12]];
    writeln(a);
    int[][] aa = [1: [5: 7], 0: [7], 0: [0: 15] /* overrides previous element 0*/, [2: 6, 1: 3], /* overrides previous element 1*/ ]; 
    writeln(aa);
}
---
[[0, 345, 6, 78, 0, 0, 12]]
[[15], [0, 3, 6]]
---


[1] http://dlang.org/spec/arrays.html#static-init-static
Comment 2 Dlang Bot 2024-07-01 20:38:36 UTC
@ntrel created dlang/dmd pull request #16644 "Fix Bugzilla 16763 - Associative array literal inside array or AA lit…" fixing this issue:

- Fix Bugzilla 16763 - Associative array literal inside array or AA literal doesn't work as initializer if variable type is known

https://github.com/dlang/dmd/pull/16644