1 module core.lifetime;
2 
3 import core.internal.attributes : betterC;
4 
5 // version (CRuntime_LIBWASM) {} // Removed the GC from here
6 
7 private extern (C) void* _d_allocmemory(size_t sz) pure nothrow;
8 // emplace
9 /**
10 Given a pointer `chunk` to uninitialized memory (but already typed
11 as `T`), constructs an object of non-`class` type `T` at that
12 address. If `T` is a class, initializes the class reference to null.
13 Returns: A pointer to the newly constructed object (which is the same
14 as `chunk`).
15  */
16 T* emplace(T)(T* chunk) @safe pure nothrow
17 {
18     import core.internal.lifetime : emplaceRef;
19 
20     emplaceRef!T(*chunk);
21     return chunk;
22 }
23 
24 ///
25 @betterC
26 @system unittest
27 {
28     static struct S
29     {
30         int i = 42;
31     }
32     S[2] s2 = void;
33     emplace(&s2);
34     assert(s2[0].i == 42 && s2[1].i == 42);
35 }
36 
37 ///
38 @system unittest
39 {
40     interface I {}
41     class K : I {}
42 
43     K k = void;
44     emplace(&k);
45     assert(k is null);
46 
47     I i = void;
48     emplace(&i);
49     assert(i is null);
50 }
51 
52 /**
53 Given a pointer `chunk` to uninitialized memory (but already typed
54 as a non-class type `T`), constructs an object of type `T` at
55 that address from arguments `args`. If `T` is a class, initializes
56 the class reference to `args[0]`.
57 This function can be `@trusted` if the corresponding constructor of
58 `T` is `@safe`.
59 Returns: A pointer to the newly constructed object (which is the same
60 as `chunk`).
61  */
62 T* emplace(T, Args...)(T* chunk, auto ref Args args)
63     if (is(T == struct) || Args.length == 1)
64 {
65     import core.internal.lifetime : emplaceRef;
66 
67     emplaceRef!T(*chunk, forward!args);
68     return chunk;
69 }
70 
71 ///
72 @betterC
73 @system unittest
74 {
75     int a;
76     int b = 42;
77     assert(*emplace!int(&a, b) == 42);
78 }
79 
80 @betterC
81 @system unittest
82 {
83     shared int i;
84     emplace(&i, 42);
85     assert(i == 42);
86 }
87 
88 /**
89 Given a raw memory area `chunk` (but already typed as a class type `T`),
90 constructs an object of `class` type `T` at that address. The constructor
91 is passed the arguments `Args`.
92 If `T` is an inner class whose `outer` field can be used to access an instance
93 of the enclosing class, then `Args` must not be empty, and the first member of it
94 must be a valid initializer for that `outer` field. Correct initialization of
95 this field is essential to access members of the outer class inside `T` methods.
96 Note:
97 This function is `@safe` if the corresponding constructor of `T` is `@safe`.
98 Returns: The newly constructed object.
99  */
100 T emplace(T, Args...)(T chunk, auto ref Args args)
101     if (is(T == class))
102 {
103     import core.internal.traits : isInnerClass;
104 
105     static assert(!__traits(isAbstractClass, T), T.stringof ~
106         " is abstract and it can't be emplaced");
107 
108     // Initialize the object in its pre-ctor state
109     const initializer = __traits(initSymbol, T);
110     (() @trusted { (cast(void*) chunk)[0 .. initializer.length] = initializer[]; })();
111 
112     static if (isInnerClass!T)
113     {
114         static assert(Args.length > 0,
115             "Initializing an inner class requires a pointer to the outer class");
116         static assert(is(Args[0] : typeof(T.outer)),
117             "The first argument must be a pointer to the outer class");
118 
119         chunk.outer = args[0];
120         alias args1 = args[1..$];
121     }
122     else alias args1 = args;
123 
124     // Call the ctor if any
125     static if (is(typeof(chunk.__ctor(forward!args1))))
126     {
127         // T defines a genuine constructor accepting args
128         // Go the classic route: write .init first, then call ctor
129         chunk.__ctor(forward!args1);
130     }
131     else
132     {
133         static assert(args1.length == 0 && !is(typeof(&T.__ctor)),
134             "Don't know how to initialize an object of type "
135             ~ T.stringof ~ " with arguments " ~ typeof(args1).stringof);
136     }
137     return chunk;
138 }
139 
140 ///
141 @safe unittest
142 {
143     () @safe {
144         class SafeClass
145         {
146             int x;
147             @safe this(int x) { this.x = x; }
148         }
149 
150         auto buf = new void[__traits(classInstanceSize, SafeClass)];
151         auto support = (() @trusted => cast(SafeClass)(buf.ptr))();
152         auto safeClass = emplace!SafeClass(support, 5);
153         assert(safeClass.x == 5);
154 
155         class UnsafeClass
156         {
157             int x;
158             @system this(int x) { this.x = x; }
159         }
160 
161         auto buf2 = new void[__traits(classInstanceSize, UnsafeClass)];
162         auto support2 = (() @trusted => cast(UnsafeClass)(buf2.ptr))();
163         static assert(!__traits(compiles, emplace!UnsafeClass(support2, 5)));
164         static assert(!__traits(compiles, emplace!UnsafeClass(buf2, 5)));
165     }();
166 }
167 
168 @safe unittest
169 {
170     class Outer
171     {
172         int i = 3;
173         class Inner
174         {
175             @safe auto getI() { return i; }
176         }
177     }
178     auto outerBuf = new void[__traits(classInstanceSize, Outer)];
179     auto outerSupport = (() @trusted => cast(Outer)(outerBuf.ptr))();
180 
181     auto innerBuf = new void[__traits(classInstanceSize, Outer.Inner)];
182     auto innerSupport = (() @trusted => cast(Outer.Inner)(innerBuf.ptr))();
183 
184     auto inner = innerSupport.emplace!(Outer.Inner)(outerSupport.emplace!Outer);
185     assert(inner.getI == 3);
186 }
187 
188 /**
189 Given a raw memory area `chunk`, constructs an object of `class` type `T` at
190 that address. The constructor is passed the arguments `Args`.
191 If `T` is an inner class whose `outer` field can be used to access an instance
192 of the enclosing class, then `Args` must not be empty, and the first member of it
193 must be a valid initializer for that `outer` field. Correct initialization of
194 this field is essential to access members of the outer class inside `T` methods.
195 Preconditions:
196 `chunk` must be at least as large as `T` needs and should have an alignment
197 multiple of `T`'s alignment. (The size of a `class` instance is obtained by using
198 $(D __traits(classInstanceSize, T))).
199 Note:
200 This function can be `@trusted` if the corresponding constructor of `T` is `@safe`.
201 Returns: The newly constructed object.
202  */
203 T emplace(T, Args...)(void[] chunk, auto ref Args args)
204     if (is(T == class))
205 {
206     enum classSize = __traits(classInstanceSize, T);
207     assert(chunk.length >= classSize, "chunk size too small.");
208 
209     enum alignment = __traits(classInstanceAlignment, T);
210     assert((cast(size_t) chunk.ptr) % alignment == 0, "chunk is not aligned.");
211 
212     return emplace!T(cast(T)(chunk.ptr), forward!args);
213 }
214 
215 ///
216 @system unittest
217 {
218     static class C
219     {
220         int i;
221         this(int i){this.i = i;}
222     }
223     auto buf = new void[__traits(classInstanceSize, C)];
224     auto c = emplace!C(buf, 5);
225     assert(c.i == 5);
226 }
227 
228 ///
229 @betterC
230 @nogc pure nothrow @system unittest
231 {
232     // works with -betterC too:
233 
234     static extern (C++) class C
235     {
236         @nogc pure nothrow @safe:
237         int i = 3;
238         this(int i)
239         {
240             assert(this.i == 3);
241             this.i = i;
242         }
243         int virtualGetI() { return i; }
244     }
245 
246     align(__traits(classInstanceAlignment, C)) byte[__traits(classInstanceSize, C)] buffer;
247     C c = emplace!C(buffer[], 42);
248     assert(c.virtualGetI() == 42);
249 }
250 
251 @system unittest
252 {
253     class Outer
254     {
255         int i = 3;
256         class Inner
257         {
258             auto getI() { return i; }
259         }
260     }
261     auto outerBuf = new void[__traits(classInstanceSize, Outer)];
262     auto innerBuf = new void[__traits(classInstanceSize, Outer.Inner)];
263     auto inner = innerBuf.emplace!(Outer.Inner)(outerBuf.emplace!Outer);
264     assert(inner.getI == 3);
265 }
266 
267 @nogc pure nothrow @safe unittest
268 {
269     static class __conv_EmplaceTestClass
270     {
271         @nogc @safe pure nothrow:
272         int i = 3;
273         this(int i)
274         {
275             assert(this.i == 3);
276             this.i = 10 + i;
277         }
278         this(ref int i)
279         {
280             assert(this.i == 3);
281             this.i = 20 + i;
282         }
283         this(int i, ref int j)
284         {
285             assert(this.i == 3 && i == 5 && j == 6);
286             this.i = i;
287             ++j;
288         }
289     }
290 
291     int var = 6;
292     align(__traits(classInstanceAlignment, __conv_EmplaceTestClass))
293         ubyte[__traits(classInstanceSize, __conv_EmplaceTestClass)] buf;
294     auto support = (() @trusted => cast(__conv_EmplaceTestClass)(buf.ptr))();
295 
296     auto fromRval = emplace!__conv_EmplaceTestClass(support, 1);
297     assert(fromRval.i == 11);
298 
299     auto fromLval = emplace!__conv_EmplaceTestClass(support, var);
300     assert(fromLval.i == 26);
301 
302     auto k = emplace!__conv_EmplaceTestClass(support, 5, var);
303     assert(k.i == 5);
304     assert(var == 7);
305 }
306 
307 /**
308 Given a raw memory area `chunk`, constructs an object of non-$(D
309 class) type `T` at that address. The constructor is passed the
310 arguments `args`, if any.
311 Preconditions:
312 `chunk` must be at least as large
313 as `T` needs and should have an alignment multiple of `T`'s
314 alignment.
315 Note:
316 This function can be `@trusted` if the corresponding constructor of
317 `T` is `@safe`.
318 Returns: A pointer to the newly constructed object.
319  */
320 T* emplace(T, Args...)(void[] chunk, auto ref Args args)
321     if (!is(T == class))
322 {
323     import core.internal.traits : Unqual;
324     import core.internal.lifetime : emplaceRef;
325 
326     assert(chunk.length >= T.sizeof, "chunk size too small.");
327     assert((cast(size_t) chunk.ptr) % T.alignof == 0, "emplace: Chunk is not aligned.");
328 
329     emplaceRef!(T, Unqual!T)(*cast(Unqual!T*) chunk.ptr, forward!args);
330     return cast(T*) chunk.ptr;
331 }
332 
333 ///
334 @betterC
335 @system unittest
336 {
337     struct S
338     {
339         int a, b;
340     }
341     void[S.sizeof] buf = void;
342     S s;
343     s.a = 42;
344     s.b = 43;
345     auto s1 = emplace!S(buf, s);
346     assert(s1.a == 42 && s1.b == 43);
347 }
348 
349 // Bulk of emplace unittests starts here
350 
351 @betterC
352 @system unittest /* unions */
353 {
354     static union U
355     {
356         string a;
357         int b;
358         struct
359         {
360             long c;
361             int[] d;
362         }
363     }
364     U u1 = void;
365     U u2 = { "hello" };
366     emplace(&u1, u2);
367     assert(u1.a == "hello");
368 }
369 
370 @system unittest // https://issues.dlang.org/show_bug.cgi?id=15772
371 {
372     abstract class Foo {}
373     class Bar: Foo {}
374     void[] memory;
375     // test in emplaceInitializer
376     static assert(!is(typeof(emplace!Foo(cast(Foo*) memory.ptr))));
377     static assert( is(typeof(emplace!Bar(cast(Bar*) memory.ptr))));
378     // test in the emplace overload that takes void[]
379     static assert(!is(typeof(emplace!Foo(memory))));
380     static assert( is(typeof(emplace!Bar(memory))));
381 }
382 
383 @betterC
384 @system unittest
385 {
386     struct S { @disable this(); }
387     S s = void;
388     static assert(!__traits(compiles, emplace(&s)));
389     emplace(&s, S.init);
390 }
391 
392 @betterC
393 @system unittest
394 {
395     struct S1
396     {}
397 
398     struct S2
399     {
400         void opAssign(S2);
401     }
402 
403     S1 s1 = void;
404     S2 s2 = void;
405     S1[2] as1 = void;
406     S2[2] as2 = void;
407     emplace(&s1);
408     emplace(&s2);
409     emplace(&as1);
410     emplace(&as2);
411 }
412 
413 @system unittest
414 {
415     static struct S1
416     {
417         this(this) @disable;
418     }
419     static struct S2
420     {
421         this() @disable;
422     }
423     S1[2] ss1 = void;
424     S2[2] ss2 = void;
425     emplace(&ss1);
426     static assert(!__traits(compiles, emplace(&ss2)));
427     S1 s1 = S1.init;
428     S2 s2 = S2.init;
429     static assert(!__traits(compiles, emplace(&ss1, s1)));
430     emplace(&ss2, s2);
431 }
432 
433 @system unittest
434 {
435     struct S
436     {
437         immutable int i;
438     }
439     S s = void;
440     S[2] ss1 = void;
441     S[2] ss2 = void;
442     emplace(&s, 5);
443     assert(s.i == 5);
444     emplace(&ss1, s);
445     assert(ss1[0].i == 5 && ss1[1].i == 5);
446     emplace(&ss2, ss1);
447     assert(ss2 == ss1);
448 }
449 
450 //Start testing emplace-args here
451 
452 @system unittest
453 {
454     interface I {}
455     class K : I {}
456 
457     K k = null, k2 = new K;
458     assert(k !is k2);
459     emplace!K(&k, k2);
460     assert(k is k2);
461 
462     I i = null;
463     assert(i !is k);
464     emplace!I(&i, k);
465     assert(i is k);
466 }
467 
468 @system unittest
469 {
470     static struct S
471     {
472         int i = 5;
473         void opAssign(S){assert(0);}
474     }
475     S[2] sa = void;
476     S[2] sb;
477     emplace(&sa, sb);
478     assert(sa[0].i == 5 && sa[1].i == 5);
479 }
480 
481 //Start testing emplace-struct here
482 
483 // Test constructor branch
484 @betterC
485 @system unittest
486 {
487     struct S
488     {
489         double x = 5, y = 6;
490         this(int a, int b)
491         {
492             assert(x == 5 && y == 6);
493             x = a;
494             y = b;
495         }
496     }
497 
498     void[S.sizeof] s1 = void;
499     auto s2 = S(42, 43);
500     assert(*emplace!S(cast(S*) s1.ptr, s2) == s2);
501     assert(*emplace!S(cast(S*) s1, 44, 45) == S(44, 45));
502 }
503 
504 @system unittest
505 {
506     static struct __conv_EmplaceTest
507     {
508         int i = 3;
509         this(int i)
510         {
511             assert(this.i == 3 && i == 5);
512             this.i = i;
513         }
514         this(int i, ref int j)
515         {
516             assert(i == 5 && j == 6);
517             this.i = i;
518             ++j;
519         }
520 
521     @disable:
522         this();
523         this(this);
524         void opAssign();
525     }
526 
527     __conv_EmplaceTest k = void;
528     emplace(&k, 5);
529     assert(k.i == 5);
530 
531     int var = 6;
532     __conv_EmplaceTest x = void;
533     emplace(&x, 5, var);
534     assert(x.i == 5);
535     assert(var == 7);
536 
537     var = 6;
538     auto z = emplace!__conv_EmplaceTest(new void[__conv_EmplaceTest.sizeof], 5, var);
539     assert(z.i == 5);
540     assert(var == 7);
541 }
542 
543 // Test matching fields branch
544 @betterC
545 @system unittest
546 {
547     struct S { uint n; }
548     S s;
549     emplace!S(&s, 2U);
550     assert(s.n == 2);
551 }
552 
553 @betterC
554 @safe unittest
555 {
556     struct S { int a, b; this(int){} }
557     S s;
558     static assert(!__traits(compiles, emplace!S(&s, 2, 3)));
559 }
560 
561 @betterC
562 @system unittest
563 {
564     struct S { int a, b = 7; }
565     S s1 = void, s2 = void;
566 
567     emplace!S(&s1, 2);
568     assert(s1.a == 2 && s1.b == 7);
569 
570     emplace!S(&s2, 2, 3);
571     assert(s2.a == 2 && s2.b == 3);
572 }
573 
574 //opAssign
575 @betterC
576 @system unittest
577 {
578     static struct S
579     {
580         int i = 5;
581         void opAssign(int){assert(0);}
582         void opAssign(S){assert(0);}
583     }
584     S sa1 = void;
585     S sa2 = void;
586     S sb1 = S(1);
587     emplace(&sa1, sb1);
588     emplace(&sa2, 2);
589     assert(sa1.i == 1);
590     assert(sa2.i == 2);
591 }
592 
593 //postblit precedence
594 @betterC
595 @system unittest
596 {
597     //Works, but breaks in "-w -O" because of @@@9332@@@.
598     //Uncomment test when 9332 is fixed.
599     static struct S
600     {
601         int i;
602 
603         this(S other){assert(false);}
604         this(int i){this.i = i;}
605         this(this){}
606     }
607     S a = void;
608     assert(is(typeof({S b = a;})));    //Postblit
609     assert(is(typeof({S b = S(a);}))); //Constructor
610     auto b = S(5);
611     emplace(&a, b);
612     assert(a.i == 5);
613 
614     static struct S2
615     {
616         int* p;
617         this(const S2){}
618     }
619     static assert(!is(immutable S2 : S2));
620     S2 s2 = void;
621     immutable is2 = (immutable S2).init;
622     emplace(&s2, is2);
623 }
624 
625 //nested structs and postblit
626 @system unittest
627 {
628     static struct S
629     {
630         int* p;
631         this(int i){p = [i].ptr;}
632         this(this)
633         {
634             if (p)
635                 p = [*p].ptr;
636         }
637     }
638     static struct SS
639     {
640         S s;
641         void opAssign(const SS)
642         {
643             assert(0);
644         }
645     }
646     SS ssa = void;
647     SS ssb = SS(S(5));
648     emplace(&ssa, ssb);
649     assert(*ssa.s.p == 5);
650     assert(ssa.s.p != ssb.s.p);
651 }
652 
653 //disabled postblit
654 @betterC
655 @system unittest
656 {
657     static struct S1
658     {
659         int i;
660         @disable this(this);
661     }
662     S1 s1 = void;
663     emplace(&s1, 1);
664     assert(s1.i == 1);
665     static assert(!__traits(compiles, emplace(&s1, s1))); // copy disabled
666     static assert(__traits(compiles, emplace(&s1, move(s1)))); // move not affected
667 
668     static struct S2
669     {
670         int i;
671         @disable this(this);
672         this(ref S2){}
673     }
674     S2 s2 = void;
675     //static assert(!__traits(compiles, emplace(&s2, 1)));
676     emplace(&s2, S2.init);
677 
678     static struct SS1
679     {
680         S1 s;
681     }
682     SS1 ss1 = void;
683     emplace(&ss1);
684     static assert(!__traits(compiles, emplace(&ss1, ss1))); // copying disabled
685     static assert(__traits(compiles, emplace(&ss1, move(ss1)))); // move unaffected
686 
687     static struct SS2
688     {
689         S2 s;
690     }
691     SS2 ss2 = void;
692     emplace(&ss2);
693     static assert(!__traits(compiles, emplace(&ss2, ss2))); // copying disabled
694     static assert(__traits(compiles, emplace(&ss2, SS2.init))); // move is OK
695 
696 
697     // SS1 sss1 = s1;      //This doesn't compile
698     // SS1 sss1 = SS1(s1); //This doesn't compile
699     // So emplace shouldn't compile either
700     static assert(!__traits(compiles, emplace(&sss1, s1)));
701     static assert(!__traits(compiles, emplace(&sss2, s2)));
702 }
703 
704 //Imutability
705 @betterC
706 @system unittest
707 {
708     //Castable immutability
709     {
710         static struct S1
711         {
712             int i;
713         }
714         static assert(is( immutable(S1) : S1));
715         S1 sa = void;
716         auto sb = immutable(S1)(5);
717         emplace(&sa, sb);
718         assert(sa.i == 5);
719     }
720     //Un-castable immutability
721     {
722         static struct S2
723         {
724             int* p;
725         }
726         static assert(!is(immutable(S2) : S2));
727         S2 sa = void;
728         auto sb = immutable(S2)(null);
729         assert(!__traits(compiles, emplace(&sa, sb)));
730     }
731 }
732 
733 @betterC
734 @system unittest
735 {
736     static struct S
737     {
738         immutable int i;
739         immutable(int)* j;
740     }
741     S s = void;
742     emplace(&s, 1, null);
743     emplace(&s, 2, &s.i);
744     assert(s is S(2, &s.i));
745 }
746 
747 //Context pointer
748 @system unittest
749 {
750     int i = 0;
751     {
752         struct S1
753         {
754             void foo(){++i;}
755         }
756         S1 sa = void;
757         S1 sb;
758         emplace(&sa, sb);
759         sa.foo();
760         assert(i == 1);
761     }
762     {
763         struct S2
764         {
765             void foo(){++i;}
766             this(this){}
767         }
768         S2 sa = void;
769         S2 sb;
770         emplace(&sa, sb);
771         sa.foo();
772         assert(i == 2);
773     }
774 }
775 
776 //Alias this
777 @betterC
778 @system unittest
779 {
780     static struct S
781     {
782         int i;
783     }
784     //By Ref
785     {
786         static struct SS1
787         {
788             int j;
789             S s;
790             alias s this;
791         }
792         S s = void;
793         SS1 ss = SS1(1, S(2));
794         emplace(&s, ss);
795         assert(s.i == 2);
796     }
797     //By Value
798     {
799         static struct SS2
800         {
801             int j;
802             S s;
803             S foo() @property{return s;}
804             alias foo this;
805         }
806         S s = void;
807         SS2 ss = SS2(1, S(2));
808         emplace(&s, ss);
809         assert(s.i == 2);
810     }
811 }
812 
813 version (CoreUnittest)
814 {
815     //Ambiguity
816     private struct __std_conv_S
817     {
818         int i;
819         this(__std_conv_SS ss)         {assert(0);}
820         static opCall(__std_conv_SS ss)
821         {
822             __std_conv_S s; s.i = ss.j;
823             return s;
824         }
825     }
826     private struct __std_conv_SS
827     {
828         int j;
829         __std_conv_S s;
830         ref __std_conv_S foo() return @property {s.i = j; return s;}
831         alias foo this;
832     }
833 }
834 
835 @system unittest
836 {
837     static assert(is(__std_conv_SS : __std_conv_S));
838     __std_conv_S s = void;
839     __std_conv_SS ss = __std_conv_SS(1);
840 
841     __std_conv_S sTest1 = ss; //this calls "SS alias this" (and not "S.this(SS)")
842     emplace(&s, ss); //"alias this" should take precedence in emplace over "opCall"
843     assert(s.i == 1);
844 }
845 
846 //Nested classes
847 @system unittest
848 {
849     class A{}
850     static struct S
851     {
852         A a;
853     }
854     S s1 = void;
855     S s2 = S(new A);
856     emplace(&s1, s2);
857     assert(s1.a is s2.a);
858 }
859 
860 //safety & nothrow & CTFE
861 @betterC
862 @system unittest
863 {
864     //emplace should be safe for anything with no elaborate opassign
865     static struct S1
866     {
867         int i;
868     }
869     static struct S2
870     {
871         int i;
872         this(int j)@safe nothrow{i = j;}
873     }
874 
875     int i;
876     S1 s1 = void;
877     S2 s2 = void;
878 
879     auto pi = &i;
880     auto ps1 = &s1;
881     auto ps2 = &s2;
882 
883     void foo() @safe nothrow
884     {
885         emplace(pi);
886         emplace(pi, 5);
887         emplace(ps1);
888         emplace(ps1, 5);
889         emplace(ps1, S1.init);
890         emplace(ps2);
891         emplace(ps2, 5);
892         emplace(ps2, S2.init);
893     }
894     foo();
895 
896     T bar(T)() @property
897     {
898         T t/+ = void+/; //CTFE void illegal
899         emplace(&t, 5);
900         return t;
901     }
902     // CTFE
903     enum a = bar!int;
904     static assert(a == 5);
905     enum b = bar!S1;
906     static assert(b.i == 5);
907     enum c = bar!S2;
908     static assert(c.i == 5);
909     // runtime
910     auto aa = bar!int;
911     assert(aa == 5);
912     auto bb = bar!S1;
913     assert(bb.i == 5);
914     auto cc = bar!S2;
915     assert(cc.i == 5);
916 }
917 
918 @betterC
919 @system unittest
920 {
921     struct S
922     {
923         int[2] get(){return [1, 2];}
924         alias get this;
925     }
926     struct SS
927     {
928         int[2] ii;
929     }
930     struct ISS
931     {
932         int[2] ii;
933     }
934     S s;
935     SS ss = void;
936     ISS iss = void;
937     emplace(&ss, s);
938     emplace(&iss, s);
939     assert(ss.ii == [1, 2]);
940     assert(iss.ii == [1, 2]);
941 }
942 
943 //disable opAssign
944 @betterC
945 @system unittest
946 {
947     static struct S
948     {
949         @disable void opAssign(S);
950     }
951     S s;
952     emplace(&s, S.init);
953 }
954 
955 //opCall
956 @betterC
957 @system unittest
958 {
959     int i;
960     //Without constructor
961     {
962         static struct S1
963         {
964             int i;
965             static S1 opCall(int*){assert(0);}
966         }
967         S1 s = void;
968         static assert(!__traits(compiles, emplace(&s,  1)));
969     }
970     //With constructor
971     {
972         static struct S2
973         {
974             int i = 0;
975             static S2 opCall(int*){assert(0);}
976             static S2 opCall(int){assert(0);}
977             this(int i){this.i = i;}
978         }
979         S2 s = void;
980         emplace(&s,  1);
981         assert(s.i == 1);
982     }
983     //With postblit ambiguity
984     {
985         static struct S3
986         {
987             int i = 0;
988             static S3 opCall(ref S3){assert(0);}
989         }
990         S3 s = void;
991         emplace(&s, S3.init);
992     }
993 }
994 
995 //static arrays
996 @system unittest
997 {
998     static struct S
999     {
1000         int[2] ii;
1001     }
1002     static struct IS
1003     {
1004         immutable int[2] ii;
1005     }
1006     int[2] ii;
1007     S  s   = void;
1008     IS ims = void;
1009     ubyte ub = 2;
1010     emplace(&s, ub);
1011     emplace(&s, ii);
1012     emplace(&ims, ub);
1013     emplace(&ims, ii);
1014     uint[2] uu;
1015     static assert(!__traits(compiles, {S ss = S(uu);}));
1016     static assert(!__traits(compiles, emplace(&s, uu)));
1017 }
1018 
1019 @system unittest
1020 {
1021     int[2]  sii;
1022     int[2]  sii2;
1023     uint[2] uii;
1024     uint[2] uii2;
1025     emplace(&sii, 1);
1026     emplace(&sii, 1U);
1027     emplace(&uii, 1);
1028     emplace(&uii, 1U);
1029     emplace(&sii, sii2);
1030     //emplace(&sii, uii2); //Sorry, this implementation doesn't know how to...
1031     //emplace(&uii, sii2); //Sorry, this implementation doesn't know how to...
1032     emplace(&uii, uii2);
1033     emplace(&sii, sii2[]);
1034     //emplace(&sii, uii2[]); //Sorry, this implementation doesn't know how to...
1035     //emplace(&uii, sii2[]); //Sorry, this implementation doesn't know how to...
1036     emplace(&uii, uii2[]);
1037 }
1038 
1039 @system unittest
1040 {
1041     bool allowDestruction = false;
1042     struct S
1043     {
1044         int i;
1045         this(this){}
1046         ~this(){assert(allowDestruction);}
1047     }
1048     S s = S(1);
1049     S[2] ss1 = void;
1050     S[2] ss2 = void;
1051     S[2] ss3 = void;
1052     emplace(&ss1, s);
1053     emplace(&ss2, ss1);
1054     emplace(&ss3, ss2[]);
1055     assert(ss1[1] == s);
1056     assert(ss2[1] == s);
1057     assert(ss3[1] == s);
1058     allowDestruction = true;
1059 }
1060 
1061 @system unittest
1062 {
1063     //Checks postblit, construction, and context pointer
1064     int count = 0;
1065     struct S
1066     {
1067         this(this)
1068         {
1069             ++count;
1070         }
1071         ~this()
1072         {
1073             --count;
1074         }
1075     }
1076 
1077     S s;
1078     {
1079         S[4] ss = void;
1080         emplace(&ss, s);
1081         assert(count == 4);
1082     }
1083     assert(count == 0);
1084 }
1085 
1086 @system unittest
1087 {
1088     struct S
1089     {
1090         int i;
1091     }
1092     S s;
1093     S[2][2][2] sss = void;
1094     emplace(&sss, s);
1095 }
1096 
1097 @system unittest //Constness
1098 {
1099     import core.internal.lifetime : emplaceRef;
1100 
1101     int a = void;
1102     emplaceRef!(const int)(a, 5);
1103 
1104     immutable i = 5;
1105     const(int)* p = void;
1106     emplaceRef!(const int*)(p, &i);
1107 
1108     struct S
1109     {
1110         int* p;
1111     }
1112     alias IS = immutable(S);
1113     S s = void;
1114     emplaceRef!IS(s, IS());
1115     S[2] ss = void;
1116     emplaceRef!(IS[2])(ss, IS());
1117 
1118     IS[2] iss = IS.init;
1119     emplaceRef!(IS[2])(ss, iss);
1120     emplaceRef!(IS[2])(ss, iss[]);
1121 }
1122 
1123 @betterC
1124 pure nothrow @safe @nogc unittest
1125 {
1126     import core.internal.lifetime : emplaceRef;
1127 
1128     int i;
1129     emplaceRef(i);
1130     emplaceRef!int(i);
1131     emplaceRef(i, 5);
1132     emplaceRef!int(i, 5);
1133 }
1134 
1135 // Test attribute propagation for UDTs
1136 pure nothrow @safe /* @nogc */ unittest
1137 {
1138     import core.internal.lifetime : emplaceRef;
1139 
1140     static struct Safe
1141     {
1142         this(this) pure nothrow @safe @nogc {}
1143     }
1144 
1145     Safe safe = void;
1146     emplaceRef(safe, Safe());
1147 
1148     Safe[1] safeArr = [Safe()];
1149     Safe[1] uninitializedSafeArr = void;
1150     emplaceRef(uninitializedSafeArr, safe);
1151     emplaceRef(uninitializedSafeArr, safeArr);
1152 
1153     static struct Unsafe
1154     {
1155         this(this) @system {}
1156     }
1157 
1158     Unsafe unsafe = void;
1159     static assert(!__traits(compiles, emplaceRef(unsafe, unsafe)));
1160 
1161     Unsafe[1] unsafeArr = [Unsafe()];
1162     Unsafe[1] uninitializedUnsafeArr = void;
1163     static assert(!__traits(compiles, emplaceRef(uninitializedUnsafeArr, unsafe)));
1164     static assert(!__traits(compiles, emplaceRef(uninitializedUnsafeArr, unsafeArr)));
1165 }
1166 
1167 @betterC
1168 @system unittest
1169 {
1170     // Issue 15313
1171     static struct Node
1172     {
1173         int payload;
1174         Node* next;
1175         uint refs;
1176     }
1177 
1178     import core.stdc.stdlib : malloc;
1179     void[] buf = malloc(Node.sizeof)[0 .. Node.sizeof];
1180 
1181     const Node* n = emplace!(const Node)(buf, 42, null, 10);
1182     assert(n.payload == 42);
1183     assert(n.next == null);
1184     assert(n.refs == 10);
1185 }
1186 
1187 @system unittest
1188 {
1189     class A
1190     {
1191         int x = 5;
1192         int y = 42;
1193         this(int z)
1194         {
1195             assert(x == 5 && y == 42);
1196             x = y = z;
1197         }
1198     }
1199     void[] buf;
1200 
1201     static align(__traits(classInstanceAlignment, A)) byte[__traits(classInstanceSize, A)] sbuf;
1202     buf = sbuf[];
1203     auto a = emplace!A(buf, 55);
1204     assert(a.x == 55 && a.y == 55);
1205 
1206     // emplace in bigger buffer
1207     buf = new byte[](__traits(classInstanceSize, A) + 10);
1208     a = emplace!A(buf, 55);
1209     assert(a.x == 55 && a.y == 55);
1210 
1211     // need ctor args
1212     static assert(!is(typeof(emplace!A(buf))));
1213 }
1214 
1215 //constructor arguments forwarding
1216 @betterC
1217 @system unittest
1218 {
1219     static struct S
1220     {
1221         this()(auto ref long arg)
1222         {
1223             // assert that arg is an lvalue
1224             static assert(__traits(isRef, arg));
1225         }
1226         this()(auto ref double arg)
1227             // assert that arg is an rvalue
1228         {
1229             static assert(!__traits(isRef, arg));
1230         }
1231     }
1232     S obj = void;
1233     long i;
1234     emplace(&obj, i);   // lvalue
1235     emplace(&obj, 0.0); // rvalue
1236 }
1237 // Bulk of emplace unittests ends here
1238 
1239 /**
1240  * Emplaces a copy of the specified source value into uninitialized memory,
1241  * i.e., simulates `T target = source` copy-construction for cases where the
1242  * target memory is already allocated and to be initialized with a copy.
1243  *
1244  * Params:
1245  *   source = value to be copied into target
1246  *   target = uninitialized value to be initialized with a copy of source
1247  */
1248 void copyEmplace(S, T)(ref S source, ref T target) @system
1249     if (is(immutable S == immutable T))
1250 {
1251     import core.internal.traits : BaseElemOf, hasElaborateCopyConstructor, Unconst, Unqual;
1252 
1253     // cannot have the following as simple template constraint due to nested-struct special case...
1254     static if (!__traits(compiles, (ref S src) { T tgt = src; }))
1255     {
1256         alias B = BaseElemOf!T;
1257         enum isNestedStruct = is(B == struct) && __traits(isNested, B);
1258         static assert(isNestedStruct, "cannot copy-construct " ~ T.stringof ~ " from " ~ S.stringof);
1259     }
1260 
1261     void blit()
1262     {
1263         import core.stdc.string : memcpy;
1264         memcpy(cast(Unqual!(T)*) &target, cast(Unqual!(T)*) &source, T.sizeof);
1265     }
1266 
1267     static if (is(T == struct))
1268     {
1269         static if (__traits(hasPostblit, T))
1270         {
1271             blit();
1272             (cast() target).__xpostblit();
1273         }
1274         else static if (__traits(hasCopyConstructor, T))
1275         {
1276             // https://issues.dlang.org/show_bug.cgi?id=22766
1277             import core.internal.lifetime : emplaceInitializer;
1278             emplaceInitializer(*(cast(Unqual!T*)&target));
1279             static if (__traits(isNested, T))
1280             {
1281                  // copy context pointer
1282                 *(cast(void**) &target.tupleof[$-1]) = cast(void*) source.tupleof[$-1];
1283             }
1284             target.__ctor(source); // invoke copy ctor
1285         }
1286         else
1287         {
1288             blit(); // no opAssign
1289         }
1290     }
1291     else static if (is(T == E[n], E, size_t n))
1292     {
1293         static if (hasElaborateCopyConstructor!E)
1294         {
1295             size_t i;
1296             try
1297             {
1298                 for (i = 0; i < n; i++)
1299                     copyEmplace(source[i], target[i]);
1300             }
1301             catch (Exception e)
1302             {
1303                 // destroy, in reverse order, what we've constructed so far
1304                 while (i--)
1305                     destroy(*cast(Unconst!(E)*) &target[i]);
1306                 throw e;
1307             }
1308         }
1309         else // trivial copy
1310         {
1311             blit(); // all elements at once
1312         }
1313     }
1314     else
1315     {
1316         *cast(Unconst!(T)*) &target = *cast(Unconst!(T)*) &source;
1317     }
1318 }
1319 
1320 ///
1321 @betterC
1322 @system pure nothrow @nogc unittest
1323 {
1324     int source = 123;
1325     int target = void;
1326     copyEmplace(source, target);
1327     assert(target == 123);
1328 }
1329 
1330 ///
1331 @betterC
1332 @system pure nothrow @nogc unittest
1333 {
1334     immutable int[1][1] source = [ [123] ];
1335     immutable int[1][1] target = void;
1336     copyEmplace(source, target);
1337     assert(target[0][0] == 123);
1338 }
1339 
1340 ///
1341 @betterC
1342 @system pure nothrow @nogc unittest
1343 {
1344     struct S
1345     {
1346         int x;
1347         void opAssign(const scope ref S rhs) @safe pure nothrow @nogc
1348         {
1349             assert(0);
1350         }
1351     }
1352 
1353     S source = S(42);
1354     S target = void;
1355     copyEmplace(source, target);
1356     assert(target.x == 42);
1357 }
1358 
1359 // preserve shared-ness
1360 @system pure nothrow unittest
1361 {
1362     auto s = new Object();
1363     auto ss = new shared Object();
1364 
1365     Object t;
1366     shared Object st;
1367 
1368     copyEmplace(s, t);
1369     assert(t is s);
1370 
1371     copyEmplace(ss, st);
1372     assert(st is ss);
1373 
1374     static assert(!__traits(compiles, copyEmplace(s, st)));
1375     static assert(!__traits(compiles, copyEmplace(ss, t)));
1376 }
1377 
1378 // https://issues.dlang.org/show_bug.cgi?id=22766
1379 @system pure nothrow @nogc unittest
1380 {
1381     static struct S
1382     {
1383         @disable this();
1384         this(int) @safe pure nothrow @nogc{}
1385         this(ref const(S) other) @safe pure nothrow @nogc {}
1386     }
1387 
1388     S s1 = S(1);
1389     S s2 = void;
1390     copyEmplace(s1, s2);
1391     assert(s2 == S(1));
1392 }
1393 
1394 version (DigitalMars) version (X86) version (Posix) version = DMD_X86_Posix;
1395 
1396 // don't violate immutability for reference types
1397 @system pure nothrow unittest
1398 {
1399     auto s = new Object();
1400     auto si = new immutable Object();
1401 
1402     Object t;
1403     immutable Object ti;
1404 
1405     copyEmplace(s, t);
1406     assert(t is s);
1407 
1408     copyEmplace(si, ti);
1409     version (DMD_X86_Posix) { /* wrongly fails without -O */ } else
1410         assert(ti is si);
1411 
1412     static assert(!__traits(compiles, copyEmplace(s, ti)));
1413     static assert(!__traits(compiles, copyEmplace(si, t)));
1414 }
1415 
1416 version (CoreUnittest)
1417 {
1418     private void testCopyEmplace(S, T)(const scope T* expected = null)
1419     {
1420         S source;
1421         T target = void;
1422         copyEmplace(source, target);
1423         if (expected)
1424             assert(target == *expected);
1425         else
1426         {
1427             T expectedCopy = source;
1428             assert(target == expectedCopy);
1429         }
1430     }
1431 }
1432 
1433 // postblit
1434 @system pure nothrow @nogc unittest
1435 {
1436     static struct S
1437     {
1438         @safe pure nothrow @nogc:
1439         int x = 42;
1440         this(this) { x += 10; }
1441     }
1442 
1443     testCopyEmplace!(S, S)();
1444     testCopyEmplace!(immutable S, S)();
1445     testCopyEmplace!(S, immutable S)();
1446     testCopyEmplace!(immutable S, immutable S)();
1447 
1448     testCopyEmplace!(S[1], S[1])();
1449     testCopyEmplace!(immutable S[1], S[1])();
1450 
1451     // copying to an immutable static array works, but `T expected = source`
1452     // wrongly ignores the postblit: https://issues.dlang.org/show_bug.cgi?id=8950
1453     immutable S[1] expectedImmutable = [S(52)];
1454     testCopyEmplace!(S[1], immutable S[1])(&expectedImmutable);
1455     testCopyEmplace!(immutable S[1], immutable S[1])(&expectedImmutable);
1456 }
1457 
1458 // copy constructors
1459 @system pure nothrow @nogc unittest
1460 {
1461     static struct S
1462     {
1463         @safe pure nothrow @nogc:
1464         int x = 42;
1465         this(int x) { this.x = x; }
1466         this(const scope ref S rhs) { x = rhs.x + 10; }
1467         this(const scope ref S rhs) immutable { x = rhs.x + 20; }
1468     }
1469 
1470     testCopyEmplace!(S, S)();
1471     testCopyEmplace!(immutable S, S)();
1472     testCopyEmplace!(S, immutable S)();
1473     testCopyEmplace!(immutable S, immutable S)();
1474 
1475     // static arrays work, but `T expected = source` wrongly ignores copy ctors
1476     // https://issues.dlang.org/show_bug.cgi?id=20365
1477     S[1] expectedMutable = [S(52)];
1478     immutable S[1] expectedImmutable = [immutable S(62)];
1479     testCopyEmplace!(S[1], S[1])(&expectedMutable);
1480     testCopyEmplace!(immutable S[1], S[1])(&expectedMutable);
1481     testCopyEmplace!(S[1], immutable S[1])(&expectedImmutable);
1482     testCopyEmplace!(immutable S[1], immutable S[1])(&expectedImmutable);
1483 }
1484 
1485 // copy constructor in nested struct
1486 @system pure nothrow unittest
1487 {
1488     int copies;
1489     struct S
1490     {
1491         @safe pure nothrow @nogc:
1492         size_t x = 42;
1493         this(size_t x) { this.x = x; }
1494         this(const scope ref S rhs)
1495         {
1496             assert(x == 42); // T.init
1497             x = rhs.x;
1498             ++copies;
1499         }
1500     }
1501 
1502     {
1503         copies = 0;
1504         S source = S(123);
1505         immutable S target = void;
1506         copyEmplace(source, target);
1507         assert(target is source);
1508         assert(copies == 1);
1509     }
1510 
1511     {
1512         copies = 0;
1513         immutable S[1] source = [immutable S(456)];
1514         S[1] target = void;
1515         copyEmplace(source, target);
1516         assert(target[0] is source[0]);
1517         assert(copies == 1);
1518     }
1519 }
1520 
1521 // destruction of partially copied static array
1522 @system unittest
1523 {
1524     static struct S
1525     {
1526         __gshared int[] deletions;
1527         int x;
1528         this(this) { if (x == 5) throw new Exception(""); }
1529         ~this() { deletions ~= x; }
1530     }
1531 
1532     alias T = immutable S[3][2];
1533     T source = [ [S(1), S(2), S(3)], [S(4), S(5), S(6)] ];
1534     T target = void;
1535     try
1536     {
1537         copyEmplace(source, target);
1538         assert(0);
1539     }
1540     catch (Exception)
1541     {
1542         static immutable expectedDeletions = [ 4, 3, 2, 1 ];
1543         version (DigitalMars)
1544         {
1545             assert(S.deletions == expectedDeletions ||
1546                    S.deletions == [ 4 ]); // FIXME: happens with -O
1547         }
1548         else
1549             assert(S.deletions == expectedDeletions);
1550     }
1551 }
1552 
1553 /**
1554 Forwards function arguments while keeping `out`, `ref`, and `lazy` on
1555 the parameters.
1556 
1557 Params:
1558     args = a parameter list or an $(REF AliasSeq,std,meta).
1559 Returns:
1560     An `AliasSeq` of `args` with `out`, `ref`, and `lazy` saved.
1561 */
1562 template forward(args...)
1563 {
1564     import core.internal.traits : AliasSeq;
1565 
1566     template fwd(alias arg)
1567     {
1568         // by ref || lazy || const/immutable
1569         static if (__traits(isRef,  arg) ||
1570                    __traits(isOut,  arg) ||
1571                    __traits(isLazy, arg) ||
1572                    !is(typeof(move(arg))))
1573             alias fwd = arg;
1574         // (r)value
1575         else
1576             @property auto fwd()
1577             {
1578                 version (DigitalMars) { /* @@BUG 23890@@ */ } else pragma(inline, true);
1579                 return move(arg);
1580             }
1581     }
1582 
1583     alias Result = AliasSeq!();
1584     static foreach (arg; args)
1585         Result = AliasSeq!(Result, fwd!arg);
1586     static if (Result.length == 1)
1587         alias forward = Result[0];
1588     else
1589         alias forward = Result;
1590 }
1591 
1592 ///
1593 @safe unittest
1594 {
1595     class C
1596     {
1597         static int foo(int n) { return 1; }
1598         static int foo(ref int n) { return 2; }
1599     }
1600 
1601     // with forward
1602     int bar()(auto ref int x) { return C.foo(forward!x); }
1603 
1604     // without forward
1605     int baz()(auto ref int x) { return C.foo(x); }
1606 
1607     int i;
1608     assert(bar(1) == 1);
1609     assert(bar(i) == 2);
1610 
1611     assert(baz(1) == 2);
1612     assert(baz(i) == 2);
1613 }
1614 
1615 ///
1616 @safe unittest
1617 {
1618     void foo(int n, ref string s) { s = null; foreach (i; 0 .. n) s ~= "Hello"; }
1619 
1620     // forwards all arguments which are bound to parameter tuple
1621     void bar(Args...)(auto ref Args args) { return foo(forward!args); }
1622 
1623     // forwards all arguments with swapping order
1624     void baz(Args...)(auto ref Args args) { return foo(forward!args[$/2..$], forward!args[0..$/2]); }
1625 
1626     string s;
1627     bar(1, s);
1628     assert(s == "Hello");
1629     baz(s, 2);
1630     assert(s == "HelloHello");
1631 }
1632 
1633 @safe unittest
1634 {
1635     auto foo(TL...)(auto ref TL args)
1636     {
1637         string result = "";
1638         foreach (i, _; args)
1639         {
1640             //pragma(msg, "[",i,"] ", __traits(isRef, args[i]) ? "L" : "R");
1641             result ~= __traits(isRef, args[i]) ? "L" : "R";
1642         }
1643         return result;
1644     }
1645 
1646     string bar(TL...)(auto ref TL args)
1647     {
1648         return foo(forward!args);
1649     }
1650     string baz(TL...)(auto ref TL args)
1651     {
1652         int x;
1653         return foo(forward!args[3], forward!args[2], 1, forward!args[1], forward!args[0], x);
1654     }
1655 
1656     struct S {}
1657     S makeS(){ return S(); }
1658     int n;
1659     string s;
1660     assert(bar(S(), makeS(), n, s) == "RRLL");
1661     assert(baz(S(), makeS(), n, s) == "LLRRRL");
1662 }
1663 
1664 @betterC
1665 @safe unittest
1666 {
1667     ref int foo(return ref int a) { return a; }
1668     ref int bar(Args)(auto ref Args args)
1669     {
1670         return foo(forward!args);
1671     }
1672     static assert(!__traits(compiles, { auto x1 = bar(3); })); // case of NG
1673     int value = 3;
1674     auto x2 = bar(value); // case of OK
1675 }
1676 
1677 ///
1678 @betterC
1679 @safe unittest
1680 {
1681     struct X {
1682         int i;
1683         this(this)
1684         {
1685             ++i;
1686         }
1687     }
1688 
1689     struct Y
1690     {
1691         private X x_;
1692         this()(auto ref X x)
1693         {
1694             x_ = forward!x;
1695         }
1696     }
1697 
1698     struct Z
1699     {
1700         private const X x_;
1701         this()(auto ref X x)
1702         {
1703             x_ = forward!x;
1704         }
1705         this()(auto const ref X x)
1706         {
1707             x_ = forward!x;
1708         }
1709     }
1710 
1711     X x;
1712     const X cx;
1713     auto constX = (){ const X x; return x; };
1714     static assert(__traits(compiles, { Y y = x; }));
1715     static assert(__traits(compiles, { Y y = X(); }));
1716     static assert(!__traits(compiles, { Y y = cx; }));
1717     static assert(!__traits(compiles, { Y y = constX(); }));
1718     static assert(__traits(compiles, { Z z = x; }));
1719     static assert(__traits(compiles, { Z z = X(); }));
1720     static assert(__traits(compiles, { Z z = cx; }));
1721     static assert(__traits(compiles, { Z z = constX(); }));
1722 
1723 
1724     Y y1 = x;
1725     // ref lvalue, copy
1726     assert(y1.x_.i == 1);
1727     Y y2 = X();
1728     // rvalue, move
1729     assert(y2.x_.i == 0);
1730 
1731     Z z1 = x;
1732     // ref lvalue, copy
1733     assert(z1.x_.i == 1);
1734     Z z2 = X();
1735     // rvalue, move
1736     assert(z2.x_.i == 0);
1737     Z z3 = cx;
1738     // ref const lvalue, copy
1739     assert(z3.x_.i == 1);
1740     Z z4 = constX();
1741     // const rvalue, copy
1742     assert(z4.x_.i == 1);
1743 }
1744 
1745 // lazy -> lazy
1746 @betterC
1747 @safe unittest
1748 {
1749     int foo1(lazy int i) { return i; }
1750     int foo2(A)(auto ref A i) { return foo1(forward!i); }
1751     int foo3(lazy int i) { return foo2(i); }
1752 
1753     int numCalls = 0;
1754     assert(foo3({ ++numCalls; return 42; }()) == 42);
1755     assert(numCalls == 1);
1756 }
1757 
1758 // lazy -> non-lazy
1759 @betterC
1760 @safe unittest
1761 {
1762     int foo1(int a, int b) { return a + b; }
1763     int foo2(A...)(auto ref A args) { return foo1(forward!args); }
1764     int foo3(int a, lazy int b) { return foo2(a, b); }
1765 
1766     int numCalls;
1767     assert(foo3(11, { ++numCalls; return 31; }()) == 42);
1768     assert(numCalls == 1);
1769 }
1770 
1771 // non-lazy -> lazy
1772 @betterC
1773 @safe unittest
1774 {
1775     int foo1(int a, lazy int b) { return a + b; }
1776     int foo2(A...)(auto ref A args) { return foo1(forward!args); }
1777     int foo3(int a, int b) { return foo2(a, b); }
1778 
1779     assert(foo3(11, 31) == 42);
1780 }
1781 
1782 // out
1783 @betterC
1784 @safe unittest
1785 {
1786     void foo1(int a, out int b) { b = a; }
1787     void foo2(A...)(auto ref A args) { foo1(forward!args); }
1788     void foo3(int a, out int b) { foo2(a, b); }
1789 
1790     int b;
1791     foo3(42, b);
1792     assert(b == 42);
1793 }
1794 
1795 // move
1796 /**
1797 Moves `source` into `target`, via a destructive copy when necessary.
1798 
1799 If `T` is a struct with a destructor or postblit defined, source is reset
1800 to its `.init` value after it is moved into target, otherwise it is
1801 left unchanged.
1802 
1803 Preconditions:
1804 If source has internal pointers that point to itself and doesn't define
1805 opPostMove, it cannot be moved, and will trigger an assertion failure.
1806 
1807 Params:
1808     source = Data to copy.
1809     target = Where to copy into. The destructor, if any, is invoked before the
1810         copy is performed.
1811 */
1812 void move(T)(ref T source, ref T target)
1813 {
1814     moveImpl(target, source);
1815 }
1816 
1817 /// For non-struct types, `move` just performs `target = source`:
1818 @safe unittest
1819 {
1820     Object obj1 = new Object;
1821     Object obj2 = obj1;
1822     Object obj3;
1823 
1824     move(obj2, obj3);
1825     assert(obj3 is obj1);
1826     // obj2 unchanged
1827     assert(obj2 is obj1);
1828 }
1829 
1830 ///
1831 pure nothrow @safe @nogc unittest
1832 {
1833     // Structs without destructors are simply copied
1834     struct S1
1835     {
1836         int a = 1;
1837         int b = 2;
1838     }
1839     S1 s11 = { 10, 11 };
1840     S1 s12;
1841 
1842     move(s11, s12);
1843 
1844     assert(s12 == S1(10, 11));
1845     assert(s11 == s12);
1846 
1847     // But structs with destructors or postblits are reset to their .init value
1848     // after copying to the target.
1849     struct S2
1850     {
1851         int a = 1;
1852         int b = 2;
1853 
1854         ~this() pure nothrow @safe @nogc { }
1855     }
1856     S2 s21 = { 3, 4 };
1857     S2 s22;
1858 
1859     move(s21, s22);
1860 
1861     assert(s21 == S2(1, 2));
1862     assert(s22 == S2(3, 4));
1863 }
1864 
1865 @safe unittest
1866 {
1867     import core.internal.traits;
1868 
1869     assertCTFEable!((){
1870         Object obj1 = new Object;
1871         Object obj2 = obj1;
1872         Object obj3;
1873         move(obj2, obj3);
1874         assert(obj3 is obj1);
1875 
1876         static struct S1 { int a = 1, b = 2; }
1877         S1 s11 = { 10, 11 };
1878         S1 s12;
1879         move(s11, s12);
1880         assert(s11.a == 10 && s11.b == 11 && s12.a == 10 && s12.b == 11);
1881 
1882         static struct S2 { int a = 1; int * b; }
1883         S2 s21 = { 10, null };
1884         s21.b = new int;
1885         S2 s22;
1886         move(s21, s22);
1887         assert(s21 == s22);
1888     });
1889     // Issue 5661 test(1)
1890     static struct S3
1891     {
1892         static struct X { int n = 0; ~this(){n = 0;} }
1893         X x;
1894     }
1895     static assert(hasElaborateDestructor!S3);
1896     S3 s31, s32;
1897     s31.x.n = 1;
1898     move(s31, s32);
1899     assert(s31.x.n == 0);
1900     assert(s32.x.n == 1);
1901 
1902     // Issue 5661 test(2)
1903     static struct S4
1904     {
1905         static struct X { int n = 0; this(this){n = 0;} }
1906         X x;
1907     }
1908     static assert(hasElaborateCopyConstructor!S4);
1909     S4 s41, s42;
1910     s41.x.n = 1;
1911     move(s41, s42);
1912     assert(s41.x.n == 0);
1913     assert(s42.x.n == 1);
1914 
1915     // Issue 13990 test
1916     class S5;
1917 
1918     S5 s51;
1919     S5 s52 = s51;
1920     S5 s53;
1921     move(s52, s53);
1922     assert(s53 is s51);
1923 }
1924 
1925 /// Ditto
1926 T move(T)(return scope ref T source)
1927 {
1928     return moveImpl(source);
1929 }
1930 
1931 /// Non-copyable structs can still be moved:
1932 pure nothrow @safe @nogc unittest
1933 {
1934     struct S
1935     {
1936         int a = 1;
1937         @disable this(this);
1938         ~this() pure nothrow @safe @nogc {}
1939     }
1940     S s1;
1941     s1.a = 2;
1942     S s2 = move(s1);
1943     assert(s1.a == 1);
1944     assert(s2.a == 2);
1945 }
1946 
1947 // https://issues.dlang.org/show_bug.cgi?id=20869
1948 // `move` should propagate the attributes of `opPostMove`
1949 @system unittest
1950 {
1951     static struct S
1952     {
1953         void opPostMove(const ref S old) nothrow @system
1954         {
1955             __gshared int i;
1956             new int(i++); // Force @gc impure @system
1957         }
1958     }
1959 
1960     alias T = void function() @system nothrow;
1961     static assert(is(typeof({ S s; move(s); }) == T));
1962     static assert(is(typeof({ S s; move(s, s); }) == T));
1963 }
1964 
1965 private void moveImpl(T)(scope ref T target, return scope ref T source)
1966 {
1967     import core.internal.traits : hasElaborateDestructor;
1968 
1969     static if (is(T == struct))
1970     {
1971         //  Unsafe when compiling without -preview=dip1000
1972         if ((() @trusted => &source == &target)()) return;
1973         // Destroy target before overwriting it
1974         static if (hasElaborateDestructor!T) target.__xdtor();
1975     }
1976     // move and emplace source into target
1977     moveEmplaceImpl(target, source);
1978 }
1979 
1980 private T moveImpl(T)(return scope ref T source)
1981 {
1982     // Properly infer safety from moveEmplaceImpl as the implementation below
1983     // might void-initialize pointers in result and hence needs to be @trusted
1984     if (false) moveEmplaceImpl(source, source);
1985 
1986     return trustedMoveImpl(source);
1987 }
1988 
1989 private T trustedMoveImpl(T)(return scope ref T source) @trusted
1990 {
1991     T result = void;
1992     moveEmplaceImpl(result, source);
1993     return result;
1994 }
1995 
1996 @safe unittest
1997 {
1998     import core.internal.traits;
1999 
2000     assertCTFEable!((){
2001         Object obj1 = new Object;
2002         Object obj2 = obj1;
2003         Object obj3 = move(obj2);
2004         assert(obj3 is obj1);
2005 
2006         static struct S1 { int a = 1, b = 2; }
2007         S1 s11 = { 10, 11 };
2008         S1 s12 = move(s11);
2009         assert(s11.a == 10 && s11.b == 11 && s12.a == 10 && s12.b == 11);
2010 
2011         static struct S2 { int a = 1; int * b; }
2012         S2 s21 = { 10, null };
2013         s21.b = new int;
2014         S2 s22 = move(s21);
2015         assert(s21 == s22);
2016     });
2017 
2018     // Issue 5661 test(1)
2019     static struct S3
2020     {
2021         static struct X { int n = 0; ~this(){n = 0;} }
2022         X x;
2023     }
2024     static assert(hasElaborateDestructor!S3);
2025     S3 s31;
2026     s31.x.n = 1;
2027     S3 s32 = move(s31);
2028     assert(s31.x.n == 0);
2029     assert(s32.x.n == 1);
2030 
2031     // Issue 5661 test(2)
2032     static struct S4
2033     {
2034         static struct X { int n = 0; this(this){n = 0;} }
2035         X x;
2036     }
2037     static assert(hasElaborateCopyConstructor!S4);
2038     S4 s41;
2039     s41.x.n = 1;
2040     S4 s42 = move(s41);
2041     assert(s41.x.n == 0);
2042     assert(s42.x.n == 1);
2043 
2044     // Issue 13990 test
2045     class S5;
2046 
2047     S5 s51;
2048     S5 s52 = s51;
2049     S5 s53;
2050     s53 = move(s52);
2051     assert(s53 is s51);
2052 }
2053 
2054 @betterC
2055 @system unittest
2056 {
2057     static struct S { int n = 0; ~this() @system { n = 0; } }
2058     S a, b;
2059     static assert(!__traits(compiles, () @safe { move(a, b); }));
2060     static assert(!__traits(compiles, () @safe { move(a); }));
2061     a.n = 1;
2062     () @trusted { move(a, b); }();
2063     assert(a.n == 0);
2064     a.n = 1;
2065     () @trusted { move(a); }();
2066     assert(a.n == 0);
2067 }
2068 /+ this can't be tested in druntime, tests are still run in phobos
2069 @safe unittest//Issue 6217
2070 {
2071     import std.algorithm.iteration : map;
2072     auto x = map!"a"([1,2,3]);
2073     x = move(x);
2074 }
2075 +/
2076 @betterC
2077 @safe unittest// Issue 8055
2078 {
2079     static struct S
2080     {
2081         int x;
2082         ~this()
2083         {
2084             assert(x == 0);
2085         }
2086     }
2087     S foo(S s)
2088     {
2089         return move(s);
2090     }
2091     S a;
2092     a.x = 0;
2093     auto b = foo(a);
2094     assert(b.x == 0);
2095 }
2096 
2097 @system unittest// Issue 8057
2098 {
2099     int n = 10;
2100     struct S
2101     {
2102         int x;
2103         ~this()
2104         {
2105             // Access to enclosing scope
2106             assert(n == 10);
2107         }
2108     }
2109     S foo(S s)
2110     {
2111         // Move nested struct
2112         return move(s);
2113     }
2114     S a;
2115     a.x = 1;
2116     auto b = foo(a);
2117     assert(b.x == 1);
2118 
2119     // Regression 8171
2120     static struct Array(T)
2121     {
2122         // nested struct has no member
2123         struct Payload
2124         {
2125             ~this() {}
2126         }
2127     }
2128     Array!int.Payload x = void;
2129     move(x);
2130     move(x, x);
2131 }
2132 
2133 private enum bool hasContextPointers(T) = {
2134     static if (__traits(isStaticArray, T))
2135     {
2136         return hasContextPointers!(typeof(T.init[0]));
2137     }
2138     else static if (is(T == struct))
2139     {
2140         import core.internal.traits : anySatisfy;
2141         return __traits(isNested, T) || anySatisfy!(hasContextPointers, typeof(T.tupleof));
2142     }
2143     else return false;
2144 } ();
2145 
2146 @safe @nogc nothrow pure unittest
2147 {
2148     static assert(!hasContextPointers!int);
2149     static assert(!hasContextPointers!(void*));
2150 
2151     static struct S {}
2152     static assert(!hasContextPointers!S);
2153     static assert(!hasContextPointers!(S[1]));
2154 
2155     struct Nested
2156     {
2157         void foo() {}
2158     }
2159 
2160     static assert(hasContextPointers!Nested);
2161     static assert(hasContextPointers!(Nested[1]));
2162 
2163     static struct OneLevel
2164     {
2165         int before;
2166         Nested n;
2167         int after;
2168     }
2169 
2170     static assert(hasContextPointers!OneLevel);
2171     static assert(hasContextPointers!(OneLevel[1]));
2172 
2173     static struct TwoLevels
2174     {
2175         int before;
2176         OneLevel o;
2177         int after;
2178     }
2179 
2180     static assert(hasContextPointers!TwoLevels);
2181     static assert(hasContextPointers!(TwoLevels[1]));
2182 
2183     union U
2184     {
2185         Nested n;
2186     }
2187 
2188     // unions can have false positives, so this query ignores them
2189     static assert(!hasContextPointers!U);
2190 }
2191 
2192 // target must be first-parameter, because in void-functions DMD + dip1000 allows it to take the place of a return-scope
2193 private void moveEmplaceImpl(T)(scope ref T target, return scope ref T source)
2194 {
2195     // TODO: this assert pulls in half of phobos. we need to work out an alternative assert strategy.
2196 //    static if (!is(T == class) && hasAliasing!T) if (!__ctfe)
2197 //    {
2198 //        import std.exception : doesPointTo;
2199 //        assert(!doesPointTo(source, source) && !hasElaborateMove!T),
2200 //              "Cannot move object with internal pointer unless `opPostMove` is defined.");
2201 //    }
2202 
2203     import core.internal.traits : hasElaborateAssign, isAssignable, hasElaborateMove,
2204                                   hasElaborateDestructor, hasElaborateCopyConstructor;
2205     static if (is(T == struct))
2206     {
2207 
2208         //  Unsafe when compiling without -preview=dip1000
2209         assert((() @trusted => &source !is &target)(), "source and target must not be identical");
2210 
2211         static if (hasElaborateAssign!T || !isAssignable!T)
2212         {
2213             import core.stdc.string : memcpy;
2214             () @trusted { memcpy(&target, &source, T.sizeof); }();
2215         }
2216         else
2217             target = source;
2218 
2219         static if (hasElaborateMove!T)
2220             __move_post_blt(target, source);
2221 
2222         // If the source defines a destructor or a postblit hook, we must obliterate the
2223         // object in order to avoid double freeing and undue aliasing
2224         static if (hasElaborateDestructor!T || hasElaborateCopyConstructor!T)
2225         {
2226             // If there are members that are nested structs, we must take care
2227             // not to erase any context pointers, so we might have to recurse
2228             static if (__traits(isZeroInit, T))
2229                 wipe(source);
2230             else
2231                 wipe(source, ref () @trusted { return *cast(immutable(T)*) __traits(initSymbol, T).ptr; } ());
2232         }
2233     }
2234     else static if (__traits(isStaticArray, T))
2235     {
2236         static if (T.length)
2237         {
2238             static if (!hasElaborateMove!T &&
2239                        !hasElaborateDestructor!T &&
2240                        !hasElaborateCopyConstructor!T)
2241             {
2242                 // Single blit if no special per-instance handling is required
2243                 () @trusted
2244                 {
2245                     assert(source.ptr !is target.ptr, "source and target must not be identical");
2246                     *cast(ubyte[T.sizeof]*) &target = *cast(ubyte[T.sizeof]*) &source;
2247                 } ();
2248             }
2249             else
2250             {
2251                 for (size_t i = 0; i < source.length; ++i)
2252                     moveEmplaceImpl(target[i], source[i]);
2253             }
2254         }
2255     }
2256     else
2257     {
2258         // Primitive data (including pointers and arrays) or class -
2259         // assignment works great
2260         target = source;
2261     }
2262 }
2263 
2264 /**
2265  * Similar to $(LREF move) but assumes `target` is uninitialized. This
2266  * is more efficient because `source` can be blitted over `target`
2267  * without destroying or initializing it first.
2268  *
2269  * Params:
2270  *   source = value to be moved into target
2271  *   target = uninitialized value to be filled by source
2272  */
2273 void moveEmplace(T)(ref T source, ref T target) @system
2274 {
2275     moveEmplaceImpl(target, source);
2276 }
2277 
2278 ///
2279 @betterC
2280 pure nothrow @nogc @system unittest
2281 {
2282     static struct Foo
2283     {
2284     pure nothrow @nogc:
2285         this(int* ptr) { _ptr = ptr; }
2286         ~this() { if (_ptr) ++*_ptr; }
2287         int* _ptr;
2288     }
2289 
2290     int val;
2291     Foo foo1 = void; // uninitialized
2292     auto foo2 = Foo(&val); // initialized
2293     assert(foo2._ptr is &val);
2294 
2295     // Using `move(foo2, foo1)` would have an undefined effect because it would destroy
2296     // the uninitialized foo1.
2297     // moveEmplace directly overwrites foo1 without destroying or initializing it first.
2298     moveEmplace(foo2, foo1);
2299     assert(foo1._ptr is &val);
2300     assert(foo2._ptr is null);
2301     assert(val == 0);
2302 }
2303 
2304 @betterC
2305 pure nothrow @nogc @system unittest
2306 {
2307     static struct Foo
2308     {
2309     pure nothrow @nogc:
2310         this(int* ptr) { _ptr = ptr; }
2311         ~this() { if (_ptr) ++*_ptr; }
2312         int* _ptr;
2313     }
2314 
2315     int val;
2316     {
2317         Foo[1] foo1 = void; // uninitialized
2318         Foo[1] foo2 = [Foo(&val)];// initialized
2319         assert(foo2[0]._ptr is &val);
2320 
2321         // Using `move(foo2, foo1)` would have an undefined effect because it would destroy
2322         // the uninitialized foo1.
2323         // moveEmplace directly overwrites foo1 without destroying or initializing it first.
2324         moveEmplace(foo2, foo1);
2325         assert(foo1[0]._ptr is &val);
2326         assert(foo2[0]._ptr is null);
2327         assert(val == 0);
2328     }
2329     assert(val == 1);
2330 }
2331 
2332 // https://issues.dlang.org/show_bug.cgi?id=18913
2333 @safe unittest
2334 {
2335     static struct NoCopy
2336     {
2337         int payload;
2338         ~this() { }
2339         @disable this(this);
2340     }
2341 
2342     static void f(NoCopy[2]) { }
2343 
2344     NoCopy[2] ncarray = [ NoCopy(1), NoCopy(2) ];
2345 
2346     static assert(!__traits(compiles, f(ncarray)));
2347     f(move(ncarray));
2348 }
2349 
2350 //debug = PRINTF;
2351 
2352 debug(PRINTF)
2353 {
2354     import core.stdc.stdio;
2355 }
2356 
2357 /// Implementation of `_d_delstruct` and `_d_delstructTrace`
2358 template _d_delstructImpl(T)
2359 {
2360     private void _d_delstructImpure(ref T p)
2361     {
2362         debug(PRINTF) printf("_d_delstruct(%p)\n", p);
2363 
2364         destroy(*p);
2365         p = null;
2366     }
2367 
2368     /**
2369      * This is called for a delete statement where the value being deleted is a
2370      * pointer to a struct with a destructor but doesn't have an overloaded
2371      * `delete` operator.
2372      *
2373      * Params:
2374      *   p = pointer to the value to be deleted
2375      *
2376      * Bugs:
2377      *   This function template was ported from a much older runtime hook that
2378      *   bypassed safety, purity, and throwabilty checks. To prevent breaking
2379      *   existing code, this function template is temporarily declared
2380      *   `@trusted` until the implementation can be brought up to modern D
2381      *   expectations.
2382      */
2383     void _d_delstruct(ref T p) @trusted @nogc pure nothrow
2384     {
2385         if (p)
2386         {
2387             alias Type = void function(ref T P) @nogc pure nothrow;
2388             (cast(Type) &_d_delstructImpure)(p);
2389         }
2390     }
2391 
2392     version (D_ProfileGC)
2393     {
2394         import core.internal.array.utils : _d_HookTraceImpl;
2395 
2396         private enum errorMessage = "Cannot delete struct if compiling without support for runtime type information!";
2397 
2398         /**
2399          * TraceGC wrapper around $(REF _d_delstruct, core,lifetime,_d_delstructImpl).
2400          *
2401          * Bugs:
2402          *   This function template was ported from a much older runtime hook that
2403          *   bypassed safety, purity, and throwabilty checks. To prevent breaking
2404          *   existing code, this function template is temporarily declared
2405          *   `@trusted` until the implementation can be brought up to modern D
2406          *   expectations.
2407          */
2408         alias _d_delstructTrace = _d_HookTraceImpl!(T, _d_delstruct, errorMessage);
2409     }
2410 }
2411 
2412 @system pure nothrow unittest
2413 {
2414     int dtors = 0;
2415     struct S { ~this() nothrow { ++dtors; } }
2416 
2417     S *s = new S();
2418     _d_delstructImpl!(typeof(s))._d_delstruct(s);
2419 
2420     assert(s == null);
2421     assert(dtors == 1);
2422 }
2423 
2424 @system pure unittest
2425 {
2426     int innerDtors = 0;
2427     int outerDtors = 0;
2428 
2429     struct Inner { ~this() { ++innerDtors; } }
2430     struct Outer
2431     {
2432         Inner *i1;
2433         Inner *i2;
2434 
2435         this(int x)
2436         {
2437             i1 = new Inner();
2438             i2 = new Inner();
2439         }
2440 
2441         ~this()
2442         {
2443             ++outerDtors;
2444 
2445             _d_delstructImpl!(typeof(i1))._d_delstruct(i1);
2446             assert(i1 == null);
2447 
2448            _d_delstructImpl!(typeof(i2))._d_delstruct(i2);
2449             assert(i2 == null);
2450         }
2451     }
2452 
2453     Outer *o = new Outer(0);
2454     _d_delstructImpl!(typeof(o))._d_delstruct(o);
2455 
2456     assert(o == null);
2457     assert(innerDtors == 2);
2458     assert(outerDtors == 1);
2459 }
2460 
2461 // https://issues.dlang.org/show_bug.cgi?id=25552
2462 pure nothrow @system unittest
2463 {
2464     int i;
2465     struct Nested
2466     {
2467     pure nothrow @nogc:
2468         char[1] arr; // char.init is not 0
2469         ~this() { ++i; }
2470     }
2471 
2472     {
2473         Nested[1] dst = void;
2474         Nested[1] src = [Nested(['a'])];
2475 
2476         moveEmplace(src, dst);
2477         assert(i == 0);
2478         assert(dst[0].arr == ['a']);
2479         assert(src[0].arr == [char.init]);
2480         assert(dst[0].tupleof[$-1] is src[0].tupleof[$-1]);
2481     }
2482     assert(i == 2);
2483 }
2484 
2485 // https://issues.dlang.org/show_bug.cgi?id=25552
2486 @safe unittest
2487 {
2488     int i;
2489     struct Nested
2490     {
2491         ~this() { ++i; }
2492     }
2493 
2494     static struct NotNested
2495     {
2496         Nested n;
2497     }
2498 
2499     static struct Deep
2500     {
2501         NotNested nn;
2502     }
2503 
2504     static struct Deeper
2505     {
2506         NotNested[1] nn;
2507     }
2508 
2509     static assert(__traits(isZeroInit, Nested));
2510     static assert(__traits(isZeroInit, NotNested));
2511     static assert(__traits(isZeroInit, Deep));
2512     static assert(__traits(isZeroInit, Deeper));
2513 
2514     {
2515         auto a = NotNested(Nested());
2516         assert(a.n.tupleof[$-1]);
2517         auto b = move(a);
2518         assert(b.n.tupleof[$-1]);
2519         assert(a.n.tupleof[$-1] is b.n.tupleof[$-1]);
2520 
2521         auto c = Deep(NotNested(Nested()));
2522         auto d = move(c);
2523         assert(d.nn.n.tupleof[$-1]);
2524         assert(c.nn.n.tupleof[$-1] is d.nn.n.tupleof[$-1]);
2525 
2526         auto e = Deeper([NotNested(Nested())]);
2527         auto f = move(e);
2528         assert(f.nn[0].n.tupleof[$-1]);
2529         assert(e.nn[0].n.tupleof[$-1] is f.nn[0].n.tupleof[$-1]);
2530     }
2531     assert(i == 6);
2532 }
2533 
2534 // https://issues.dlang.org/show_bug.cgi?id=25552
2535 @safe unittest
2536 {
2537     int i;
2538     struct Nested
2539     {
2540         align(32) // better still find context pointer correctly!
2541         int[3] stuff = [0, 1, 2];
2542         ~this() { ++i; }
2543     }
2544 
2545     static struct NoAssign
2546     {
2547         int value;
2548         @disable void opAssign(typeof(this));
2549     }
2550 
2551     static struct NotNested
2552     {
2553         int before = 42;
2554         align(Nested.alignof * 4) // better still find context pointer correctly!
2555         Nested n;
2556         auto after = NoAssign(43);
2557     }
2558 
2559     static struct Deep
2560     {
2561         NotNested nn;
2562     }
2563 
2564     static struct Deeper
2565     {
2566         NotNested[1] nn;
2567     }
2568 
2569     static assert(!__traits(isZeroInit, Nested));
2570     static assert(!__traits(isZeroInit, NotNested));
2571     static assert(!__traits(isZeroInit, Deep));
2572     static assert(!__traits(isZeroInit, Deeper));
2573 
2574     {
2575         auto a = NotNested(1, Nested([3, 4, 5]), NoAssign(2));
2576         auto b = move(a);
2577         assert(b.n.tupleof[$-1]);
2578         assert(a.n.tupleof[$-1] is b.n.tupleof[$-1]);
2579         assert(a.n.stuff == [0, 1, 2]);
2580         assert(a.before == 42);
2581         assert(a.after == NoAssign(43));
2582 
2583         auto c = Deep(NotNested(1, Nested([3, 4, 5]), NoAssign(2)));
2584         auto d = move(c);
2585         assert(d.nn.n.tupleof[$-1]);
2586         assert(c.nn.n.tupleof[$-1] is d.nn.n.tupleof[$-1]);
2587         assert(c.nn.n.stuff == [0, 1, 2]);
2588         assert(c.nn.before == 42);
2589         assert(c.nn.after == NoAssign(43));
2590 
2591         auto e = Deeper([NotNested(1, Nested([3, 4, 5]), NoAssign(2))]);
2592         auto f = move(e);
2593         assert(f.nn[0].n.tupleof[$-1]);
2594         assert(e.nn[0].n.tupleof[$-1] is f.nn[0].n.tupleof[$-1]);
2595         assert(e.nn[0].n.stuff == [0, 1, 2]);
2596         assert(e.nn[0].before == 42);
2597         assert(e.nn[0].after == NoAssign(43));
2598     }
2599     assert(i == 6);
2600 }
2601 
2602 // wipes source after moving
2603 pragma(inline, true)
2604 private void wipe(T, Init...)(return scope ref T source, ref const scope Init initializer) @trusted
2605 if (!Init.length ||
2606     ((Init.length == 1) && (is(immutable T == immutable Init[0]))))
2607 {
2608     static if (__traits(isStaticArray, T) && hasContextPointers!T)
2609     {
2610         for (auto i = 0; i < T.length; i++)
2611             static if (Init.length)
2612                 wipe(source[i], initializer[0][i]);
2613             else
2614                 wipe(source[i]);
2615     }
2616     else static if (is(T == struct) && hasContextPointers!T)
2617     {
2618         import core.internal.traits : anySatisfy;
2619         static if (anySatisfy!(hasContextPointers, typeof(T.tupleof)))
2620         {
2621             static foreach (i; 0 .. T.tupleof.length - __traits(isNested, T))
2622                 static if (Init.length)
2623                     wipe(source.tupleof[i], initializer[0].tupleof[i]);
2624                 else
2625                     wipe(source.tupleof[i]);
2626         }
2627         else
2628         {
2629             static if (__traits(isNested, T))
2630                 enum sz = T.tupleof[$-1].offsetof;
2631             else
2632                 enum sz = T.sizeof;
2633 
2634             static if (Init.length)
2635                 *cast(ubyte[sz]*) &source = *cast(ubyte[sz]*) &initializer[0];
2636             else
2637                 *cast(ubyte[sz]*) &source = 0;
2638         }
2639     }
2640     else
2641     {
2642         import core.internal.traits : hasElaborateAssign, isAssignable;
2643         static if (Init.length)
2644         {
2645             static if (hasElaborateAssign!T || !isAssignable!T)
2646                 *cast(ubyte[T.sizeof]*) &source = *cast(ubyte[T.sizeof]*) &initializer[0];
2647             else
2648                 source = *cast(T*) &initializer[0];
2649         }
2650         else
2651         {
2652             *cast(ubyte[T.sizeof]*) &source = 0;
2653         }
2654     }
2655 }
2656 
2657 /**
2658  * Allocate an exception of type `T` from the exception pool.
2659  * `T` must be `Throwable` or derived from it and cannot be a COM or C++ class.
2660  *
2661  * Note:
2662  *  This function does not call the constructor of `T` because that would require
2663  *  `forward!args`, which causes errors with -dip1008. This inconvenience will be
2664  *  removed once -dip1008 works as intended.
2665  *
2666  * Returns:
2667  *   allocated instance of type `T`
2668  */
2669 T _d_newThrowable(T)() @trusted
2670     if (is(T : Throwable) && __traits(getLinkage, T) == "D")
2671 {
2672     debug(PRINTF) printf("_d_newThrowable(%s)\n", cast(char*) T.stringof);
2673 
2674     auto init = __traits(initSymbol, T);
2675     void* p = _d_allocmemory(init.length);
2676     if (!p)
2677     {
2678         import core.exception : onOutOfMemoryError;
2679         onOutOfMemoryError();
2680     }
2681 
2682     debug(PRINTF) printf(" p = %p\n", p);
2683 
2684     // initialize it
2685     p[0 .. init.length] = init[];
2686 
2687 
2688     debug(PRINTF) printf("initialization done\n");
2689 
2690     (cast(Throwable) p).refcount() = 1;
2691 
2692     return cast(T) p;
2693 }
2694 
2695 @system unittest
2696 {
2697     class E : Exception
2698     {
2699         this(string msg = "", Throwable nextInChain = null)
2700         {
2701             super(msg, nextInChain);
2702         }
2703     }
2704 
2705     Throwable exc = _d_newThrowable!Exception();
2706     Throwable e = _d_newThrowable!E();
2707 
2708     assert(exc.refcount() == 1);
2709     assert(e.refcount() == 1);
2710 }
2711 
2712 /**
2713  * Create a new class instance.
2714  * Allocates memory and sets fields to their initial value, but does not call a
2715  * constructor.
2716  * ---
2717  * new C() // _d_newclass!(C)()
2718  * ---
2719  * Returns: newly created object
2720  */
2721 T _d_newclassT(T)() @trusted
2722 if (is(T == class))
2723 {
2724     import core.internal.traits : hasIndirections;
2725     import core.exception : onOutOfMemoryError;
2726 
2727     alias BlkAttr = GC.BlkAttr;
2728 
2729     auto init = __traits(initSymbol, T);
2730     void* p = _d_allocmemory(init.length);
2731 
2732     debug(PRINTF)
2733     {
2734         printf("p = %p\n", p);
2735         printf("init.ptr = %p, len = %llu\n", init.ptr, cast(ulong)init.length);
2736         printf("vptr = %p\n", *cast(void**) init);
2737         printf("vtbl[0] = %p\n", (*cast(void***) init)[0]);
2738         printf("vtbl[1] = %p\n", (*cast(void***) init)[1]);
2739         printf("init[0] = %x\n", (cast(uint*) init)[0]);
2740         printf("init[1] = %x\n", (cast(uint*) init)[1]);
2741         printf("init[2] = %x\n", (cast(uint*) init)[2]);
2742         printf("init[3] = %x\n", (cast(uint*) init)[3]);
2743         printf("init[4] = %x\n", (cast(uint*) init)[4]);
2744     }
2745 
2746     // initialize it
2747     p[0 .. init.length] = init[];
2748 
2749     debug(PRINTF) printf("initialization done\n");
2750     return cast(T) p;
2751 }
2752 
2753 /**
2754  * TraceGC wrapper around $(REF _d_newclassT, core,lifetime).
2755  */
2756 T _d_newclassTTrace(T)(string file, int line, string funcname) @trusted
2757 {
2758     version (D_TypeInfo)
2759     {
2760         import core.internal.array.utils : TraceHook, gcStatsPure, accumulatePure;
2761         mixin(TraceHook!(T.stringof, "_d_newclassT"));
2762 
2763         return _d_newclassT!T();
2764     }
2765     else
2766         assert(0, "Cannot create new class if compiling without support for runtime type information!");
2767 }
2768 
2769 /**
2770  * Allocate an initialized non-array item.
2771  *
2772  * This is an optimization to avoid things needed for arrays like the __arrayPad(size).
2773  * Used to allocate struct instances on the heap.
2774  *
2775  * ---
2776  * struct Sz {int x = 0;}
2777  * struct Si {int x = 3;}
2778  *
2779  * void main()
2780  * {
2781  *     new Sz(); // uses zero-initialization
2782  *     new Si(); // uses Si.init
2783  * }
2784  * ---
2785  *
2786  * Returns:
2787  *     newly allocated item
2788  */
2789 T* _d_newitemT(T)() @trusted
2790 {
2791     import core.internal.lifetime : emplaceInitializer;
2792     import core.internal.traits : hasIndirections;
2793 
2794     immutable tiSize = TypeInfoSize!T;
2795     immutable itemSize = T.sizeof;
2796     immutable totalSize = itemSize + tiSize;
2797 
2798     auto p = _d_allocmemory(totalSize);
2799 
2800     emplaceInitializer(*(cast(T*) p));
2801 
2802     return cast(T*) p;
2803 }
2804 
2805 // Test allocation
2806 @safe unittest
2807 {
2808     class C { }
2809     C c = _d_newclassT!C();
2810 
2811     assert(c !is null);
2812 }
2813 
2814 // Test initializers
2815 @safe unittest
2816 {
2817     {
2818         class C { int x, y; }
2819         C c = _d_newclassT!C();
2820 
2821         assert(c.x == 0);
2822         assert(c.y == 0);
2823     }
2824     {
2825         class C { int x = 2, y = 3; }
2826         C c = _d_newclassT!C();
2827 
2828         assert(c.x == 2);
2829         assert(c.y == 3);
2830     }
2831 }
2832 
2833 // Test allocation
2834 @safe unittest
2835 {
2836     struct S { }
2837     S* s = _d_newitemT!S();
2838 
2839     assert(s !is null);
2840 }
2841 
2842 // Test initializers
2843 @safe unittest
2844 {
2845     {
2846         // zero-initialization
2847         struct S { int x, y; }
2848         S* s = _d_newitemT!S();
2849 
2850         assert(s.x == 0);
2851         assert(s.y == 0);
2852     }
2853     {
2854         // S.init
2855         struct S { int x = 2, y = 3; }
2856         S* s = _d_newitemT!S();
2857 
2858         assert(s.x == 2);
2859         assert(s.y == 3);
2860     }
2861 }
2862 
2863 // Test GC attributes
2864 version (CoreUnittest)
2865 {
2866     struct S1
2867     {
2868         int x = 5;
2869     }
2870     struct S2
2871     {
2872         int x;
2873         this(int x) { this.x = x; }
2874     }
2875     struct S3
2876     {
2877         int[4] x;
2878         this(int x) { this.x[] = x; }
2879     }
2880     struct S4
2881     {
2882         int *x;
2883     }
2884 
2885 }
2886 @system unittest
2887 {
2888     import core.memory : GC;
2889 
2890     auto s1 = new S1;
2891     assert(s1.x == 5);
2892     assert(GC.getAttr(s1) == GC.BlkAttr.NO_SCAN);
2893 
2894     auto s2 = new S2(3);
2895     assert(s2.x == 3);
2896     assert(GC.getAttr(s2) == GC.BlkAttr.NO_SCAN);
2897 
2898     auto s3 = new S3(1);
2899     assert(s3.x == [1, 1, 1, 1]);
2900     assert(GC.getAttr(s3) == GC.BlkAttr.NO_SCAN);
2901     debug(SENTINEL) {} else
2902         assert(GC.sizeOf(s3) == 16);
2903 
2904     auto s4 = new S4;
2905     assert(s4.x == null);
2906     assert(GC.getAttr(s4) == 0);
2907 }
2908 
2909 // Test struct finalizers exception handling
2910 debug(SENTINEL) {} else
2911 @system unittest
2912 {
2913     import core.memory : GC;
2914 
2915     bool test(E)()
2916     {
2917         import core.exception;
2918         static struct S1
2919         {
2920             E exc;
2921             ~this() { throw exc; }
2922         }
2923 
2924         bool caught = false;
2925         S1* s = new S1(new E("test onFinalizeError"));
2926         try
2927         {
2928             GC.runFinalizers((cast(char*)(typeid(S1).xdtor))[0 .. 1]);
2929         }
2930         catch (FinalizeError err)
2931         {
2932             caught = true;
2933         }
2934         catch (E)
2935         {
2936         }
2937         GC.free(s);
2938         return caught;
2939     }
2940 
2941     assert(test!Exception);
2942     import core.exception : InvalidMemoryOperationError;
2943     assert(!test!InvalidMemoryOperationError);
2944 }
2945 
2946 version (D_ProfileGC)
2947 {
2948     /**
2949     * TraceGC wrapper around $(REF _d_newitemT, core,lifetime).
2950     */
2951     T* _d_newitemTTrace(T)(string file, int line, string funcname) @trusted
2952     {
2953         version (D_TypeInfo)
2954         {
2955             import core.internal.array.utils : TraceHook, gcStatsPure, accumulatePure;
2956             mixin(TraceHook!(T.stringof, "_d_newitemT"));
2957 
2958             return _d_newitemT!T();
2959         }
2960         else
2961             assert(0, "Cannot create new `struct` if compiling without support for runtime type information!");
2962     }
2963 }
2964 
2965 template TypeInfoSize(T)
2966 {
2967     import core.internal.traits : hasElaborateDestructor;
2968     enum TypeInfoSize = hasElaborateDestructor!T ? size_t.sizeof : 0;
2969 }