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

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



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

Compiler changes

  1. Argument mismatch errors have been improved

    dmd now shows which argument failed to match a parameter with an explanatory error message.

    void fill(ref char[16] buf, char c);
    
    void main()
    {
        fill("1234567890123456", '*');
    
        const char[16] s;
        fill(s, '*');
    }
    

    Output:

    fillchar.d(5): Error: function fillchar.fill(ref char[16] buf, char c) is not callable using argument types (string, char)
    fillchar.d(5):        cannot pass rvalue argument "1234567890123456" of type string to parameter ref char[16] buf
    fillchar.d(8): Error: function fillchar.fill(ref char[16] buf, char c) is not callable using argument types (const(char[16]), char)
    fillchar.d(8):        cannot pass argument s of type const(char[16]) to parameter ref char[16] buf
    

    Note: Currently this change doesn't apply when the function has overloads.

  2. The deprecation period of using the result of comma expression has ended

    Comma expressions have proven to be a frequent source of confusion, and bugs. Using their result will now trigger an error message.

    The comma operator (,) allows executing multiple expressions and discards the result of them except for the last which is returned.

    int a = 1;
    int b = 2;
    bool ret = a == 2, b == 2; // true
    

    It's also common to use the comma operator in for-loop increment statements to allow multiple expressions.

    for (; !a.empty && !b.empty; a.popFront, b.popFront)
    

    Hence, using the comma operator in for-loop increment statements is still allowed.

    Corrective Action

    If possible, split the comma operator in two statements. Otherwise use lambdas.

    auto result = foo(), bar();
    
    // split off in two statements
    foo();
    auto result = bar();
    
    // or use lambdas
    auto result = {foo(); return bar();}();
    

    Rationale

    The comma operator leads to unintended behavior (see below for a selection) Moreover it is not commonly used and it blocks the ability to implement tuples as a language feature using commas.

    A selection of problems through the accidental use of the comma operator:

    writeln( 6, mixin("7,8"), 9 ); // 6, 8, 9
    
    struct Vec
    {
        this(T...)(T args) { ... }
    }
    // missing type name
    Vec v = (0, 0, 3); // Vec(3)
    
    int a = 0;
    int b = 2;
    if (a == 1, b == 2) {
        // will always be reached
    }
    
    void foo(int x, int y=0) {}
    foo((a, b)); // Oops, foo(b) is called
    
    synchronized (lockA, lockB) {}
    // multiple expressions aren't currently implemented, but it compiles due to the comma operator
    

  3. Function parameters with default values are now allowed after variadic template parameters

    Function parameters with default values are now allowed after variadic template parameters and when IFTI is used, always take their default values. This allows using special tokens (eg __FILE__) after variadic parameters, which was previously impossible.

    For example:

    string log(T...)(T a, string file = __FILE__, int line = __LINE__)
    {
      return text(file, ":", line, " ", a);
    }
    
    assert(log(10, "abc") == text(__FILE__, ":", __LINE__, " 10abc"));
    

    This should be preferred to the previous workaround, which causes a new template instantiation for every invocation:

    string log(string file = __FILE__, int line = __LINE__, T...)(T a);
    
  4. The delete keyword has been deprecated.

    See the Deprecated Features for more information.

    Starting with this release, using the delete keyword will result in a deprecation warning.

    As a replacement, users are encouraged to use destroy if feasible, or core.memory.__delete as a last resort.

  5. The deprecation period of the -dylib flag on OSX has ended. Use -shared

    The deprecation period of the -dylib flag on OSX has ended.

    dmd -dylib awesome_d_library.d

    Use the -shared flag to generate a shared library:

    dmd -shared awesome_d_library.d

  6. Experimental @nogc Exception throwing with -dip1008

    [DIP1008](https://github.com/dlang/DIPs/blob/master/DIPs/DIP1008.md) has been merged and it can be previewed under the experimental -dip1008 flag:

    void main() @nogc
    {
        throw new Exception("I'm @nogc now");
    }
    

    rdmd -dip1008 app.d

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

  8. Fix Issue 17630 - selective imports find symbols in private imports of other modules

    Selectively importing a symbol should work only if the symbol imported is defined or publicly imported in the imported module. Due to a compiler bug, selectively importing a symbol works even if the symbol is defined in a privately imported module in the imported module.

    //a.d
    int bar;
    
    //b.d
    import a;
    
    //c.d
    import b : bar;
    

    The above code will now result in a deprecation message which states that bar cannot be accessed since it is privately imported in b.

  9. Fix issue 17899 - Allow delegates to be initialised at compile time

    delegates may now be initialised at module scope. This changes the effect of the fix for 13259 (turning the ICE that resulted into an error) making the follow legal:

    void delegate() bar = (){};
    

    The function pointer is set to the function of the delegate, the context pointer is set to null.

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

  11. Fix Issue 18219 - Private import inside struct leaks symbols when used as VarDeclaration types

    When implementing a struct which has a local private import the imported symbols are leaked if present in a VarDeclaration statement. For more information and examples see : https://issues.dlang.org/show_bug.cgi?id=18219

    Symbols from the private import should not visible outside the struct scope. A deprecation is now issued when such cases are encountered

  12. Fix issue 18361 - Ddoc ability to opt-out of automatic keyword highlighting in running text

    Currently, ddoc automatically highlights all occurrences of words in running text that coincide with the symbol or module being documented, or a parameter name of a function being documented. While convenient, it often caused unintended highlighting of normal words in text when module, function, or parameter identifiers coincide with normal words. This led to a proliferation of prefixing words with _ in order to suppress this behaviour.

    Now a better solution has been implemented to completely opt-out of this feature via the DDOC_AUTO_PSYMBOL, DDOC_AUTO_KEYWORD, and DDOC_AUTO_PARAM macros, which are used for all such automatically-highlighted words in running text. Occurrences of module, function, or parameter names inside code blocks are not included. By default, these macros simply redirect to DDOC_PSYMBOL, DDOC_KEYWORD, and DDOC_PARAM, but the user can now redefine these macros so that they simply expand to the word itself without any highlighting:

    DDOC_AUTO_PSYMBOL = 
    DDOC_AUTO_KEYWORD = 
    DDOC_AUTO_PARAM = 
    

    Furthermore, whenever a word is prefixed with _ to suppress automatic highlighting, it is now wrapped in the DDOC_AUTO_PSYMBOL_SUPPRESS macro. This is to provide users who wish to opt out of automatic highlighting an easy way to find all occurrences of these underscore prefixes so that they can be removed from the text. For example, they can redefine this macro to something highly-visible and easily searched for, such as:

    DDOC_AUTO_PSYMBOL_SUPPRESS = FIXME_UNDERSCORE_PREFIX 
    

    and then search the generated documentation for the string FIXME_UNDERSCORE_PREFIX and delete the _ prefix from all corresponding parts of the documentation comment text.

  13. D ABI change on Win32 and OSX targets

    The compiler has been updated to prefix all extern(D) symbols with an extra underscore where the platform expects one on all external symbols. This allows compiled code to work better with binutil programs, such as the ability to list symbols demangled inside a debugger.

    This is an ABI breaking change and requires recompiling libraries.

  14. HexString literals are deprecated.

    HexString literals are deprecated. Use std.conv.hexString instead.

  15. Added the -i command line option to automatically include imports

    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 -i=-foo.bar

    The option -i by itself is equivalent to:

    dmd -i=-std -i=-core -i=-etc -i=-object

  16. Added -Xi=<name> to include more fields in the JSON output

    Added -Xi=<name> to include more fields in the JSON output. Currently there are 4 fields that can be included: "compilerInfo", "buildInfo", "modules" and "semantics", i.e.

    dmd -Xi=compilerInfo -Xi=buildInfo -Xi=semantics -Xi=modules

    will generate a JSON file with the following:

    {
      "compilerInfo" : {
        "binary" : "<filename-of-compiler-binary>",
        "version" : "<compiler-version>",
        "supportsIncludeImports" : true,
      },
      "buildInfo" : {
        "config" : "<config-filename>",
        "cwd" : "<cwd-during-build>",
        "importParths" : [
          "<import-path1>",
          "<import-path2>",
          // ...
        ]
      },
      "semantics" : {
        "modules" : [
          {
            "name" : "<module-name>",
            "file" : "<module-filename>",
            "isRoot" : true|false
          },
          // more module objects...
        ]
      },
      "modules" : [
        // an array of the syntax data for all the modules,
        // this is the same array that would be generated
        // for a JSON file with no -Xi=<field> options
      ]
    }
    

    If JSON is generated without any -Xi= options then the old format is used. The old format is the same data that would appear in the new "modules" field.

    Also note that the compiler can now be invoked with no source files as long as at least one JSON field is provided, i.e.

    dmd -Xi=compilerInfo

    This is an experimental command-line flag and will be stabilized in the next release.

  17. Lambda comparison using __traits(isSame, ...)

    It is now possible to compare two lambda functions, under certain constraints, using __traits(isSame, lamda1, lambda2). In order to correctly compare two lambdas, the following conditions must be satisfied:

    • the lambda function arguments must not have a template instantiation as an explicit argument type. Any other argument types (basic, user-defined, template) are supported.
    • the lambda function body must contain a single expression (no return statement) which contains only numeric values, manifest constants, enum values and arguments. If the expression contains local variables, function calls or return statements, the function is considered uncomparable.

    These limitations might be lifted in the next release version.

    Whenever a lambda is considered uncomparable, the __traits(isSame, ...) expression in which it's used will return false, no matter what other lambda is used in the comparison.

  18. Windows: Visual C++ and the Windows SDK are no longer required to build 64-bit executables

    The Windows installer now adds platform libraries built from the MinGW definitions and a wrapper library for the VC2010 shared C runtime. When building COFF object files with -m64 or -m32mscoff and no Visual Studio installation is detected or no platform libraries are found these will be used as replacements. If the Microsoft linker is not found, the LLVM linker LLD will be used.

  19. Using D with no/minimal/custom runtime implementation in a pay-as-you-go fashion

    DMD has been further decoupled from the runtime so it is now easier and more convenient to use D without the runtime in a pay-as-you-go fashion. This will be of interest to users wishing to incrementally or partially port D to new platforms, users targeting bare-metal or resource constrained platforms, and users wishing to use D as a library from other languages without the runtime.

    Prior to this release, if one attempted to compile a simple D application that made no use of any runtime features, the compiler would have emitted a number of errors about a missing object.d, a missing Error class, missing TypeInfo, and missing ModuleInfo, among others.

    Starting with this release, one can now create a library for use from another language, requiring only the .d source file that implements that library, and an empty object.d file

    Example 1

    module object
    
    module math;
    
    extern(C) int add(int a, int b)
    {
        return a + b;
    }
    

    dmd -conf= -lib math.d
    size math.a
       text    data     bss     dec     hex filename
          0       0       0       0       0 math.o (ex math.a)
         20       0       0      20      14 math_1_129.o (ex math.a)
    

    Also, starting with this release, one can now create very small executables with a minimal runtime implementation.

    Example 2

    DMD auto-generates a call to _d_run_main which, in turn, calls the user-defined main function. DMD automatically generates a call to g++ which links in the C runtime.

    module object;
    
    private alias extern(C) int function(char[][] args) MainFunc;
    private extern (C) int _d_run_main(int argc, char** argv, MainFunc mainFunc)
    {
        return mainFunc(null);  // assumes `void main()` for simplicity
    }
    
    module main;
    
    void main() { }
    

    dmd -conf= -defaultlib= -fPIC main.d object.d -of=main
    size main
       text    data     bss     dec     hex filename
       1403     584      16    2003     7d3 main
    

    Example 3

    Manually generated call to main. No C runtime.

    module object;
    
    extern(C) void __d_sys_exit(long arg1)
    {
        asm
        {
            mov RAX, 60;
            mov RDI, arg1;
            syscall;
        }
    }
    
    extern void main();
    private extern(C) void _start()
    {
        main();
        __d_sys_exit(0);
    }
    
    module main;
    
    void main() { }
    

    dmd -c -lib main.d object.d -of=main.o
    ld main.o -o main
    size main
       text    data     bss     dec     hex filename
         56       0       0      56      38 main
    

    Usage of more advanced D features (e.g. classes, exceptions, etc...) will require runtime implementation code, but they can be implemented in a pay-as-you-go fashion.

  20. 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).

  21. Deprecate the use of selectively imported private members

    The specification states that a private member is visible only from within the same module. Prior to this release, due to a bug, private members were visible through selective imports from other modules, violating the specification. Beginning with this release, accessing private members from outside the module in which they are declared will result in a deprecation message.

  22. .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;
    }
    

Runtime changes

  1. core.memory.__delete has been added

    core.memory.__delete allows easy migration from the deprecated delete. __delete behaves exactly like delete:

    bool dtorCalled;
    class B
    {
        int test;
        ~this()
        {
            dtorCalled = true;
        }
    }
    B b = new B();
    B a = b;
    b.test = 10;
    
    __delete(b);
    assert(b is null);
    assert(dtorCalled);
    // but be careful, a still points to it
    assert(a !is null);
    

    For example, on a Posix platform you can simply run:

    sed "s/delete \(.*\);/__delete(\1);/" -i **/*.d
    

    Users should prefer object.destroy` to explicitly finalize objects, and only resort to core.memory.__delete when object.destroy would not be a feasible option.

  2. The garbage collector is now lazily initialized on first use

    The runtime now lazily initializes the GC on first use, thus allowing applications that do not use the GC to skip its initialization.

Library changes

  1. std.typecons.BitFlags now supports opDispatch-based property access

    std.typecons.BitFlags was extended so that enum members can be set and tested directly on the BitFlags instead of having to & with the underlying enum.

    enum Features
    {
        fast = 1 << 0,
        size = 1 << 1,
    }
    
    void run(BitFlags!Features features)
    {
        // get
        if (features.fast && !features.size) {} // new new new
        if ((features & Features.fast) && !(features & Features.size)) {} // old old old
        // set
        features.fast = true; // new new new
        features.fast = false; // new new new
        features.fast |= Features.fast; // old old old
        features.fast &= ~Features.fast; // old old old
    }
    

    This also works for unsafe BitFlags where the property get access tests for an exact match of all bits of the unsafe BitFlags combination. Analogously, the property set access clears or sets all bits of the unsafe BitFlags combination.

    enum Features
    {
        fast = 1 << 0,
        size = 1 << 1,
        combined = fast | size,
    }
    
    void run(BitFlags!(Features, Yes.unsafe) features)
    {
        // get
        if (features.combined) {} // new new new
        if ((features & Features.combined) == BitFlags!(Features, Yes.unsafe)(Features.combined)) {} // old old old
        // set
        features.combined = true; // new new new
        features.combined = false; // new new new
        features.combined |= Features.combined; // old old old
        features.combined &= ~Features.combined; // old old old
    }
    

List of all bug fixes and enhancements in D 2.080.0:

DMD Compiler regressions

  1. Bugzilla 16243: wrong C++ argument passing with empty struct when interfacing with Clang

DMD Compiler bugs

  1. Bugzilla 5212: no escape analysis for typesafe variadic function arguments
  2. Bugzilla 9433: Deprecate delete
  3. Bugzilla 15653: IFTI fails for immutable parameter
  4. Bugzilla 16555: Stack corruption when calling multi-parameter outer function from nested function
  5. Bugzilla 16578: bogus deprecation - switch skips declaration of variable
  6. Bugzilla 17284: Template function attribute inference wrongly infers @safe for accessing overlapping pointer fields in unions
  7. Bugzilla 17892: Scope analysis with -dip1000 fails for templated structs
  8. Bugzilla 17959: [DIP1000] Can store scope delegate in non-scope member
  9. Bugzilla 18000: [scope] auto-generated opAssign not scope aware
  10. Bugzilla 18505: delete deprecation message is misleading
  11. Bugzilla 18575: making delegate from member function can lead to unsafe code
  12. Bugzilla 18576: Compiler not doing RVO with auto returns

DMD Compiler enhancements

  1. Bugzilla 16037: assigning delegate to a scope variable shouldn't allocate closure
  2. Bugzilla 18460: Improve error message for missing 'new' for class instantiation
  3. Bugzilla 18503: Confusing error message for erroneous postblit
  4. Bugzilla 18551: Improve hint for "does not override any function
  5. Bugzilla 18574: Unclear error message when trying to inherit from multiple classes
  6. Bugzilla 18591: DMD should allow access to mixin template declarations

Phobos regressions

  1. Bugzilla 17961: std.uni does not compile with -unittest -dip1000
  2. Bugzilla 18565: std.regex Captures opAssign returns void since v2.079.0

Phobos bugs

  1. Bugzilla 7879: format of class with not const toString()
  2. Bugzilla 13642: std.container.Array: change of length reallocates without notifying GC
  3. Bugzilla 18133: BitArray constructors are poorly documented.
  4. Bugzilla 18134: BitArray >>= broken when length % (8 * size_t.sizeof) == 0
  5. Bugzilla 18524: std.range.Zip.moveBack instead performs moveFront
  6. Bugzilla 18548: [2.079] std.format ignores templated toString if another toString is not a template
  7. Bugzilla 18579: No group separators for floating point number formatted with zero decimal digits

Phobos enhancements

  1. Bugzilla 8341: topN(zip()) too?
  2. Bugzilla 10828: datetime toString functions should accept sink
  3. Bugzilla 18158: std.file.getcwd should be usable in @safe
  4. Bugzilla 18166: std.array.replace should be usable in @safe for dstrings
  5. Bugzilla 18168: std.base64.encode for output ranges should be usable in @safe
  6. Bugzilla 18182: std.uri should be usable in @safe
  7. Bugzilla 18501: randomShuffle and partialShuffle should return their input argument

Druntime bugs

  1. Bugzilla 18482: wincrypt functions should be @nogc nothrow
  2. Bugzilla 18536: Bad stack traces when building with -m32mscoff
  3. Bugzilla 18537: Cannot pass absolute path to coverage options
  4. Bugzilla 18547: Win32: throwing exception in fiber crashes application

Contributors to this release (42)

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

previous version: 2.079.0