1 /*
2 TEST_OUTPUT:
3 ---
4 fail_compilation/test8556.d(21): Error: template instance test8556.Grab!(Circle!(uint[])) does not match template declaration Grab(Range) if (!isSliceable!Range)
5 fail_compilation/test8556.d(52): Error: template instance test8556.grab!(Circle!(uint[])) error instantiating
6 ---
7 */
8 
9 extern(C) int printf(const char*, ...);
10 
isSliceable(R)11 template isSliceable(R)
12 {
13     enum bool isSliceable = is(typeof( R.init[1 .. 2] ));
14 }
15 
16 struct Grab(Range) if (!isSliceable!Range)
17 {
18     public Range source;
19 }
20 
21 Grab!R grab(R)(R input)
22 {
23     return Grab!R(input);
24 }
25 
26 // 3. evaluate isSliceable in template constraint
27 auto grabExactly(R)(R range) if (!isSliceable!R) { return 0; }
28 auto grabExactly(R)(R range) if ( isSliceable!R) { return 0; }
29 
Circle(Range)30 struct Circle(Range)
31 {
32     // 2. auto return opSlice
33     auto opSlice(size_t i, size_t j)
34     {
35         //pragma(msg, typeof(opSlice)); // prints "fwdref err" with B, but doesn't with A
36 
37         printf("%d %d\n", i, j);
38         assert(j >= i);
39 
40         // 1. grabExactly curcular refers this opSlice.
41         return grabExactly(typeof(this)());     // broken execution with A
42     }
43 }
44 
45 Circle!R circle(R)()
46 {
47     return Circle!R();
48 }
49 
main()50 void main()
51 {
52     auto t = grab(circle!(uint[])());
53 
54     auto cx = circle!(uint[])();
55     auto slice = cx[23 .. 33];
56 }
57