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:

previous version: 2.080.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


comes with 19 major changes and 30 fixed Bugzilla issue{bugzillaIssuesPluaral}. A huge thanks goes to the 33 contributor{nrControbutorsPlural} who made possible.

List of all upcoming bug fixes and enhancements in D .

Compiler changes

  1. Deprecate conditional expression followed by an assign expression

    When a conditional expression is the left operand of an assign expression, they would be parsed as an assignment to the result of the conditional. This has now been deprecated. To preserve the existing behaviour, add parentheses for the conditional without including the assignment:

    bool test;
    int a, b, c;
    ...
    test ? a = b : c = 2;   // Deprecated
    (test ? a = b : c) = 2; // Equivalent
    

    This makes the intent clearer, because the first statement can easily be misread as the following code:

    test ? a = b : (c = 2);
    
  2. Unsafe code can now be used in debug blocks

    When writing debug code, one isn't interested in the type safety, but a pleasant debugging experience. The type checker already allowed to escape pure and @nogc within debug statement. With this release, @system code can be called from debug statements too:

    void main()
    {
        int[] arr = [1, 2];
        debug unsafeCode(arr);
    }
    
    @system void unsafeCode(T)(T[] arr)
    {
        import core.stdc.stdio;
        printf("arr.ptr: %p", arr.ptr);
    }
    
  3. Deprecatie usage of opDot

    opDot was the D1 analog to alias this. However, alias this covers all use cases of opDot, but ensures safety.

    struct S
    {
        int a, b;
    }
    struct T
    {
        S s;
    
        S* opDot()
        {
            return &s;
        }
    }
    
    void main()
    {
        T t;
        t.a = 4;
        assert(t.a == 4);
        t.b = 5;
    }
    

    With alias this:

    struct S
    {
        int a, b;
    }
    struct T
    {
        S s;
    
        alias s this;
    }
    
    void main() @safe
    {
        T t;
        t.a = 4;
        assert(t.a == 4);
        t.b = 5;
    }
    
  4. D now supports deprecated, @disable and user-defined attributes on enum members

    Example

    template AliasSeq(TList...)
    {
        alias AliasSeq = TList;
    }
    
    enum MyEnum
    {
        @("uda0") value0,
        @disable value1,
        deprecated value2  // Deprecation: enum member `main.MyEnum.value2` is deprecated
    }
    
    static assert(__traits(getAttributes, MyEnum.value0) == AliasSeq!("uda0"));
    
    void main()
    {
        auto v1 = MyEnum.value1;  // Error: enum member `main.MyEnum.value1` cannot be used because it is annotated with `@disable`
    }
    
  5. Deprecated C-style array declarations will now result in a compilation error

    The deprecation period for C-style array declarations has expired. Beginning with this release, declaring arrays with C-style syntax will result in an error.

    int a[2];  // Error: instead of C-style syntax, use D-style `int a[2]`
    int[2] b;  // OK
    
  6. Mangling of extern(C++) template on Windows now correctly mangles const non-pointer template parameters.

    It used to ignore the const and was missing the $$C escape prefix.

    extern(C++) struct foo(T) {}
    
    extern(C++) void test(foo!(const(char)) a) {}
    // New
    static assert(test.mangleof == "?test@@YAXU?$foo@$$CBD@@@Z");
    // Old
    //static assert(test.mangleof == "?test@@YAXU?$foo@D@@@Z");
    
  7. 64-bit OS X: Revert C++ mangling of long to pre-2.079 to restore size_t interop

    Direct interop of D size_t and C++ size_t was working before 2.079, on all platforms except for 32-bit OS X. By mangling D long as C++ long long on 64-bit OS X starting with 2.079, size_t interop broke on a more relevant platform. With new/fixed aliases, e.g., core.stdc.stdint.int64_t, core.stdc.stdint.uint64_t and core.stdc.config.cpp_size_t, there are now proper tools for portable C++ interop wrt. integers. Reverting to the previous C++ mangling on 64-bit OS X (C++ long) may save mixed D/C++ code bases from the need of manual adaptations by skipping the 2.079 and 2.080 DMD versions.

  8. UDAs on function arguments are now supported

    User-defined attributes on function arguments behave analogous to existing UDAs:

    void test(A)(@(22) A a)
    {
        static assert([__traits(getAttributes, a)] == [22]);
    }
    

Runtime changes

  1. Filenames and line numbers have been added to stacktraces on macOS

    When an exception is throw and not caught, a stacktrace is printed. On Linux, FreeBSD and DragonFlyBSD this stacktrace includes the filenames and line numbers, if the application was built with debug info enabled. This feature has now been added to macOS.

    This requires support from the compiler since debug info is stripped by the linker on macOS.

    Example:

    void bar()
    {
        throw new Exception("bar");
    }
    
    void foo()
    {
        bar();
    }
    
    void main()
    {
        foo();
    }
    

    Compiling the above code, with debug info enabled, by running: dmd -g main.d. When running the application it will produce an output similar to:

    [email protected](3): bar
    main.d:3 void main.bar() [0x71afdfb]
    main.d:8 void main.foo() [0x71afe0c]
    main.d:13 _Dmain [0x71afd78]
    

  2. object.destroy() supports extern(C++) classes.

    object.destroy() was crashing when called with an extern(C++) class. It now correctly destructs and resets the object to init.

  3. Exception trapping can now be disabled via --DRT-trapExceptions=0

    Previously it was only possible to disable the trapping of exception by setting the global variable rt_trapExceptions to false. Now you can, for example, immediately open gdb at the uncaught exception:

    > gdb -ex run --args  --DRT-trapExceptions=0
    [Thread debugging using libthread_db enabled]
    Using host libthread_db library "/usr/lib/libthread_db.so.1".
    uncaught exception
    object.Exception@src/rt_trap_exceptions_drt.d(4): foo
    ––––––––––
    src/rt_trap_exceptions_drt.d:4 void rt_trap_exceptions_drt.test() [0x55591026]
    src/rt_trap_exceptions_drt.d:9 _Dmain [0x55591058]
    
    Program received signal SIGABRT, Aborted.
    0x00007ffff6e7b86b in raise () from /usr/lib/libc.so.6
    (gdb) bt full
    #0  0x00007ffff6e7b86b in raise () from /usr/lib/libc.so.6
    No symbol table info available.
    #1  0x00007ffff6e6640e in abort () from /usr/lib/libc.so.6
    No symbol table info available.
    #2  0x00005555555918cc in _d_throwdwarf (o=0x7ffff7ea4000) at src/rt/dwarfeh.d:233
            eh = 0x7ffff7fa4740
            refcount = 0
            r = 5
    #3  0x0000555555591027 in rt_trap_exceptions_drt.test() () at ../../src/object.d:2695
            innerLocal = 20
    #4  0x0000555555591059 in D main (args=...) at src/rt_trap_exceptions_drt.d:9
            myLocal = "bar"
    

    This Week in D for an in-depth explanation of rt_trapExceptions

  4. Add missing declarations to core.sys.darwin.mach.getsect

    Declarations that were missing from mach-o/getsect.h has been added to core.sys.darwin.mach.getsect.

  5. Additional functions for associative arrays

    The require function provides a means to construct a new value when the key is not present.

    class C{}
    C[string] aa;
    
    auto a = aa.require("a", new C);    // lookup "a", construct if not present
    

    The update function allows different operations to be performed depending on whether a value already exists or needs to be constructed.

    class C{}
    C[string] aa;
    
    C older;
    C newer;
    aa.update("a",
    {
        newer = new C;
        return newer;
    },
    (ref C c)
    {
        older = c;
        newer = new C;
        return newer;
    });
    

    The functions avoid the need to perform multiple key lookups. Further details are available in the spec.

Library changes

  1. The deprecated std.c package has been removed.

    Use the core.stdc package instead.

  2. The performance of std.algorithm.iteration.joiner has been improved

    DMD

    > dmd -O -inline -release ./joiner.d && ./joiner
    before.joiner   = 57 secs, 834 ms, 289 μs, and 3 hnsecs
    new.joiner      = 44 secs, 936 ms, 706 μs, and 5 hnsecs
    

    LDC

    > ldmd -O3 -release -inline joiner.d && ./joiner
    before.joiner   = 5 secs, 180 ms, 193 μs, and 7 hnsecs
    new.joiner      = 3 secs, 168 ms, 560 μs, and 6 hnsecs
    

    The benchmark code can be found here.

  3. std.algorithm.mutation.remove now only accepts integral values or pair of integral values as offset

    Previously, without being stated in the documentation, std.algorithm.remove used to accept any values as offset. This behavior was very error-prone:

    import std.algorithm, std.stdio;
    [0, 1, 2, 3, 4].remove(1, 3).writeln; // 0, 2, 4  -- correct
    [0, 1, 2, 3, 4].remove([1, 3]).writeln; // 0, 3, 4  -- incorrect
    

    With this release, using arrays as individual elements is no longer valid. std.typecons.tuple can be used to explicitly indicate that a range from start to stop (non-enclosing) should be removed:

    import std.algorithm, std.stdio, std.typecons;
    [0, 1, 2, 3, 4].remove(tuple(1, 3)).writeln; // 0, 3, 4
    

    However, only 2-tuples are allowed to avoid this un-intuitive scenario:

    import std.algorithm, std.stdio, std.typecons;
    [0, 1, 2, 3, 4].remove(tuple(1, 3, 4)).writeln; // 0, 4?
    
  4. Deprecated functions for getting the timezone have been removed.

    Due to the fact that Microsoft changes its timezone definitions too frequently to maintain the conversion between the IANA TZ Database names and the names that Microsoft uses in the standard library, several functions in std.datetime.timezone related to getting the time zone independently of the host OS were previously deprecated: TimeZone.getTimeZone, TimeZone.getInstalledTZNames, tzDatabaseNameToWindowsTZName, and windowsTZNameToTZDatabaseName. These functions have now been fully removed.

    Instead of TimeZone.getTimeZone, std.datetime.timezone.PosixTimeZone.getTimeZone and std.datetime.timezone.WindowsTimeZone.getTimeZone should be used directly. Instead of Timezone.getInstalledTimeZones, std.datetime.timezone.PosixTimeZone.getInstalledTZNames and std.datetime.timezone.WindowsTimeZone.getInstalledTZNames should be used directly. And any programs looking to convert between the TZ Database names and the Windows names can use std.datetime.timezone.parseTZConversions with the current windowsZones.xml file to get the current conversions (see the documenation for std.datetime.timezone.parseTZConversions for details).

  5. Changed semantics of std.math.{fmin,fmax} wrt. NaNs.

    The semantics of std.math.fmin and std.math.fmax have been streamlined with the C functions: if one of the arguments is a NaN, return the other. This involves an additional std.math.isNaN check. Use std.algorithm.comparison.min and std.algorithm.comparison.max for the previous semantics performing a single comparison.

    import std.math;
    assert(fmin(real.nan, 2.0L) == 2.0L);
    assert(fmin(2.0L, real.nan) == 2.0L); // previously: NaN
    assert(isNaN(fmin(real.nan, real.nan)));
    
    import std.algorithm.comparison;
    assert(min(real.nan, 2.0L) == 2.0L);
    assert(isNaN(min(2.0L, real.nan)));
    assert(isNaN(min(real.nan, real.nan)));
    

