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.077.0 (upcoming)

previous version: 2.076.0

Download D nightlies
To be released


List of all upcoming bug fixes and enhancements.

Compiler changes

  1. AVX2 was added as -mcpu=avx2 architecture.

    This allows the backend to emit AVX2 instructions. The compiler will add the predefined version D_AVX2. AVX2 support is automatically detected with -mcpu=native.

  2. -betterC enhancements

    Many improvements were added to the dmd's -betterC implementation, most notably programs compiled with -betterC will no longer reference unused druntime symbols, asserts are implemented as C <assert.h> calls, and phobos is not linked by default.

    See the Better C specs for more details.

  3. Fix Issue 17697 - Ddoc: automatically highlight URLs outside of macro arguments

    URLs which appear in Ddoc text:

    /****
     * http://www.fooa.com/test1
     */
    

    will be treated as if they were written:

    /****
     * $(LINK http://www.fooa.com/test1)
     */
    

    and a clickable hyperlink will be emitted to the resulting .html file.

    This detection does not happen if the URL is part of a macro argument:

    /****
     * $(DOLLAR)$(LPAREN)ABC http://www.fooa.com/test1$(RPAREN)
     */
    

    The behavior of that is unchanged. URLs can start with http:// or https://

    http: and https: at the beginning of the line are no longer treated as section headings.

  4. Implement DIP 1010 - Static foreach

    Support for static foreach has been added.

    static foreach is a conditional compilation construct that is to foreach what static if is to if. It is a convenient way to generate declarations and statements by iteration.

    import std.conv: to;
    
    static foreach(i; 0 .. 10)
    {
    
        // a `static foreach` body does not introduce a nested scope
        // (similar to `static if`).
        
        // The following mixin declaration is at module scope:
        mixin(`enum x` ~ to!string(i) ~ ` = i;`); // declares 10 variables x0, x1, ..., x9
    }
    
    import std.range: iota;
    // all aggregate types that can be iterated with a standard `foreach`
    // loop are also supported by static foreach:
    static foreach(i; iota(10))
    {
        // we access the declarations generated in the first `static foreach`
        pragma(msg, "x", i, ": ", mixin(`x` ~ to!string(i)));
        static assert(mixin(`x` ~ to!string(i)) == i);
    }
    
    void main()
    {
        import std.conv: text;
        import std.typecons: tuple;
        import std.algorithm: map;
        import std.stdio: writeln;
    
        // `static foreach` has both declaration and statement forms
        // (similar to `static if`).
        
        static foreach(x; iota(3).map!(i => tuple(text("x", i), i)))
        {
            // generates three local variables x0, x1 and x2.
            mixin(text(`int `,x[0],` = x[1];`));
    
            scope(exit) // this is within the scope of `main`
            {
                writeln(mixin(x[0]));
            }
        }
        
        writeln(x0," ",x1," ",x2); // first runtime output
    }
    

Runtime changes

  1. Print unhandled exception's trace and abort if rt_trapExceptions is false

    D exception handling was assuming the top level exception handler, so all exceptions would be handled somewhere. In case rt_trapExceptions is cleared, this handler would not be enabled, and this assertion would fail, aborting the program, but without any information about the exception. This is now changed, so the exception information will be printed to the stderr, followed by abort.

Library changes

  1. Base64URLNoPadding (URL-safe Base64 without padding) was added

    std.base64.Base64URLNoPadding allows encoding/decoding without padding:

    import std.base64 : Base64URLNoPadding;
    
    ubyte[] data = [0x83, 0xd7, 0x30, 0x7b, 0xef];
    assert(Base64URLNoPadding.encode(data) == "g9cwe-8");
    assert(Base64URLNoPadding.decode("g9cwe-8") == data);
    
  2. std.digest.digest was renamed to std.digest.

    Motivation:

    The fully qualified name of the digest function template was std.digest.digest.digest. This is because std.digest is a package, with a module named digest in it, and the function digest inside that.

    std.digest contains the former std.digest.digest package.

  3. std.meta.Stride was added

    std.meta.Stride allows selecting a subset of template by a step size and offset:

    alias attribs = AliasSeq!(short, int, long, ushort, uint, ulong);
    static assert(is(Stride!(3, attribs) == AliasSeq!(short, ushort)));
    static assert(is(Stride!(3, attribs[1 .. $]) == AliasSeq!(int, uint)));
    
  4. Config.detached flag for spawnProcess has been added

    Config.detached allows spawning processes which run independently from the current process. There is no need to wait on the processes created with this flag, and no zombie process will be left after they exit. Attempts to call std.process.wait or std.process.kill on detached processes will throw.

  5. std.range.chunks was extended to support non-forward input ranges.

    Now std.range.chunks can be used with input ranges that are not forward ranges, albeit with limited semantics as imposed by the underlying range.

    import std.algorithm.comparison : equal;
    
    int i;
    
    // The generator doesn't save state, so it cannot be a forward range.
    auto inputRange = generate!(() => ++i).take(10);
    
    // We can still process it in chunks, but it will be single-pass only.
    auto chunked = inputRange.chunks(2);
    
    assert(chunked.front.equal([1, 2]));
    assert(chunked.front.empty); // Iterating the chunk has consumed it
    chunked.popFront;
    assert(chunked.front.equal([3, 4]));
    
  6. std.socket.UnixAddress now supports abstract addresses.

    UNIX domain sockets are usually identified by pathnames. Linux offers a non-portable extension to this scheme, known as abstract socket addresses, which are independent of the filesystem. An abstract socket address starts with a null byte ('\0'), e.g.:

    auto addr = new UnixAddress("\0/tmp/dbus-OtHLWmCLPR");
    
  7. Added possibility to use a baseclass when auto-implementing an interface

    A second std.typecons.AutoImplement template has been added, which differs from the existing one in accepting an extra type parameter. The extra parameter specifies a class to derive from while auto-implementing an interface.

    The base class used may contain non-default constructors. Matching constructors will be created in the auto-implemented class and be implemented as just a call to super with all arguments.

Tools changes

  1. rdmd now checks for a D compiler binary in the directory it's in first

    If you downloaded a zip/tar file with the compiler before and ran rdmd, it would invoke the D compiler from the system PATH rather than the compiler right next to it, failing if there wasn't one in the PATH. rdmd will now try to use the D compiler next to it first, and only fall back to the PATH if there isn't one adjacent. If you want rdmd to run a specific compiler, add the --compiler flag to force it, as always.

    To restore the old behaviour of only using the compiler from your PATH, add --compiler=dmd (or ldmd2 or gdmd).


List of all bug fixes and enhancements in D 2.077.0 (upcoming):

DMD Compiler bugs

  1. Bugzilla 11259: __traits(isSame) fails on the result of __traits(parent) if parent is a package
  2. Bugzilla 17370: [scope] Escaping scope pointers possible via struct GC allocation
  3. Bugzilla 17568: [scope] addresses to fields can be escaped from scope method
  4. Bugzilla 17725: [scope] escape from nested function to enclosing local
  5. Bugzilla 17782: The identifier delimiter of a delimited string can not begin with '_'
  6. Bugzilla 17790: [scope] Escaping pointer possible through array of aggregates

DMD Compiler enhancements

  1. Bugzilla 10523: Don't call array op functions for short vector ops
  2. Bugzilla 13262: Cannot send certain shared data to another thread
  3. Bugzilla 15831: IFTI voldemort type exploding bloat
  4. Bugzilla 17787: Add a BetterC predefined version so libraries can adapt

Phobos bugs

  1. Bugzilla 10444: writeln of a SIMD register
  2. Bugzilla 12470: std.array.replace does not work with inout(char)[]
  3. Bugzilla 15096: std.array.array cannot be instantiated for pointers to ranges

Phobos enhancements

  1. Bugzilla 6004: std.range.unzip()
  2. Bugzilla 9183: Add a Nullable.get(x) overload
  3. Bugzilla 16512: std.allocator: Nullify the argument passed to allocator.dispose
  4. Bugzilla 17803: std.typecons.Tuple: opAssign should return ref Tuple

Druntime bugs

  1. Bugzilla 16230: core.atomic.atomicLoad removes shared from aggregate types too eagerly

dlang.org bugs

  1. Bugzilla 9958: "Integer FloatSuffix" is not a valid FloatLiteral

dlang.org enhancements

  1. Bugzilla 17581: Document behavior of -betterC
previous version: 2.076.0