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

Download D 2.108.0
released Apr 01, 2024

2.108.0 comes with 8 major changes and 36 fixed Bugzilla issues. A huge thanks goes to the 36 contributors who made 2.108.0 possible.

List of all bug fixes and enhancements in D 2.108.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.

Dub changes

  1. The fetch command now supports multiple arguments, recursive fetch, and is project-aware

    Previously, dub fetch could only fetch a single package, and was working independently of the working directory.

    With this release, support for multiple packages have been added, such that the following is now possible:

    $ dub fetch [email protected] [email protected] [email protected]
    

    When called with no argument, dub fetch used to error out. However, it will now attempt to fetch dependencies for the current project, if any exists.

    Finally, when fetching a package, it might be useful to fetch all its dependencies. This is done automatically for projects, and can now be done for direct fetch as well:

    $ dub fetch --recursive [email protected] [email protected]
    

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 23786: __traits(parent, {}) in overloaded function produces wierd results dependent on declaration order
  3. Bugzilla 23818: Error HMODULE not defined, please use HMODULE
  4. Bugzilla 24293: ImportC: C preprocessor output should use temporary files
  5. Bugzilla 24309: Memory allocation failed on Azure pipeline
  6. Bugzilla 24359: slice equality expression can be discarded
  7. Bugzilla 24363: hex string postfixes are useless
  8. Bugzilla 24383: Index assignment expression in __traits(compiles) fails to parse
  9. Bugzilla 24387: Base class construction ignores private
  10. Bugzilla 24389: importC: Building zlib in Phobos with importC fails on FreeBSD 14
  11. Bugzilla 24390: AssertError@src/dmd/backend/cgxmm.d(1476): Assertion failure

DMD Compiler enhancements

  1. Bugzilla 3543: [tdpl] ternary operator can't find common type for classes/interfaces
  2. Bugzilla 18919: __FILE__ and __LINE__ should work when used in default argument expressions
  3. Bugzilla 24316: Allow CTFE access to immutable variable through pointer
  4. Bugzilla 24397: Support C preprocessor function-like macros

Phobos bug fixes

  1. Bugzilla 24339: std.mmfile has poor documentation
  2. Bugzilla 24348: Inaccurate documentation for hasSlicing with infinite range
  3. Bugzilla 24384: roundRobin crashes with empty first argument
  4. Bugzilla 24403: Nullable doesn't work with non-mutable types with a destructor
  5. Bugzilla 24458: Mac M3 associative array keys on std.net.curl gets overwritten
  6. Bugzilla 24465: Tuple does not get a copy constructor when its members need it

Phobos enhancements

  1. Bugzilla 24318: Nullable should support non-copyable objects
  2. Bugzilla 24382: std.range.only should have assignable elements

Druntime regression fixes

  1. Bugzilla 24453: [REG2.108] idup fails for inout(T)[] slices

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
  3. Bugzilla 24404: The names of the union fields in Linux's ifaddrs are named incorrectly.
  4. Bugzilla 24405: FreeBSD's ifaddrs missing the ifa_broadaddr field
  5. Bugzilla 24408: AF_INET6 duplicated in core.sys.linux.sys.socket
  6. Bugzilla 24417: core.sys.posix.sys.select: fds_bits named __fds_bits on FreeBSD

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 (36)

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

previous version: 2.107.1