www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - inout delegate

reply Manu via Digitalmars-d <digitalmars-d puremagic.com> writes:
Can someone explain this to me?

class Test
{
  inout(int) f() inout { return 10; }

  void t()
  {
    f(); // calls fine with mutable 'this'
    auto d = &this.f; // error : inout method Test.f is not callable
using a mutable this
    d();
  }
}

That error message seems very unhelpful, and it's not true. Of course
an inout method is callable with a mutable 'this'...

I suspect that the problem is the type for the delegate; "inout(int)
delegate()" doesn't leave anything for the type system to resolve the
inout with.
I guess the expectation is that this delegate has it's inout-ness
resolved when you capture the delegate:
  is(typeof(&this.f) == int delegate())
Or if 'this' were const:
  is(typeof(&this.f) == const(int) delegate())

But I get this unhelpful error instead.

What's the story here?
Oct 02 2016
next sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 10/2/16 2:55 AM, Manu via Digitalmars-d wrote:
 Can someone explain this to me?

 class Test
 {
   inout(int) f() inout { return 10; }

   void t()
   {
     f(); // calls fine with mutable 'this'
     auto d = &this.f; // error : inout method Test.f is not callable
 using a mutable this
     d();
   }
 }

 That error message seems very unhelpful, and it's not true. Of course
 an inout method is callable with a mutable 'this'...

 I suspect that the problem is the type for the delegate; "inout(int)
 delegate()" doesn't leave anything for the type system to resolve the
 inout with.
 I guess the expectation is that this delegate has it's inout-ness
 resolved when you capture the delegate:
   is(typeof(&this.f) == int delegate())
 Or if 'this' were const:
   is(typeof(&this.f) == const(int) delegate())
I think this is a bug, and I 100% agree with you. The type of the delegate should be based on the mutability of 'this'. The error message probably stems from logic that was meant to prevent invalid const/immutable delegate capture, but inout wasn't thought of. -Steve
Oct 02 2016
next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 02.10.2016 18:00, Steven Schveighoffer wrote:
 On 10/2/16 2:55 AM, Manu via Digitalmars-d wrote:
 Can someone explain this to me?

 class Test
 {
   inout(int) f() inout { return 10; }

   void t()
   {
     f(); // calls fine with mutable 'this'
     auto d = &this.f; // error : inout method Test.f is not callable
 using a mutable this
     d();
   }
 }

 That error message seems very unhelpful, and it's not true. Of course
 an inout method is callable with a mutable 'this'...

 I suspect that the problem is the type for the delegate; "inout(int)
 delegate()" doesn't leave anything for the type system to resolve the
 inout with.
 I guess the expectation is that this delegate has it's inout-ness
 resolved when you capture the delegate:
   is(typeof(&this.f) == int delegate())
 Or if 'this' were const:
   is(typeof(&this.f) == const(int) delegate())
I think this is a bug, and I 100% agree with you. The type of the delegate should be based on the mutability of 'this'. The error message probably stems from logic that was meant to prevent invalid const/immutable delegate capture, but inout wasn't thought of. -Steve
Definitely a bug. (My frontend implementation accepts the code and correctly determines the delegate type as 'int delegate()'.)
Oct 02 2016
prev sibling parent reply Manu via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 3 October 2016 at 02:00, Steven Schveighoffer via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On 10/2/16 2:55 AM, Manu via Digitalmars-d wrote:
 Can someone explain this to me?

 class Test
 {
   inout(int) f() inout { return 10; }

   void t()
   {
     f(); // calls fine with mutable 'this'
     auto d = &this.f; // error : inout method Test.f is not callable
 using a mutable this
     d();
   }
 }

 That error message seems very unhelpful, and it's not true. Of course
 an inout method is callable with a mutable 'this'...

 I suspect that the problem is the type for the delegate; "inout(int)
 delegate()" doesn't leave anything for the type system to resolve the
 inout with.
 I guess the expectation is that this delegate has it's inout-ness
 resolved when you capture the delegate:
   is(typeof(&this.f) == int delegate())
 Or if 'this' were const:
   is(typeof(&this.f) == const(int) delegate())
