On Monday, 5 April 2021 at 15:05:24 UTC, kdevel wrote:
You changed the definition of ``bar`` while the exception collector (``EC``) is meant to catch and collect an exception thrown from the *unmodified* function.

My point was that the code will work if you do explicitly what `lazy` does implicitly. If you don't want to modify `bar`, then it looks like this:

```D
import std.stdio,std.typecons;

struct EC {
    Exception [] ex;
    auto opAssign (X) (scope X f)
        if(is(X : void delegate()) || is(X : void function()))
    {
        writeln (__PRETTY_FUNCTION__);
        try return f (); catch (Exception e) ex ~= e;
    }
}

class E : Exception { this (string s) { super (s); } }
void bar (int i) { if (i == 1) throw new E ("E"); }

void main ()
{
    EC ec;

    ec = () { bar (1); }; // okay

    ec.writeln;
}
```

It seems that the operator ``+=`` or ``~=`` may be better
suited to express that intent. Rewriting this in terms of
``opOpAssign`` works as expected:

Given that you define the operation to append `~` to `ex` rather than overwriting it, `~=` is the best fit, I think.

However, `=` and `~=` should not treat `lazy void` parameters differently. They should either both work, or neither. I checked and this is actually a very old regression; both worked way back in DMD 2.061. So, I've filed a front-end bug report:
    https://issues.dlang.org/show_bug.cgi?id=21802


Reply via email to