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