Dub changes

  1. DUB supports "customCachePaths" for providing read-only package paths

    With this release DUB allows defining additional paths that contain packages in subfolders with the pattern "(name)-(version)/(name)/" by defining a "customCachePaths" field in /etc/dub/settings.json or ~/.dub/settings.json.

    "customCachePaths" can be used to provide prebuilt DUB libraries (e.g. for distribution package maintainers).


List of all bug fixes and enhancements in D :

DMD Compiler bugs

  1. Bugzilla 9701: UDAs cannot be attached to enum values.
  2. Bugzilla 17580: Marking methods as synchronized is allowed despite spec
  3. Bugzilla 18985: bad error message for += operation on shared Object
  4. Bugzilla 19018: Lexer allows invalid integer literals, like 0x
  5. Bugzilla 19035: Escape in scope inference, improve scope inference
  6. Bugzilla 19043: Incorrect mangling for extern(C++) const template parameter on windows
  7. Bugzilla 19053: debug should escape @safe

DMD Compiler enhancements

  1. Bugzilla 17602: improve message for deprecated enum comparison
  2. Bugzilla 18743: ConditionalExpression and AssignExpression should require parentheses
  3. Bugzilla 18994: Use noncopyable variable in foreach loop without ref results in error message without line number
  4. Bugzilla 19022: CTorFlow: Show the line of the duplicated initialization for const/immutable fields

Phobos bugs

  1. Bugzilla 12507: SysTime.init.toString should not segfault
  2. Bugzilla 18804: std.algorithm.mutation.copy puts whole source range into target range when it should put elements
  3. Bugzilla 18933: std.range.assumeSorted should not nest SortedRange!(SortedRange!(...), pred)
  4. Bugzilla 18995: std.array.array doesn't free elements

Phobos enhancements

  1. Bugzilla 16745: Add template helper for creating static arrays with the size inferred
  2. Bugzilla 18790: can't put a const(char)[] into a char[]

Druntime bugs

  1. Bugzilla 19046: OSX: bad value for core.stdc.time.CLOCKS_PER_SEC

Druntime enhancements

  1. Bugzilla 18918: core.internal.hash should perform memberwise hashing of structs with references
  2. Bugzilla 18921: make core.internal.hash cater to memberwise hash chaining
  3. Bugzilla 18923: Semaphore internal handle should be protected instead of private
  4. Bugzilla 18942: core.internal.hash can take advantage of alignment info on non-x86
  5. Bugzilla 18981: SIGSEGV during backtrace when debug info is compressed
  6. Bugzilla 19009: core.internal.hash.hashOf default hash (absent toHash) should be @nogc
  7. Bugzilla 19048: In core.internal.hash.hashOf reduce template bloat: remove auto ref where unneeded and add const where possible
  8. Bugzilla 19049: object.hashOf - don't wrap a public function with an identical public function

dlang.org bugs

  1. Bugzilla 18558: Template alias spec incomplete
  2. Bugzilla 18782: Documentation error: ProtectionAttributes should say Visibility Attributes

Installer bugs

  1. Bugzilla 2473: Linux system install instructions incorrect
  2. Bugzilla 10941: object.d not found when following Mac installation instructions

Contributors to this release (33)

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

previous version: 2.080.1