Skip to content

Fix __traits(getMember, this, ...) not capturing enclosing this in nested functions - #23437

Open
niy-ati wants to merge 1 commit into
dlang:masterfrom
niy-ati:fix-getMember-nested-this
Open

Fix __traits(getMember, this, ...) not capturing enclosing this in nested functions#23437
niy-ati wants to merge 1 commit into
dlang:masterfrom
niy-ati:fix-getMember-nested-this

Conversation

@niy-ati

@niy-ati niy-ati commented Jul 20, 2026

Copy link
Copy Markdown

Summary

__traits(getMember, this, "field") inside a nested function does not register a nested reference to the enclosing member this. The compiler then omits vthis from the closure frame, causing a segfault when the delegate runs.

getMember with wantsym returns the member VarDeclaration without keeping a ThisExp use. After expressionSemantic on the resolved member, when the lookup object is this, this patch calls checkNestedReference on te.var so closure building matches a direct field access.

Test plan

Added compiler/test/runnable/test_getMember_nested_this.d: nested function returned as a delegate that reads a field via getMember on this.

Fixes #23436.
Also fixes ldc-developers/ldc#5203.

…sted functions

getMember with wantsym returns the member VarDeclaration without a
ThisExp use, so nested functions that only access a field through
getMember(this, ...) never register a nested reference to the
enclosing this and the compiler omits vthis from the closure frame.

After expressionSemantic on the resolved member, when the lookup
object is this, call checkNestedReference on te.var so closure
building matches a direct field access.

Fixes dlang#23436.
Comment thread compiler/src/dmd/traits.d
Comment on lines +1170 to +1185
// getMember with wantsym returns the member VarDeclaration
// without a ThisExp use, so nested functions that only access
// a field through getMember(this, ...) never register a nested
// reference to the enclosing `this`. Force that here.
if (ex && !ex.isErrorExp())
{
if (auto e0 = isExpression(o))
{
e0 = e0.expressionSemantic(sc);
if (auto te = e0.isThisExp())
{
if (te.var && te.var.checkNestedReference(sc, e.loc))
return ErrorExp.get();
}
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This kind of "if (code == issue) fix();" patch is not robust

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants