Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.

Change Log: 2.113.0

previous version: 2.112.0

Download D nightlies
To be released


This changelog has been automatically generated from all commits in master since the last release.

  • The full-text messages are assembled from the changelog/ directories of the respective repositories: dmd, druntime, phobos, tools, dlang.org, installer, and dub.
  • See the DLang-Bot documentation for details on referencing Bugzilla. The DAutoTest PR preview doesn't include the Bugzilla changelog.
  • The pending changelog can be generated locally by setting up dlang.org and running the pending_changelog target:
    make -f posix.mak pending_changelog


2.113.0 comes with 20 major changes and 81 fixed Bugzilla issues. A huge thanks goes to the 64 contributors who made 2.113.0 possible.

List of all upcoming bug fixes and enhancements in D 2.113.0.

Compiler changes

  1. The compiler now lowers associative array operations to a templated implementation in druntime

    The compiler now lowers associative array operations to templates defined in core.internal.newaa instead of relying on a precompiled implementation based on TypeInfo.

    In addition to better performance by not having to go through TypeInfo and allowing inlining of simple operations, this paves the way for proper inference of function attributes inherited from key and value constructors, toHash() on the key and comparison of key values. This inference is currently mostly avoided to keep backward compatibility with the runtime implementation that doesn't check function attributes.

    Some changes that are the result of the refactoring:

    • AA support no longer available at CTFE without object.d/newaa.d. Some operations used to work, but now need the lowerings before these can be intercepted by the interpreter.

    • creating an AA literal at runtime passes keys and values as arguments normally, not with special move/blit operations, so more postblit/destructor operations can happen

    • _d_assocarrayliteralTXTrace removed. Apart from the creation of associative array literals no other AA operation is hooked for -profile-gc. You will now see the allocations as done by the AA implementation.

    • aa[key] = S() with S.__ctor and S.opAssign is no longer a double lookup

    • aa.remove(key) now works with alias this

  2. Keywords auto and ref must be adjacent for auto ref return.

    Similar to auto ref parameters in 2.111, it's now deprecated to declare an auto ref return type without putting those two keywords next to each other as well.

    ref auto int f() => 3;
    auto { ref int g() => 3; }
    
    // Correction:
    auto ref f() => 3;
    auto ref g() => 3;
    
  3. Bitfields Are Now Incorporated

    There is no longer a requirement to throw the switch -preview=bitfields.

  4. An error is now issued for dangling else statements

    This used to give a warning when compiled with -w and now gives an error:

    int i, j;
    if (i)
        if (j)
            return 1;
        else    // Error: else is dangling, add { } after condition `if (i)`
            return 2;
    
  5. The compiler now accepts -extern-std=c++23

    The compiler now accepts c++23 as a supported standard for -extern-std=. Currently this only changes the value of __traits(getTargetInfo, "cppStd").

  6. External import path switch

    A new switch is added, the external import path (-extI). It is similar to the import path switch (-I) except it indicates that a module found from it is external to the currently compiling binary.

    It is used on Windows when the dllimport override switch is set to anything other than none to force an external module's symbols as DllImport.

    If a build system supports the external import path switch, it is recommend to not use the all option for the dllimport override switch which applies to symbols that should not be getting DllImport'd.

  7. C files can now include a module statement

    Similar to the __import extension, the __module keyword brings D's module declaration to C.

    It's particularly useful when you want to import multiple C files with the same name (e.g. hello/utils.c and world/utils.c), since both have to be imported with import utils when they are listed on the command line, resulting in conflicts.

    Now you can do:

    hello/utils.c:

    #if __IMPORTC__
    __module hello.utils;
    #endif
    
    int sqr(int x) { return x * x; }
    

    world/utils.c:

    #if __IMPORTC__
    __module world.utils;
    #endif
    
    int max(int a, int b) { return a > b ? a : b; }
    

    app.d:

    import hello.utils;
    import world.utils;
    
    static assert(sqr(3) == 9);
    static assert(max(3, 5) == 5);
    

    A __module declaration can appear anywhere in the top level scope. When there are multiple, the first one will be used. Therefore, every #include containing a __module declaration should come after the file's own module declaration, or it will be overwritten. When you always put the __module declaration at the very top like in D, there won't be such problems.

  8. Implicit integer conversions in int op= float assignments has been deprecated

    This is to prevent potential mistakes when op= assignment would implicitly truncate the right hand side expression from a non-zero value to zero.

    uint a;
    float b = 0.1;
    a += b; // Deprecation: `uint += float` is performing truncating conversion
    

    The corrective action if truncating was intentional is to explicitly cast the floating point expression to integer.

    a += cast(uint) b;
    

