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

previous version: 2.078.0

Download D nightlies
To be released


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

Compiler changes

  1. A compiler trait used to detect if a function is marked with @disable has been added.

    Prior to this release is was impossible to filter out @disable functions without using __trait(compiles), which was less than ideal since false could be returned for other reasons.

    Now, in metaprogramming code, @disable functions can be detected accurately, using __traits(isDisabled) and even in overload sets:

    module runnable;
    
    struct Foo
    {
        import std.stdio;
        @disable static void foo() {__PRETTY_FUNCTION__.writeln;}
        static void foo(int v) {__PRETTY_FUNCTION__.writeln;}
        static void bar() {__PRETTY_FUNCTION__.writeln;}
        @disable static void bar(int v) {__PRETTY_FUNCTION__.writeln;}
    }
    
    void test(T)()
    {
        foreach (member; __traits(allMembers, T))
            foreach (overload; __traits(getOverloads, T, member))
                static if (!__traits(isDisabled, overload))
        {
            static if (is(typeof(&overload) == void function()))
                overload();
            else static if (is(typeof(&overload) == void function(int)))
                overload(42);
        }
    }
    
    void main(){test!Foo;}
    

    prints:

    void runnable.Foo.foo(int v)
    void runnable.Foo.bar()
    

  2. Fix Issue 18053 - mangle long/ulong as int64_t/uint64_t

    This is a breaking change (on OSX 64).

    Due to the erratic implementation defined behavior of C++ name mangling, it was difficult to get D's long/ulong to portably match up with the corresponding C++ compiler.

    By instead relying on how the corresponding C++ compiler mangled int64_t/uint64_t it makes the C++ side of the D<=>C++ interface much simpler.

    For the current platforms dmd supports, only the OSX 64 bit mangling changes. In this case from 'm' to 'y'.

    Note: int64_t and uint64_t are defined in stdint.h

  3. Automatically include imports via -i command line option

    Added the command line option -i which causes the compiler to treat imported modules as if they were given on the command line. The option also accepts "module patterns" that include/exclude modules based on their name. For example, the following will include all modules whose names start with "foo", except for those that start with "foo.bar":

    dmd -i=foo,-foo.bar
    

    The option -i by itself is equivalent to:

    dmd -i=-std,-core,-etc,-object
    
  4. Allow multiple selective imports from different modules in a single import statement

    It is now possible to add imports from a different module after a selective import list, when those import are also selective or when the imported module has a qualified name.

    import pkg.mod1 : sym1, mod2 : sym2;
    import pkg.mod1 : sym1, sym2, pkg.mod2;
    

    Unqualified modules or renamed imports following a selective import will be parsed as part of the selective import list, not as separate modules.

    import pkg.mod1 : sym1, mod2;           // selectively imports mod2 from pkg.mod1
    import pkg.mod1 : sym1, name=mod2;      // selectively imports mod2 as name from pkg.mod1
    import pkg.mod1 : sym1, name=pkg1.mod1; // parsing renamed selective imports fails due to qualfier
    
  5. macOS deployment target was increased to 10.9

    The compiler has been updated to use 10.9 and link with libc++ on OSX. This is due the shared libstdc++ library from older versions of macOS having compatibility issues with the headers included in a modern XCode.

    The minimum required version of running the compiler is now Mac OS X Mavericks (10.9).

  6. .ptr on arrays can no longer be used in @safe code

    The deprecation period for using .ptr on arrays in @safe ended. The following now triggers an error instead of a deprecation:

    @safe ubyte* oops(ubyte[] arr) {
        return arr.ptr;
    }
    

    Use &arr[0] instead:

    @safe ubyte* oops(ubyte[] arr) {
        return &arr[0];
    }
    

    Note that this only applies to SafeD - in @system code .ptr may still be used:

    @system ubyte* oops(ubyte[] arr) {
        return arr.ptr;
    }
    

