Skip to content

Commit 19bf7a4

Browse files
authored
[spec/expression] Add array literal heap allocation section (#3885)
* [spec/expression] Add array literal heap allocation section Also tweak `@nogc` items. * Add 3 more cases
1 parent 1880c8d commit 19bf7a4

File tree

2 files changed

+38
-5
lines changed

2 files changed

+38
-5
lines changed

spec/expression.dd

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2143,7 +2143,9 @@ $(GNAME ArrayLiteral):
21432143
are inserted as expressions in place of the sequence.
21442144
)
21452145

2146-
$(P Escaping array literals are allocated on the memory managed heap.
2146+
$(H4 $(LNAME2 array-literal-heap, GC Allocation))
2147+
2148+
$(P Escaping array literals are always allocated on the memory managed heap.
21472149
Thus, they can be returned safely from functions:)
21482150

21492151
---
@@ -2153,6 +2155,36 @@ $(GNAME ArrayLiteral):
21532155
}
21542156
---
21552157

2158+
$(P An array literal is not GC allocated if:)
2159+
2160+
* It initializes or assigns to a static array.
2161+
* It initializes a $(DDSUBLINK spec/attribute, scope, `scope`) slice.
2162+
* It is used on one side of a $(GLINK EqualExpression) or $(GLINK RelExpression).
2163+
* It is immediately $(RELATIVE_LINK2 index_operations, indexed) and used as an rvalue.
2164+
* It is used as a `foreach` aggregate where the element variable is not `ref`.
2165+
2166+
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
2167+
---
2168+
void f(scope int[] a, int[2] sa) @nogc
2169+
{
2170+
sa = [7, 8];
2171+
}
2172+
void g(int[] b) @nogc; // `b` is not scope, so may escape
2173+
2174+
void main() @nogc
2175+
{
2176+
int[3] sa = [1, 2, 3];
2177+
f([1, 2], [3, 4]);
2178+
//scope int[] a = [5, 6]; // requires `-preview=dip1000`
2179+
//g([1, 2]); // error, array literal heap allocated
2180+
assert([1, 2] < [3, 2]);
2181+
assert([1, 2][1] == 2);
2182+
foreach (e; [4, 2, 9])
2183+
assert(e > 0);
2184+
}
2185+
---
2186+
)
2187+
21562188
$(H4 $(LNAME2 cast_array_literal, Casting))
21572189

21582190
$(P When array literals are cast to another array type, each

spec/function.dd

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3723,16 +3723,17 @@ $(H2 $(LNAME2 nogc-functions, No-GC Functions))
37233723
)
37243724

37253725
$(OL
3726-
$(LI $(DDSUBLINK spec/expression, ArrayLiteral, constructing an array) on the heap)
3726+
$(LI $(DDSUBLINK spec/expression, array-literal-heap, constructing an array) on the heap)
37273727
$(LI resizing an array by writing to its $(D .length) property)
37283728
$(LI $(DDSUBLINK spec/expression, CatExpression, array concatenation))
37293729
$(LI $(DDSUBLINK spec/expression, simple_assignment_expressions, array appending))
37303730
$(LI $(DDSUBLINK spec/expression, AssocArrayLiteral, constructing an associative array))
37313731
$(LI $(DDSUBLINK spec/expression, IndexOperation, indexing) an associative array
3732-
$(NOTE because it may throw $(D RangeError) if the specified key is not present))
3732+
$(RATIONALE Indexing may throw a $(D RangeError) if the specified key is not present.))
37333733
$(LI $(DDSUBLINK spec/expression, NewExpression, allocating an object with `new`) on the heap
3734-
$(NOTE `new` declarations of $(D class types) in function scopes are compatible with
3735-
$(D @nogc) if used for $(D scope) variables, as they result in allocations on the stack))
3734+
$(NOTE `new` declarations of $(D class) types in function scopes are compatible with
3735+
$(D @nogc) if used to initialize a $(DDSUBLINK spec/attribute, scope-class-var, $(D scope) variable),
3736+
as they result in allocations on the stack.))
37363737
$(LI calling functions that are not `@nogc`, unless the call is
37373738
in a $(GLINK2 version, ConditionalStatement)
37383739
controlled by a $(GLINK2 version, DebugCondition))

0 commit comments

Comments
 (0)