Runtime changes

  1. Templatized _d_arraysetlengthT to remove TypeInfo dependency

    The internal runtime function _d_arraysetlengthT was templatized to operate directly on the type T, removing its dependency on TypeInfo. This improves type safety, reduces runtime reflection, and allows the compiler to generate specialized code paths for different array element types.

    This change preserves the semantics of .length assignment on dynamic arrays, ensuring memory allocation, element initialization, and postblit handling continue to work as expected.

    /**
    Resize a dynamic array by setting its `.length` property.
    
    New elements are initialized according to their type:
    - Zero-initialized if applicable
    - Default-initialized via `emplace`
    - Or `memcpy` if trivially copyable
    */
    size_t _d_arraysetlengthT(Tarr : T[], T)(return ref scope Tarr arr, size_t newlength);
    
    int[] a = [1, 2];
    a.length = 3; // becomes _d_arraysetlengthT!(int)(a, 3)
    

    This reduces runtime dependency on TypeInfo, making the function more predictable and performant.

    See also: PR #21151

  2. Templatize _d_arrayappendcTX runtime hook

    This refactorization discards the TypeInfo parameter, replacing it with a template type parameter.

  3. Templatize _d_arraysetcapacity runtime hook

    This refactorization discards the TypeInfo parameter, replacing it with a template type parameter.

  4. core.int128: Add mul and udivmod overloads for 64-bit operands

    These map to a single x86_64 instruction and have accordingly been optimized via inline assembly.

    import core.int128;
    
    ulong a, b;
    Cent product128 = mul(a, b);
    
    ulong divisor64 = …;
    ulong modulus64;
    ulong quotient64 = udivmod(product128, divisor64, modulus64);
    
  5. Fixed generated binaries crashing on macOS 15.4

    macOS 15.4 has introduced an undocumented ABI change to the format of thread local variable section, which causes almost all executable built with previous D compiler versions to crash during initialization, if they use DRuntime. This release introduces a mitigation for this issue that is backwards compatible with previous versions of macOS.

  6. C Macro translations in druntime have been translated to templates

    This prevents linking errors when using -betterC. For example:

    import core.sys.posix.stdlib;
    import core.sys.posix.unistd;
    
    extern(C) int main()
    {
        int status, pid = vfork();
        if (pid == 0)
        {
            // ...
            return 0;
        }
    
        waitpid(pid, &status, 0);
        if (WIFEXITED(status))
        {
            // ...
        }
        return 0;
    }
    

    This would fail to compile with the -betterC flag:

    Error: undefined reference to `core.sys.posix.sys.wait.WIFEXITED(int)`
           referenced from `main`
    

    The reason is that WIFEXITED is a C macro that was translated to a D function in druntime, which requires linking with druntime to use. Now that it's a template, it will be lazily instantiated and the program compiles.

Library changes

  1. Add lazyCache to std.algorithm.iteration

    The new lazyCache function provides a lazily evaluated range caching mechanism. Unlike cache, which eagerly evaluates range elements during construction, lazyCache defers evaluation until elements are explicitly requested.

    auto result = iota(-4, 5).map!(a => tuple(a, expensiveComputation(a)))().lazyCache();
    // No computations performed at this point
    
    auto firstElement = result.front;
    // First element is now evaluated
    

    See the std.algorithm.iteration.lazyCache documentation for more details.

  2. getrandom() backwards compatibility shim

    To restore compatibility with older Linux platforms where getrandom() is unavailable either due to an outdated kernel or a legacy C library, Phobos now ships with a shim that emulates a limited subset of getrandom()’s behavior by reading random bytes from /dev/urandom.

    To enable the shim, build DMD and Phobos with the environment variable LINUX_LEGACY_EMULATE_GETRANDOM set to 1.

    cd phobos
    LINUX_LEGACY_EMULATE_GETRANDOM=1 make
    

    This functionality is a temporary fix and expected to be removed again soon by an upcoming release (approx. v2.112.0 or v2.113.0). The expected change is to replace the current “binding or shim” solution with a syscall wrapper and automatic /dev/urandom fallback.

  3. Add an internal multi-backend entropy system

    This Phobos release introduces an internal multi-backend system for the retrieval of entropy (as in cryptographically-secure random numbers obtained from a suitable random number generator provided by the operating system).

    The current implementation supports the getrandom syscall on Linux.

    On BSD systems arc4random_buf or getentropy are used — depending on which is implemented by the OS and powered by a secure (non-RC4) algorithm.

    Additionally, reading entropy from the character devices /dev/urandom and /dev/random is available on all POSIX targets.

    On Windows BCryptGenRandom (from the Cryptography API: Next Generation (“BCrypt”)) is provided as a backend. CryptGenRandom from the legacy CryptoAPI is not supported for the time being.

    Furthermore, this replaces the getrandom backwards compatibility shim that had been added by v2.111.1 for Linux targets. Instead backwards compatibility is now provided by a hunt strategy algorithm that tries potentially available entropy sources one by one to find one that is available on the running system. Given that the character devices serve as a fallback option here, urandom is favored over random. That is because modern kernel versions — where random would exhibit the usually more preferable behavior of blocking only until the entropy pool has been initialized — will also provide the getrandom syscall in the first place. Performing the syscall, in turn, is even better as it does not depend on the runtime environment exposing the special devices in predefined locations, thus working also within chroot environments.

  4. std.uni has been upgraded from Unicode 16.0.0 to 17.0.0

    This Unicode update was released September 9, 2025, and adds new blocks with characters. See: https://www.unicode.org/versions/Unicode17.0.0/

    import std;
    
    void main()
    {
        const alphaCount = iota(0, dchar.max).filter!(std.uni.isAlpha).walkLength;
        writeln(alphaCount);
        // formerly: 142759
        // now:      147421
    }
    
  5. Add uuid v7 support to std.uuid

    Add uuid v7 support to the UUID type located in std.uuid. The first 48 bits of v7 stores the milliseconds since the unix epoch (1970-01-01), additionally 74 bit are used to store random data.

    Example:

    SysTime st = DateTime(2025, 8, 19, 10, 38, 45);
    UUID u = UUID(st);
    SysTime o = u.v7Timestamp();
    assert(o == st);
    
    string s = u.toString();
    UUID u2 = UUID(s);
    SysTime o2 = u2.v7Timestamp();
    assert(o2 == st);
    
  6. Add writeText, writeWText, and writeDText to std.conv

    These functions are variants of the existing text, wtext, and dtext functions. Instead of returning a string, they write their output to an output range.

    Like text, writeText can accept an interpolated expression sequence as an argument.

    Example:

    import std.conv : writeText;
    import std.array : appender;
    
    auto output = appender!string();
    output.writeText(i"2 + 2 == $(2 + 2)");
    assert(output.data == "2 + 2 == 4");
    

