1 /*
2 TEST_OUTPUT:
3 ---
4 fail_compilation/fail12255.d(29): Error: AA key type SC1 does not have 'bool opEquals(ref const SC1) const'
5 fail_compilation/fail12255.d(30): Error: AA key type SC2 does not support const equality
6 fail_compilation/fail12255.d(35): Error: AA key type SD1 should have 'size_t toHash() const nothrow @safe' if opEquals defined
7 fail_compilation/fail12255.d(36): Error: AA key type SD2 supports const equality but doesn't support const hashing
8 fail_compilation/fail12255.d(40): Error: AA key type SE1 should have 'size_t toHash() const nothrow @safe' if opEquals defined
9 fail_compilation/fail12255.d(41): Error: AA key type SE2 supports const equality but doesn't support const hashing
10 ---
11 */
12 
13 void main()
14 {
15     /* Key comparison and hashing are based on object bit representation,
16      * and they fully supported in runtime (TypeInfo.equals and TypeInfo.getHash)
17      */
18     int[SA1] a1;    // OK
19     int[SA2] a2;    // OK
20 
21     /* If only toHash is defined, AA assumes that is customized object hashing.
22      */
23     int[SB1] b1;    // OK
24     int[SB2] b2;    // OK
25 
26     /* If key does not support const equality,
27      * it is disallowed, because TypeInfo.equals will throw Error.
28      */
29     int[SC1] c1;    // NG
30     int[SC2] c2;    // NG
31 
32     /* If opEquals defined for const equality, corresponding toHash method
33      * is required to guarantee (a != b || a.toHash() == b.toHash()).
34      */
35     int[SD1] d1;    // NG
36     int[SD2] d2;    // NG
37 
38     /* same as SD cases
39      */
40     int[SE1] e1;    // NG
41     int[SE2] e2;    // NG
42 }
43 
44 struct SA1 { int val; }
45 struct SA2 { SA1 s; }
46 
47 struct SB1
48 {
49     // AA assumes this is specialized hashing (?)
50     size_t toHash() const nothrow @safe { return 0; }
51 }
52 struct SB2
53 {
54     SB1 s;
55     // implicit generated toHash() calls s.toHash().
56 }
57 
58 struct SC1
59 {
60     // does not support const equality
61     bool opEquals(typeof(this)) /*const*/ { return true; }
62 }
63 struct SC2
64 {
65     SC1 s;
66 }
67 
68 struct SD1
69 {
70     // Supports const equality, but
71     // does not have corresponding toHash()
72     bool opEquals(typeof(this)) const { return true; }
73 }
74 struct SD2
75 {
76     SD1 s;
77 }
78 
79 struct SE1
80 {
81     // Supports const equality, but
82     // does not have corresponding valid toHash()
83     bool opEquals(typeof(this)) const { return true; }
84     size_t toHash() @system { return 0; }
85 }
86 struct SE2
87 {
88     SE1 s;
89 }
90 
91 /*
92 TEST_OUTPUT:
93 ---
94 fail_compilation/fail12255.d(108): Error: bottom of AA key type SC1 does not have 'bool opEquals(ref const SC1) const'
95 fail_compilation/fail12255.d(109): Error: bottom of AA key type SC2 does not support const equality
96 fail_compilation/fail12255.d(110): Error: bottom of AA key type SD1 should have 'size_t toHash() const nothrow @safe' if opEquals defined
97 fail_compilation/fail12255.d(111): Error: bottom of AA key type SD2 supports const equality but doesn't support const hashing
98 fail_compilation/fail12255.d(112): Error: bottom of AA key type SE1 should have 'size_t toHash() const nothrow @safe' if opEquals defined
99 fail_compilation/fail12255.d(113): Error: bottom of AA key type SE2 supports const equality but doesn't support const hashing
100 ---
101 */
102 void testSArray()
103 {
104     int[SA1[1]] a1;    // OK
105     int[SA2[1]] a2;    // OK
106     int[SB1[1]] b1;    // OK
107     int[SB2[1]] b2;    // OK
108     int[SC1[1]] c1;    // NG
109     int[SC2[1]] c2;    // NG
110     int[SD1[1]] d1;    // NG
111     int[SD2[1]] d2;    // NG
112     int[SE1[1]] e1;    // NG
113     int[SE2[1]] e2;    // NG
114 }
115 
116 /*
117 TEST_OUTPUT:
118 ---
119 fail_compilation/fail12255.d(133): Error: bottom of AA key type SC1 does not have 'bool opEquals(ref const SC1) const'
120 fail_compilation/fail12255.d(134): Error: bottom of AA key type SC2 does not support const equality
121 fail_compilation/fail12255.d(135): Error: bottom of AA key type SD1 should have 'size_t toHash() const nothrow @safe' if opEquals defined
122 fail_compilation/fail12255.d(136): Error: bottom of AA key type SD2 supports const equality but doesn't support const hashing
123 fail_compilation/fail12255.d(137): Error: bottom of AA key type SE1 should have 'size_t toHash() const nothrow @safe' if opEquals defined
124 fail_compilation/fail12255.d(138): Error: bottom of AA key type SE2 supports const equality but doesn't support const hashing
125 ---
126 */
127 void testDArray()
128 {
129     int[SA1[]] a1;    // OK
130     int[SA2[]] a2;    // OK
131     int[SB1[]] b1;    // OK
132     int[SB2[]] b2;    // OK
133     int[SC1[]] c1;    // NG
134     int[SC2[]] c2;    // NG
135     int[SD1[]] d1;    // NG
136     int[SD2[]] d2;    // NG
137     int[SE1[]] e1;    // NG
138     int[SE2[]] e2;    // NG
139 }
140