Library changes

  1. std.format with strings passed during compile-time has been optimized

    Giving std.format.format a string as a template parameter allows the type correctness of the parameters to be checked at compile time:

    import std.format : format;
    
    auto s1 = format!"%d"(4); // works fine
    auto s2 = format("%d"); // runtime exception
    auto s3 = format!"%d"(); // compile time error
    

    Now, using this overload also allows std.format to make an educated guess at the length of the resulting string, reducing the total number of reallocations made to the output buffer.

    import std.format : format;
    
    auto s1 = format!"%02d:%02d:%02d"(10, 30, 50); // known for certain to be 8 chars long
    auto s2 = format!"%s %d"("Error Code: ", 42); // Makes an educated guess
    

    Longer format strings benefit the most from this change.

  2. Nullable!C.nullify no longer calls .destroy when C is a class or interface

    Previously, when .nullify is called on a Nullable!C where C is a class or interface, the underlying object is destructed immediately via the .destroy function. This led to bugs when there are still references to the object outside of the Nullable instance:

    class C
    {
        int canary = 0xA71FE;
        ~this()
        {
            canary = 0x5050DEAD;
        }
    }
    
    auto c = new C;
    assert(c.canary == 0xA71FE);
    
    Nullable!C nc = nullable(c);
    nc.nullify;
    assert(c.canary == 0xA71FE); // This would fail
    

    The .nullify method has been fixed so that it no longer calls .destroy on class or interface instances, and the above code will now work correctly.

  3. fold is added to std.parallelism.TaskPool

    std.parallelism.TaskPool.fold is functionally equivalent to reduce except the range parameter comes first and there is no need to use tuple for multiple seeds.

    static int adder(int a, int b)
    {
        return a + b;
    }
    static int multiplier(int a, int b)
    {
        return a * b;
    }
    
    // Just the range
    auto x = taskPool.fold!adder([1, 2, 3, 4]);
    assert(x == 10);
    
    // The range and the seeds (0 and 1 below; also note multiple
    // functions in this example)
    auto y = taskPool.fold!(adder, multiplier)([1, 2, 3, 4], 0, 1);
    assert(y[0] == 10);
    assert(y[1] == 24);
    
    // The range, the seed (0), and the work unit size (20)
    auto z = taskPool.fold!adder([1, 2, 3, 4], 0, 20);
    assert(z == 10);
    
  4. std.range.slide (a fixed-size sliding window range) was added

    std.range.slide allows to iterate a range in sliding windows:

    import std.array : array;
    import std.algorithm.comparison : equal;
    
    assert([0, 1, 2, 3].slide(2).equal!equal(
        [[0, 1], [1, 2], [2, 3]]
    ));
    assert(5.iota.slide(3).equal!equal(
        [[0, 1, 2], [1, 2, 3], [2, 3, 4]]
    ));
    
    assert(iota(7).slide(2, 2).equal!equal([[0, 1], [2, 3], [4, 5]]));
    assert(iota(12).slide(2, 4).equal!equal([[0, 1], [4, 5], [8, 9]]));
    
    // set a custom stepsize (default 1)
    assert(6.iota.slide(1, 2).equal!equal(
        [[0], [2], [4]]
    ));
    
    assert(6.iota.slide(2, 4).equal!equal(
        [[0, 1], [4, 5]]
    ));
    
    // allow slide with less elements than the window size
    assert(3.iota.slide!(No.withPartial)(4).empty);
    assert(3.iota.slide!(Yes.withPartial)(4).equal!equal(
        [[0, 1, 2]]
    ));
    

List of all bug fixes and enhancements in D 2.079.0:

DMD Compiler regressions

  1. Bugzilla 16621: [REG2.060] DMD hang in semantic3 on alias this
  2. Bugzilla 18030: Segmentation fault with __traits(getProtection) on template function.
  3. Bugzilla 18093: [Reg 2.071] MSCOFF: dmd crashes when overriding a C++ method in a mixin template

DMD Compiler bugs

  1. Bugzilla 12901: Assignments to outside members in in/out contracts shouldn't be allowed
  2. Bugzilla 13742: undefined reference to __coverage
  3. Bugzilla 14907: DMD crash when using template name as a default value of template's typed argument
  4. Bugzilla 16042: Identifier on template arguments should consider eponymous member lookup
  5. Bugzilla 18057: [ICE] Segmentation fault (stack overflow) in Expression::ctfeInterpret()
  6. Bugzilla 18083: -w doesn't work for the ddoc build
  7. Bugzilla 18111: unittests get different names depending on how the files are passed to dmd
  8. Bugzilla 18143: in/out contracts should be implicitly 'this' const
  9. Bugzilla 18190: [asan] heap-buffer-overflow in Module.load.checkModFileAlias
  10. Bugzilla 18212: Usage of cfloat,cdouble,cfloat,ifloat,idouble,ireal shouldn't trigger an error in deprecated code
  11. Bugzilla 18218: __traits(isDeprecated, creal) should return true
  12. Bugzilla 18232: Union methods fail to initialize local variables to .init
  13. Bugzilla 18233: building with -m64 doesn't work with sc.ini from the zip distribution and VS2017
  14. Bugzilla 18261: Linkage information isn't part of the json output

DMD Compiler enhancements

  1. Bugzilla 6549: Implement contracts without implementation.
  2. Bugzilla 11714: Improve error message for wrongly initialized thread-local class instances
  3. Bugzilla 13855: Allow multiple selective imports from different modules in a single import statement
  4. Bugzilla 18053: Use stdint.h mangling for int64_t/uint64_t when mangling D long/ulong
  5. Bugzilla 18149: Add a compiler trait to detect if a function is @disable

Phobos bugs

  1. Bugzilla 15157: std.experimental.allocator.building_blocks docs
  2. Bugzilla 15391: Problems loading libcurl.so and running datetime unittest on NixOS package build
  3. Bugzilla 18092: Can't combine take and takeExactly
  4. Bugzilla 18124: std.regex.RegexMatch's front property is under-documented
  5. Bugzilla 18153: deprecate public symbols ByLine, ByRecord, ByChunk
  6. Bugzilla 18215: std.array.replace throws a range violation if the from range is longer than the array
  7. Bugzilla 18224: BigInt modulo uint must return long.
  8. Bugzilla 18244: Generic functions in std.math cannot be overloaded
  9. Bugzilla 18259: allocatorObject's CAllocatorImpl should store the passed allocator within

Phobos enhancements

  1. Bugzilla 5489: std.typecons tuples dynamically iterable
  2. Bugzilla 17440: Nullable.nullify() resets referenced object
  3. Bugzilla 18096: Add fold() to std.parallelism
  4. Bugzilla 18116: to!wchar([string, dstring]), and to!char([wstring, dstring]) don't compile
  5. Bugzilla 18152: std.format.formattedRead should work with rvalues.
  6. Bugzilla 18186: std.array.replaceSlice should be usable in @safe
  7. Bugzilla 18214: TemplateOf should return void for non-templated symbols
  8. Bugzilla 18217: Don't repeatedly call unpredictableSeed to initialize rndGen
  9. Bugzilla 18230: multiwayUnion sets wrong pred lambdas
  10. Bugzilla 18239: std.experimental.allocator fillWithMemcpy could use memset when T.sizeof==1

Druntime regressions

  1. Bugzilla 18193: module config is in file 'rt/config.d' which cannot be read

Druntime bugs

  1. Bugzilla 18240: core.stdc.wchar_ wmemset, etc. should be pure

dlang.org bugs

  1. Bugzilla 14475: man page is outdated
  2. Bugzilla 16017: package functions show up in std.experimental.allocator.common docs
  3. Bugzilla 16490: Usage of attributes in inline asm blocks is not documented

dlang.org enhancements

  1. Bugzilla 17998: Document Options for install.sh
  2. Bugzilla 18202: Show TOC overview in the dlang specification pages

Contributors to this release (50)

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

previous version: 2.078.0