Skip to content

__traits(getMember, this, ...) in nested function does not capture enclosing this #23436

Description

@niy-ati

Summary

When a nested function accesses a struct field only through __traits(getMember, this, "field"), the compiler does not register a nested reference to the enclosing member this. As a result, vthis is omitted from the closure frame, and the delegate segfaults at runtime.

A direct field access (this.field) in the same position works correctly because expressionSemantic on a DotVarExp with ThisExp calls checkNestedReference. But getMember with wantsym returns the member VarDeclaration without keeping a ThisExp use, so the nested capture is never recorded.

Reproducer

struct Struct
{
    int field = 42;

    auto nestedThunk()
    {
        int inner()
        {
            return __traits(getMember, this, "field");
        }
        return &inner;
    }
}

void main()
{
    auto s = Struct();
    auto dg = s.nestedThunk();
    assert(dg() == 42);  // segfault: vthis missing from closure frame
}

Replacing __traits(getMember, this, "field") with this.field makes it work.

Expected behaviour

The delegate returned by nestedThunk should capture this and return 42.

Where

compiler/src/dmd/traits.d, inside the getMember branch of semanticTraits: after expressionSemantic on the resolved member, when the lookup object is this, checkNestedReference should be called on te.var (the enclosing member this).

Also affects LDC (ldc-developers/ldc#5203) since it shares the same frontend code.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions