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:
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