void main() { static struct Iter { ~this() { ++_dtor; } bool opCmp(ref const Iter rhs) { return _pos == rhs._pos; } void opUnary(string op:"++")() { ++_pos; } size_t _pos; static size_t _dtor; } foreach(ref iter; Iter(0) .. Iter(10)) { assert(Iter._dtor == 0); } assert(Iter._dtor == 2); } --- The iteration is done using destructed instances.
A foreach range statement: foreach (iter; lower .. upper) {} is always translated to a for statement: for (auto iter = lower, limit = upper; iter != upper; ++iter) {} So, this is a lifetime issue declared in for statement Initialize part.
https://github.com/D-Programming-Language/dmd/pull/826
Commit pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/b5aa4bc4cdb52ed6996e0afab9368fa6d0ae5934 Merge pull request #826 from 9rnsr/fix6659 fix Issue 6659 - Destructor in range foreach called after initialization