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

previous version: 2.109.1

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.111.0 comes with 30 major changes and 142 fixed Bugzilla issues. A huge thanks goes to the 71 contributors who made 2.111.0 possible.

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

Compiler changes

  1. Keywords auto and ref must be adjacent

    It's now deprecated to declare auto ref parameters without putting those two keywords next to each other. This way it's clear that auto ref semantics are intended, rather than ref and auto semantics separately. For the newly introduced ref local / global variables, it's an error immediately.

    void t()(ref const auto int x) // Deprecation
    {
        ref auto y = x; // Error
    }
    
    // Correction:
    void t()(auto ref const int x)
    {
        auto ref y = x;
    }
    
  2. Copying from const(void)[] to void[] is disallowed with -preview=fixImmutableConv

    If const(void)[] data contains tail const pointers, copying to void[] can subsequently violate const data:

    void f(int*[] a, const int*[] b)
    {
        void[] va = a;
        const void[] vb = b;
        va[] = vb[]; // fills `a` with pointers to const
        *a[0] = 0; // const data mutated
    }
    

    Copying vb data to va is no longer allowed with the -preview=fixImmutableConv switch.

  3. The align attribute now allows to specify default explicitly

    A lone align sets the alignment to the type’s default. Alternatively, to be more explicit, align(default) does the same.

    struct S
    {
        align(4)
        {
            byte x;
            align(default) long y;
            long z;
        }
    }
    
    void main()
    {
        pragma(msg, S.x.alignof); // 4
        pragma(msg, S.y.alignof); // 8
        pragma(msg, S.z.alignof); // 4
    }
    
  4. An error is now given for case fallthough for multivalued cases

    This used to give a deprecation, this now gives an error:

    int i;
    switch (0)
    {
        case 0, 1: i = 20;
        default: assert(0); // Error: switch case fallthrough - use 'goto default;' if intended
    }
    
    switch (0)
    {
        default:
        case 0, 1: i = 20;
        case 2, 3: i = 30; // Error: switch case fallthrough - use 'goto case;' if intended
    }
    
  5. An error is now given for constructors with field destructors with stricter attributes
    struct HasDtor
    {
        ~this() {}
    }
    
    struct Pure
    {
        HasDtor member;
        this(int) pure {} // Error: `this` has stricter attributes than its destructor (`pure`)
    }
    
    struct Nothrow
    {
        HasDtor member;
        this(int) nothrow {} // Error: `this` has stricter attributes than its destructor (`nothrow`)
    }
    
    struct NoGC
    {
        HasDtor member;
        this(int) @nogc {} // Error: `this` has stricter attributes than its destructor (`@nogc`)
    }
    
    struct Safe
    {
        HasDtor member;
        this(int) @safe {} // Error: `this` has stricter attributes than its destructor (`@safe`)
    }
    
  6. An error is now issued for in/out contracts of nothrow functions that may throw

    This used to issue a deprecation, it is now an error:

    void test() nothrow
    in
    {
        throw new Exception(null); // Error: `in` contract may throw but function is marked as `nothrow`
    }
    out
    {
        throw new Exception(null); // Error: `out` contract may throw but function is marked as `nothrow`
    }
    do
    {
    }
    
  7. -preview=fieldwise is now enabled by default

    This fixes a bug that affected some struct comparisons using the == operator. For more information, see the entry for -preview=fieldwise in the 2.085.0 changelog.

    The new -revert=fieldwise switch can be used to disable the bug fix and restore the original behavior of the == operator.

  8. Build time profiling has been added to dmd

    The -ftime-trace switch that the LDC compiler already has, is now also available in dmd. It can be used to figure out which parts of your code take the longest to compile, so you can optimize your build times.

    dmd -ftime-trace app.d
    

    This will output app.o.time-trace.

    A different output file can be selected with -ftime-trace-file=trace.json.

    The output is in Google Chrome's profiler format, which can be viewed in an interactive viewer like ui.perfetto.dev.

    See also this YouTube tutorial: Easily Reduce Build Times by Profiling the D Compiler

  9. Add __traits getBitfieldOffset and getBitfieldWidth

    This completes the introspection capabilities of builtin bitfields. For example:

    struct S
    {
        int a,b;
        int :2, c:3;
    }
    
    static assert(__traits(getBitfieldOffset, S.b) == 0);
    static assert(__traits(getBitfieldOffset, S.c) == 2);
    static assert(__traits(getBitfieldWidth, S.b) == 32);
    static assert(__traits(getBitfieldWidth, S.c) == 3);
    
  10. Using the compiler flag -i will now properly pick up C source files

    Previously you needed to manually include .c source files, it now works just like with .d files

  11. Import expressions are now treated as hex strings

    While Import expressions are typed as string, they are also used to embed binary files. By treating them the same as hex strings, they will implicitly convert to arrays of integral types other than char.

    // Formerly, a cast was required:
    immutable ubyte[] iconImg = cast(immutable ubyte[]) import("icon.png");
    
    // Now, it implicitly converts to integral arrays:
    immutable ubyte[] iconImg = import("icon.png");
    
  12. A pragma for ImportC allows to set nothrow, @nogc or pure

    The following new pragma for ImportC allows to set default storage classes for function declarations:

    #pragma attribute(push, [storage classes...])
    

    The storage classes nothrow, nogc and pure are supported. Unrecognized attributes are ignored. Enabling a default storage class affects all function declarations after the pragma until it is disabled with another pragma. Declarations in includes are also affected. The following example enables @nogc and nothrow for a library:

    #pragma attribute(push, nogc, nothrow)
    #include <somelibrary.h>
    

    The changed storage classes are pushed on a stack. The last change can be undone with the following pragma:

    #pragma attribute(pop)
    

    This can also disable multiple default storage classes at the same time, if they were enabled with a single #pragma attribute(push, ...) directive.

  13. New trait isCOMClass to detect if a type is a COM class

    A COM class inherits from a possibly user defined interface called IUnknown. To detect this during compilation use the trait __traits(isCOMClass, Type). Or for during runtime use the TypeInfo_Class flag.

  14. Mixin templates can now use assignment syntax

    Previously, giving a name to a mixed-in mixin template instance required putting the name at the end. Now, it can also go in front of the instantiation using assignment syntax.

    mixin MyMixinTemplate!(Args) myName; // old style
    mixin myName = MyMixinTemplate!(Args); // new style
    
  15. Objective-C selectors are now automatically generated when not specified with @selector.

    Additionally, the Objective-C selector generation rules have changed, following these steps:

    1. Functions marked with @property will generate setXYZ: for the setters.
    2. For property functions named with a "is" prefix, the is will be stripped off in the setter.
    3. Selector generation now uses the names of the function parameters instead of their D mangled types.

    Selectors may still be specified with the @selector UDA, in which case it takes precedence over the automatically generated selectors.

    These new rules apply both for extern and non-extern objective-c classes and protocols.

    extern(Objective-C)
    extern class NSObject {
        static NSObject alloc(); // Generates as `alloc`
        NSObject init(); // Generates as `init`
    }
    
    extern(Objective-C)
    class Fox : NSObject {
        bool fluffy;
    
        @property bool isFluffy() => fluffy; // `isFluffy`
        @property void isFluffy(bool value) { fluffy = value; } // `setFluffy:`
    
        void yip(int a) @selector("bark:") { // `bark:`
            // ...
        }
    
        void doSomething(int a, int b, int c) { // `doSomething:b:c:`
            // ...
        }
    }
    

    These changes should not break any existing code as the automatic selector generation was not present before. And automatic selector generation only applies to extern(Objective-C) methods.

  16. Add -oq switch to DMD

    The switch gives fully qualified names to object files, preventing name conflicts when using the -od switch while compiling multiple modules with the same name, but inside different packages. The switch already existed in LDC, but is now in dmd as well.

    Example:

    dmd -c -oq -od=. app.d util/app.d misc/app.d
    

    This will output app.obj, util.app.obj, and misc.app.obj, instead of just app.obj.

    -oq also applies to other outputs, such as DDoc (-D -Dd=.) and .di header generation (-H -Hd=.).

  17. Postfix type qualifier method attributes for -H and -D

    .di interface file generation and Ddoc output will now have type qualifier attributes placed after the parameter list for methods (and constructors). This avoids confusion with the return type.

    struct S
    {
        const int f(); // before
        int f() const; // now
    }
    
  18. ref and auto ref can now be applied to local, static, extern, and global variables

    For example, one can now write:

    struct S { int a; }
    
    void main()
    {
        S s;
        ref int r = s.a;
        r = 3;
        assert(s.a == 3);
    
        auto ref x = 0;
        auto ref y = x;
        static assert(!__traits(isRef, x));
        static assert( __traits(isRef, y));
    }
    
  19. Add primary expression of the form __rvalue(expression) which causes expression to be treated as an rvalue, even if it is an lvalue.

    Overloads on ref:

    foo(S s); // selected if `s` is an rvalue
    foo(ref S s); // selected if argument `s` is an lvalue
    
    S s;
    S bar();
    ...
    foo(s); // selects foo(ref S)
    foo(bar()); // selects foo(S)
    

    With this change,

    foo(__rvalue(s)); // selects foo(S)
    

    This also applies to constructors and assignments, meaning move constructors and move assignments are enabled. Moving instead of copying can be much more resource efficient, as, say, a string can be moved rather than copied/deleted.

    A moved object can still be destructed, so take that into account when moving a field - set it to a benign value that can be destructed.

  20. Add -preview=safer switch for safety checking on unattributed functions

    All the checks currently enabled in @safe code, that are easily fixed (as in the fix is constrained to the function), will be enabled in -preview=safer code.

    Code not easily fixed, such as calls to @system or unattributed functions, will be allowed as before.

    void f();
    @system void g();
    
    void main()
    {
        int* p;
        p++; // Error, pointer arithmetic
        f(); // allowed
        g(); // allowed
    }
    

    For more information, see: safer.md

  21. Shortened method syntax can now be used in constructors

    This used to raise an error "cannot return expression from constructor", but it's now supported:

    struct Number
    {
        int x;
    
        void vf(int);
        this(int x) => vf(x);
        this(float x) => this(cast(int) x);
    }
    

    The expression body must be a this/super call or have type void.

    Postblits and destructors already supported shortened method syntax because they return void.

  22. bool values other than 0 or 1 are not @safe

    The spec was updated (for 2.109) so that only 0 and 1 are safe values for bool. This means that reading a bool value whose underlying byte representation has other bits set is implementation-defined and should be avoided. Consequently the following are deprecated in @safe code:

    • void initialization of booleans (since 2.109)
    • Reading a bool field from a union (since 2.109)
    • Runtime casting a dynamic array to a bool dynamic array type
    • Runtime casting a bool dynamic array to a tail mutable dynamic array type
    • Casting a pointer to a bool pointer type
    • Casting a bool pointer to a tail mutable pointer type

Runtime changes

  1. Remove criticalRegionLock

    The criticalRegionLock feature suffer from a serious design flaw: https://issues.dlang.org/show_bug.cgi?id=24741

    It turns out it is not used, so rather than fixing the flaw, the feature was removed.

  2. Adds expect, [un]likely, trap to core.builtins

    Adds the functions expect and likely/unlikely for branch and value hints for the LDC/GDC compilers. DMD ignores these hints.

    Adds trap to lowered to the target dependent trap instruction. If the target does not have a trap instruction, this intrinsic will be lowered to the call of the abort() function.

Library changes

  1. Extend the functionality of formattedRead to permit a std.file.slurp like execution.

    Template argument types can now be passed to formattedRead along with a format string to parse and read the input range as a Tuple of those arguments. All arguments must be read successfully, otherwise, and unlike std.file.slurp which has non exhaustive option for partial reads, it'll throw a std.format.FormatException.

    import std.exception : assertThrown;
    import std.format : FormatException;
    import std.typecons : tuple;
    
    @safe pure unittest
    {
        auto complete = "hello!34.5:124".formattedRead!(string, double, int)("%s!%s:%s");
        assert(complete == tuple("hello", 34.5, 124));
    
        assertThrown!FormatException("hello!34.5:".formattedRead!(string, double, int)("%s!%s:%s"));
    }
    
    /// The format string can be checked at compile-time:
    @safe pure unittest
    {
        auto expected = tuple("hello", 124, 34.5);
        auto result = "hello!124:34.5".formattedRead!("%s!%s:%s", string, int, double);
        assert(result == expected);
    
        assertThrown!FormatException("hello!34.5:".formattedRead!("%s!%s:%s", string, double, int));
    }
    
  2. Added fromHexString and fromHexStringAsRange functions to std.digest.

    This new function enables the converion of a hex string to a range of bytes. Unlike the template std.conv.hexString that was designed to supersede a language feature, this function is usable with runtime input.

    The std.conv module lacks facilities to conveniently transform the input to a series of bytes directly. Both std.conv.parse and std.conv.to can only handle the conversion for a single value of the requested target integer type. Furthermore, said functions would allocate a new buffer for the result, while fromHexStringAsRange operates lazily by implementing a forward range.

    For further convenience, a validation function std.digest.isHexString was added as well.

  3. Added popGrapheme function to std.uni.

    The new function is a cross between the existing std.uni.graphemeStride and std.uni.decodeGrapheme functions. The new function both supports @safe pure nothrow @nogc like graphemeStride does as long as you don't rely on autodecoding (side node: @nogc support for graphemeStride added in this release), and works with any non-array ranges just like decodeGrapheme does.

    Example:

    import std.uni;
    
    // Two Union Jacks of the Great Britain in each
    string s = "\U0001F1EC\U0001F1E7\U0001F1EC\U0001F1E7";
    wstring ws = "\U0001F1EC\U0001F1E7\U0001F1EC\U0001F1E7";
    dstring ds = "\U0001F1EC\U0001F1E7\U0001F1EC\U0001F1E7";
    
    // String pop length in code units, not points.
    assert(s.popGrapheme() == 8);
    assert(ws.popGrapheme() == 4);
    assert(ds.popGrapheme() == 2);
    
    assert(s == "\U0001F1EC\U0001F1E7");
    assert(ws == "\U0001F1EC\U0001F1E7");
    assert(ds == "\U0001F1EC\U0001F1E7");
    
    import std.algorithm.comparison : equal;
    import std.algorithm.iteration : filter;
    
    // Also works for non-random access ranges as long as the
    // character type is 32-bit.
    auto testPiece = "\r\nhello!"d.filter!(x => !x.isAlpha);
    // Windows-style line ending is two code point in a single grapheme.
    assert(testPiece.popGrapheme() == 2);
    assert(testPiece.equal("!"d));
    
  4. Added the SharedAllocatorList, as the thread-safe version of the regular AllocatorList.

    The new std.experimental.allocator.building_blocks.allocator_list.SharedAllocatorList has the same semantics as the regular AllocatorList. Just as the regular AllocatorList, if the BookkeepingAllocator is NullAllocator, the SharedAllocatorList will switch to ouroboros mode, allocationg memory for its own metadata.

    SharedAllocatorList!((n) => SharedAscendingPageAllocator(max(n, numPages * pageSize)), NullAllocator) a;
    auto b = a.allocate(100);
    assert(b.length == 100);
    
    assert(a.deallocate(b));
    
  5. std.uni has been upgraded from Unicode 15.1.0 to 16.0.0

    This Unicode update was released September 10, 2024, and adds new blocks with characters. See: https://www.unicode.org/versions/Unicode16.0.0/

    import std;
    
    void main()
    {
        const alphaCount = iota(0, dchar.max).filter!(std.uni.isAlpha).walkLength;
        writeln(alphaCount);
        // formerly: 138387
        // now:      142759
    }
    

