https://issues.dlang.org/show_bug.cgi?id=24798
Jonathan M Davis <[email protected]> changed: What |Removed |Added ---------------------------------------------------------------------------- Component|phobos |dmd Severity|normal |regression --- Comment #1 from Jonathan M Davis <[email protected]> --- After dustmiting, I've reduced it to --- import std.range; void main() { static struct S { int val; ~this() { assert(val != 99, "Double Destroy"); val = 99; } } auto arr = [S(0), S(1), S(2), S(3)]; auto result = arr.mySubstitute(S(1), S(42)); auto front = result.front; } auto mySubstitute(R, Substs...)(R r, Substs) { struct MySubstituteElement { Substs substs; auto opCall(E)(E ) { return substs[0]; } } auto er = MySubstituteElement.init; return r.myMap!er; } template myMap(fun...) { auto myMap(Range)(Range r) { return MyMapResult!(fun, Range)(r); } } struct MyMapResult(alias fun, Range) { Range _input; @property empty() { return _input.empty; } void popFront() { } @property front() { return fun(_input); } } --- I could probably reduce it further if I understood the issue better, but any further transformations that I've tried have made the problem go away. In any case, given that all of the Phobos code was removed aside from import std.range to get the range primitives for arrays, it looks to me like this is a compiler bug. Also, trying it on run.dlang.org, it looks like it broke with dmd 2.068.2. Looking at the changelog - https://dlang.org/changelog/2.068.2.html - it looks like the problem was likely caused by reverting the fix for issue 14708: https://issues.dlang.org/show_bug.cgi?id=14708 I haven't dug into any of the details, so I really don't know what the exact issue is, but destructors need to not be running on an already destroyed object. It can potentially be worked around by explicitly setting a struct to its init value at the end of a destructor, but no one is going to think of doing that normally. I suspect that the main reason that this wasn't caught previously is simply because destructors aren't used all that frequently in D, but I ran into it at work when trying to add a destructor to an existing type, and this is one of the problems that I hit. --
