On Tuesday, 16 January 2024 at 15:39:07 UTC, Anonymouse wrote:
If I make a `scope` variable of the delegate and pass *it* to `receiveTimeout`, there no longer seems to be any mention of the closure in the error (given 2.092 or later).

```d
void foo(Thing thing) @nogc
{
    void sendThing(const string where, int i)
    {
        send(thing, where, i);
    }

    scope scopeSendThing = &sendThing;
    receiveTimeout(Duration.zero, scopeSendThing);
}
```

Ignoring that it doesn't compile for other reasons; provided `scope scopeSendThing = &sendThing;` compiles -- as in, `&sendThing` is eligible for `scope` -- is this a valid workaround?

Correct. The problem is that `receiveTimeout` is defined as a template variadic function: it *can* take a scoped function, but it doesn't (can't) declare that its argument is always scoped, so since scoped parameters are opt-in, it defaults to unscoped. And &sendThing has to also default to unscoped, because you can pass unscoped values to scoped parameters but not the other way around, so it defaults to the most generic type available. With your scoped variable you provide DMD the critical hint that actually you want the closure to be scoped, and once the value is scoped it stays scoped.

Reply via email to