Dub changes

  1. dub.selections.json files are now looked up in parent directories too

    In case the root package directory doesn't contain a dub.selections.json file, dub now looks in parent directories too and potentially uses the first (deepest) one it finds - if and only if that JSON file contains an optional new "inheritable": true flag.

    This allows using a 'central' dub.selections.json file for a repository containing multiple dub projects, making it automatically apply to all builds in that source tree if located in the repository root directory (unless a local dub.selections.json overrides it).

    Such an inherited selections file is never mutated when running dub for a nested project, i.e., changes are always saved to a local dub.selections.json file. E.g., when running dub upgrade for a nested project.


List of all bug fixes and enhancements in D 2.111.0:

DMD Compiler regression fixes

  1. Bugzilla 20562: [dmd] Memory allocation failed (ERROR: This is a compiler bug)
  2. Bugzilla 24431: dmd -vcg-ast crashes printing failed template instantiation
  3. Bugzilla 24599: [REG2.103] Wrongly elided TypeInfo emission leading to undefined symbols at link-time
  4. Bugzilla 24687: [REG2.110] Cannot cast string-imports to select overload anymore
  5. Bugzilla 24699: [REG2.108] No short-circuit evaluation of mixing template bool argument
  6. Bugzilla 24812: [REG 2.106] Incorrect highlighting when diagnosing an empty enum declaration since #15664
  7. Bugzilla 24882: COM class is allocated using GC not malloc

