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

Commit 69d120f

Browse files
authored
Merge pull request #3065 from n8sh/issue-20767-20768
[DIP1014] __move_post_blt: recursively call on fields that are static arrays & do not recursively call on non-field members merged-on-behalf-of: Nicholas Wilson <thewilsonator@users.noreply.github.com>
2 parents d11dd8c + e4b00e7 commit 69d120f

File tree

1 file changed

+61
-3
lines changed

1 file changed

+61
-3
lines changed

src/core/internal/moving.d

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,12 @@ Note:
2929
void __move_post_blt(S)(ref S newLocation, ref S oldLocation) nothrow
3030
if (is(S == struct))
3131
{
32-
static foreach (memberName; __traits(allMembers, S))
32+
import core.internal.traits : hasElaborateMove;
33+
static foreach (i, M; typeof(S.tupleof))
3334
{
34-
static if (is(typeof(__traits(getMember, S, memberName)) == struct))
35+
static if (hasElaborateMove!M)
3536
{
36-
__move_post_blt(__traits(getMember, newLocation, memberName), __traits(getMember, oldLocation, memberName));
37+
__move_post_blt(newLocation.tupleof[i], oldLocation.tupleof[i]);
3738
}
3839
}
3940

@@ -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
@@ -87,3 +99,49 @@ void __move_post_blt(S)(ref S newLocation, ref S oldLocation) nothrow
8799
__move_post_blt(dest, src);
88100
assert(dest.movedInto && dest.a.movedInto);
89101
}
102+
103+
@safe nothrow unittest
104+
{
105+
static struct DoNotMove
106+
{
107+
bool movedInto;
108+
void opPostMove(const ref DoNotMove oldLocation)
109+
{
110+
movedInto = true;
111+
}
112+
}
113+
static DoNotMove doNotMove;
114+
115+
struct A
116+
{
117+
@property ref DoNotMove member()
118+
{
119+
return doNotMove;
120+
}
121+
}
122+
A src, dest;
123+
__move_post_blt(dest, src);
124+
assert(!doNotMove.movedInto);
125+
}
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)