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

previous version: 2.094.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.095.0 comes with 14 major changes and 61 fixed Bugzilla issues. A huge thanks goes to the 50 contributors who made 2.095.0 possible.

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

Compiler changes

  1. Template usage diagnostics via -vtemplates has been improved.

    Every template having at least one instantiation is now printed using standard compiler diagnostics formatting for easy navigation to the point of its declaration.

    All messages of this kind are sorted by descending unique instantiation count.

    If the flag argument list-instances is passed (such as -vtemplates=list-instances), each location where a template was instantiated is printed along with the reason for the instantiation (implicit or explicit).

    For instance, a D source file named main.d containing

    void foo(int I)() { }
    void goo1(int I)() { }
    void goo2(int I)() { goo1!(I); }
    void test()

    compiled with -vtemplates=list-instances will output

    main.d(1): vtemplate: 3 (2 unique) instantiation(s) of template `foo(int I)()` found, they are:
    main.d(7): vtemplate: explicit instance `foo!1`
    main.d(8): vtemplate: explicit instance `foo!1`
    main.d(9): vtemplate: explicit instance `foo!2`
    main.d(2): vtemplate: 2 (1 unique) instantiation(s) of template `goo1(int I)()` found, they are:
    main.d(11): vtemplate: explicit instance `goo1!1`
    main.d(3): vtemplate: implicit instance `goo1!1`
    main.d(3): vtemplate: 1 (1 unique) instantiation(s) of template `goo2(int I)()` found, they are:
    main.d(13): vtemplate: explicit instance `goo2!1`
  2. Deprecate bypassing of symbol visibility when doing overload resolution

    If an aggregate declaration contains a private method and a public method in the same overload set it is possible to call the private method from a different module.


    module foo;
    struct Foo
      import std : writeln;
      private int _x;
      private ref int x() return
        writeln("ref int");
        return _x;
      int x() const
        return _x;

    module main;

    void main() { import std : writeln; import foo : Foo;

    auto f = Foo(); f.x = 3; // ok to call private method writeln(f); } ===========================

    Starting from this version a deprecation message will be issued in such situations.
  3. Deprecation triggered inside of templates now show instantiation trace

    A common issue when dealing with deprecations is to have it trigger in library code, for example having a deprecated alias this, or a hook (opApply, range primitives...) being called by a function deeply nested inside Phobos.

    In such cases, finding out where the instantiation comes from can be quite tedious. From this release, if a deprecation is triggered inside a template, the compiler will show the template instantiation trace, just like it already does on error. The same limit apply (6 frames, recursive templates are compressed), and -v can be used to lift it.

  4. Improvements for the C++ header generation

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

    • Enums are no longer emitted in macros and enum class is used when the C++ standard set from -extern-std= is c++11 or later.
    • Forward referenced declarations are now properly indented.
    • Default functions parameters are properly emitted
    • Tuple members/parameters/variables are emitted as individual variables using the compiler internal names instead of causing an assertion failure.
    • Interfaces are now emitted as base classes.
    • Aggregate members will be emitted with proper protection levels
    • Protected enums in aggregates are emitted again
    • Private member methods are no longer emitted
    • No auto-generated default constructor for unions
    • No longer ignores declarations nested inside an extern block, e.g. extern(D) extern(C++) void foo() {}
    • Opaque enums no longer cause segfaults & are properly exported for C++ 11
    • C++11 constructs are avoided when compiling with -extern-std=c++98.
    • Using typeof(null) type no longer causes an assertion failure.
    • The base type of floating point literals is propagated into the header
    • NaN, Infinity are emitted using NAN/INFINITY from math.h.
    • Final classes are marked as final
    • immutable is emitted as const instead of mutable
    • Identifier chains in templates are printed completely
    • Proper vtable layout is ensured by emitting hidden placeholders for virtual functions that are not extern(C|C++).
    • Fixed missing const for class members/methods
    • Templated class declarations are now emitted
    • Manifest constants that are not extern(C|C++) are no longer emitted.

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

  5. Diagnostics for conflicting function definitions within a module

    Previously, multiple definitions of identical functions within a module were not recognized, although they have the same mangling. This was problematic because a binary cannot contain multiple definitions of a symbol, which caused undefined behavior depending on the compiler backend.

    DMD will now raise an error message if there are conflicting implementations within a single module:

    void foo() {}
    void foo() {} // error

    Multiple declarations are still allowed as long as there is at most one definition:

    void bar(int);
    void bar(int) { }
    void bar(int);

    DMD will issue a deprecation for mangling schemes that don't support overloading (extern(C|Windows|System)):

    void foo(int) { }
    void foo(double) { } // deprecation

    This deprecation will become an error in 2.105.

  6. extern(Pascal) has been removed

    This unused linkage was deprecated in and has now been removed.

  7. C++ compability standard now c++11 by default

    The default setting for -extern-std= has been updated to c++11.

    Declarations with extern(C++) linkage are no longer guaranteed to link with code compiled by a C++98 compiler. Additionally, C++ headers generated by -HC will use constructs only available from C++11 onwards.

    If compatibility with older C++ compilers is required, you must now pass -extern-std=c++98 on the command-line.

  8. Add -preview=inclusiveincontracts: in contracts must be an explicit superset of the parent in contracts.

    As per Liskov, in contracts can only loosen the conditions placed on the method they appear on. Currently this is enforced by automatically "oring" together the in contract with the in contract on the parent method, creating a combined contract that is necessarily looser than the parent.

    However, this leads to odd behavior like this code passing:

    class A
        void foo(int i) in (i > 0) { }
    class B : A
        void foo(int i) in (i < 0) { }
    unittest { (new B).foo(5); }

    That is because the in contract of is implicitly || i < 0, ie. i > 0 || i < 0

    With -preview=inclusiveincontracts, this code will now fail with an AssertError. To reach the previous behavior, you would have to write out in (i > 0 || i < 0); that is, you explicitly include the parent's in contract in the child's.

  9. Add __traits(getCppNamespaces, symbol) to retrieve the C++ namespaces a symbol resides in.

    This new trait returns a tuple of strings representing the namespace(s) the symbol resides in. This enables determining what namespaces a given symbol resides in for use in reflection, and can be used directly with an extern(C++) declaration as demonstrated below.

    extern(C++, "ns")
    struct Foo {}
    static assert(__traits(getCppNamespaces, Foo)[0] == "ns");
    struct Bar {}
    static assert(!__traits(getCppNamespaces, Foo).length);
    extern(C++, __traits(getCppNamespaces, Foo)) struct Baz {}
    static assert(__traits(getCppNamespaces, Foo) ==  __traits(getCppNamespaces, Baz));

Library changes

  1. Return the number of characters consumed by std.conv.parse

    By setting the flag doCount to Yes.doCount, the function returns a named tuple. The tuple contains the fields data and count. The field data is of type Target and it contains the result of the original function. The field count is of type size_t and it contains the number of characters consumed. The function is keeping its original behaviour otherwise. Example:

    import std.typecons : Flag, Yes, No;
    string s1 = "123";
    auto a1 = parse!(int, string, Yes.doCount)(s1);
    assert( == 123 && a1.count == 3);

Dub changes

  1. Dub will now automatically exclude mainSourceFile from other configurations

    By default, Dub uses all files it can find under its sourcePaths. However, a common pattern when dealing with multiple targets is to use configurations to represent said targets. In the case those targets are executables, users would be forced to add main files from other configurations to the excludedSourceFiles list, or store the main in a different directory outside of the sourcePaths.

    To simplify this workflow, Dub will now exclude files listed in mainSourceFile for other configuration. In case this is not desirable, the files need to be manually added to the sourceFiles list.

  2. Add support for -betterC compiler flag to the visuald project generator

    If betterC is specified in the buildOptions, visuald project files will also be configured to use betterC.

  3. Caching of generated unittest runner (dub test)

    For projects without a user-defined unittest configuration dub test generates a main file automatically. This main file is now being cached and won't be regenerated won subsequent runs without file changes.

  4. Support for .netrc file added

    Basic authentication credentials defined in .netrc file will now be taken into account while connecting to secured repositories.

List of all bug fixes and enhancements in D 2.095.0:

DMD Compiler regressions

  1. Bugzilla 20608: [REG2.087] Cannot pass tuple.expand to auto ref T... template argument pack
  2. Bugzilla 21282: mixin of AliasSeq "cannot alias an expression"
  3. Bugzilla 21294: [REG 2.095]: DMD fails to link since PR11743
  4. Bugzilla 21312: [REG 2.095] Newly triggered is not an lvalue and cannot be modified
  5. Bugzilla 21325: Flags not set for ?: evaluation with floating point operands
  6. Bugzilla 21328: Forwarding static float array element inside a lambda crashes dmd backend
  7. Bugzilla 21357: [REG2.093] postblit aliases old and new struct pointers
  8. Bugzilla 21364: Improperly aligned struct when one member is a GPR and the other is an XMM

DMD Compiler bugs

  1. Bugzilla 3713: Tail call optimization not enabled with the ?: operator
  2. Bugzilla 8156: Very slow compilation with string-imported file ~100 MiB
  3. Bugzilla 10664: Win64: exception handling does not work with COMDAT folding
  4. Bugzilla 11049: array bounds error uses module file name rather than file name modified by #line directive
  5. Bugzilla 11435: Pushing indirect ref to byte or short can read beyond edge of valid memory
  6. Bugzilla 14708: destructor for temporary not called during stack unwinding
  7. Bugzilla 15909: Duplicate case error reports characters as numbers
  8. Bugzilla 19754: cast() sometimes yields lvalue, sometimes yields rvalue
  9. Bugzilla 19970: [CTFE] 0 ptr is not null
  10. Bugzilla 20195: -preview=nosharedaccess has some access problems
  11. Bugzilla 20604: [ICE] dtoh ICE with nested template structs (and probably most templates
  12. Bugzilla 20714: Struct with postblitting member does not call it's copy constructor
  13. Bugzilla 20716: Wrong code/ABI for extern(C++) interface method that returns non-POD
  14. Bugzilla 20916: hard to find where a deprecation comes from
  15. Bugzilla 20965: Implicitly generated postblit overrides disabled copy ctor
  16. Bugzilla 20970: Test Suite Azure Pipelines Windows_LDC_Debug x64-debug-ldc failed due to heisenbug
  17. Bugzilla 21218: dtoh: protection attributes should be emitted to headers
  18. Bugzilla 21227: import(".\file") doesn't work on Windows
  19. Bugzilla 21234: Import expression can read files outside of -J path in case of symlink/hardlink
  20. Bugzilla 21246: Compiler must show mismatching types when functions do not properly override
  21. Bugzilla 21255: "overload alias ... forward declaration" when overload set of imported template functions is passed to alias template parameter
  22. Bugzilla 21271: C++ header generation ignores extern(D) class methods affecting vtable layout
  23. Bugzilla 21283: [C++] Wrong mangling for ref of parameter pack
  24. Bugzilla 21293: dtoh: segfault when encountering opaque enum
  25. Bugzilla 21299: [LINK] undefined reference to dmd.root.stringtable.StringValue!(Type).StringValue.lstring()
  26. Bugzilla 21300: C++ header generation produce nonsense code on enum with enum as parent
  27. Bugzilla 21320: @live mistakes borrowed pointer for owner in parameter

DMD Compiler enhancements

  1. Bugzilla 8044: Print names, not casted values when using enum template parameter
  2. Bugzilla 21204: Error in generated copy constructor gives confusing message
  3. Bugzilla 21259: struct initialization with deprecated fields should issue deprecation warnings
  4. Bugzilla 21275: Overload resolution bypasses private access
  5. Bugzilla 21340: extern(C++,(emptyTuple)) should result in no namespace not an error

Phobos bugs

  1. Bugzilla 13930: std.concurrency can't send immutable AA to another thread
  2. Bugzilla 15425: std.traits.hasIndirections fails to recognize nested structs
  3. Bugzilla 18789: std.stdio messes up UTF conversions on output
  4. Bugzilla 18801: std.stdio.File doesn't work with MSVCRT's UTF-8 mode
  5. Bugzilla 20924: std.numeric.gcd cannot be used with const BigInt
  6. Bugzilla 21231: Unreachable warning for empty struct in VariantN with preview=fieldwise
  7. Bugzilla 21249: clamp() is not stable and is not constrained
  8. Bugzilla 21253: Can't compile Variant.visit!(...) with generic function
  9. Bugzilla 21296: std.variant.Variant cannot be initialized with immutable AA
  10. Bugzilla 21302: std.uni's documentation contains a dead link to its source file

Phobos enhancements

  1. Bugzilla 6484: compose can't take multi arg functions
  2. Bugzilla 20869: std.algorithm.mutation : move is overly trusting of opPostMove
  3. Bugzilla 20980: std.bigint.BigInt: special case x & non-negative int to avoid unnecessary allocation
  4. Bugzilla 21233: std.conv.parse doesn't report the number of characters consumed
  5. Bugzilla 21237: isLvalueAssignable and isRvalueAssignable should be public
  6. Bugzilla 21347: std.functional.adjoin should work in BetterC
  7. Bugzilla 21407: Make std.math.NaN and std.math.getNaNPayload work in CTFE

Druntime bugs

  1. Bugzilla 14226: invalid Runtime.traceHandler setup

Druntime enhancements

  1. Bugzilla 21030: Reduce template function instantiations related to array equality bugs

  1. Bugzilla 21189: Plain Old Data and copy constructors
  2. Bugzilla 21273: [spec] Inexistent contrast for shell snippets make them unreadable (CSS)

Contributors to this release (50)

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

previous version: 2.094.2