DMD Compiler bug fixes

  1. Bugzilla 10257: .tupleof loses protection information upon iteration
  2. Bugzilla 10386: Package import feature breaks with static libraries
  3. Bugzilla 10587: __traits(getAttributes) doesn't work on incomplete templated types
  4. Bugzilla 10603: Refused pure attribute on the left for function pointer argument
  5. Bugzilla 12885: const union wrongly converts implicitly to mutable
  6. Bugzilla 16643: CTFE internal error with null
  7. Bugzilla 17148: Copying from const(void)[] to void[] breaks immutable
  8. Bugzilla 20587: _rt_loadLibrary symbol not found
  9. Bugzilla 20603: 'cannot use non-constant CTFE pointer in an initializer' in recursive structure with overlap
  10. Bugzilla 20610: const in a .tupleof loop is ignored
  11. Bugzilla 21995: Struct with size uint.max or greater causes ICE
  12. Bugzilla 23131: With -vasm all the X87 instructions are printed wrong.
  13. Bugzilla 23294: [dip1000] parameter to parameter assignment leads to incorrect scope inference
  14. Bugzilla 23722: Lambdas are mangled incorrectly when using multiple compilation units, resulting in incorrect code
  15. Bugzilla 23830: Azure failure for OMF: Module name not printed before struct symbol
  16. Bugzilla 23841: isZeroInit does not take into account unions
  17. Bugzilla 23957: Casting to derived extern(C++) class is unsafe
  18. Bugzilla 24153: Inliner breaks -betterC by requiring TypeInfo
  19. Bugzilla 24337: Segfault when printing an int[] cast from a string literal
  20. Bugzilla 24375: ImportC: .di generator outputs C expression with -> operator
  21. Bugzilla 24447: ImportC: extern symbols cannot have initializers
  22. Bugzilla 24534: Having a label on a declaration makes it possible to skip it with goto
  23. Bugzilla 24558: C asserts segfault on Glibc
  24. Bugzilla 24577: Struct with constructor returned from C++ wrong
  25. Bugzilla 24582: Detect unsafe cast(bool[])
  26. Bugzilla 24583: di generator emits return scope and scope return in wrong order
  27. Bugzilla 24592: ImportC: Bitfield layout wrong for int64 on 32-bit Linux
  28. Bugzilla 24594: ImportC: Packed struct has wrong layout
  29. Bugzilla 24603: Can copy from non-void array into void[] in safe code
  30. Bugzilla 24622: Modify const data with void[] concatenation/append
  31. Bugzilla 24630: Casting a bool pointer to a mutable pointer type is unsafe
  32. Bugzilla 24631: Pointer cast allows changing @system field in @safe code
  33. Bugzilla 24634: Parse error initializing array from expression with StructInitializer
  34. Bugzilla 24651: Bitfield layout wrong for 48-bit field on 32-bit Linux
  35. Bugzilla 24663: dip1000 doesn't check slice expression implicitly converted to static array
  36. Bugzilla 24669: ImportC: C files are not compiled with '-i' flag
  37. Bugzilla 24670: importC: .di generation does not place parentheses around const struct return types
  38. Bugzilla 24694: [DIP1000] can escape stack pointer through struct.class.field
  39. Bugzilla 24701: No error produced from casted noreturn variable
  40. Bugzilla 24705: Arguments of synchronized method are unintentionally treated as shared with -preview=nosharedaccess
  41. Bugzilla 24706: Missing errors for first operand of comma expression
  42. Bugzilla 24707: error message has bad parameter attribute order
  43. Bugzilla 24731: IFTI cannot handle integer expressions
  44. Bugzilla 24733: ImportC: #pragma pack(pop) restores wrong alignment
  45. Bugzilla 24748: DMD can't output object files with fully qualified name, making -od overwirte each other file
  46. Bugzilla 24760: ICE on variadic after default argument
  47. Bugzilla 24762: @nogc false positive error
  48. Bugzilla 24764: ICE when -vcg-ast prints imported invariant
  49. Bugzilla 24776: Struct with anonymous union has wrong isZeroInit
  50. Bugzilla 24790: -vcg-ast ICE on lowered assign exp
  51. Bugzilla 24803: __traits(location) is inconsistent with modules
  52. Bugzilla 24807: Error message missing parens for template instance
  53. Bugzilla 24819: Optimizer changes result of float calculations on 32-bit
  54. Bugzilla 24822: When passing a non-POD argument to an rvalue parameter, an unnecessary blit is done
  55. Bugzilla 24830: separate compilation + circular deps + templated opCmp = missing symbols
  56. Bugzilla 24832: Segfault in hex string
  57. Bugzilla 24836: struct return by hidden struct arg does not need copy to become an rvalue
  58. Bugzilla 24845: Compiler error when trying to assign to an AA value of an enum instance
  59. Bugzilla 24848: bad parser diagnostic for a partial MulExp
  60. Bugzilla 24855: VRP fails to prevent overflow after division
  61. Bugzilla 24861: Vestige of 16 bit code being accidentally generated
  62. Bugzilla 24871: DDoc strips indent in triple slash comments
  63. Bugzilla 24883: Speculative template overload error escapes with -preview=rvaluerefparam
  64. Bugzilla 24884: backend generates wrong 32-bit code after inlining math with double[4]
  65. Bugzilla 24891: Two scope attributes emitted as part of .di generation

