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.106.0

previous version: 2.105.2

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,, 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 and running the pending_changelog target:
    make -f posix.mak pending_changelog

2.106.0 comes with 14 major changes and 35 fixed Bugzilla issues. A huge thanks goes to the 25 contributors who made 2.106.0 possible.

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

Compiler changes

  1. Catch clause must take only const or mutable exceptions

    In 2.104, throwing qualified types was deprecated.

    It is also unsafe to catch an exception as immutable, inout or shared. This is because the exception may still be accessible through another mutable or non-shared reference. Catching an exception with those qualifiers is now deprecated.

    auto e = new Exception("first");
    try {
            throw e;
    } catch(immutable Exception ie) { // now an error
            e.msg = "second";
            assert(ie.msg == "first"); // would fail
  2. Improvements for the C++ header generation

    The following features/bugfixes/improvements were implemented for the experimental C++ header generator:

    • Static variables used in a default argument context are now emitted using their fully qualified name.

    Note: The header generator is still considered experimental, so please submit any bugs encountered to the bug tracker.

  3. A function with enum storage class is now deprecated, not an error

    The error was introduced in 2.105.0.

  4. Add -nothrow Switch to Compiler

    dmd itself (and presumably others) do not throw Exceptions, preferring other methods for dealing with errors. There is a cost, however, in supporting Exceptions even when they are never thrown. The cost is in adding stack unwinders for things like RAII objects, and preventing numerous optimizations across try-catch boundaries.

    Adding nothrow to all the code in a project turns out to be an inordinate amount of work if the program is large. Putting nothrow: at the top of the module doesn't influence the status for member functions in a class or struct, the nothrow: will have to be repeated for each class/struct.

    Adding the -nothrow switch to the compiler causes the stack unwinders to not be added and enables the optimizations. This capability is already there for -betterC code, this would just enable it for regular D code.

    The switch does not affect semantic analysis, just the code generation. Name mangling is not affected.

    The switch is useful for determining what effect exception handling has on an executable's size and performance in non-throwing code.

  5. Added support for Intel CET (Control-flow Enforcement Technology) IBT (Indirect Branch Tracking) protection

    CET is a technology that is useful for preventing an attacker from redirecting a program's control flow, specifically IBT prevents an attacker from causing an indirect branch to go to an unintended place.

    Intel IBT expects the compiler to emit special instructions (endbr32 and endbr64) which in older processors that do not support IBT are equivalent to nop instructions, consequently a program compiled with active IBT will be compatible on any x86 processor and the protection will be opportunistically active on supported processors.

    To enable Intel IBT protection in DMD you need to pass the -fIBT flag to the compiler, consequently the compiler will manage the emission of instructions for IBT by itself. Be careful when using inline assembly, the compiler will not automatically handle IBT inside an inline assembly.

    To find out within a D program whether IBT has been activated or not use the traits getTargetInfo as follows:

    // IBT active
    static assert(__traits(getTargetInfo, "CET") == 1);  // CET == 1 if IBT is active
    // IBT not active
    static assert(__traits(getTargetInfo, "CET") == 0);  // CET == 0 if IBT is not active
  6. Creating a scope class instance with a non-scope constructor is @system only with DIP1000

    The fix for issue 23145 broke existing code, so it's put behind -preview=DIP1000 now, just like other scope related errors.

  7. Global const variables can no longer be initialized from a non-shared static constructor

    Just like immutable data, global const data is not placed in Thread Local Storage (TLS), so initializing it in a thread-local static constructor allows you to violate const: see issue 24056 for details. Doing this will now result in a deprecation:

    int x;
    const int y;
    immutable int z;
    static this()
        x = 1;
        y = 2; // Deprecation: cannot modify const variable
        z = 3; // Error: cannot modify immutable variable (same as before)

    As a corrective action, move the initialization to a shared static constructor:

    const int y;
    shared static this()
        y = 4; // OK
  8. Global variables can now be initialized with Associative Arrays

    Formerly, module constructors or enum had to be used to initialize global variables with Associtive Arrays. By internally lowering to Steven Schveighoffer's newaa struct implementation, Associative Arrays can now be used directly.

    immutable string[string] table = ["key": "value"];
    void main()
        assert(table["key"] == "value");

    When the key/value types have toHash, opEquals or ~this defined, they must be callable at compile time. An if (!__ctfe) branch can be used to make a destructor only run at run time. Future enhancements may obviate the need for this workaround.

Runtime changes

  1. 4 core.memory.GC functions have been marked @safe

    • GC.enable
    • GC.disable
    • GC.collect
    • GC.minimize

Library changes

  1. Undo etc.c.odbc deprecation and enable usage on non-Windows systems

    Previously, the etc.c.odbc bindings were deprecated and forwarded the versions of the bindings via public import. However, ODBC is supported on all major platforms and the machine translated MinGW bindings in have version(Windows) specified which results in being unable to use those bindings on non-Windows platforms. The bindings have been returned to etc.c.odbc, undeprecated, and support for non-Windows platforms enabled.

Dub changes

  1. Added --deep= switch to dub build

    By specifying this flag, you can now build all the dependencies of a staticLibrary. The default behavior is to only build the library located in the root directory of the dub configuration file. This allows better integration with other build systems which require the libraries to be built upfront.

    dub build --deep

    If a staticLibrary A depends on staticLibrary B, and the --deep flag is specified, dub will output both the A and B libraries.

  2. Added default-config, configs, default-build, builds data to dub describe

    • default-config will be a single string that is the --config configuration that DUB would pick when not provided any configuration such as in a simple dub build call
    • configs is a list of all available configurations (default generated application and/or library, or the manually specified ones in the recipe)
    • default-build will be a single string that is the --build build type that DUB would pick when not provided any (currently always "debug")
    • builds is a list of all available build types (built-in + custom defined)

  3. Dub init now has a select menu for package format and license

    When creating a package using dub init you are now prompted to select a license for the package.

  4. Added --recipe= switch to DUB

    You can now override which file is used as recipe, instead of the default dub.sdl and dub.json. This means you can define multiple dub.json files for local development, for example for special local-machine-only operations, and select which one to use over the CLI.

    dub build --recipe=custom-dub.json

    This can also be used to pick dub.sdl over dub.json, if both of them exist in the same directory. Although this is discouraged for interoperability with other DUB-supporting tools and general confusion for users. Both existing at the same time may also become an error when this switch is not specified in the future.

List of all bug fixes and enhancements in D 2.106.0:

DMD Compiler regression fixes

  1. Bugzilla 20655: [REG: 2.072] attribute inference accepts unsafe union access as @safe
  2. Bugzilla 24066: __traits(isAbstractClass) causes a segfault when passed an opaque class

DMD Compiler bug fixes

  1. Bugzilla 8662: Better error for duplicate labels inside static foreach body
  2. Bugzilla 11455: Overriding template methods should raise a compile error
  3. Bugzilla 18578: First enum value assigned 0 instead of EnumBaseType.init
  4. Bugzilla 22682: pragma(mangle) does not work for nested functions
  5. Bugzilla 23103: static initialization of associative arrays is not implemented
  6. Bugzilla 23522: Error message when enum type is not integral and a value lacks an initializer
  7. Bugzilla 24036: assert message in CTFE becomes ['m', 'e', 's', 's', 'a', 'g', 'e'][0..7] if produced using std.format.format
  8. Bugzilla 24051: Safety attrib inference of enum/immut/const decls inconsistent with mutable static variable decls
  9. Bugzilla 24054: return expression expected on noreturn function
  10. Bugzilla 24055: is(x == __parameters) does not work on function pointer/delegate types
  11. Bugzilla 24056: const uninitialized data at module scope is not in TLS
  12. Bugzilla 24065: __traits(getTargetInfo) causes a segfault when passed a non value
  13. Bugzilla 24070: Opaque struct with nested definition when taking pointer segfaults
  14. Bugzilla 24071: When enum has typedef integer constants do not have types determined correctly
  15. Bugzilla 24105: Dip1000 C variadics not marked as scope should not accept scope arguments
  16. Bugzilla 24107: The error for exceeding the CTFE recursion limit bypasses speculative compilation.
  17. Bugzilla 24108: dmd -H and -X fail when given an importC module
  18. Bugzilla 24117: noreturn can be used as expression
  19. Bugzilla 24129: ImportC: MS-Link cannot handle multiple COMDATs with the same name
  20. Bugzilla 24130: ImportC: Windows headers use inline asm with different syntax
  21. Bugzilla 24133: printf format checking of %n allows writing to const pointers

DMD Compiler enhancements

  1. Bugzilla 15752: Diagnostic: Better Error Message for Assigning Incorrect AA Empty Value
  2. Bugzilla 21520: dmd does not honor the NO_COLOR environment variable
  3. Bugzilla 21852: diagnostic: One-liner errors with formatted Loc should print context when -verrors=context
  4. Bugzilla 23958: ImportC: undefined identifier __builtin__sprintf_chk
  5. Bugzilla 24060: Improve "Cannot create instance of abstract class" error
  6. Bugzilla 24084: Add -nothrow Switch to Compiler

Phobos bug fixes

  1. Bugzilla 24049: string to enum conversion is not documented

Phobos enhancements

  1. Bugzilla 24082: add Int128.toString that supports std.format
  2. Bugzilla 24142: Allow casting Int128 to integral and floating types

Druntime bug fixes

  1. Bugzilla 24079: returns bad pointer
  2. Bugzilla 24123: More importc definitions are needed for macOS enhancements

  1. Bugzilla 24012: [spec/cpp_interface] _d_dynamicArray generated by -HC not documented

Contributors to this release (25)

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

previous version: 2.105.2