This is an extension of runnable/nested.d:test35() --- class Foo35 { int x = 42; void bar() { int y = 43; new class Object { this() { //writefln("x = %s", x); //writefln("y = %s", y); assert(x == 42); assert(y == 43); assert(this.outer.__monitor is null); // <-- nested.d(14): Assertion failure } }; } } void test35() { Foo35 f = new Foo35(); f.bar(); } --- The place in marked above will assert at runtime because it's value is '43'. This tells us that the frontend thinks that the parent chain of the inner class should be 'Foo35' and not the closure that 'Foo35.bar' creates. What should happen is that a compiler error be issued. nested.d(14): Error: no property '__monitor' for type 'void*'
Also affects the debug code written. As all you see of this parent chain is garbage values. (gdb) p this $1 = (__anonclass1 &) @0x7ffff7ed5fc0: { <Object> = { __vptr = 0x4890e0 <vtable nested.Foo35.bar().__anonclass1>, __monitor = 0x0 }, this = @0x7ffff7ed6ff0 // <-- closure pointer } (gdb) p this.this $2 = (Foo35 &) @0x7ffff7ed6ff0: { <Object> = { __vptr = 0x7ffff7ed5fe0, // <-- Foo35 object reference __monitor = 0x2b // <-- 'y' value }, x = 0 // <-- Excess garbage }
Is it effectively another manifestation of "have one context pointer, need many" issue?
(In reply to Dicebot from comment #2) > Is it effectively another manifestation of "have one context pointer, need > many" issue? Maybe... though in this scenario you can get away with just the one context pointer: anonclass this { void *this (bar.__closptr) { Foo35 this { int x = 42; } int y = 43; } } So you know that the following: assert(x == 42); assert(y == 43); Is lowered to: assert((cast(Foo35)(*cast(CLOSURE bar *)this.this)).x == 42); assert((cast(CLOSURE bar *)this.this).y == 43);
This would be a root of issue 15422. Will be fixed by: https://github.com/D-Programming-Language/dmd/pull/5308
Commit pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/8c60fe029f576efacc7bd15f6bec52d0d652c97c fix Issue 14442 - Wrong this.outer reference in nested classes