map(fun...)1 template map(fun...)
2 {
3     auto map(R)(R r)
4     {
5         return MapResult!(fun, R)(r);
6     }
7 }
8 
MapResult(alias fun,R)9 struct MapResult(alias fun, R)
10 {
11     R _input;
12 
13     @property bool empty() { return _input.length == 0; }
14     @property auto front() { return fun(_input[0]); }
15     void popFront() { _input = _input[1..$]; }
16 }
17 
18 class Foo
19 {
baz()20     int baz() { return 1; }
bar()21     void bar()
22     {
23         auto s = [1].map!(i => baz()); // compiles
24         auto r = [1].map!(  // returns MapResult-1
25             // lambda1
26             i =>
27                 [1].map!(   // returns MapResult-2
28                     // lambda2
29                     j =>
30                         baz()
31                 )
32         ); // compiles <- error
33 
34         // When lambda1 is called in MapResult-1.front(), it was changed to
35         // TOKfunction in functionResolve. But in that time, MapResult-2 semantic3
36         // was not yet finished, then the lambda2 call in MapResult-2.front()
37         // could not access to enclosing scope frame to call baz().
38         // To fix the issue, MapResult-2 semantic3 should be finished during the
39         // lambda1 body analysis.
40     }
41 }
42 
43 class Bar
44 {
45     int baz;
bar()46     void bar()
47     {
48         auto s = [1].map!(i => baz); // compiles
49         auto r = [1].map!(
50             // lambda1
51             i =>
52                 [1].map!(
53                     // lambda2
54                     j =>
55                         baz
56                 )
57         ); // compiles <- error
58     }
59 }
60 
61 /*******************************************/
62 
ChunkByImpl(alias eq)63 struct ChunkByImpl(alias eq)
64 {
65     struct Group
66     {
67         int[] start;
68         int[] current;
69 
70         void popFront()
71         {
72             // In here:
73             //  SortedRange.pred == (a, b) => a  @ test14978b()
74             //  ChunkByImpl.eq == (a, b) => pred(a, b)  @ SortedRange.groupBy()
75             //
76             // The context deduction should be:
77             //  First pred is deduced to function pointer,
78             //  and then, eq is also deduced to function pointer because pred is function pointer.
79             //
80             // Therefore, when ChunkByImpl is instantiated in groupBy(), its semantic3
81             // needs to be invoked to analyze ???
82             eq(start, current);
83         }
84     }
85 }
86 
87 struct SortedRange(alias pred)
88 {
89     int[] input;
90 
91     auto groupBy()
92     {
93         ChunkByImpl!(
94             (a, b) => pred(a, b)
95         ) r;
96     }
97 }
98 
99 void test14973b()
100 {
101     SortedRange!(
102         (a, b) => a
103     ) r;
104 }
105