List of all bug fixes and enhancements in D 2.113.0:

DMD Compiler regression fixes

  1. Bugzilla 20927: GIT HEAD: dmd gets confused if a struct defines copy constructor, but the struct using it does not
  2. Bugzilla 22048: [REG2.095] alias a = int p; compiles
  3. Bugzilla 22118: Const union causes false multiple-initialization error in constructor
  4. Bugzilla 22157: Bad diagnostic for static/non-static overload resolution conflict
  5. Bugzilla 22170: interface thunk doesn't set EBX to GOT
  6. Bugzilla 22292: REG[2.084.1] Recursive class literal segfaults compiler
  7. Bugzilla 22427: betterC: casting an array causes linker error in string comparison.
  8. Bugzilla 22512: importC: incomplete array type must have initializer
  9. Bugzilla 22621: [REG2.094] static real array not passed correctly to function as r-value

DMD Compiler bug fixes

  1. Bugzilla 10429: RDMD: --loop option doesn't work due to symbol conflict
  2. Bugzilla 10459: align(16) does not work on Win64 with seperate compilation
  3. Bugzilla 10743: mixin+static assert+__MODULE__=ICE
  4. Bugzilla 10758: Unsound type checking for inout.
  5. Bugzilla 10759: DMD crashes when using nested interfaces and inheritance from them.
  6. Bugzilla 10760: compiler drops opDispatch if it contains an error(s)
  7. Bugzilla 10858: CTFE wrong code for comparison of array of pointers
  8. Bugzilla 10915: std.typecons.Nullable throws in writeln() if it's null
  9. Bugzilla 10940: Interface post-condition breaks sub-interface covariance.
  10. Bugzilla 19163: static/tuple foreach counted incorrectly in coverage analysis
  11. Bugzilla 19675: Just calling an empty @safe function crashes the program on Linux x86 - wrong code gen?
  12. Bugzilla 19721: Cannot take address of scope local variable even with dip1000 if a member variable is a delegate
  13. Bugzilla 19905: Floating point .init should be bitwise identical to .nan
  14. Bugzilla 20152: numeric expression should not evaluate to const type
  15. Bugzilla 20275: Tuple created in template in with() includes with-symbol
  16. Bugzilla 20433: Don't complain about implicit cast when an explicit cast would also be in error
  17. Bugzilla 20825: the filename of the error messages generated by dmd build.d script miss the "src/" part of the path
  18. Bugzilla 21399: DDoc doesn't document symbols inside static foreach loops
  19. Bugzilla 21925: attribute inference not done on first typeof on member function
  20. Bugzilla 21945: importC AssertError@src/dmd/dsymbolsem.d(4787): Assertion failure
  21. Bugzilla 21976: importC: does not distinguish between cast-expression and unary-expression correctly
  22. Bugzilla 22069: importC: Error: found '&' instead of statement
  23. Bugzilla 22111: Can't deduce template argument for non-eponymous templated type
  24. Bugzilla 22135: Spurious "has scoped destruction, cannot build closure" on mixing closures, tuples and destructor
  25. Bugzilla 22153: Non-void arrays do not match inout void[] arguments in implicit function template instantiation (IFTI)
  26. Bugzilla 22202: Wrong error message for implicit call to @system copy constructor in @safe code
  27. Bugzilla 22239: Can't migrate from postblits if they are used without frame pointer
  28. Bugzilla 22322: ImportC: struct with floating point members causes problems with generated toHash() function
  29. Bugzilla 22323: Link error for virtual destructor of C++ class in DLL
  30. Bugzilla 22397: Out of memory during compilation
  31. Bugzilla 22399: importC: Error: static variable cannot be read at compile time
  32. Bugzilla 22463: OpenBSD: Allow DMD to work on 32-bit OpenBSD
  33. Bugzilla 22489: C header generation ignores custom mangling
  34. Bugzilla 22517: [REG 2.093][ICE] Bus error at dmd/lexer.d:398
  35. Bugzilla 22560: ImportC: extra semicolon not allowed outside of functions
  36. Bugzilla 22613: Alias to template instantiation can act as the template itself
  37. Bugzilla 22658: Inline asm rejects [RIP+RAX] but not [RAX+RIP]
  38. Bugzilla 22667: Nullable of struct containing unrelated Nullable errors with "inout can only be declared inside inout function"

