Error: @nogc function 'test.func2' cannot call non- at nogc delegate 'msg'
A Guy With a Question
aguywithanquestion at gmail.com
Sun Dec 10 13:57:27 UTC 2017
On Sunday, 10 December 2017 at 11:44:20 UTC, Jonathan M Davis
wrote:
> On Sunday, December 10, 2017 12:54:00 Shachar Shemesh via
> Digitalmars-d wrote:
>> void func1(scope lazy string msg) @nogc {
>> }
>>
>> void func2(scope lazy string msg) @nogc {
>> func1(msg);
>> }
>>
>> What? Why is msg GC allocating, especially since I scoped the
>> lazy? Why is msg even evaluated?
>>
>> Something seems off here.
>
> Well, I'm not exactly sure how lazy is implemented underneath
> the hood (other than the fact that it generates a delegate and
> potentially a closure), but based on the error message, it
> sounds like the delegate that's being generated isn't @nogc, so
> it can't be called within the function, which would be a
> completely different issue from allocating a closure.
> Curiously, pure doesn't seem to have the same problem, and I
> would have guessed that it would given that @nogc does.
>
> But if it matters that the delegate be pure or @nogc because
> the function is marked that way, then that's a bit of a
> problem, because presumably, there can only be one delegate
> (since the function isn't templated), and the same function
> could be called with an expression that allocated and with an
> expression that didn't allocate. So, if the delegate is
> restricted like that, then that would restrict the caller,
> which doesn't follow how non-lazy arguments work, and an
> argument could be made that whether calling the delegate
> allocates memory or not or is pure or not doesn't matter even
> if the function being called is @nogc or pure on the basis that
> it's conceptually just a delayed evaluation of the argument in
> the caller's scope. But for that to work, the generated
> delegate can't be checked for @nogc or pure or nothrow or any
> of that inside the function with the lazy parameter. Given that
> pure works but @nogc doesn't, it makes it seem like the
> compiler was made smart enough to ignore purity for lazy
> parameters but not smart enough to ignore the lack of @nogc.
>
> As for scope, I don't know if it really applies to lazy
> parameters or not at this point. Without -dip1000, all it
> applies to is delegates, but lazy parameters are turned into
> delegates, so you would _think_ that scope would apply, but I
> don't know. scope has always been underimplemented, though
> Walter's work on -dip1000 is fixing that. Regardless, the error
> message makes it sound like scope and closures have nothing to
> do with the problem (though it could potentially be a problem
> once the @nogc problem with the delegate is fixed).
>
> In any case, I think that it's pretty clear that this merits
> being reported in bugzilla. The fact that pure works while
> @nogc doesn't strongly indicates that something is off with
> @nogc - especially if scope is involved. Worst case, a fix will
> have to be lumped in with -dip1000, depending on what scope is
> supposed to be doing now and exactly how lazy is working
> underneath the hood, but I definitely think that your code
> should work.
>
> - Jonathan M Davis
What does D throw so many errors on code people don't write? I
realize that "lowering" has some uses and I'm not advocating
*not* doing it, but why not after a semantic pass? Why is it so
consistently throwing semantic errors on code it's users did not
write...
It would cut down on the cryptic errors...
More information about the Digitalmars-d
mailing list