1 
2 extern(C) int printf(const char* fmt, ...);
3 
4 /***************************************/
5 
test1()6 void test1()
7 {
8     char[] a;
9 
10     int foo()
11     {
12         printf("foo\n");
13         a ~= "foo";
14         return 10;
15     }
16 
17     foreach (i; 0 .. foo())
18     {
19         printf("%d\n", i);
20         a ~= cast(char)('0' + i);
21     }
22     assert(a == "foo0123456789");
23 
24     foreach_reverse (i; 0 .. foo())
25     {
26         printf("%d\n", i);
27         a ~= cast(char)('0' + i);
28     }
29     assert(a == "foo0123456789foo9876543210");
30 }
31 
32 /***************************************/
33 // 2411
34 
35 struct S2411
36 {
37     int n;
38     string s;
39 }
40 
test2411()41 void test2411()
42 {
43     S2411 s;
44     assert(s.n == 0);
45     assert(s.s == "");
46     foreach (i, ref e; s.tupleof)
47     {
48         static if (i == 0)
49             e = 10;
50         static if (i == 1)
51             e = "str";
52     }
53     assert(s.n == 10);
54     assert(s.s == "str");
55 }
56 
57 /***************************************/
58 // 2442
59 
canForeach(T,E)60 template canForeach(T, E)
61 {
62     enum canForeach = __traits(compiles,
63     {
64         foreach(a; new T)
65         {
66             static assert(is(typeof(a) == E));
67         }
68     });
69 }
70 
test2442()71 void test2442()
72 {
73     struct S1
74     {
75         int opApply(int delegate(ref const(int) v) dg) const { return 0; }
76         int opApply(int delegate(ref int v) dg)              { return 0; }
77     }
78           S1 ms1;
79     const S1 cs1;
80     foreach (x; ms1) { static assert(is(typeof(x) ==       int)); }
81     foreach (x; cs1) { static assert(is(typeof(x) == const int)); }
82 
83     struct S2
84     {
85         int opApply(int delegate(ref  int v) dg) { return 0; }
86         int opApply(int delegate(ref long v) dg) { return 0; }
87     }
88     S2 ms2;
89     static assert(!__traits(compiles, { foreach (    x; ms2) {} }));    // ambiguous
90     static assert( __traits(compiles, { foreach (int x; ms2) {} }));
91 
92     struct S3
93     {
94         int opApply(int delegate(ref int v) dg) const        { return 0; }
95         int opApply(int delegate(ref int v) dg) shared const { return 0; }
96     }
97     immutable S3 ms3;
98     static assert(!__traits(compiles, { foreach (int x; ms3) {} }));    // ambiguous
99 
100     // from https://github.com/dlang/dmd/pull/120
101     static class C
102     {
103         int opApply(int delegate(ref              int v) dg)              { return 0; }
104         int opApply(int delegate(ref        const int v) dg) const        { return 0; }
105         int opApply(int delegate(ref    immutable int v) dg) immutable    { return 0; }
106         int opApply(int delegate(ref       shared int v) dg) shared       { return 0; }
107         int opApply(int delegate(ref shared const int v) dg) shared const { return 0; }
108     }
109     static class D
110     {
111         int opApply(int delegate(ref int v) dg) const        { return 0; }
112     }
113     static class E
114     {
115         int opApply(int delegate(ref int v) dg) shared const { return 0; }
116     }
117 
118     static assert( canForeach!(             C  ,              int  ));
119     static assert( canForeach!(       const(C) ,        const(int) ));
120     static assert( canForeach!(   immutable(C) ,    immutable(int) ));
121     static assert( canForeach!(      shared(C) ,       shared(int) ));
122     static assert( canForeach!(shared(const(C)), shared(const(int))));
123 
124     static assert( canForeach!(             D  , int));
125     static assert( canForeach!(       const(D) , int));
126     static assert( canForeach!(   immutable(D) , int));
127     static assert(!canForeach!(      shared(D) , int));
128     static assert(!canForeach!(shared(const(D)), int));
129 
130     static assert(!canForeach!(             E  , int));
131     static assert(!canForeach!(       const(E) , int));
132     static assert( canForeach!(   immutable(E) , int));
133     static assert( canForeach!(      shared(E) , int));
134     static assert( canForeach!(shared(const(E)), int));
135 }
136 
137 /***************************************/
138 // 2443
139 
140 struct S2443
141 {
142     int[] arr;
opApplyS2443143     int opApply(int delegate(size_t i, ref int v) dg)
144     {
145         int result = 0;
146         foreach (i, ref x; arr)
147         {
148             if ((result = dg(i, x)) != 0)
149                 break;
150         }
151         return result;
152     }
153 }
154 
test2443()155 void test2443()
156 {
157     S2443 s;
158     foreach (i, ref v; s) {}
159     foreach (i,     v; s) {}
160     static assert(!__traits(compiles, { foreach (ref i, ref v; s) {} }));
161     static assert(!__traits(compiles, { foreach (ref i,     v; s) {} }));
162 }
163 
164 /***************************************/
165 // 3187
166 
167 class Collection
168 {
opApply(int delegate (ref Object)a)169     int opApply(int delegate(ref Object) a)
170     {
171         return 0;
172     }
173 }
174 
testForeach(Collection level1,Collection level2)175 Object testForeach(Collection level1, Collection level2)
176 {
177     foreach (first; level1) {
178         foreach (second; level2)
179             return second;
180     }
181     return null;
182 }
183 
test3187()184 void test3187()
185 {
186     testForeach(new Collection, new Collection);
187 }
188 
189 /***************************************/
190 // 4090
191 
test4090a()192 void test4090a()
193 {
194     double[10] arr = 1;
195     double tot = 0;
196 
197   static assert(!__traits(compiles, {
198     foreach (immutable ref x; arr) {}
199   }));
200     foreach (const ref x; arr)
201     {
202         static assert(is(typeof(x) == const double));
203         tot += x;
204     }
205     foreach (immutable x; arr)
206     {
207         static assert(is(typeof(x) == immutable double));
208         tot += x;
209     }
210     assert(tot == 1*10 + 1*10);
211 }
212 
test4090b()213 void test4090b()
214 {
215     int tot = 0;
216 
217   static assert(!__traits(compiles, {
218     foreach (immutable ref x; 1..11) {}
219   }));
220     foreach (const ref x; 1..11)
221     {
222         static assert(is(typeof(x) == const int));
223         tot += x;
224     }
225     foreach (immutable x; 1..11)
226     {
227         static assert(is(typeof(x) == immutable int));
228         tot += x;
229     }
230     assert(tot == 55 + 55);
231 }
232 
233 /***************************************/
234 // 5605
235 
236 struct MyRange
237 {
238     int theOnlyOne;
239 
emptyMyRange240     @property bool empty() const
241     {
242         return true;
243     }
244 
frontMyRange245     @property ref int front()
246     {
247         return theOnlyOne;
248     }
249 
popFrontMyRange250     void popFront()
251     {}
252 }
253 
254 struct MyCollection
255 {
opSlice()256     MyRange opSlice() const
257     {
258         return MyRange();
259     }
260 }
261 
test5605()262 void test5605()
263 {
264     auto coll = MyCollection();
265 
266     foreach (i; coll) {            // <-- compilation error
267         // ...
268     }
269 }
270 
271 /***************************************/
272 // 7004
273 
func7004(A...)274 void func7004(A...)(A args)
275 {
276     foreach (i, e; args){}        // OK
277     foreach (uint i, e; args){}   // OK
278     foreach (size_t i, e; args){} // NG
279 }
test7004()280 void test7004()
281 {
282     func7004(1, 3.14);
283 }
284 
285 /***************************************/
286 // 7406
287 
TypeTuple7406(T...)288 template TypeTuple7406(T...)
289 {
290     alias T TypeTuple7406;
291 }
292 
foobar7406(T)293 template foobar7406(T)
294 {
295     enum foobar = 2;
296 }
297 
test7406()298 void test7406()
299 {
300     foreach (sym; TypeTuple7406!(int, double))     // OK
301         pragma(msg, sym.stringof);
302 
303     foreach (sym; TypeTuple7406!(foobar7406))      // OK
304         pragma(msg, sym.stringof);
305 
306     foreach (sym; TypeTuple7406!(test7406))        // OK
307         pragma(msg, sym.stringof);
308 
309     foreach (sym; TypeTuple7406!(int, foobar7406)) // Error: type int has no value
310         pragma(msg, sym.stringof);
311 
312     foreach (sym; TypeTuple7406!(int, test7406))   // Error: type int has no value
313         pragma(msg, sym.stringof);
314 }
315 
316 /***************************************/
317 // 6659
318 
test6659()319 void test6659()
320 {
321     static struct Iter
322     {
323         ~this()
324         {
325             ++_dtor;
326         }
327 
328         bool opCmp(ref const Iter rhs) { return _pos == rhs._pos; }
329         void opUnary(string op:"++")() { ++_pos; }
330         size_t _pos;
331 
332         static size_t _dtor;
333     }
334 
335     foreach (ref iter; Iter(0) .. Iter(10))
336     {
337         assert(Iter._dtor == 0);
338     }
339     assert(Iter._dtor == 2);
340 
341     Iter._dtor = 0; // reset
342 
343     for (auto iter = Iter(0), limit = Iter(10); iter != limit; ++iter)
344     {
345         assert(Iter._dtor == 0);
346     }
347     assert(Iter._dtor == 2);
348 }
349 
test6659a()350 void test6659a()
351 {
352     auto value = 0;
353     try
354     {
355         for ({scope(success) { assert(value == 1); value = 2;} }  true; )
356         {
357             value = 1;
358             break;
359         }
360         assert(value == 2);
361     }
362     catch (Exception e)
363     {
364         assert(0);
365     }
366     assert(value == 2);
367 }
368 
test6659b()369 void test6659b()
370 {
371     auto value = 0;
372     try
373     {
374         for ({scope(failure) value = 1;}  true; )
375         {
376             throw new Exception("");
377         }
378         assert(0);
379     }
380     catch (Exception e)
381     {
382         assert(e);
383     }
384     assert(value == 1);
385 }
386 
test6659c()387 void test6659c()
388 {
389     auto value = 0;
390     try
391     {
392         for ({scope(exit) value = 1;}  true; )
393         {
394             throw new Exception("");
395         }
396         assert(0);
397     }
398     catch (Exception e)
399     {
400         assert(e);
401     }
402     assert(value == 1);
403 }
404 
405 /***************************************/
406 
407 // 10221
408 
test10221()409 void test10221()
410 {
411     // All of these should work, but most are too slow.  Just check they compile.
412     foreach(char i; char.min..char.max+1) {}
413     if (0) foreach(wchar i; wchar.min..wchar.max+1) {}
414     if (0) foreach(dchar i; dchar.min..dchar.max+1) {}
415     foreach(byte i; byte.min..byte.max+1) {}
416     foreach(ubyte i; ubyte.min..ubyte.max+1) {}
417     if (0) foreach(short i; short.min..short.max+1) {}
418     if (0) foreach(ushort i; ushort.min..ushort.max+1) {}
419     if (0) foreach(int i; int.min..int.max+1U) {}
420     if (0) foreach(uint i; uint.min..uint.max+1L) {}
421     if (0) foreach(long i; long.min..long.max+1UL) {}
422 
423     foreach_reverse(char i; char.min..char.max+1) { assert(i == typeof(i).max); break; }
424     foreach_reverse(wchar i; wchar.min..wchar.max+1) { assert(i == typeof(i).max); break; }
425     foreach_reverse(dchar i; dchar.min..dchar.max+1) { assert(i == typeof(i).max); break; }
426     foreach_reverse(byte i; byte.min..byte.max+1) { assert(i == typeof(i).max); break; }
427     foreach_reverse(ubyte i; ubyte.min..ubyte.max+1) { assert(i == typeof(i).max); break; }
428     foreach_reverse(short i; short.min..short.max+1) { assert(i == typeof(i).max); break; }
429     foreach_reverse(ushort i; ushort.min..ushort.max+1) { assert(i == typeof(i).max); break; }
430     foreach_reverse(int i; int.min..int.max+1U) { assert(i == typeof(i).max); break; }
431     foreach_reverse(uint i; uint.min..uint.max+1L) { assert(i == typeof(i).max); break; }
432     foreach_reverse(long i; long.min..long.max+1UL) { assert(i == typeof(i).max); break; }
433 }
434 
435 /***************************************/
436 // 7814
437 
438 struct File7814
439 {
~thisFile7814440     ~this(){}
441 }
442 
443 struct ByLine7814
444 {
445     File7814 file;
446 
447     // foreach interface
empty()448     @property bool empty() const    { return true; }
front()449     @property char[] front()        { return null; }
popFront()450     void popFront(){}
451 }
452 
test7814()453 void test7814()
454 {
455     int dummy;
456     ByLine7814 f;
457     foreach (l; f) {
458         scope(failure) // 'failure' or 'success' fails, but 'exit' works
459             dummy = -1;
460         dummy = 0;
461     }
462 }
463 
464 /***************************************/
465 // 10049
466 
467 struct ByLine10049
468 {
emptyByLine10049469     bool empty() { return true; }
frontByLine10049470     string front() { return null; }
popFrontByLine10049471     void popFront() {}
472 
~thisByLine10049473     ~this() {}  // necessary
474 }
475 
test10049()476 void test10049()
477 {
478     ByLine10049 r;
479     foreach (line; r)
480     {
481         doNext:
482             {}
483     }
484 }
485 
486 /******************************************/
487 
T11955(T...)488 struct T11955(T...) { T field; alias field this; }
489 
490 alias X11955 = uint;
491 
492 struct S11955
493 {
494     enum empty = false;
495     T11955!(uint, uint) front;
popFrontS11955496     void popFront() {}
497 }
498 
test11955()499 void test11955()
500 {
501     foreach(X11955 i, v; S11955()) {}
502 }
503 
504 /******************************************/
505 // 6652
506 
test6652()507 void test6652()
508 {
509     size_t sum;
510     foreach (i; 0 .. 10)
511         sum += i++; // 0123456789
512     assert(sum == 45);
513 
514     sum = 0;
515     foreach (ref i; 0 .. 10)
516         sum += i++; // 02468
517     assert(sum == 20);
518 
519     sum = 0;
520     foreach_reverse (i; 0 .. 10)
521         sum += i--; // 9876543210
522     assert(sum == 45);
523 
524     sum = 0;
525     foreach_reverse (ref i; 0 .. 10)
526         sum += i--; // 97531
527     assert(sum == 25);
528 
529     enum ary = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
530     sum = 0;
531     foreach (i, v; ary)
532     {
533         assert(i == v);
534         sum += i++; // 0123456789
535     }
536     assert(sum == 45);
537 
538     sum = 0;
539     foreach (ref i, v; ary)
540     {
541         assert(i == v);
542         sum += i++; // 02468
543     }
544     assert(sum == 20);
545 
546     sum = 0;
547     foreach_reverse (i, v; ary)
548     {
549         assert(i == v);
550         sum += i--; // 9876543210
551     }
552     assert(sum == 45);
553 
554     sum = 0;
555     foreach_reverse (ref i, v; ary)
556     {
557         assert(i == v);
558         sum += i--; // 97531
559     }
560     assert(sum == 25);
561 
562     static struct Iter
563     {
564         ~this()
565         {
566             ++_dtorCount;
567         }
568 
569         bool opCmp(ref const Iter rhs)
570         {
571             return _pos == rhs._pos;
572         }
573 
574         void opUnary(string op)() if(op == "++" || op == "--")
575         {
576             mixin(op ~ q{_pos;});
577         }
578 
579         size_t _pos;
580         static size_t _dtorCount;
581     }
582 
583     Iter._dtorCount = sum = 0;
584     foreach (v; Iter(0) .. Iter(10))
585         sum += v._pos++; // 0123456789
586     assert(sum == 45 && Iter._dtorCount == 12);
587 
588     Iter._dtorCount = sum = 0;
589     foreach (ref v; Iter(0) .. Iter(10))
590         sum += v._pos++; // 02468
591     assert(sum == 20 && Iter._dtorCount == 2);
592 
593     // additional dtor calls due to unnecessary postdecrements
594     Iter._dtorCount = sum = 0;
595     foreach_reverse (v; Iter(0) .. Iter(10))
596         sum += v._pos--; // 9876543210
597     assert(sum == 45 && Iter._dtorCount >= 12);
598 
599     Iter._dtorCount = sum = 0;
600     foreach_reverse (ref v; Iter(0) .. Iter(10))
601         sum += v._pos--; // 97531
602     assert(sum == 25 && Iter._dtorCount >= 2);
603 }
604 
605 /***************************************/
606 // 8595
607 
608 struct OpApply8595
609 {
opApplyOpApply8595610     int opApply(int delegate(ref int) dg)
611     {
612         assert(0);
613     }
614 }
615 
test8595()616 string test8595()
617 {
618     foreach (elem; OpApply8595.init)
619     {
620         static assert(is(typeof(return) == string));
621     }
622     assert(0);
623 }
624 
625 /***************************************/
626 // 9068
627 
628 struct Foo9068
629 {
630     static int[] destroyed;
631     int x;
~thisFoo9068632     ~this() { destroyed ~= x; }
633 }
634 
635 struct SimpleCounter9068
636 {
637     static int destroyedCount;
638     enum int limit = 5;
639     int counter;
~this()640     ~this() { destroyedCount++; }
641 
642     // Range primitives.
empty()643     @property bool empty() const { return counter >= limit; }
front()644     @property int front() { return counter; }
popFront()645     void popFront() { counter++; }
646 }
647 
test9068()648 void test9068()
649 {
650     //----------------------------------------
651     // There was never a bug in this case (no range).
652     int sum;
653 loop_simple:
654     foreach (i; [10, 20])
655     {
656         sum += i;
657         break loop_simple;
658     }
659     assert(sum == 10);
660 
661     //----------------------------------------
662     // There was a bug with loops over ranges.
663     int last = -1;
664 X:  foreach (i; SimpleCounter9068())
665     {
666         switch(i)
667         {
668             case 3:
669                 break X;
670             default:
671                 last = i;
672        }
673     }
674     assert(last == 2);
675     assert(SimpleCounter9068.destroyedCount == 1);
676 
677     //----------------------------------------
678     // Simpler case: the compiler error had nothing to do with the switch.
679     last = -1;
680 loop_with_range:
681     foreach (i; SimpleCounter9068())
682     {
683         last = i;
684         break loop_with_range;
685     }
686     assert(last == 0);
687     assert(SimpleCounter9068.destroyedCount == 2);
688 
689     //----------------------------------------
690     // Test with destructors: the loop is implicitly wrapped into two
691     // try/finally clauses.
692 loop_with_dtors:
693     for (auto x = Foo9068(4), y = Foo9068(5); x.x != 10; ++x.x)
694     {
695         if (x.x == 8)
696             break loop_with_dtors;
697     }
698     assert(Foo9068.destroyed == [5, 8]);
699     Foo9068.destroyed = null;
700 
701     //----------------------------------------
702     // Same with an unlabelled break.
703     for (auto x = Foo9068(4), y = Foo9068(5); x.x != 10; ++x.x)
704     {
705         if (x.x == 7)
706             break;
707     }
708     assert(Foo9068.destroyed == [5, 7]);
709     Foo9068.destroyed = null;
710 }
711 
712 /***************************************/
713 // 11885
714 
715 struct Foo11885
716 {
717     static int[] destroyed;
718     int x;
~thisFoo11885719     ~this() { destroyed ~= x; }
720 }
721 
722 struct SimpleCounter11885
723 {
724     static int destroyedCount;
725     enum int limit = 5;
726     int counter;
~this()727     ~this() { destroyedCount++; }
728 
729     // Range primitives.
empty()730     @property bool empty() const { return counter >= limit; }
front()731     @property int front() { return counter; }
popFront()732     void popFront() { counter++; }
733 }
734 
test11885()735 void test11885()
736 {
737     //----------------------------------------
738     // There was never a bug in this case (no range).
739     int sum;
740 loop_simple:
741     foreach (i; [10, 20])
742     {
743         sum += i;
744         continue loop_simple;
745     }
746     assert(sum == 30);
747 
748     //----------------------------------------
749     // There was a bug with loops over ranges.
750     int last = -1;
751 X:  foreach (i; SimpleCounter11885())
752     {
753         switch(i)
754         {
755             case 3:
756                 continue X;
757             default:
758                 last = i;
759        }
760     }
761     assert(last == 4);
762     assert(SimpleCounter11885.destroyedCount == 1);
763 
764     //----------------------------------------
765     // Simpler case: the compiler error had nothing to do with the switch.
766     last = -1;
767 loop_with_range:
768     foreach (i; SimpleCounter11885())
769     {
770         last = i;
771         continue loop_with_range;
772     }
773     assert(last == 4);
774     assert(SimpleCounter11885.destroyedCount == 2);
775 
776     //----------------------------------------
777     // Test with destructors: the loop is implicitly wrapped into two
778     // try/finally clauses.
779 loop_with_dtors:
780     for (auto x = Foo11885(4), y = Foo11885(5); x.x != 10; ++x.x)
781     {
782         if (x.x == 8)
783             continue loop_with_dtors;
784     }
785     assert(Foo11885.destroyed == [5, 10]);
786     Foo11885.destroyed = null;
787 
788     //----------------------------------------
789     // Same with an unlabelled continue.
790     for (auto x = Foo11885(4), y = Foo11885(5); x.x != 10; ++x.x)
791     {
792         if (x.x == 7)
793             continue;
794     }
795     assert(Foo11885.destroyed == [5, 10]);
796     Foo11885.destroyed = null;
797 }
798 
799 /***************************************/
800 // 10475
801 
test10475a()802 void test10475a()
803 {
804     struct DirIterator
805     {
806         int _store = 42;
807         ~this() { assert(0); }
808     }
809 
810     DirIterator dirEntries()
811     {
812         throw new Exception("");
813     }
814 
815     try
816     {
817         for (DirIterator c = dirEntries(); true; ) {}
818         assert(0);
819     }
820     catch (Exception e)
821     {
822         assert(e.next is null);
823     }
824 }
825 
test10475b()826 void test10475b()
827 {
828     uint g;
829     struct S
830     {
831         uint flag;
832         ~this() { g |= flag; }
833     }
834 
835     S thrown()
836     {
837         throw new Exception("");
838     }
839 
840     g = 0x0;
841     try
842     {
843         for (auto x = S(0x1), y = S(0x2), z = thrown(); true; ) {}
844         assert(0);
845     }
846     catch (Exception e)
847     {
848         assert(e.next is null);
849     }
850     assert(g == 0x3);
851 
852     g = 0x0;
853     try
854     {
855         for (auto x = S(0x1), y = thrown(), z = S(0x2); true; ) {}
856         assert(0);
857     }
858     catch (Exception e)
859     {
860         assert(e.next is null);
861     }
862     assert(g == 0x1);
863 
864     g = 0x0;
865     try
866     {
867         for (auto x = thrown(), y = S(0x1), z = S(0x2); true; ) {}
868         assert(0);
869     }
870     catch (Exception e)
871     {
872         assert(e.next is null);
873     }
874     assert(g == 0x0);
875 }
876 
877 /***************************************/
878 // 11291
879 
test11291()880 void test11291()
881 {
882     struct Tuple(T...)
883     {
884         T field;
885         alias field this;
886     }
887     struct zip
888     {
889         string[] s1, s2;
890 
891         bool empty() { return true; }
892         auto front() { return Tuple!(string, string)(s1[0], s2[0]); }
893         void popFront() {}
894     }
895 
896     foreach (const a, const b; zip(["foo"], ["bar"]))
897     {
898         static assert(is(typeof(a) == const string));
899         static assert(is(typeof(b) == const string));
900 
901         static assert(!__traits(compiles, a = "something"));
902         static assert(!__traits(compiles, b = "something"));
903     }
904 }
905 
906 /***************************************/
907 // 12103
908 
909 alias TypeTuple12103(TL...) = TL;
910 
911 alias Id12103(alias a) = a;
912 
test12103()913 void test12103()
914 {
915     alias fs1 = TypeTuple12103!(() => 0, () => 1);
916     foreach (i, f; fs1)
917     {
918         static assert(f() == i);
919         static assert(Id12103!f() == i);
920         assert(f() == i);
921         assert(Id12103!f() == i);
922     }
923 
924     alias fs2 = TypeTuple12103!(x=>x+0, y=>y+1);
925     foreach (i, f; fs2)
926     {
927         static assert(f(0) == i);
928         static assert(Id12103!f(0) == i);
929         assert(f(0) == i);
930         assert(Id12103!f(0) == i);
931     }
932 }
933 
934 /***************************************/
935 // 12739
936 
937 struct S12739
938 {
939 nothrow:
opApplyS12739940     int opApply(int delegate(ref int) nothrow dg)
941     {
942         return 0;
943     }
944 }
945 
test12739()946 void test12739() nothrow
947 {
948     S12739 s;
949     foreach (e; s) {}
950 }
951 
952 /***************************************/
953 // 12932
954 
test12932()955 void test12932() @nogc
956 {
957     int sum;
958     foreach (e; [1,2,3])
959     {
960         sum += e;
961     }
962     assert(sum == 6);
963 }
964 
965 /***************************************/
966 // 13756
967 
test13756()968 void test13756()
969 {
970     printf("test13756()\n");
971     int[int] org = [1:2], aa;
972 
973     aa = org.dup;
974     foreach (v; aa)
975     {
976         static assert(is(typeof(v) == int));
977         v = 20;
978     }
979     assert(aa == [1:2]);
980 
981     aa = org.dup;
982     foreach (ref v; aa)
983     {
984         static assert(is(typeof(v) == int));
985         v = 20;
986     }
987     assert(aa == [1:20]);
988 
989     aa = org.dup;
990     foreach (k, v; aa)
991     {
992         static assert(is(typeof(k) == int));
993         static assert(is(typeof(v) == int));
994         k = 10;
995         v = 20;
996     }
997     assert(aa == [1:2]);
998 
999     aa = org.dup;
1000     foreach (k, ref v; aa)
1001     {
1002         static assert(is(typeof(k) == int));
1003         static assert(is(typeof(v) == int));
1004         k = 10;
1005         v = 20;
1006     }
1007     assert(aa == [1:20]);
1008 
1009     aa = org.dup;
1010     foreach (ref k, v; aa)      // NG -> OK
1011     {
1012         static assert(is(typeof(k) == const int));
1013         static assert(is(typeof(v) == int));
1014         static assert(!__traits(compiles, k = 10));
1015         v = 20;
1016     }
1017     assert(aa == [1:2]);
1018 
1019     aa = org.dup;
1020     foreach (ref k, ref v; aa)  // NG -> OK
1021     {
1022         static assert(is(typeof(k) == const int));
1023         static assert(is(typeof(v) == int));
1024         static assert(!__traits(compiles, k = 10));
1025         v = 20;
1026     }
1027     assert(aa == [1:20]);
1028 
1029     foreach (ref const k, v; aa)  // NG -> OK, same with 'ref k'
1030     {
1031         static assert(is(typeof(k) == const int));
1032     }
1033 }
1034 
1035 /***************************************/
1036 // 14653
1037 
1038 static string result14653;
1039 
1040 class RangeClass14653
1041 {
1042     int a;
1043 
this(T)1044     this(T)(T...) { result14653 ~= "c"; }
~this()1045     ~this()       { result14653 ~= "d"; a = -1; }
1046 
empty()1047     @property bool empty() { result14653 ~= "e"; return a >= 2; }
front()1048     @property int front()  { result14653 ~= "f"; assert(a >= 0); return a; }
popFront()1049     void popFront()        { result14653 ~= "p"; ++a; }
1050 }
1051 
scoped14653(T,A...)1052 auto scoped14653(T, A...)(A args)
1053 {
1054     static struct Scoped(T)
1055     {
1056         void[__traits(classInstanceSize, T)] store;
1057         T payload() { return cast(T)cast(void*)store.ptr; }
1058         alias payload this;
1059 
1060         ~this()
1061         {
1062             //.destroy(payload);
1063             payload.__dtor();
1064             (cast(byte[])store)[] = 0;
1065         }
1066     }
1067 
1068     Scoped!T result = void;
1069 
1070     //emplace!T(result.store[], args);
1071     result.store[] = typeid(T).initializer[];
1072     result.payload.__ctor(args);
1073 
1074     return result;
1075 }
1076 
test14653()1077 void test14653()
1078 {
1079     printf("test14653()\n");
1080     foreach (e; scoped14653!RangeClass14653(1))
1081     {
1082         result14653 ~= "b";
1083     }
1084     assert(result14653 == "cefbpefbped", result14653);
1085 }
1086 
1087 /***************************************/
1088 
main()1089 int main()
1090 {
1091     test1();
1092     test2411();
1093     test2442();
1094     test2443();
1095     test3187();
1096     test4090a();
1097     test4090b();
1098     test5605();
1099     test7004();
1100     test10221();
1101     test7406();
1102     test6659();
1103     test6659a();
1104     test6659b();
1105     test6659c();
1106     test7814();
1107     test6652();
1108     test9068();
1109     test11885();
1110     test10475a();
1111     test10475b();
1112     test11291();
1113     test12103();
1114     test12739();
1115     printf("test12932()\n");
1116     test12932();
1117     test13756();
1118     test14653();
1119 
1120     printf("Success\n");
1121     return 0;
1122 }
1123