www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 11886] New: "cannot access frame" error on lambda in lambda

reply d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=11886

           Summary: "cannot access frame" error on lambda in lambda
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Keywords: rejects-valid
          Severity: regression
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: verylonglogin.reg gmail.com


--- Comment #0 from Denis Shelomovskij <verylonglogin.reg gmail.com> 2014-01-10
00:38:44 MSK ---
This code should compile:
---
struct S(alias fun)
{ void sf() { fun(1); } }

void f(alias fun)()
{ fun(); }

void g(alias fun)()
{ auto s = S!fun(); } // line 8

void main()
{
    int n;
    f!(() => g!(b => n)())(); // line 13
}
---
main.d(13): Error: delegate main.main.__lambda1.__lambda1 cannot access frame
of function D main
main.d(13): Error: pure nested function '__lambda1' cannot access mutable data
'n'
main.d(8):        instantiated from here: S!(__lambda1)
main.d(13):        instantiated from here: g!((b) => n)
---

It worked with previous dmd. As a result dmd rejects now such previously
working code:
---
import std.algorithm, std.array;

auto makeInoutArray(alias func, T)(inout T[] src)
{
    return cast(inout) func(cast(T[]) src).array();
}

void f(inout(int)[] iarr)
{
    int n;
    iarr.makeInoutArray!(arr => arr.map!(a => n)())();
}
---

Also dmd ICEs once while reducing this code to minimal testcase.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 09 2014
next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=11886


Kenji Hara <k.hara.pg gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|rejects-valid               |
           Severity|regression                  |enhancement


--- Comment #1 from Kenji Hara <k.hara.pg gmail.com> 2014-01-09 18:08:11 PST ---
The change is introduced by fixing bug 9050 (5fb19ce). But it's not a
regression.

With old versions, the OP code had been *wrongly* accepted. So it was
accepts-invalid bug. The error message is intended and reject invalid code
expectedly.

===

To be things more clear, I'd explain a current limitation.

Currently, D/dmd does not support nested context inference for indirectly
instantiated template lambdas. It is known limitation (at least to me).
For example following case does not work:

struct Lambda(alias fun)
{
    auto opCall(A...)(A args) { return fun(args); } // Line 3
}
void main()
{
    int n = 10;
    Lambda!(x => x + n) f;
    assert(f(1) == 11); // Line 9
}

Output:
test.d(3): Error: function test.main.Lambda!((x) => x +
n).Lambda.opCall!(int).opCall cannot access frame of function D main
test.d(9): Error: template instance test.main.Lambda!((x) => x +
n).Lambda.opCall!(int) error instantiating

The template lambda x => x + n has context access (reading local variable n
declared in main).
But, until Lambda.opCall is instantiated, the 'nestedness' is unknown.
Therefore compiler won't supply hidden member for Lambda!(x => x + n) struct
object.
Finally, f(1) will call `fun` from instantiated opCall method, but it does not
know the context pointer of main function, so fun(args) makes the error "cannot
access frame of function D main".

Because of the limitation, currently it is impossible to create polymorpthic
lambda by using existing language primitives.

===

The OP code hits the limitation. By the dmd bug, it had been wrongly accepted.
But currently it is fixed and expectedly rejected.

So, I'll change this issue to 'enhancement'.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 09 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=11886



--- Comment #2 from Denis Shelomovskij <verylonglogin.reg gmail.com> 2014-01-13
18:38:28 MSK ---
(In reply to comment #1)
 The change is introduced by fixing bug 9050 (5fb19ce). But it's not a
 regression.
 
 With old versions, the OP code had been *wrongly* accepted. So it was
 accepts-invalid bug. The error message is intended and reject invalid code
 expectedly.

So does it mean there was a feature in dmd that worked and now is silently removed breaking some code? Or had it produced a wrong code? I'd like to know whether I can use the old dmd with this feature. -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 13 2014
prev sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=11886



--- Comment #3 from Kenji Hara <k.hara.pg gmail.com> 2014-01-13 08:27:36 PST ---
(In reply to comment #2)
 (In reply to comment #1)
 The change is introduced by fixing bug 9050 (5fb19ce). But it's not a
 regression.
 
 With old versions, the OP code had been *wrongly* accepted. So it was
 accepts-invalid bug. The error message is intended and reject invalid code
 expectedly.

So does it mean there was a feature in dmd that worked and now is silently removed breaking some code? Or had it produced a wrong code? I'd like to know whether I can use the old dmd with this feature.

No. There was no such feature and not yet implemented. So I think that it had not generate correct code and accidentally worked. -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 13 2014