I think this is a bug, and I 100% agree with you. The type of the delegate should be based on the mutability of 'this'. The error message probably stems from logic that was meant to prevent invalid const/immutable delegate capture, but inout wasn't thought of. -Steve
Okay, well my current project is blocked on this. I can't progress. https://issues.dlang.org/show_bug.cgi?id=16572
Oct 02 2016
next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2016-10-03 05:06, Manu via Digitalmars-d wrote:

 Okay, well my current project is blocked on this. I can't progress.
 https://issues.dlang.org/show_bug.cgi?id=16572
I You can remove "inout" ;) -- /Jacob Carlborg
Oct 03 2016
parent Manu via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 3 October 2016 at 17:18, Jacob Carlborg via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On 2016-10-03 05:06, Manu via Digitalmars-d wrote:

 Okay, well my current project is blocked on this. I can't progress.
 https://issues.dlang.org/show_bug.cgi?id=16572
I You can remove "inout" ;)
That just makes a different problem, ie, the one that requires it to be inout in the first place.
Oct 03 2016
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 03.10.2016 05:06, Manu via Digitalmars-d wrote:
 Okay, well my current project is blocked on this. I can't progress.
 https://issues.dlang.org/show_bug.cgi?id=16572
Probably you can work around the issue using unsafe type casts.
Oct 03 2016
next sibling parent Manu via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 4 October 2016 at 10:50, Timon Gehr via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On 03.10.2016 05:06, Manu via Digitalmars-d wrote:
 Okay, well my current project is blocked on this. I can't progress.
 https://issues.dlang.org/show_bug.cgi?id=16572
Probably you can work around the issue using unsafe type casts.
Mmm, I'll see how much work it is to detect the case to do such a cast...
Oct 03 2016
prev sibling next sibling parent Manu via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 4 October 2016 at 11:15, Manu <turkeyman gmail.com> wrote:
 On 4 October 2016 at 10:50, Timon Gehr via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 On 03.10.2016 05:06, Manu via Digitalmars-d wrote:
 Okay, well my current project is blocked on this. I can't progress.
 https://issues.dlang.org/show_bug.cgi?id=16572
Probably you can work around the issue using unsafe type casts.
Mmm, I'll see how much work it is to detect the case to do such a cast...
I'm really struggling with this issue.. multiple times a day. I can't find a reasonable workaround. casting, or trying to re-synth the delegate type from the function signature doesn't seem to be reasonable. I lose all the attributes, and storage class on parameters are an endless nuisance that should never have existed. Cloning the function signature verbatim, but with inout resolved seems to be really hard and probably buggy. I really just need this bug fixed... is it a particularly tricky fix?
Oct 05 2016
prev sibling next sibling parent reply Manu via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 6 October 2016 at 00:29, Manu <turkeyman gmail.com> wrote:
 On 4 October 2016 at 11:15, Manu <turkeyman gmail.com> wrote:
 On 4 October 2016 at 10:50, Timon Gehr via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 On 03.10.2016 05:06, Manu via Digitalmars-d wrote:
 Okay, well my current project is blocked on this. I can't progress.
 https://issues.dlang.org/show_bug.cgi?id=16572
Probably you can work around the issue using unsafe type casts.
Mmm, I'll see how much work it is to detect the case to do such a cast...
I'm really struggling with this issue.. multiple times a day. I can't find a reasonable workaround. casting, or trying to re-synth the delegate type from the function signature doesn't seem to be reasonable. I lose all the attributes, and storage class on parameters are an endless nuisance that should never have existed. Cloning the function signature verbatim, but with inout resolved seems to be really hard and probably buggy. I really just need this bug fixed... is it a particularly tricky fix?
Goodnight. I'm really hoping I wake up tomorrow and someone has some comment on this issue... I'm a post about it every day. I'm completely blocked while this regression stands ;)
Oct 06 2016
parent reply Jinx <Jinx goole.com> writes:
On Thursday, 6 October 2016 at 15:00:56 UTC, Manu wrote:
 On 6 October 2016 at 00:29, Manu <turkeyman gmail.com> wrote:
 On 4 October 2016 at 11:15, Manu <turkeyman gmail.com> wrote:
 [...]
