Lightweight getMember resolution for aggregate types#22546
Lightweight getMember resolution for aggregate types#22546CyberShadow wants to merge 1 commit intodlang:masterfrom
Conversation
|
Thanks for your pull request, @CyberShadow! Bugzilla referencesYour PR doesn't reference any Bugzilla issue. If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog. Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub run digger -- build "master + dmd#22546" |
9e295a8 to
74ced6d
Compare
|
@dkorpel What do you think about this one? I don't fully understand it, but it's green and the diff is small 😛 |
|
I like the approach, but this can cause regressions, when the result of struct S(T)
{
static void f()
{
}
}
pragma(msg, __traits(getMember, S!int, "f").mangleof);With DMD v2.112.0 this prints CTFE also does not work anymore: struct S(T)
{
static int f()
{
return 42;
}
}
pragma(msg, __traits(getMember, S!int, "f")());DMD with this PR prints the following: |
When __traits(getMember, T, name) is used inside allMembers loops on template struct types, the normal path through expressionSemantic triggers functionSemantic → functionSemantic3 (eager body compilation) on member functions, causing circular dependency errors. Add a lightweight fast path in getMember that resolves via sym.search() and returns a DsymbolExp with the type pre-set, bypassing the cascade. This covers both auto-return functions (inferRetType) and instantiated functions in template structs (isInstantiated). Also handle DsymbolExp in TemplateInstance_semanticTiargs so that function symbols are stored directly as Dsymbols rather than being passed to ctfeInterpret, which would fail. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Argh, good catch. Let me have a look. |
74ced6d to
4ec6296
Compare
|
@tim-dlang Latest revision adds more |
|
Yes, I think the direction makes sense. I worry that other traits, properties or Here is another failing test case: struct S5(int line)
{
static void badfunc()
{
undefined;
}
}
static assert(!__traits(compiles,__traits(getMember, S5!__LINE__, "badfunc")));
static assert(!is(typeof(__traits(getMember, S5!__LINE__, "badfunc")))); |
Generated by Claude Opus 4.6, usual disclaimers apply.
Implements the idea in #22541 (comment) .
Supersedes #22541, #22542, and #22545.
When __traits(getMember, T, name) is used inside allMembers loops on
template struct types, the normal path through expressionSemantic
triggers functionSemantic → functionSemantic3 (eager body compilation)
on member functions, causing circular dependency errors.
Add a lightweight fast path in getMember that resolves via sym.search()
and returns a DsymbolExp with the type pre-set, bypassing the cascade.
This covers both auto-return functions (inferRetType) and instantiated
functions in template structs (isInstantiated).
Also handle DsymbolExp in TemplateInstance_semanticTiargs so that
function symbols are stored directly as Dsymbols rather than being
passed to ctfeInterpret, which would fail.