file1.d: -------------- class F(T, alias s) { this() { s.c += cast(T)2; } } class A(T) { T c; } void main() { for (int Mi = 0; Mi < 10; Mi++) { scope a = new A!(float)(); scope f = new F!(float, a)(); } } -------------- file2.d: -------------- class A { void foo() {} } class B(alias G) { void bar() { G.foo(); } } void bzium(A g) { new B!(g)(); } -------------- $ dmd2 file1.d file2.d file1.d(13): Error: variable bug35xx.main.a has scoped destruction, cannot build closure Internal error: e2ir.c 725 $ This is minimal test case I found in big program. actually removing file2.d from command line helps (file1.d doesn't need anything from file2.d) $ dmd2 file1.d file1.d(13): Error: variable bug35xx.main.a has scoped destruction, cannot build closure $
slightly smaller file1.d: file1.d: -------- class E {} class F(alias s) { void zz() { s.toHash(); } } void main() { scope e = new E(); // line 11 auto f = new F!(e)(); } -------- $ dmd2 file1.d file2.d file1.d(11): Error: variable file1.main.e has scoped destruction, cannot build closure Internal error: e2ir.c 725 $
Reduced test case shows that this is some form of memory corruption. ------ class A {} struct F(alias g) { void e() { assert(g); } } void bzium(A a) { scope A b; F!(b) c; F!(a) d; } ---- file2.d(10): Error: variable file2.bzium.b has scoped destruction, cannot build closure Internal error: e2ir.c 739
This was fixed in DMD2.053.