Repository navigation
druntime: take no .init of the inspected type in traits - #24072
Merged
Merged
Conversation
For a struct or a static array, `T.init` makes the compiler build the type's whole default-initializer literal, one entry per static-array element. hasElaborateAssign, hasElaborateMove, AliasThisTypeOf (behind DynamicArrayTypeOf), __move_post_blt's opPostMove check and core.lifetime.hasContextPointers used it only to form an expression of type `T`. They now use lvalueOf, so their compile-time memory and time no longer grow with the size of `T`.
thewilsonator
approved these changes
Oct 18, 2026
Contributor
|
Please refer to principle 2 in https://drive.google.com/file/d/1Z1RA5o8jPkQ3UQ7umimKI3akxx7nKgBy/view
|
Contributor
Are you referring to me or Ehudt here? |
Contributor
|
Referring to
If you take responsibility for understanding and maintaining it, then that's fine by me |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Rationale
For a struct or a static array, an expression
T.initmakes the compiler build the type'swhole default-initializer literal, with one element expression per static-array element. A
trait that writes
S.init.opAssign(...)only to get an expression of typeSthereforecosts memory and time in proportion to the size of
S. With aubyte[1 << 20]field, a fewdruntime trait queries take 0.85 s and 303 MiB.
lvalueOf!Tfromcore.internal.traitsis a declared, never-defined function returningref T. It gives an expression of the same type without building any literal. This PR uses itat every druntime site where
.initof the inspected type served only that purpose:core/internal/traits.dhasElaborateMoveS.init.opPostMove(...)lvalueOf!S.opPostMove(...)core/internal/traits.dhasElaborateAssignS.init.opAssign(...)lvalueOf!S.opAssign(...)core/internal/traits.dAliasThisTypeOf(used byDynamicArrayTypeOf)__traits(getMember, T.init, ...)__traits(getMember, lvalueOf!T, ...)core/internal/moving.d__move_post_blt,opPostMovesignature checkS.init.opPostMove(...)lvalueOf!S.opPostMove(...)core/lifetime.dhasContextPointers(static arrays)typeof(T.init[0])typeof(lvalueOf!T[0])No trait answer changes. The companion Phobos PR, dlang/phobos#11119, makes the same change in
std.traits,std.range.primitivesand their users. The two PRs do not depend on each other.Measurements
These were measured before a rebase onto current master that left the diff unchanged. An
x86_64 dmd built from master
e64474adcwas used for both trees (macOS,-o-, peak RSS from/usr/bin/time -l).hasElaborateAssign,hasElaborateMoveandcore.lifetime.moveon structs holding aubyte[N]:On ordinary code there is no measurable effect. On the two Phobos workloads of the dmd perf
check, with Phobos master and only druntime changed, peak RSS was 581–582 MiB before and after
for
dmd -c -i=std -preview=dip1000 std/package.d. For thectRegexunittests it was2051–2054 MiB before and 2053–2054 MiB after. Time was equal within run-to-run noise (3 runs
each).
Testing
All of this ran at the current revision, with an x86_64 dmd built from master
7023163b4(macOS, under Rosetta 2).
DynamicArrayTypeOf, which goes throughAliasThisTypeOf. It covers aplain slice, alias this to a slice, a
constalias-this struct, nested alias this, andalias this to a static array, which is rejected.
make -C druntime unittest(release, x86_64): all 76 modules pass on master and on this PR.The
test/directories pass on both trees,test/traitsandtest/lifetimeamong them,except seven that fail identically on both because of this environment (GNU make 3.81
shipped with macOS, the local C++ toolchain).
types, each in 5 qualifier variants: structs with and without indirections, destructors,
postblits, copy constructors, disabled copy, default construction and assignment, alias
this to every builtin kind, unions, enums, classes, and ranges. Compiled against master and
against this PR (with the Phobos PR applied),
hasElaborateAssign,hasElaborateMove,DynamicArrayTypeOf,moveandmoveEmplacegive the same answers on both trees. ThePhobos traits that the companion PR changes are covered in that PR.
A regression test that bounds compile-time memory is not practical in the test suite, so no
test exercises the size directly.
LLM/AI disclosure
This PR was written entirely by an LLM/AI.
An AI coding agent (Claude, by Anthropic) wrote the code, the tests and this description, ran
the checks and measurements in it, and opened this PR at @ehudt-weka's request, from that
account; "I" above is the agent. Its only review so far is the agent's own (the tests, the
differential check and the measurements), not a human code review.