On 1 August 2018 at 18:52, Shachar Shemesh via Digitalmars-d <digitalmars-d@puremagic.com> wrote: > On 01/08/18 17:13, Steven Schveighoffer wrote: >> >> On 8/1/18 3:59 AM, Shachar Shemesh wrote: >>> >>> Thank you! Finally! >>> >>> Let me just state, for the record, that having *yet another* syntax >>> special case is just appalling. >> >> >> The lazy variadic thing is a distinction between specifying variadic lazy >> parameters and a lazy variadic array. The distinction is so miniscule, but >> necessary to have a disambiguous syntax. >> >> But I had actually thought for a while, that you could simply specify a >> delegate, and it would be treated as a lazy parameter, which would probably >> solve your problem. I really think this syntax should be available. >> >>> With that said, I was hoping that specifying it explicitly as a delegate >>> would allow me to scope it. Apparently, that doesn't work :-( >>> >> >> I guess you mean you can't scope the delegates? I'm surprised if that >> doesn't work. >> >> -Steve > > > > > import std.string; > > alias Dg = string delegate() @nogc nothrow; > > void myAssert(bool cond, scope Dg[1] msg_dg ...) @nogc nothrow > { > import core.stdc.stdio; > if (!cond) > { > string msg = msg_dg[0](); > printf("%*s\n", msg.length, msg.ptr); > } > } > > void main() @nogc { > string msg = "Hello"; > myAssert(true, msg); // <- errors on this line > } > > It errors out: complains it needs to allocate main's frame on the GC, but > main is @nogc. The same happens if I move the scope to the alias.
My first thought was to have a look at enforce(), but on closer observation it is neither @nogc or nothrow. Maybe you should raise a bug report? It's certainly worth an attempt to bridge these two features together. I think it makes sense enough that lazy parameters should infer attributes from the function, and that it should be an error to pass a parameter that does not meet those constraints. i.e: --- // Signatures. void myAssert(bool cond, lazy string msg) @nogc nothrow; string mayAlloc() nothrow; string mayThrow() @nogc; // Code myAssert(cond, mayAlloc()); // violates @nogc myAssert(cond, mayThrow()); // violates nothrow --- Iain.