I'm really struggling with this issue.. multiple times a day. I can't find a reasonable workaround. casting, or trying to re-synth the delegate type from the function signature doesn't seem to be reasonable. I lose all the attributes, and storage class on parameters are an endless nuisance that should never have existed. Cloning the function signature verbatim, but with inout resolved seems to be really hard and probably buggy. I really just need this bug fixed... is it a particularly tricky fix?
Goodnight. I'm really hoping I wake up tomorrow and someone has some comment on this issue... I'm a post about it every day. I'm completely blocked while this regression stands ;)
Why not make a template function that does the necessary conversion? Going from the delegate to a void* then back again with the appropriate attributes applied by a cast?
Oct 06 2016
parent reply Manu via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 7 October 2016 at 05:58, Jinx via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On Thursday, 6 October 2016 at 15:00:56 UTC, Manu wrote:
 On 6 October 2016 at 00:29, Manu <turkeyman gmail.com> wrote:
 On 4 October 2016 at 11:15, Manu <turkeyman gmail.com> wrote:
 [...]
I'm really struggling with this issue.. multiple times a day. I can't find a reasonable workaround. casting, or trying to re-synth the delegate type from the function signature doesn't seem to be reasonable. I lose all the attributes, and storage class on parameters are an endless nuisance that should never have existed. Cloning the function signature verbatim, but with inout resolved seems to be really hard and probably buggy. I really just need this bug fixed... is it a particularly tricky fix?
Goodnight. I'm really hoping I wake up tomorrow and someone has some comment on this issue... I'm a post about it every day. I'm completely blocked while this regression stands ;)
Why not make a template function that does the necessary conversion? Going from the delegate to a void* then back again with the appropriate attributes applied by a cast?
storage class and attributes are so hard to work with. It's a serious pain to do what you suggest. Since this is a bug (and a very recent regression no less), I just want it fixed so I can get on with it. Writing massively complex workarounds for it is just not worth the energy. Seriously, I'm sure I could spend a whole day on it trying to cover all cases! Perhaps you'd like to give it a go ;) Something like: template delegateTypeForInoutMethod(T, string method) { alias delegateTypeForInoutMethod = [write lots of stuff here]; } struct S { inout(int)[] f(ref const(int) arg) inout pure nothrow { return [ arg ]; } } static assert(delegateTypeForInoutMethod!(const(S), "f") == const(int)[] delegate(ref const(int)) pure nothrow, "You failed!");
Oct 06 2016
next sibling parent reply Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Friday, 7 October 2016 at 02:13:21 UTC, Manu wrote:
 Since this is a bug (and a very recent regression no less)
Do you know the cause? i.e. would dustmiting/`git bisect` tell you anything you don't already know?
Oct 08 2016
parent Adam D. Ruppe <destructionator gmail.com> writes:
On Sunday, 9 October 2016 at 04:20:26 UTC, Nicholas Wilson wrote:
 Do you know the cause? i.e. would dustmiting/`git bisect` tell 
 you anything you don't already know?
