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

previous version: 2.107.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.108.0 comes with 10 major changes and 18 fixed Bugzilla issues. A huge thanks goes to the 28 contributors who made 2.108.0 possible.

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

Compiler changes

  1. A string literal as an assert condition is deprecated

    Boolean evaluation of a string literal could happen unintentionally e.g. when an assert(0, "message") was meant and the 0 was missing.

    assert("unexpected runtime condition");
    static assert("unhandled case for `", T, "`");
    

    The 2 asserts would silently always have no effect. Now these cases will be detected with deprecation messages. If the original behaviour was actually intended, use expr !is null instead:

    assert("" !is null);
    static assert("" !is null);
    
  2. Makefiles cleanup for the compiler

    The Makefiles for building the compiler (compiler/src/{posix,win32,win64}.mak) have been deprecated for a while, and finally removed. Please use the compiler/src/build.d tool directly now (see docs), or build compiler and druntime in one step via the top-level Makefile in the repo root, e.g., for an optimized build using an LDC host compiler: make -jN HOST_DMD=ldmd2 ENABLE_RELEASE=1 ENABLE_LTO=1

    The top-level Makefile has been renamed from posix.mak to Makefile (with a deprecated posix.mak forwarder). The semantics of some targets have slightly changed, e.g., druntime is included in the test, install and clean targets now.

    The legacy src/posix.mak file still exists, but forwards to the top-level Makefile. So e.g. the default all target now includes druntime too, not just the compiler.

    Top-level win{32,64}.mak and legacy src/win{32,64}.mak files (for DigitalMars make) have been removed altogether. The generic top-level Makefile works on Windows too - with a GNU make (and a git installation providing bash and GNU tools).

    Long-deprecated compiler/test/Makefile has also been removed; use compiler/test/run.d directly instead (see docs).

  3. Unrecognized pragmas are no longer an error, but instead simply ignored

    Previously, unrecognized pragmas would issue a hard error unless you used the -ignore dmd switch. Now, they are always ignored and the -ignore dmd switch is ignored.

  4. Added @standalone for module constructors

    When two modules import each other and both have module constructors, druntime would throw an error because it can't determine which to run first.

    This could be circumvented by using pragma(crt_constructor) instead, but in C runtime constructors, druntime isn't initialized. Therefore the Garbage Collector can't be used in such constructors.

    @standalone is a new attribute that can be used to mark module constructors that run after druntime has been initialized, but do not depend on any other module constructors being run before it, so it will not cause a cyclic dependency error. It must be imported from core.attribute.

    The compiler doesn't verify that the module constructor truly doesn't depend on other variables being initialized, so it must be enforced manually. Because of this, they must be marked @system or @trusted.

    import core.attribute : standalone;
    
    immutable int* x;
    
    @standalone @system shared static this()
    {
        x = new int(10);
    }
    
    void main()
    {
        assert(*x == 10);
    }
    

    If possible, prefer to solve cyclic dependency errors by putting the offending module constructors into their own smaller modules instead of using @standalone.

  5. _d_newarray{mTX,miTX,OpT} are converted to a single template: _d_newarraymTX

    The template _d_newarraymTX now uses DBI to check what type of initialiser is required by the type of the elements in the array. Thus it replaces both _d_newarraymTX and _d_newarraymiTX.

    _d_newarrayOpT was the generic implementation of both of the above hooks. It first allocated the "outer" arrays as pointer arrays and then it called either _d_newarrayT or _d_newarrayiT, to allocate initialise the "inner" 1-dimensional arrays accordingly. Now this is no longer needed due to the merge between _d_newarraymTX and _d_newarraymiTX.

    Now the compiler performs the following lowering:

    S[][] s = new S[][](2, 3)
    
    // is now lowered to:
    S[] s = _d_newarraymTX!(S[][], S)([2, 3]);
    

    This change adds the new template to core.internal.array.construction.

