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

previous version: 2.108.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.109.0 comes with 7 major changes and 5 fixed Bugzilla issues. A huge thanks goes to the 22 contributors who made 2.109.0 possible.

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

Compiler changes

  1. Added .nameSig field to TypeInfo_Class in object.d

    This is a 16 byte md5 signature of the fully qualified name of the class. It is used to compare two classes for equality, rather than comparing the pointers with a fallback to doing a string compare on the name, which can be rather slow.

    The result is both druntime and phobos will need to be recompiled to be compatible with this change. Any libraries will need to be recompiled as well.

  2. Keywords like __FILE__ are always evaluated at the call site

    Default arguments for functions can contain the keywords __FILE__, __FILE_FULL_PATH__, __MODULE__, __LINE__, __FUNCTION__ and __PRETTY_FUNCTION__. They are now evaluated at the source location of the calling function in more complex expressions as long as used in an initializer, directly or not. Previously they had to be used directly in the initializer to be evaluated at the call site. Here are some examples, where more complex initializers are now evaluated at the call site:

    void func1(const(char)* file = __FILE__.ptr, size_t line = __LINE__)
    {
        // This now prints the filename of the calling function.
        // Previously it was the filename of func1 itself.
        printf("%s:%zd\n", file, line);
    }
    
    struct Loc
    {
       string file;
       size_t line;
    }
    
    void func2(Loc loc = Loc(__FILE__, __LINE__))
    {
        // Variable loc now contains file and line of the calling function.
        // Previously it was the location of func2.
        writeln(loc.file, ":", loc.line);
    }
    
    Loc defaultLoc(string file = __FILE__, size_t line = __LINE__)
    {
        return Loc(file, line);
    }
    
    void func3(Loc loc = defaultLoc)
    {
        // Variable loc contains file and line of the calling function of
        // func3 and not the location of func3 or defaultLoc.
        writeln(loc.file, ":", loc.line);
    }
    
  3. Hex strings now convert to integer arrays

    Hex strings are the most efficient way to embed binary data into source files. However, they couldn't easily be used to initialize a short[], int[] or long[] because re-interpret casting arrays is not allowed during CTFE. Now, hex strings implicitly convert to all integer arrays. A big endian byte order is assumed, consistent with how integer literals are written.

    immutable uint[] data = x"AABBCCDD";
    
    static assert(data[0] == 0xAABBCCDD);
    

    Character postfixes can now also be used to explicitly set an element size of 2 or 4.

    immutable ushort[] f = x"80 3F"w;
    static assert(f[0] == 0x803F);
    
    immutable ubyte[] g = x"80 35"w; // error: size mismatch
    

    Formerly, they would pad each byte with 1 or 3 zeros, which did not serve a purpose (See Issue 24363).

    If the string's byte length is not a multiple of the target element size, it is an error:

    immutable ushort[] e = x"AABBCC"w; // Error, 3 bytes is not a multiple of `ushort.sizeof`
    
  4. Add support for Interpolated Expression Sequences

    Interpolated Expression Sequences are a way to implement things like string interpolation in library code. Three forms of literals are added:

    i"Content $(a + 4)"
    i`Content $(a + 4)`
    iq{Content $(a + 4)}
    

    all provide the same thing: a tuple that can be passed to other functions, like writeln from std.stdio and text from std.conv:

    int a = 6;
    writeln(i"Content $(a + 4)"); // prints "Content 10"
    

    You can also pass them to other functions which understand the types in the new core.interpolation module. Numerous examples can be found documentation of that module or in this repository: https://github.com/adamdruppe/interpolation-examples/

  5. Named arguments for functions have been implemented and documented

    When calling a function, arguments may be preceded with a parameter name for purposes of clarity and flexible ordering. Consequently, default arguments need not be at the end of the parameter list anymore.

    void createWindow(bool fullScreen = false, int width, int height, string title);
    
    void main()
    {
        createWindow(title: "Skynet", width: 1280, height: 720);
    }
    

    Named arguments can also be used in struct/union literals. A union can now be initialized by setting a field different than the first one.

    union U
    {
        float asFloat;
        uint asInt;
    }
    
    auto u0 = U(1.0); // this sets the `asFloat` field
    auto u1 = U(asInt: 0x3F800000); // formerly not possible
    

    Relevant specification pages are:

    Note that the implementation for regular functions and struct literals has been around since dmd 2.103, but it was undocumented and wouldn't work with template functions.

    This implements DIP1030 for function arguments, but named template arguments are not implemented yet. Also, there are still implementation details to be ironed out which the DIP doesn't specify, such as how named arguments interact with tuples. For more information, see: Named Arguments Status Update

Library changes

  1. isForwardRange, isBidirectionalRange, and isRandomAccessRange now take an optional element type

    In Phobos 2.106, an optional second template parameter was added to isInputRange to enable conveniently checking a range's element type. Now, the same parameter has been added to isForwardRange, isBidirectionalRange, and isRandomAccessRange.

    As before, if a second type argument is passed to one of these templates, the range's element type is checked to see if it is qualifier-convertible to the given type, and this additional check must pass in order for the template to evaluate to true.

    Examples:

    // exact match
    static assert( isForwardRange!(int[], int));
    
    // match with qualifier conversion
    static assert( isBidirectionalRange!(int[], const(int));
    
    // not a match
    static assert(!isRandomAccessRange!(int[], string));
    
  2. std.uni has been upgraded from Unicode 15.0.0 to 15.1.0

    This Unicode update was released September 12, 2023. See: https://www.unicode.org/versions/Unicode15.1.0/

    import std;
    
    void main()
    {
        const alphaCount = iota(0, dchar.max).filter!(std.uni.isAlpha).walkLength;
        writeln(alphaCount);
        // formerly: 137765
        // now:      138387
        // 622 new dchars return true for `isAlpha`
    }
    

    The internal unicode tables (std/internal/unicode_tables.d) have also been changed to use hex strings instead of array literals, which makes them faster to import. The exact speed up depends on your computer and D compiler, but it likely cuts between 30 and 100 milliseconds if you compile something which imports std.string or std.uni.


List of all bug fixes and enhancements in D 2.109.0:

DMD Compiler enhancements

  1. Bugzilla 21718: Preview switches have insufficient descriptions
  2. Bugzilla 24111: [ImportC] fatal error C1034: stdio.h: no include path set
  3. Bugzilla 24450: apply VRP to foreach indices when array is of known length
  4. Bugzilla 24452: Can't disable coverage at runtime

Phobos bug fixes

  1. Bugzilla 15708: std.range.choose assumes hasElaborateCopyConstructor means "has __postblit"

Contributors to this release (22)

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

previous version: 2.108.0