DMD Compiler enhancements

  1. Bugzilla 9997: Missed misspell suggestions for UFCS
  2. Bugzilla 18235: Group logically similar tests into the same module in the D2 testsuite
  3. Bugzilla 20243: inout not substituted for in associative array key type
  4. Bugzilla 20614: CTFE supports typeid(stuff).name but not classinfo.name
  5. Bugzilla 21564: Allow assignment syntax for instantiating mixin templates
  6. Bugzilla 23449: spellchecker should suggest corrections for pointer members
  7. Bugzilla 23812: ImportC: allow adding function attributes to imported C functions
  8. Bugzilla 24135: Eponymous template member overloads not shown as call candidates
  9. Bugzilla 24580: ImportC: Asm label after attributes results in syntax error
  10. Bugzilla 24598: OpenBSD: adapt compiler tests
  11. Bugzilla 24623: Rename version CppRuntime_Clang/Gcc to CppRuntime_libcxx/libstdcxx.
  12. Bugzilla 24639: ImportC: defines of negative constants not detected for enum conversion
  13. Bugzilla 24645: Hidden static assert error messages if more than 20 errors
  14. Bugzilla 24738: Import core.interpolation suggestion
  15. Bugzilla 24745: Better error message when creating an associative array with the wrong syntax
  16. Bugzilla 24749: A clause consisting only of "throw" should be the unlikely path
  17. Bugzilla 24841: UTF-16 surrogates when used as an escape of a string should hint on error

