Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.

Commit e4b00e7

Browse files
committed
Fix Issue 20768 - __move_post_blt must recursively call itself on static arrays whose elements are structs or static arrays that recursively contain structs [DIP1014]
NB: this fix disregards DIP1014's advice to either not use hasElaborateMove!T within __move_post_blt or to use it only once at the start of the function.
1 parent cc4b3e1 commit e4b00e7

File tree

1 file changed

+35
-1
lines changed

1 file changed

+35
-1
lines changed

src/core/internal/moving.d

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,10 @@ Note:
2929
void __move_post_blt(S)(ref S newLocation, ref S oldLocation) nothrow
3030
if (is(S == struct))
3131
{
32+
import core.internal.traits : hasElaborateMove;
3233
static foreach (i, M; typeof(S.tupleof))
3334
{
34-
static if (is(M == struct))
35+
static if (hasElaborateMove!M)
3536
{
3637
__move_post_blt(newLocation.tupleof[i], oldLocation.tupleof[i]);
3738
}
@@ -48,6 +49,17 @@ void __move_post_blt(S)(ref S newLocation, ref S oldLocation) nothrow
4849
}
4950
}
5051

52+
void __move_post_blt(S)(ref S newLocation, ref S oldLocation) nothrow
53+
if (__traits(isStaticArray, S))
54+
{
55+
import core.internal.traits : hasElaborateMove;
56+
static if (S.length && hasElaborateMove!(typeof(newLocation[0])))
57+
{
58+
foreach (i; 0 .. S.length)
59+
__move_post_blt(newLocation[i], oldLocation[i]);
60+
}
61+
}
62+
5163
@safe nothrow unittest
5264
{
5365
struct A
@@ -111,3 +123,25 @@ void __move_post_blt(S)(ref S newLocation, ref S oldLocation) nothrow
111123
__move_post_blt(dest, src);
112124
assert(!doNotMove.movedInto);
113125
}
126+
127+
@safe nothrow unittest
128+
{
129+
static struct A
130+
{
131+
bool movedInto;
132+
void opPostMove(const ref A oldLocation)
133+
{
134+
movedInto = true;
135+
}
136+
}
137+
static struct B
138+
{
139+
A[2] a;
140+
}
141+
B src, dest;
142+
__move_post_blt(dest, src);
143+
foreach (ref a; src.a)
144+
assert(!a.movedInto);
145+
foreach (ref a; dest.a)
146+
assert(a.movedInto);
147+
}

0 commit comments

Comments
 (0)