Runtime changes

  1. Using an invalid MemoryOrder for core.atomic operations are now rejected at compile time

    The following core.atomic functions have become more restrictive:

    1. atomicLoad and atomicStore now reject being instantiated with the
    argument MemoryOrder.acq_rel. Previously atomicLoad and atomicStore only rejected MemoryOrder.rel and MemoryOrder.acq respectively.

    In most cases, code that previously used MemoryOrder.acq_rel should switch to use MemoryOrder.seq instead.

    // Error:
    atomicLoad!(MemoryOrder.acq_rel)(src);
    atomicStore!(MemoryOrder.acq_rel)(dest, value);
    
    // Corrective action:
    atomicLoad!(MemoryOrder.seq)(src);
    atomicStore!(MemoryOrder.seq)(dest, value);
    
    // Or:
    atomicLoad(src);
    atomicStore(dest, value);
    

    1. atomicExchange now rejects being instantiated with the argument
    MemoryOrder.acq.

    In most cases, code that previously used MemoryOrder.acq should switch to use MemoryOrder.seq instead.

    // Error:
    atomicExchange!(MemoryOrder.acq)(dest, value);
    
    // Corrective action:
    atomicExchange!(MemoryOrder.seq)(dest, value);
    
    // Or:
    atomicExchange(dest, value);
    

    1. atomicCompareExchangeWeak and atomicCompareExchangeStrong now reject
    being instantiated when the second fail argument is MemoryOrder.rel or MemoryOrder.acq_rel.

    In most cases, code that previously used either of these should switch to use MemoryOrder.raw instead.

    // Error:
    atomicExchangeWeak!(MemoryOrder.rel, MemoryOrder.rel)(dest, compare, value);
    atomicExchangeWeakNoResult!(MemoryOrder.acq_rel, MemoryOrder.acq_rel)(dest, compare, value);
    atomicExchangeStrong!(MemoryOrder.acq, MemoryOrder.rel)(dest, compare, value);
    atomicExchangeStrongNoResult!(MemoryOrder.seq, MemoryOrder.acq_rel)(dest, compare, value);
    
    // Corrective action:
    atomicExchangeWeak!(MemoryOrder.rel, MemoryOrder.raw)(dest, compare, value);
    atomicExchangeWeakNoResult!(MemoryOrder.acq_rel, MemoryOrder.raw)(dest, compare, value);
    atomicExchangeStrong!(MemoryOrder.acq, MemoryOrder.raw)(dest, compare, value);
    atomicExchangeStrongNoResult!(MemoryOrder.seq, MemoryOrder.raw)(dest, compare, value);
    

    1. atomicCompareExchangeWeak and atomicCompareExchangeStrong additionally
    now reject being instantiated when the second fail argument has a greater value than its first succ argument.

    In most cases, code that violates this contract should use the same MemoryOrder for both succ and fail arguments.

    // Error:
    atomicExchangeWeak!(MemoryOrder.raw)(dest, compare, value);
    atomicExchangeStrong!(MemoryOrder.acq, MemoryOrder.seq)(dest, compare, value);
    
    // Corrective action:
    atomicExchangeWeak!(MemoryOrder.raw, MemoryOrder.raw)(dest, compare, value);
    atomicExchangeStrong!(MemoryOrder.acq, MemoryOrder.acq)(dest, compare, value);
    
  2. Makefiles cleanup for druntime

    The {posix,win32,win64}.mak Makefiles have been merged to a generic Makefile (including the ones in druntime/test/). posix.mak is kept as a deprecated forwarder for now.

    On Windows, you can/need to use the generic Makefile too - with a GNU make (and a git installation providing bash and GNU tools). Windows devs can finally exploit parallelism via -j! You may download a prebuilt zipped .exe from https://github.com/dlang/dmd/releases/download/nightly/gnumake-4.4-win64.zip.

  3. New addition of the C stdatomic header implemented in D

    The goal of this module is to assist in porting efforts for code from C to D and to give as close as possible same code generation as the system C compiler counterpart.

    If you do not care about code generation quality should the aliases to the function names not exist, you may append _impl to get at the implementation.

    If the code generation provided by a given function is not on-par to the system C compiler and it matters to your use case, please report it as a bug.

Library changes

  1. isForwardRange now takes an optional element type.

    isForwardRange now has an optional 2nd template parameter that defaults to void. If not void, it only evaluates to true if the range's element type is the same type as this extra argument, modulo const. For instance, isForwardRange!(int[], const(int)) is true, but isForwardRange!(int[], string) is false.

  2. Makefiles cleanup

    The {posix,win32,win64}.mak Makefiles have been merged to a generic Makefile. posix.mak is kept as a deprecated forwarder for now.

    On Windows, you can/need to use the generic Makefile too - with a GNU make (and a git installation providing bash and GNU tools). Windows devs can finally exploit parallelism via -j! You may download a prebuilt zipped .exe from https://github.com/dlang/dmd/releases/download/nightly/gnumake-4.4-win64.zip.


List of all bug fixes and enhancements in D 2.108.0:

DMD Compiler regression fixes

  1. Bugzilla 24179: Ddoc broke D code sections
  2. Bugzilla 24315: dmd/cpreprocess.d:87: warning: use of tmpnam is dangerous use mkstemp

DMD Compiler bug fixes

  1. Bugzilla 23515: Named Enum of function SIGSEGFAULT
  2. Bugzilla 23818: Error HMODULE not defined, please use HMODULE
  3. Bugzilla 24293: ImportC: C preprocessor output should use temporary files
  4. Bugzilla 24359: slice equality expression can be discarded
  5. Bugzilla 24363: hex string postfixes are useless

DMD Compiler enhancements

  1. Bugzilla 18919: __FILE__ and __LINE__ should work when used in default argument expressions
  2. Bugzilla 24316: Allow CTFE access to immutable variable through pointer

Phobos bug fixes

  1. Bugzilla 24339: std.mmfile has poor documentation
  2. Bugzilla 24348: Inaccurate documentation for hasSlicing with infinite range

Phobos enhancements

  1. Bugzilla 24318: Nullable should support non-copyable objects

Druntime bug fixes

  1. Bugzilla 4071: Missing support to share memory and objects between DLLs and executable
  2. Bugzilla 24349: object noreturn link is missing

Druntime enhancements

  1. Bugzilla 15504: core.demangle uses exception handling for normal control flow
  2. Bugzilla 19702: Remove usage of DECLARE_HANDLE

dlang.org enhancements

  1. Bugzilla 24313: Download page should reference Github nightlies
  2. Bugzilla 24331: @nogc and GC.disable() are often confused

Contributors to this release (28)

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

previous version: 2.107.0