On the bug report, I linked to the commit and a small patch that fixes the problem: https://github.com/dlang/dmd/commit/3c53a0fd9ed1b40f8dbeb75b4dfa11f6df5b3062#commitcomment-19312704 I'd just like one of the compiler devs to review it and see if that's actually the right thing to do.
Oct 09 2016
prev sibling parent reply Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Friday, 7 October 2016 at 02:13:21 UTC, Manu wrote:
 Perhaps you'd like to give it a go ;)

 Something like:

 template delegateTypeForInoutMethod(T, string method)
 {
   alias delegateTypeForInoutMethod = [write lots of stuff here];
 }

 struct S
 {
   inout(int)[] f(ref const(int) arg) inout pure nothrow { 
 return [ arg ]; }
 }

 static assert(delegateTypeForInoutMethod!(const(S), "f") ==
 const(int)[] delegate(ref const(int)) pure nothrow, "You 
 failed!");
https://gist.github.com/thewilsonator/06fe58b06eb7b2d97a675f95bb4d3fac passes the static assert. Sorry for the ugly mess, I don't have much time to clean it up today. Lesson: never be afraid to resort to mixins.
Oct 08 2016
parent Manu via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 9 October 2016 at 16:04, Nicholas Wilson via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On Friday, 7 October 2016 at 02:13:21 UTC, Manu wrote:
 Perhaps you'd like to give it a go ;)

 Something like:

 template delegateTypeForInoutMethod(T, string method)
 {
   alias delegateTypeForInoutMethod = [write lots of stuff here];
 }

 struct S
 {
   inout(int)[] f(ref const(int) arg) inout pure nothrow { return [ arg ];
 }
 }

 static assert(delegateTypeForInoutMethod!(const(S), "f") ==
 const(int)[] delegate(ref const(int)) pure nothrow, "You failed!");
https://gist.github.com/thewilsonator/06fe58b06eb7b2d97a675f95bb4d3fac passes the static assert. Sorry for the ugly mess, I don't have much time to clean it up today. Lesson: never be afraid to resort to mixins.
stringof + mixin fails when there are default args... they don't stringify properly.
Oct 09 2016
prev sibling parent Manu via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 7 October 2016 at 01:00, Manu <turkeyman gmail.com> wrote:
 On 6 October 2016 at 00:29, Manu <turkeyman gmail.com> wrote:
 On 4 October 2016 at 11:15, Manu <turkeyman gmail.com> wrote:
 On 4 October 2016 at 10:50, Timon Gehr via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 On 03.10.2016 05:06, Manu via Digitalmars-d wrote:
 Okay, well my current project is blocked on this. I can't progress.
 https://issues.dlang.org/show_bug.cgi?id=16572
Probably you can work around the issue using unsafe type casts.
Mmm, I'll see how much work it is to detect the case to do such a cast...
I'm really struggling with this issue.. multiple times a day. I can't find a reasonable workaround. casting, or trying to re-synth the delegate type from the function signature doesn't seem to be reasonable. I lose all the attributes, and storage class on parameters are an endless nuisance that should never have existed. Cloning the function signature verbatim, but with inout resolved seems to be really hard and probably buggy. I really just need this bug fixed... is it a particularly tricky fix?
Goodnight. I'm really hoping I wake up tomorrow and someone has some comment on this issue... I'm a post about it every day. I'm completely blocked while this regression stands ;)
Still blocked on this. Project on hold for almost a week! :(
Oct 08 2016
prev sibling parent Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Sunday, 2 October 2016 at 09:55:26 UTC, Manu wrote:
 Can someone explain this to me?

 class Test
 {
   inout(int) f() inout { return 10; }

   void t()
   {
     f(); // calls fine with mutable 'this'
     auto d = &this.f; // error : inout method Test.f is not 
 callable
 using a mutable this
     d();
   }
 }

 That error message seems very unhelpful, and it's not true. Of 
 course an inout method is callable with a mutable 'this'...

 I suspect that the problem is the type for the delegate; 
 "inout(int)
 delegate()" doesn't leave anything for the type system to 
 resolve the
 inout with.
 I guess the expectation is that this delegate has it's 
 inout-ness
 resolved when you capture the delegate:
   is(typeof(&this.f) == int delegate())
 Or if 'this' were const:
   is(typeof(&this.f) == const(int) delegate())

 But I get this unhelpful error instead.

 What's the story here?
That doesn't compile for me (using ad4a81b), but I get a different error message with an accompanying main void main() { const ct = new Test(); ct.t(); auto at = new Test(); at.t(); immutable it = new Test(); it.t(); } Error: mutable method Test.t is not callable using a (const|immutable) object Note t, not f. Making t inout fixes this.
Oct 08 2016