DMD Compiler enhancements

  1. Bugzilla 4380: Poor optimisation of x*x, where x is real
  2. Bugzilla 17483: std.numeric.gcd cannot inline function
  3. Bugzilla 21519: [CI] Missing code coverage for some supported platforms
  4. Bugzilla 21997: CTFE should allow function pointer casts with different attributes
  5. Bugzilla 22243: Storage classes should be inferred for parameters of function literals
  6. Bugzilla 22290: Disallow assignment to a non-elaborate field of an rvalue
  7. Bugzilla 22354: Header generation is producing trailing whitespace on enum declarations

Phobos regression fixes

  1. Bugzilla 18316: std.net.curl.SMTP.mailTo fails to compile
  2. Bugzilla 21920: [REG master] Error: auto can only be used as part of auto ref for template function parameters
  3. Bugzilla 22176: Nullable creates autogenerated opAssign, triggering invariants

Phobos bug fixes

  1. Bugzilla 64: Unhandled errors should go to stderr
  2. Bugzilla 10774: std.range.indexed RangeError when indexing string with std.range.recurrence!"n"(0)
  3. Bugzilla 10916: toHash on VariantN not being recognised
  4. Bugzilla 19733: expi documentation links broken
  5. Bugzilla 20145: Random unittest failures inf std.datetime.stopwatch
  6. Bugzilla 20246: isCallable fails for template opCall overload
  7. Bugzilla 20985: std.socket random failures due to environment socket.d(1004)
  8. Bugzilla 21381: std.random.uniform!T(urng) when T is long or ulong and urng.front is signed int will be biased in its high bits
  9. Bugzilla 21634: std.bitmanip: bitfields may generate invalid variable
  10. Bugzilla 22394: std.getopt cannot handle "-"
  11. Bugzilla 22430: OpenBSD: Add OpenBSD to the timezone unittest

Phobos enhancements

  1. Bugzilla 9871: std.typecons.asArray
  2. Bugzilla 20425: Proxy opCmp fails to compile with types that overloaded opCmp
  3. Bugzilla 22393: OpenBSD: Add polyImpl implementation for x86

Druntime regression fixes

  1. Bugzilla 20578: Parallel GC causes segfault in dl

Druntime bug fixes

  1. Bugzilla 9783: profiling recursive function calls yields bad tree timing
  2. Bugzilla 21323: (64-bit Windows only) core.stdcpp.vector could not have core.stdcpp.vector as element

Druntime enhancements

  1. Bugzilla 22481: Thread.sleep should be pure

dlang.org bug fixes

  1. Bugzilla 22281: unreadable quotes in the upcoming 2.099 changelog
  2. Bugzilla 22282: corrupted tables in the upcoming 2.099 changelog
  3. Bugzilla 22504: spec/type.html: 6.1 Basic Data Types: Backslash missing in default value for {,d,w}char

dlang.org enhancements

  1. Bugzilla 21495: File.readf documentation does not state what what is returned.

Tools bug fixes

  1. Bugzilla 22381: DUB and gdmd: Invalid SemVer format: 2.076.1

Installer bug fixes

  1. Bugzilla 10062: installers should use CDN

Contributors to this release (64)

A huge thanks goes to all the awesome people who made this release possible.

previous version: 2.112.0