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

previous version: 2.102.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.103.0 comes with 13 major changes and 95 fixed Bugzilla issues. A huge thanks goes to the 47 contributors who made 2.103.0 possible.

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

Compiler changes

  1. A missed case of conflicting extern (D) @system function definitions has been deprecated

    Having multiple definitions of functions within a module had been turned into an error in DMD 2.095.0.

    However, the compiler would not issue an error when two implementations differed by an explicit and inferred @system attribute, although they have the same mangling.

    void foo() {}
    void foo() @system {} // no error
    

    This bug has been fixed, and DMD will now issue a deprecation if there are such conflicting @system function implementations. Starting from DMD 2.112, it will produce a multiple definition error just like other kinds of conflicting functions within a module.

  2. Deprecate the ability to call __traits(getAttributes) on overload sets

    Up until this release, __traits(getAttributes) could be called both on individual functions and on overload sets. However, in the latter case, the compiler simply collected the user defined attributes for the first lexically defined function. This behavior is error prone. Consider:

    module test;
    
    @("gigi")
    void fun() {}
    @("mimi")
    void fun(int) {}
    
    void main()
    {
        static foreach(attr; __traits(getAttributes, fun))
            pragma(msg, attr);
    

    The above code will print "gigi" although there is no indication on what overload is actually queried. The first one is always picked.

    Starting with this release, this sort of usage of __traits(getAttributes) is deprecated. If a specific overload needs to be handled, __traits(getOverloads) may be used in conjunction with __traits(getAttributes) for proper behavior:

    module test;
    
    @("gigi")
    void fun() {}
    @("mimi")
    void fun(int) {}
    
    void main()
    {
        static foreach (t; __traits(getOverloads, test, "fun"))
            static foreach(attr; __traits(getAttributes, t))
                pragma(msg, attr);
    

    The above code prints:

    gigi
    mimi
    
  3. Deprecate non-empty for statement Increment clause with no effect

    The last clause of a for statement should not produce a value without also having some meaningful side-effect. This is now detected with a deprecation message. The following for statements each trigger the deprecation:

    // evaluating `j` has no side-effects
    int j;
    for (;; j) {...}
    
    // unnecessary dereference
    for (ubyte* sp;; *sp++) {...}
    
    // first clause is a block statement
    // last clause is a function literal, not a block statement
    for({j = 2; int d = 3;} j + d < 7; {j++; d++;}) {...}
    

    Note: Calling a function returning void is not deprecated even if the function does nothing. This is for generic code.

  4. Array literals assigned to scope array variables can now be allocated on the stack

    Formerly, they were always allocated with the Garbage Collector, making it unavailable in @nogc or -betterC code. This led to frequent use of the following workaround:

    void main() @nogc
    {
        int[3] buffer = [10, 20, 30];
        int[] arr = buffer[];
    }
    

    This can now be written in a single line:

    void main() @nogc
    {
        scope int[] arr = [10, 20, 30];
    }
    

    With the following limitations:

    • The variable must be explicitly annotated scope, not just inferred scope
    • The -preview=dip1000 must be passed, to prevent introducing memory corruption in legacy code.
    Note that in @system and @trusted code, the compiler doesn't verify that your scope variable doesn't escape.
    • The array literal must be initializing the variable. Subsequent array literals assignments still use the GC.
    • The array elements may not have a destructor

    Some of these limitations might get lifted in the future.

  5. static assert now supports multiple message arguments

    When the condition evaluates to false, any subsequent expressions will each be converted to string and then concatenated. The resulting string will be printed out along with the error diagnostic.

    enum e = 3;
    static assert(false, "a = ", e);
    

    Will print:

    file.d(2): Error: static assert:  a = 3
    

  6. -preview=systemVariables has been added

    Since DIP 1035 - System Variables has been accepted, variables marked @system may no longer be accessed from @safe code. To avoid code breakage, the compiler will start with emitting deprecation warnings. The preview switch will turn these into errors, and it will be enabled by default in a future release.

    @system int* p;
    
    struct S
    {
        @system int i;
    }
    
    void main() @safe
    {
        int x = *p; // error with `-preview=systemVariables`, deprecation otherwise
    
        S s;
        s.i = 0; // ditto
    }
    

    Note that currently this is limited to variables explicitly marked @system, inference of @system based on a variable's initializer is yet to be implemented.

Runtime changes

  1. The default Throwable.TraceInfo generation now is @nogc.

    The way this works:

    1. The runtime now has 2 trace-related functions, one for allocating a traceinfo, and one for deallocating the traceinfo. Both are set via the same Runtime.traceHandler function. The second parameter that sets the deallocation function is optional (so existing code will not be affected).
    2. When a Throwable is thrown, if the trace info is not yet set, the runtime uses the designated function to allocate a trace info. If the deallocation function is non-null, the function pointer is copied into the Throwable, into the new member infoDeallocator.
    3. When the Throwable is destroyed, if the infoDeallocator member is set, it is called on the info member.

    The default allocator and deallocator now uses C malloc and free to allocate and deallocate the TraceInfo. Almost everything was already nogc, except for the allocation of the TraceInfo object itself.

    The benefits:

    1. Stack traces can now be generated when run inside the GC collection routine.
    2. InvalidMemoryOperationError now has a stack trace.
    3. Little known is that even inside @nogc functions, throwing a Throwable actually was using the GC, that is no longer the case (by default).
    4. Certain GC hangs have been fixed (see bug fixes listed below).

    One possible drawback is that the TraceInfo is deallocated upon Throwable being finalized, leading to a potential dangling pointer situation. If you do copy the info out of the Throwable, makes sure to not keep it beyond the lifetime of the Throwable, or make sure to set the infoDeallocator member to null.

Library changes

  1. Single- and double-precision implementations for log function families

    New float and double overloads of std.math.exponential.log, std.math.exponential.log10, std.math.exponential.log1p, std.math.exponential.log2, and std.math.exponential.logb have been added to Phobos with proper 'software' implementations in the corresponding precision. Furthermore, std.math.exponential.logb is now pure.

    While this may result in a slowdown in some cases for DMD, the overall speed-up factor for GDC and LDC is over 3x, for both double and float.

    This also implies less precise results, especially in single-precision, so if your code depended on more accurate results via 80-bit intermediate precision, you'll have to cast the argument(s) explicitly now.

  2. The Unicode property "C" aka "Other" has had the wrong properties associated with it.

    If you use unicode.c or unicode.Other (case insensitive) from std.uni, you should mitigate or fix your codebase.

    This change makes it match the Unicode Techical Report #44. Unfortunately if you are already using it with its previous wrong values, this will break your code, below is a function which reflects the original values that you can use to mitigate against any breakage.

    @property auto loadPropertyOriginal(string name)() pure
    {
        import std.uni : unicode;
    
        static if (name == "C" || name == "c" || name == "other" || name == "Other")
        {
            auto target = unicode.Co;
            target |= unicode.Lo;
            target |= unicode.No;
            target |= unicode.So;
            target |= unicode.Po;
            return target;
        }
        else
            return unicode.opDispatch!name;
    }
    
  3. Unicode table generator is now in Phobos, tables are updated to version 15.

    It is likely that this change will result in breakage in code and program usage. This is due to a number of factors, the tables being updated so significantly and the table generator not having all its changes commited throughout the years.

  4. std.typecons.Unique now calls destroy on struct types

    When Unique goes out of scope, any destructor will now be called. Previously the destructor was not called then.

    static int i;
    
    struct S
    {
        ~this()
        {
            i++;
        }
    }
    {
        Unique!S u = new S;
        // S.~this now called here
    }
    assert(i == 1);
    

    Note: Above, the struct destructor will also be called by the GC just before the memory for new S is reclaimed. Take care that any struct destructor used will handle being called again on the struct .init value.

Installer changes

  1. Update the bundled VisualD package

    The VisualD package version that the installer downloads hasn't been updated in years. This has been remedied by a version bump to 1.3.1, the latest release of VisualD.

  2. Prefer 64 bit over 32 bit DMD on Windows 64 bit.

    The NSIS installer for Windows has the option "Add to PATH". Previously, only the 32 bit version of DMD was added to the PATH environment variable. Now, on Windows 64 bit, the 64 bit version of DMD will be selected from PATH.


List of all bug fixes and enhancements in D 2.103.0:

DMD Compiler regression fixes

  1. Bugzilla 15985: [REG2.068/2.069] Code doesn't link unless compiled with -debug
  2. Bugzilla 18472: [Reg 2.078] betterC: cannot use format at compile time.
  3. Bugzilla 21772: [REG2.069] Consecutive different-signed double.nans in an array literal take the sign of the previous nan (same for float and real)
  4. Bugzilla 22039: ICE on infinite recursion in default parameter
  5. Bugzilla 23674: incompatible types for array comparison: string and string
  6. Bugzilla 23688: FTBFS: error: cannot convert 'Expression' to 'Expression*'
  7. Bugzilla 23710: [REG master] Reachable code inside an 'if (false)' block no longer gets codegen
  8. Bugzilla 23732: Cannot create shared instance of class with -preview=nosharedaccess
  9. Bugzilla 23745: Segfault with forward reference mismatched override with undeclared type
  10. Bugzilla 23758: [REG 2.103] Segfault accessing NewExp::argprefix from C++
  11. Bugzilla 23799: Link error with -betterC

DMD Compiler bug fixes

  1. Bugzilla 10886: Typeof on @property function triggers 'wrong this' type error
  2. Bugzilla 11051: Unmatched case in a final switch should throw in both release and non-release mode
  3. Bugzilla 16098: align(N) not respected for stack variables if N > platform stack alignment
  4. Bugzilla 16213: CTFE internal error with static array $ as template argument
  5. Bugzilla 20781: Can call @live function without checking dip1021 rules
  6. Bugzilla 20908: -preview=nosharedaccess requires zero-initializion for aggregates
  7. Bugzilla 21288: Wrong context pointer for alias this function
  8. Bugzilla 21492: betterC: TypeInfo is generated for code guarded by if(__ctfe)
  9. Bugzilla 21821: Optimizer assumes immutables do not change, but they can in @system code
  10. Bugzilla 22916: [dip1000] copy of ref return still treated as scope variable
  11. Bugzilla 23145: Stack allocation of scope new variables defeats @safe
  12. Bugzilla 23195: Win64 function ABI bug for small non-POD arguments
  13. Bugzilla 23261: druntime core.std.attribute.Tagged1_2 constructor is unsafe
  14. Bugzilla 23387: ImportC: identical structs defined in two C files lead to duplicate .init symbol on macOS
  15. Bugzilla 23407: ImportC: function-local struct definition as part of variable declaration doesn’t shadow global definition
  16. Bugzilla 23514: Incorrect compilation when adding a 64-bit constant to a link-time address
  17. Bugzilla 23545: export int a; should generate dllexport, not dllimport
  18. Bugzilla 23583: ImportC: undefined identifier __builtin___memmove_chk
  19. Bugzilla 23584: ImportC: __builtin_bit_cast not supported
  20. Bugzilla 23598: Circular reference bug with static if and eponymous templates
  21. Bugzilla 23606: betterC with CTFE and gc
  22. Bugzilla 23616: ImportC: clang __has_feature and __has_extension not recognized
  23. Bugzilla 23617: traits(child) compile error need this for something that doesn't need this
  24. Bugzilla 23622: ImportC #defines conflict with declarations
  25. Bugzilla 23635: Nonsensical "case must be a string or an integral constant, not x"
  26. Bugzilla 23639: Casting to shared not allowed with -preview=nosharedaccess
  27. Bugzilla 23648: Replace all sprintf with snprintf
  28. Bugzilla 23650: Using typeid with struct defined in in __traits(compiles, ...) causes linker error
  29. Bugzilla 23651: Order dependency in semantic analysis of template members
  30. Bugzilla 23658: .di generation of variables should turn them into declarations
  31. Bugzilla 23662: ImportC bad handling of enum arguments for a function
  32. Bugzilla 23669: [DIP1000] Compound assignment to length of slice member variable in scope method fails
  33. Bugzilla 23672: importC: Infinite recursion: Error: found 'End of File' when expecting ','
  34. Bugzilla 23676: Static foreach hangs compilation for some time
  35. Bugzilla 23679: off-by-one error for static array size limit
  36. Bugzilla 23682: dip1000 problem with return by ref
  37. Bugzilla 23694: compilable/ctests2.c:51:9: error: initializer element is not constant
  38. Bugzilla 23705: dmd: src/dmd/backend/cgcod.d:734: Assertion `sz >= 0' failed.
  39. Bugzilla 23711: compilable/testcstuff1.c:63:1: error: invalid use of restrict
  40. Bugzilla 23717: runnable/bitfields.c:192:5: error: unknown type name S; use struct keyword to refer to the type
  41. Bugzilla 23743: wrong code with foreach, ubyte, >=, ternary operator
  42. Bugzilla 23752: ImportC: can't take address of dereferenced void pointer
  43. Bugzilla 23760: Error: unknown
  44. Bugzilla 23763: ICE on operations involving zero-initialized structs
  45. Bugzilla 23767: ImportC: ternary with null constant has wrong pointer type
  46. Bugzilla 23778: Code generator fails to handle __c_complex_real properly for Windows
  47. Bugzilla 23781: [ICE] Segmentation Fault when taking the address of a ref return at CTFE
  48. Bugzilla 23783: -preview=nosharedaccess does not detect comparison of shared data
  49. Bugzilla 23790: Cannot use cas on member variable with -preview=nosharedaccess
  50. Bugzilla 23792: lexer warns about preprocessor inside token strings

DMD Compiler enhancements

  1. Bugzilla 11316: Some cases of missing delegate argument type inference
  2. Bugzilla 13656: clarify error message upon trying to declare a variable of type ref
  3. Bugzilla 16495: __traits(fullyQualifedName) instead of std.traits.fullyQualifiedName
  4. Bugzilla 20101: BetterC: Template instantiation in CTFE only context should skip codegen / nogc / ... Phases
  5. Bugzilla 23558: add __traits(getModuleClasses [, module name])
  6. Bugzilla 23597: .di files not compatible with -i

Phobos regression fixes

  1. Bugzilla 23776: getSymbolsByUDA fails to fetch symbols from module

Phobos bug fixes

  1. Bugzilla 23474: Grapheme should end after carriage return if not followed by line feed.
  2. Bugzilla 23600: [std.format.read] formattedRead static asserts with Tuple and compile time format string
  3. Bugzilla 23668: Can't stable sort structs with disabled default constructor.
  4. Bugzilla 23724: HTTP.onReceive example does not compile
  5. Bugzilla 23750: log1p for floats/doubles not actually providing extra accuracy

Phobos enhancements

  1. Bugzilla 19567: [std.stdio] Not really helpful documentation of tell
  2. Bugzilla 20397: [std.algorithm] documentation nthPermutation
  3. Bugzilla 23683: std.file.setTimes requests more permissions than needed
  4. Bugzilla 23706: Do not escape POSIX shell parameters unless necessary

Druntime regression fixes

  1. Bugzilla 23608: [musl 32-bit] Time functions linked incorrectly on musl >=1.2.0 / 32-bit

Druntime bug fixes

  1. Bugzilla 19575: core.cpuid not usable without a runtime
  2. Bugzilla 23625: Function ZeroMemory missing in windows headers

dlang.org bug fixes

  1. Bugzilla 6583: cast() operation not fully specified
  2. Bugzilla 11493: dlang.org/type.html incorrectly says that you can't cast from -1 to unsigned types
  3. Bugzilla 16707: [Templates] run variadic templates example failed
  4. Bugzilla 21132: Ff two keys in an associative array literal are equal
  5. Bugzilla 21178: It is not explained what is "unknown"
  6. Bugzilla 23716: ImportC: Missing documentation on the asm keyword accepted as an extension

dlang.org enhancements

  1. Bugzilla 18765: [Arrays] Docs need info on initialization of static array with element literal
  2. Bugzilla 20997: Missing example of scope guard executing after return statement
  3. Bugzilla 22418: Error in documentation on strings
  4. Bugzilla 22594: Update "Interfacing to C" to include intptr_t and uintptr_t
  5. Bugzilla 23612: Template constraints article not listed in article index
  6. Bugzilla 23636: No spec docs for shared qualifer
  7. Bugzilla 23730: Clarify IsExpression Identifier : and == TypeCtor spec

Tools bug fixes

  1. Bugzilla 23624: Race condition in test runner for DMD
  2. Bugzilla 23634: Possible data race with runnable example tester

Contributors to this release (47)

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

previous version: 2.102.0