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

previous version: 2.089.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.090.0 comes with 11 major changes and 93 fixed Bugzilla issues. A huge thanks goes to the 53 contributors who made 2.090.0 possible.

Library changes

  1. Added std.traits.Unconst

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

Compiler changes

  1. Deprecate allowing shadowing in foreach loops

    Up until this version it was allowed to shadow a variable in a foreach loop, although it is dissallowed in a normal for loop. This patch makes the behavior of the foreach loop consistent with the for loop one. To fix any issues encountered, rename the variable inside the foreach body that shadows the one from the upper scope.

  2. IsExpressions now correctly match combinations of const, inout, and shared.

    With Bugzilla 20138 fixed, IsExpressions now correctly match combinations of the qualifiers const, inout, and shared.

    Examples that failed previously but pass now:

    static assert(is(shared(const int) U == shared U) && is(U == const int));
    static assert(is(shared(inout int) U == inout U) && is(U == shared int));
    

    Note that the behavior of code like the following changes:

    static if (is(T U == const U) { ...}
    else static if (is(T U == shared const U)) { ... }
    

    The second case will never be reached, because the first one now matches when T is shared const. To get the old behavior, switch the order.

  3. extern(C) declarations in template mixins now mangle as C symbols when mixed in at global scope

    This was already true for string mixins, but since template mixins introduce a new scope, symbols inside them got mangled as D symbols. However, users often use extern(C) inside a mixin template to automatically generate boilerplate code that should be accessible from C.

    // library code
    mixin template WasmEntryPoint() {
        extern(C) export void _start() {
            // boilerplate code
        }
    }
    
    mixin template UseGpuInsteadOfIntegratedGraphics() {
        extern(C) export uint NvOptimusEnablement = 0x00000001;
        extern(C) export int AmdPowerXpressRequestHighPerformance = 1;
    }
    
    // application code
    mixin WasmEntryPoint;
    mixin UseGpuInsteadOfIntegratedGraphics;
    
    static assert(_start.mangleof == "_start");
    static assert(NvOptimusEnablement.mangleof == "NvOptimusEnablement");
    

    Previously, _start would be mangled like _D9onlineapp8__mixin46_startUkZv and users had to manually add pragma(mangle, "_start") or use a string mixin instead. With the new behavior this is not necessary anymore for extern(C), as well as extern(Windows) and extern(Objective-C). extern(C++) remains unchanged since it already always mangles to C++, even in nested scopes.

    There is a possibility this breaks code if you mix in different extern(C) declarations with the same name in the global scope of multiple modules.

    import core.stdc.stdio;
    
    mixin template GenPrintCallback(string text) {
        extern(C):
    
        auto textLength = text.length;
        auto textPointer = text.ptr;
    
        void callBackOnly() {
            printf("%.*s\n", textLength, textPointer);
        }
    
        mixin(`auto `, text, ` = &callBackOnly;`);
    }
    
    mixin GenPrintCallback!"foo";
    
    // in a different module:
    mixin GenPrintCallback!"bar";
    

    In this case textLength, textPointer and callBackOnly will be defined multiple times, so the linker either picks one or raises and error. The solution is to not make variables extern(C) and make C callback functions anonymous:

    import core.stdc.stdio;
    
    mixin template GenPrintCallback(string text) {
    
        auto textLength = text.length; // not below an extern(C): anymore
        auto textPointer = text.ptr;
    
        alias FunT = extern(C) void function();
        enum FunT callBackOnly = () {
            printf("%.*s\n", textLength, textPointer);
        };
    
        mixin(`auto `, text, ` = callBackOnly;`);
    }
    
  4. The default linker for the Digital Mars tool chain is now optlink.exe

    The default linker when building with -m32 under Windows has been changed from link.exe to optlink.exe to avoid calling the wrong linker when both the Digital Mars tool chain and the Microsoft compiler tools are found in the PATH environment variable.

  5. New -Xcc compiler flag to address issue 6952

    On POSIX, dmd passes -L-prefixed compiler flags through the linker driver (cc by default) to the linker (e.g. ld) by prepending them with -Xlinker. Therefore, it was not possible to pass flags directly to the linker driver.

    This release adds a new compiler flag, -Xcc, which specifies a flag to pass to the linker driver. This switch has already existed in the LDC compiler for several releases. Some use cases for it would be -nostartfiles, -pthread, and -static, which can now be specified as -Xcc=-nostartfiles, -Xcc=-pthread, and -Xcc=-static respectively.

    Note that it was previously also possible to specify linker driver options by setting the CC environment variable, e.g. CC='cc -pthread' dmd ..., or by setting the CC variable to point to a custom linker driver wrapper script. -Xcc improves on this through composability and better opportunities for integration into build systems.

    See also:

Runtime changes

  1. Added core.atomic.atomicFetchAdd and core.atomic.atomicFetchSub.

    Added core.atomic.atomicFetchAdd and core.atomic.atomicFetchSub to the atomic suite.

  2. Make wstatus predicates pure and @safe

    The predicates that operate on the wstatus value reported by wait(2) are now marked pure and @safe, allowing them to be used in functions with those attributes.

Library changes

  1. Added std.traits.Unconst

    std.traits.Unconst works like std.traits.Unqual, but removes only const, inout and immutable qualifiers from a type.

Dub changes

  1. Builds dynamicLibrary targets as dynamic libraries instead of static libraries.

    Dub will no longer build dynamicLibrary targetType's as staticLibrary.

    Except for x86_omf. This has been disabled due to numerous issues that will lead this to not doing what is expected of it.

    No compiler or linker flags have been added at this time, you will need to specify the relevant flag to get the compiler to link dynamically against Phobos.

  2. The $DUB_BUILD_PATH variable was added

    The $DUB_BUILD_PATH variable is now defined inside the postBuildCommands section. It contains the absolute path in which the package was built, and can be used to copy by-products of the build process to their intended locations.

    For example, if an executable exports symbols, you will want to make the resulting import library and symbols export file available somewhere. That can be done with a dub.json section like this:

        "postBuildCommands-windows": [
            "copy /y $DUB_BUILD_PATH\\$DUB_TARGET_NAME.lib $PACKAGE_DIR\\lib"
            "copy /y $DUB_BUILD_PATH\\$DUB_TARGET_NAME.exp $PACKAGE_DIR\\lib"
        ],
    
  3. Command environment variable substitution changed

    Now users can use the documented predefined variables inside custom command directives without the need for a wrapper shell script.

    Before this would have failed:

    "preBuildCommands": ["$DC -run foo.d"]
    
    unless DC was defined as environment variable outside DUB.

    It was before possible to run a script that used the $DC environment variable or on POSIX escape the $ with $$DC to make the shell substitute the variable. These workarounds are no longer needed now.

    API change: none of the different command directives are no longer substituted with the process environment variables. You now access the raw commands as provided by the user in the recipe. dub describe has been adjusted and now also processes the predefined environment variables as well as the process environment variables.


List of all bug fixes and enhancements in D 2.090.0:

DMD Compiler regressions

  1. Bugzilla 15069: [REG2.064] nonsense struct template instantiations still compile
  2. Bugzilla 19884: [regression] Error: alias op = op; cannot alias itself, use a qualified name to create an overload set
  3. Bugzilla 20348: [Reg 2.089.0-rc.1] Bad debug info for enum forward references
  4. Bugzilla 20349: [REG2.087] ICE with sqrt
  5. Bugzilla 20376: @disable this(ref return scope Foo rhs) enables broken binaries (out-of-bounds access)
  6. Bugzilla 20383: [REG 2.084.z] illegal conversion from int[] to ubyte[] is accepted
  7. Bugzilla 20388: Parse error when compiling lambdas in mixins as template parameters
  8. Bugzilla 20416: [Regression 2.073.2] compiler complains about escaping reference in certain cases
  9. Bugzilla 20418: Unittest failure in bitarray.d on Win32
  10. Bugzilla 20420: [REG2.067] inlining error with a valid function
  11. Bugzilla 20465: Dynamic + static array declaration fail

DMD Compiler bugs

  1. Bugzilla 6592: di header file created even if errors occur
  2. Bugzilla 8684: Missing ')' in argument list creates a sea of error messages
  3. Bugzilla 9490: 'this' is not found when expression is in parentheses
  4. Bugzilla 10562: Cannot initialize arrays by an element value when the elements are fixed-length arrays
  5. Bugzilla 14696: destructor for temporary called before statement is complete with conditional operator
  6. Bugzilla 17125: Header Generation Incorrectly Formats Floating Point Number
  7. Bugzilla 19432: Cannot initialize ulong with decimal value above signed long range
  8. Bugzilla 20092: void[1] auto slicing makes the compiler hang
  9. Bugzilla 20151: particular directory layout causes DMD to crash with an access violation
  10. Bugzilla 20220: pragma(crt_constructor) does not work with clang 9
  11. Bugzilla 20253: bad debug line info for function without epilog
  12. Bugzilla 20264: ICE on illegal cast to vector.
  13. Bugzilla 20280: Compiler segfault when building two small files
  14. Bugzilla 20318: Illegal instruction (core dumped)
  15. Bugzilla 20326: stringof on opaque type results in forward reference error
  16. Bugzilla 20366: CTFE foreach_reverse on array with utf characters crashes compiler
  17. Bugzilla 20367: Postblit cannot be disabled when copy ctor is defined
  18. Bugzilla 20400: CTFE increasing length of array of characters changes its value
  19. Bugzilla 20401: ref variable copied before return
  20. Bugzilla 20406: Copy constructor requires default constructor
  21. Bugzilla 20413: C++ mangling bug with templates & the std namespace
  22. Bugzilla 20417: __traits(compiles) returns false result if expression is not wrapped inside a lambda while typeof works correctly
  23. Bugzilla 20419: is(missing == module/package) results in unknown identifier
  24. Bugzilla 20431: Allow a Mixin Type to resolve to an expression where it makes sense
  25. Bugzilla 20441: Wrong code with -O -fPIC and pointer subtraction
  26. Bugzilla 20466: Optimizer clobbering msw register when testing it for 0
  27. Bugzilla 20475: Struct of static array of strings is bitwise-compared instead of member-wise

DMD Compiler enhancements

  1. Bugzilla 4544: Better error-message when expecting string but got a character constant
  2. Bugzilla 11038: static has no effect as a block attribute for imports
  3. Bugzilla 18809: Improve error message on nonexistent property
  4. Bugzilla 20334: posix.mak clean target does not remove all generated files
  5. Bugzilla 20356: exceeding template expansion limits
  6. Bugzilla 20448: Error: unknown when mutating an escaped member reference from a template function

Phobos regressions

  1. Bugzilla 20054: getSymbolsByUDA no longer works on modules
  2. Bugzilla 20350: JSONType deprecations should be undeprecated
  3. Bugzilla 20354: interface is not supported by CanCAS in core.internal.atomic

Phobos bugs

  1. Bugzilla 9588: format prints context pointer for struct
  2. Bugzilla 9592: Justified Tuple printing
  3. Bugzilla 10126: Make TaskPool terminate on its own or improve docs to make it clear that it won't
  4. Bugzilla 10448: min and max are not NaN aware
  5. Bugzilla 10902: some phobos unittests take an excessive amount of time
  6. Bugzilla 11013: ignoring variable inside the predicate of findSplitBefore
  7. Bugzilla 11782: format pointer to range prints range
  8. Bugzilla 15405: FormatSpec.writeUpToNextSpec() not documented
  9. Bugzilla 15940: ImplicitConversionTargets and class alias in struct
  10. Bugzilla 16223: BigUint: undefined shift for small instantiation type
  11. Bugzilla 18248: radix overload of std.conv.parse fails to throw on non-empty range without number
  12. Bugzilla 18446: Wrong curl onProgress examples
  13. Bugzilla 19283: [std.mathspecial] documentation for normal distribution doesn't list parameters
  14. Bugzilla 19626: RedBlackTree of an enum fails in unittest mode
  15. Bugzilla 19733: expi documentation links broken
  16. Bugzilla 20160: ThreadInfo.cleanup() clears local thread's registered names instead of "this"'s
  17. Bugzilla 20260: CustomFloat with 0 precision/exponentWidth
  18. Bugzilla 20261: CustomFloat.epsilon yields infinity
  19. Bugzilla 20263: Wrong value for CustomFloat.min_exp
  20. Bugzilla 20281: CustomFloat is limited to 64 bit
  21. Bugzilla 20282: CustomFloat.dig fails at some values.
  22. Bugzilla 20283: CustomFloat.max_exp not working in some cases
  23. Bugzilla 20284: CustomFloat.max_10_exp does not work for types with too many digits in exponent
  24. Bugzilla 20286: CustomFloat.min_normal fails, when not allowDenorm
  25. Bugzilla 20313: Inconsistent behavior of wouldHaveBlocked on Windows
  26. Bugzilla 20314: passing const variables to only forces const range element type
  27. Bugzilla 20357: format should obey space flag when printing nan or inf
  28. Bugzilla 20396: format!"%a" leeds to wrong result for denormalized float
  29. Bugzilla 20398: Wrong number of totalEntries in std.zip
  30. Bugzilla 20408: style checker should not check backup files

Phobos enhancements

  1. Bugzilla 20198: Make std.math.nextUp and nextDown and nextafter work in CTFE for float and double
  2. Bugzilla 20288: std.format double with NaN fails with range violation on comma
  3. Bugzilla 20425: Proxy opCmp fails to compile with types that overloaded opCmp
  4. Bugzilla 20439: memoize fails with types that have a void opAssign

Druntime regressions

  1. Bugzilla 20438: [Reg 2.086] GC: memory not reusable when calling GC.collect after GC.free

Druntime bugs

  1. Bugzilla 20299: checkaction=context not working with temporary destructors
  2. Bugzilla 20303: Memory leak in core.thread
  3. Bugzilla 20315: checkaction=context fails for const(void[]) argument
  4. Bugzilla 20322: checkaction=context fails for wstring/dstring arguments
  5. Bugzilla 20323: checkaction=context fails for non-copyable arguments
  6. Bugzilla 20346: std.uuid does not compile with checkaction=context
  7. Bugzilla 20355: undefined identifier U in core.atomic
  8. Bugzilla 20364: [REG2.069] changing length for typeof(null)[] array seg faults in _d_arraysetlengthiT()
  9. Bugzilla 20440: Associative arrays with values whose opAssign doesn't return a ref don't support require function

Druntime enhancements

  1. Bugzilla 17563: gc_inFinalizer should be public

Tools bugs

  1. Bugzilla 20386: Test extractor shouldn't emit unit tests, but regular functions for @betterC tests

Contributors to this release (53)

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

previous version: 2.089.0