Phobos regression fixes

  1. Bugzilla 23487: std.experimental.logger assigning FileLogger to sharedLog no longer works
  2. Bugzilla 24637: [REG 2.104] Cannot insert const/immutable elements into DList
  3. Bugzilla 24686: SumType stopped working on LDC 1.37 with unmatched DeducedParameterType template

Phobos bug fixes

  1. Bugzilla 10581: Undefined identifier "std.uni.isWhite" when passing string lambda to std.algorithm.filter
  2. Bugzilla 14138: std.parallelism.task breaks @safety
  3. Bugzilla 15315: can break immutable with std.algorithm.move
  4. Bugzilla 20870: std.outbuffer.printf is trusted
  5. Bugzilla 20872: std.array.assocArray trusts user-provided 'front' for values
  6. Bugzilla 23300: std.array : array wrongly propagates scopeness of source
  7. Bugzilla 24564: std.file.DirEntry throws Exception instead of FileException
  8. Bugzilla 24667: goo.gl is going away
  9. Bugzilla 24685: std.stdio.File.rawRead allows reading raw pointers from files in @safe code
  10. Bugzilla 24704: The error message for DateTime.fromISOExtString says that valid ISO extended strings that it does not support are invalid ISO extended strings
  11. Bugzilla 24715: std/process: Default to libc closefrom in spawnProcessPosix
  12. Bugzilla 24773: Stable sort() invokes the destructor on uninitialized elements
  13. Bugzilla 24801: RefRange doesn’t work if range primitives are not const
  14. Bugzilla 24809: In some cases, stable sort assigns to unininitialized elements
  15. Bugzilla 24824: std.process.browse returns on failure in forked child
  16. Bugzilla 24827: maxElement does not correctly handle types with opAssign

Phobos enhancements

  1. Bugzilla 17214: std.array.Appender has an unnecessary indirection
  2. Bugzilla 17479: Public constructor for std.process.Pid
  3. Bugzilla 22293: Nullable should define opCast!bool
  4. Bugzilla 24524: Very slow process fork if RLIMIT_NOFILE is too high
  5. Bugzilla 24698: Appender needs to expose readonly property 'size_t length' without using 'data' property
  6. Bugzilla 24823: std.json: Allow optionally preserving the order of fields in JSON objects
  7. Bugzilla 24851: Some members of CustomFloat can have const this
  8. Bugzilla 24875: std.traits.isAggregateType does not consider enums of aggregate types to be aggregate types

Druntime bug fixes

  1. Bugzilla 10380: [AA] Wrong code using associative array as key type in associative array
  2. Bugzilla 24579: stat_t has wrong size for Android armv7a
  3. Bugzilla 24626: hasUDA does not handle multiple UDAs of the same symbol
  4. Bugzilla 24660: atomic_wchar_t has wrong size on Posix
  5. Bugzilla 24661: wctype_t and wctrans_t are platform-dependent
  6. Bugzilla 24835: hasElaborateAssign is true for structs where opAssign is disabled if a member variable has elaborate assignment
  7. Bugzilla 24846: atomicLoad does not work for class arguments with -preview=nosharedaccess
  8. Bugzilla 24864: hasElaborateDestructor incorrectly true for structs with anonymous unions
  9. Bugzilla 24872: Assigning non-copyable value to array has no effect

Druntime enhancements

  1. Bugzilla 17416: SocketOption.REUSEPORT not available on linux
  2. Bugzilla 19369: core.sys.posix.setjmp lacks support for Darwin
  3. Bugzilla 20567: GC should not start threads for parallel marking in simple programs
  4. Bugzilla 24590: Illegal instruction with module constructors cycle and shared libphobos2 in _d_criticalenter2

dlang.org bug fixes

  1. Bugzilla 14945: unions are missing from the ABI page
  2. Bugzilla 20601: [Oh No! Page Not Found]
  3. Bugzilla 24543: The @__future attribute is (almost) undocumented
  4. Bugzilla 24548: [spec] Boolean condition conversion is not documented
  5. Bugzilla 24565: out contract variable is implicitly const
  6. Bugzilla 24680: [dip1000] final auto class method infers scope but no return
  7. Bugzilla 24732: FAQ article is out of date on calling printf

dlang.org enhancements

  1. Bugzilla 19348: Struct casts should be better documented.
  2. Bugzilla 24659: Memory safe D page lacks information on return ref
  3. Bugzilla 24868: Undocumented cast from struct to static array
  4. Bugzilla 24876: Undocumented cast from slice to static array
  5. Bugzilla 24890: spec/arrays.dd should mention comparison and warn about dangling .ptr

Installer bug fixes

  1. Bugzilla 24600: DMD nightly builds are outdated

Contributors to this release (71)

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

previous version: 2.109.1