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

previous version: 2.085.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.086.0 comes with 22 major changes and 85 fixed Bugzilla issues. A huge thanks goes to the 55 contributors who made 2.086.0 possible.

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

Compiler changes

  1. Add support for Objective-C classes

    Prior to this release D interfaces were used to represent Objective-C classes. Now proper support for Objective-C classes has been added and D classes can be used instead to represent Objective-C classes. It's preferred to use D classes to represent Objective-C classes.

    This release also adds support for implementing Objective-C subclasses and methods in D.

    To match the behavior in Objective-C some additional changes have been made:

    • static and final methods are virtual. Although final methods are virtual it's not possible to override a final method in a subclass
    • static methods are overridable in subclasses

    Example:

    extern (Objective-C)
    class NSObject
    {
        static NSObject alloc() @selector("alloc");
        NSObject init() @selector("init");
        void release() @selector("release");
    }
    
    extern (Objective-C)
    class Foo : NSObject
    {
        override static Foo alloc() @selector("alloc");
        override Foo init() @selector("init");
    
        int bar(int a) @selector("bar:")
        {
            return a;
        }
    }
    
    void main()
    {
        auto foo = Foo.alloc.init;
        scope (exit) foo.release();
    
        assert(foo.bar(3) == 3);
    }
    
  2. Add support for Objective-C instance variable

    It's now possible to declare instance variables in Objective-C classes.

    Instance variables in Objective-C are non-fragile. That means that the base class can change (add or remove instance variables) without the subclasses needing to recompile or relink. Thanks to this feature it's not necessary to declare instance variables when creating bindings to Objective-C classes.

    Example:

    extern (Objective-C)
    class NSObject {}
    
    extern (Objective-C)
    class Foo : NSObject
    {
        int bar;
    
        static Foo alloc() @selector("alloc");
        Foo init() @selector("init");
        void release() @selector("release");
    
        void getBar() @selector("getBar")
        {
            return bar;
        }
    }
    
    void main()
    {
        auto foo = Foo.alloc.init;
        scope (exit) foo.release();
        foo.bar = 3;
    
        assert(foo.getBar() == 3);
    }
    
  3. Add support for Objective-C super calls

    It's now possible to implement an Objective-C method and make a super call to a method in the base class.

    Example:

    extern (Objective-C)
    class NSObject
    {
        void release() @selector("release");
    }
    
    extern (Objective-C)
    class Foo : NSObject
    {
        int foo() @selector("foo")
        {
            return 3;
        }
    }
    
    extern (Objective-C)
    class Bar : Foo
    {
        static Bar alloc() @selector("alloc");
        Bar init() @selector("init");
    
        override int foo() @selector("foo")
        {
            return super.foo() + 1;
        }
    }
    
    void main()
    {
        auto bar = Bar.alloc.init;
        scope (exit) bar.release();
    
        assert(bar.foo() == 4);
    }
    
  4. Deprecate Objective-C interfaces

    Prior to this release, it was necessary to represent an Objective-C class as a D interface. Now support for Objective-C classes has been implemented and the class keyword should be used instead.

    The reason for this deprecation is to allow extern (Objective-C) interfaces to be repurposed for representing Objective-C protocols in the future.

    Deprecated:

    extern (Objective-C) interface NSObject {} // deprecated
    

    Replace with:

    extern (Objective-C) class NSObject {}
    
  5. Context-aware assertion error messages

    With this release DMD supports generating context-aware assertion error messages when no error message has been provided by the user. For example, currently the following file:

    void main()
    {
        int a, b = 2;
        assert(a == b);
    }
    

    would yield this error when compiled and run:

    > dmd -run main.d
    [email protected](4): Assertion failure
    ––––––––––
    ??:? _d_assertp [0x1c4eae48]
    onlineapp.d:4 _Dmain [0x1c4ead85]
    

    However, with the new experimental compiler switch -checkaction=context it yields:

    > dmd -checkaction=context -run main.d
    [email protected](4): 0 != 2
    ––––––––––
    ??:? _d_assert_msg [0x4a3f9cf0]
    ??:? _Dmain [0x4a3f8fc4]
    

    The new switch already supports a variety of assertion messages:

    string dlang = "d2";
    assert(dlang != dlang); // ERROR: "d2" == "d2"
    
    struct S { int s; }
    assert(S(0) == S(1)); // ERROR: "S(0) !is S(1)"
    
    int a = 1, b = 2;
    assert(a > b); // ERROR: 1 <= 2
    

    Also if no error message can be generated, it will now fallback to displaying the text of the assert expression. For example, for this more complicated assert expression:

    void main()
    {
        int a, b = 2;
        assert(a && (a == b));
    }
    

    Compiling and running with -checkaction=context will now result in:

    > dmd -checkaction=context -run main.d
    [email protected](4): assert(a && (a == b)) failed
    ––––––––––
    ??:? _d_assert_msg [0xb7e5fdfc]
    ??:? _Dmain [0xb7e5fd40]
    

    This switch for context-aware assertion error messages is still experimental and feedback is welcome.

  6. Avoid calling the struct constructor from const-casts

    In previous versions of DMD, there was an undocumented interaction of const-cast with regular cast, ie. cast(), cast(const) and cast(immutable), where these casts would be expressed as cast(const(typeof(expr))) expr; hence if expr was of type Struct, these casts could potentially call its constructor Struct(expr), as per spec.

    The dangerous part however, was if this occurred with structs that used their first field as alias this, the implicit conversion via alias this would potentially satisfy an implicit struct constructor, leaving the other fields set to init and leading to apparent data corruption from a mere cast().

    In other words, cast() s to S(s) to S(s.implicitCast).

    This can no longer occur, since cast(), cast(const) and cast(immutable) will no longer generate an implicit constructor call. Implicit constructor calls to S() will only occur when one explicitly uses cast(S).

  7. dmd now supports expressive diagnostic error messages with -verrors=context

    With the new CLI option -verrors=context dmd will now show the offending line directly in its error messages. Consider this faulty program test.d:

    void foo()
    {
        a = 1;
    }
    

    Now run it with -verrors=context:

    > dmd -verrors=context test.d
    test.d(4): Error: undefined identifier a
        a = 1;
        ^
    

  8. memcmp() compares are no longer performed for struct equality tests, memberwise comparisons are done instead, per the spec

    The compiler would sometimes generate code for struct equality tests using memcmp() across the whole struct object. This assumed that:

    1. alignment holes were filled with 0, which is not always the case
    2. there were no floating point NaN values, which should compare as not equal even if the bit patterns match

    The spec requires that the comparison be done in a memberwise manner. This brings the implementation in line with this.

    Equality Expressions

    This can break existing code that relied on the former erroneous behavior. To correct such code, use one of the following:

    1. define an opEquals() operator overload to achieve the desired behavior
    2. use is instead of ==, as is will do a bit compare of the struct object.

    This new behavior is enabled with the -preview=fieldwise compiler switch. It will eventually become the default behavior.

  9. OSX 32-bit is no longer supported

    With this release, the DMD compiler will no longer officially support building 32-bit applications for OSX. For legacy purposes, older releases can be used.

    Motivation: The latest macOS release Mojave is the last version of OSX with support for running 32-bit applications. The D development team wants to focus its efforts and build/test infrastructure on active and important platforms.

  10. -preview and -revert command line switches have been introduced

    Command line switches adding or subtracting features of the D language have been normally added on an ad-hoc basis. Over time this has grown to:

    • -dip25
    • -dip1000
    • -dip1000
    • -dip1008

    Moreover, in parallel -transition has been introduced and the following DMD example is only a subset of the transitional features that DMD supports at the moment:

    dmd -transition=3449 -transition=10378 -transition=14246 -transition=14888 -transition=16997
    

    While these transitions also have a name alias, it's still not clear for the user whether the transition is (a) an experimental feature or an upcoming breaking change, (b) a warning or help on an upcoming change, or (c) revert of a change for users who don't want to deal with the breaking change for now.

    With this release, DMD gained a -preview command line switch which can be used to test upcoming features or potentially breaking changes. For example, with this release the list of upcoming features is:

    • -preview=dip25: Implements DIP25 (Sealed references)
    • -preview=dip1000: Implements DIP1000 (Scoped Pointers)
    • -preview=dip1008: Implements DIP1008 (@nogc Throwables)
    • -preview=markdown: Enables Markdown replacements in Ddoc
    • -preview=fixAliasThis: Enables a potentially breaking fix for alias this with which DMD will first check the this scope before searching in upper scopes
    • -preview=intpromote: Enables integral promotion for the unary +, - and ~ operators
    • -preview=dtorfields: Enables a potentially breaking fix which enables to destruct fields of partially constructed objects

    Adding new features can be disruptive to existing code bases. By initially putting them behind a -preview switch users will have ample opportunity to adapt to them at their own pace.

    Therefore, for end users the new -preview interface allows a glimpse into the future. As always, feedback and bug reports for all -preview features is very welcome and encouraged, so that potential problems or breakages can be caught early.

    Whenever a -preview feature gets enabled by default, it must pass on all Continuous Integrations, pass the test suite of about 50 of the most popular D packages and be without any other known major real-world issues on Bugzilla.

    However, as the behavior of DMD could still deviate slightly from previous versions, sometimes a -revert switch might be introduced by the D development team which allows an easy opt-out of a new feature for users in case they run into issues. As of now, DMD offers these reverts:

    • -preview=dip25: Reverts DIP25 changes
    • -revert=import: Revert to single phase name lookup

    Transitioning to new features (or fixing an important bug) is very often not trivial which is why an additional -transition exists. The -transition options are informational only and intended to help gauge the problems of an upcoming change or assist debugging these changes. For example, DMD currently supports these transitions:

    • -transition=field: List all non-mutable fields which occupy an object instance
    • -transition=checkimports: Emit deprecation messages about 10378 anomalies
    • -transition=complex: Emit deprecation messages for all usages of complex or imaginary types
    • -transition=tls: List all variables going into the thread local storage
    • -transition=vmarkdown: List instances of Markdown replacements in Ddoc

    -transition command line switches might be turned into actual deprecations if the importance of a change is considered high enough (compared to the impact on real-world code), but they are only intended as information for developers on where they would be affected by a certain transition.

    As all of this information will be updated continuously with each release, all three command line switches support a help page with either h, help or ? option listing all currently available options:

    > dmd -preview=help
    ...
    > dmd -revert=help
    ...
    > dmd -transition=help
    ...
    

    IMPORTANT: All old command line switches will continue to work and won't be deprecated. However, they were removed from the documentation and new code is encouraged to use -preview or -revert where applicable.

  11. Transition to C++11 character types

    With C++11 comes the advent of changed character type mangling. D's default behavior will be to conform to this after a one release transition period. A new switch -extern-std={c++98,c++11} is added to control the version that compatibility is set to. This switch sets __traits(getTargetInfo, "cppStd") to the value of __cplusplus that the corresponding version of the C++ standard defines.

    Of particular note is the new difference between wchar and wchar_t on Windows. This will manifest itself as compile errors when interfacing wchar* with wchar_t* code when calling the Windows API. A cast will resolve the issue.

    Going forward we recommend using WCHAR instead of wchar or wchar_t when interfacing to Windows API functions. (WCHAR is Microsoft Windows' 16 bit character type.)

    C++ Type Equivalence

    c++98 behavior:

    D Posix DMC++ Windows VC++ Windows
    wchar unsigned short wchar_t wchar_t
    dchar wchar_t unsigned unsigned
    wchar_t wchar_t wchar_t wchar_t
    WCHAR -- wchar_t wchar_t

    c++11:

    D Posix DMC++ Windows VC++ Windows
    wchar char16_t wchar_t char16_t
    dchar char32_t unsigned char32_t
    wchar_t wchar_t wchar wchar_t
    WCHAR -- wchar wchar_t

    Name Mangling:

    c++98 behavior:

    D Posix DMC++ Windows VC++ Windows
    wchar t _Y _W
    dchar w I I
    wchar_t w _Y _W

    c++11:

    D Posix DMC++ Windows VC++ Windows
    wchar Ds _Y _S
    dchar Di I _U
    wchar_t w _Y _W

Runtime changes

  1. Added GC.profileStats() to core.memory

    Allows access to current GC profiling information. See core.memory.GC.ProfileStats for a list of profile stats.

  2. Added core.stdcpp.new_

    Added core.stdcpp.new_, which exposes interfaces for C++ global new/delete operators. This allows D programs to conveniently allocate from the C++ heap, which is useful when sharing memory between languages.

  3. Added core.sys.linux.sched.CPU_COUNT.

    Added core.sys.linux.sched.CPU_COUNT, which returns the number of CPUs in set.

  4. Added core.sys.linux.sched.CPU_ISSET.

    Added core.sys.linux.sched.CPU_ISSET, which tests to see if cpu is a member of set.

  5. Moved std.conv.emplace, std.algorithm.mutation.move, std.algorithm.mutation.moveEmplace, and std.functional.forward to core/lifetime.d

    emplace is the counterpart to destroy, so it has been moved to also live in druntime (core/lifetime.d) where it is accessible by projects that use a shallow runtime library stack. move, moveEmplace, and forward are related low-level construction machinery which also belong in core.lifetime.

  6. GC cleanup can now be configured as a DRT GC option

    The default cleanup method for the GC is to unconditionally run a collection before runtime termination to finalize objects that are still alive and hold resources that affect system state outside the current process. This combines the worst of possible alternatives: it can cause a considerable delay and does not guarantee finalization of all objects as roots might still exist.

    The cleanup behaviour can now be configured by a DRT option to the GC configuration, e.g. by passing --DRT-gcopt=cleanup:none on the command line. Three options are provided:

    • collect: run a collection (the default for backward compatibility)
    • none: do nothing
    • finalize: all live objects are finalized unconditionally

    As usual, you can also embed the configuration into the application by redefining rt_options, e.g.

    extern(C) __gshared string[] rt_options = [ "gcopt=cleanup:none" ];
    
  7. A garbage collector with precise heap scanning can now be selected

    Precise heap scanning can now be enabled by a DRT option to the GC configuration, e.g. by passing --DRT-gcopt=gc:precise on the command line or by redefining rt_options. See the documentation for details.

  8. GC.realloc is now more consistent and robust

    The specification of core.memory.GC.realloc has changed slightly:

    • GC.realloc now returns null for failure. (It used to return the original pointer but that is is not a good indication of failure as it might also be returned on success. It can lead to overwriting memory if an enlargement was requested.)
    • as with GC.free, the caller has to ensure that there are no other live pointers to the memory passed to GC.realloc (This used to be required only when passing a new size 0).
    • as a consequence the GC is allowed to free the memory immediately (the previous implementation did this for objects larger than 4kB when shrinking).
    • block attribute bits on the existing block are only set if it is reused (the previous implementation didn't set bits if it reused a small block).

    The implementation now properly verifies that pointers are actually base pointers to allocated GC memory (passing other pointers could have crashed immediately or corrupt the GC).

  9. User supplied garbage collectors can now be linked with the runtime

    A GC registry has been implemented that allows to add garbage collector implementations by just linking them into the binary. See the documentation for details.

  10. Added core.stdcpp.allocator

    Added core.stdcpp.allocator, which exposes the C++ std::allocator<T> class. This is a required foundation for any of the allocating STL container types.

  11. char/wchar fields in most D runtime (core.* and rt.*) structs are now zero-initialized

    Fields that are single char/wchar or fixed-length arrays of such are now initialized to all zero bits instead of all one bits for most structs in the D runtime (core.* and rt.*` modules

    . This simplifies initialization and removes the need to store init data when it makes the entire struct zero-initialized. Most affected structs are used for interoperability with C APIs.

List of all bug fixes and enhancements in D 2.086.0:

DMD Compiler regressions

  1. Bugzilla 17684: [REG 2.062] static alias this bug or incomplete implementation?
  2. Bugzilla 18810: root/ctfloat depends upon backend
  3. Bugzilla 19519: cannot determine length of static array at compile time
  4. Bugzilla 19655: DMD generates wrong code for some circular dependencies
  5. Bugzilla 19656: D compiler fails to resolve circular module dependency when modules are compiled separately
  6. Bugzilla 19657: D compiler fails to resolve circular module dependency when modules are compiled together
  7. Bugzilla 19691: ICE on null default value for struct parameter in constructor
  8. Bugzilla 19718: DMD 2.085 changes to gsroa make DCD crashing
  9. Bugzilla 19722: botched implementation of semantic3Errors causes compiler assert fail
  10. Bugzilla 19724: Regression: wrong order of linker arguments, again: -L-l before -L--start-group
  11. Bugzilla 19730: if (auto x) {} isn't properly rejected
  12. Bugzilla 19746: DMD fails to compile some circular dependencies spiced with is (T == super) condition
  13. Bugzilla 19750: [Reg v2.070.2] DMD fails with some circular module refs with Template/Mixin instances
  14. Bugzilla 19774: wrong code caused by opIndex
  15. Bugzilla 19778: ICE when accessing empty array at compile time
  16. Bugzilla 19782: alias this appends null instead of inner/aliased element to array
  17. Bugzilla 19804: fails to compile with fixes size array T[1]... argument
  18. Bugzilla 19822: 2.086 regression wrt. union initializers
  19. Bugzilla 19833: The member as template cannot be acquired by getMember
  20. Bugzilla 19840: Ice in e2ir.d visit(CastExp) assert(false, "This case should have been rewritten to __ArrayCast in the semantic phase");

DMD Compiler bugs

  1. Bugzilla 5050: No way to declare delegates with ref return
  2. Bugzilla 10806: Interface covariance for more than one interface at once also broken
  3. Bugzilla 11934: Allow ref in foreach over range iff front returns by ref
  4. Bugzilla 13285: wrong codegen for destructor call of unnamed struct instance on 64 bit environments
  5. Bugzilla 15875: case of undetected circular reference in function parameter
  6. Bugzilla 17259: ICE with multiple mixin templates containing conflicting ctor declarations
  7. Bugzilla 17285: Segfault when types are used in array literals
  8. Bugzilla 17289: With Xcode 8.3 linker, warnings of "pointer not aligned"
  9. Bugzilla 17290: DMD crash due to circular reference in function return type
  10. Bugzilla 17651: Segfault when parsing Ddoc ESCAPES macro
  11. Bugzilla 18573: cast(void) leads to floating point return value not being popped from FPU stack
  12. Bugzilla 19051: Undefined functions Set/GetWindowLongPtr in mingw libs
  13. Bugzilla 19099: Struct with field that has postblit or destructor makes struct assignable
  14. Bugzilla 19442: multiple argument string mixin dont support char literals
  15. Bugzilla 19463: DIP1008 - _d_newclass is called instead of _d_newThrowable
  16. Bugzilla 19540: ICE when using typeof(new class {}) as default value for template parameter
  17. Bugzilla 19563: extern(C++) Incorrect ABI passing small struct
  18. Bugzilla 19569: overload resolution not right?
  19. Bugzilla 19635: -checkaction=context not working with attributes
  20. Bugzilla 19658: C++ enum mangling is wrong on Windows for other integer types
  21. Bugzilla 19679: variable escapes unnoticed when referenced in function called from function whose address is taken
  22. Bugzilla 19688: [ICE] Default function argument concatenation crashes DMD
  23. Bugzilla 19700: [2.085.0-beta.2] Obj-C wrong code overloading selectors and extern(D)
  24. Bugzilla 19717: case of segfault due to undetected forward reference
  25. Bugzilla 19719: Debugging string mixins using -mixin doesn't work
  26. Bugzilla 19734: isDataseg returns true for non-static declarations
  27. Bugzilla 19735: Error: variable extern symbols cannot have initializers
  28. Bugzilla 19744: Confusing error message when annotating a non-member function with return
  29. Bugzilla 19747: No debug line info for code in scope(exit)
  30. Bugzilla 19755: Compiler crash
  31. Bugzilla 19757: crash on invalid initializer at CTFE
  32. Bugzilla 19775: multiple argument string mixin doesn't expand tuples
  33. Bugzilla 19797: File.seek() terminates ungracefully on incorrect origin for -m32mscoff and -m64

DMD Compiler enhancements

  1. Bugzilla 8065: No way to write function/delegate literals returning ref T
  2. Bugzilla 12330: array.reserve at compile time too
  3. Bugzilla 15361: Incomprehensible error message: function declaration without return type.
  4. Bugzilla 15371: __traits(getMember) should bypass the protection
  5. Bugzilla 16271: Should be able to express that a lambda returns by reference
  6. Bugzilla 16657: alias this interacts with generated opCmp and opEquals
  7. Bugzilla 18825: No syntax for function literal returning a reference
  8. Bugzilla 19441: alias this causes partial assignment
  9. Bugzilla 19809: override block affects passing lambda as argument

Phobos regressions

  1. Bugzilla 18818: VariantN has unittests that are compiled into user modules
  2. Bugzilla 19777: [REG2.086a] SortedRange.opSlice is wrongly @trusted

Phobos bugs

  1. Bugzilla 18728: std.math.fdim does not handle nan correctly
  2. Bugzilla 19042: Chunking a padRight'ed range leads to range violations
  3. Bugzilla 19151: std.utf.toUTF16z() can not be used for LPWSTR
  4. Bugzilla 19681: std.range.padRight.popFront does not correctly adjust length
  5. Bugzilla 19689: large types cannot be moved
  6. Bugzilla 19751: std.stdio.File should not retry fclose after error
  7. Bugzilla 19765: std.algorithm.searching.findAmong doesn't save like it should
  8. Bugzilla 19799: templated string formatting fails with const Nullable!string
  9. Bugzilla 19806: phobos/std/uri.d: ietf link outdated

Phobos enhancements

  1. Bugzilla 15853: std.random save methods must be const
  2. Bugzilla 18806: minIndex should be able to take an input range but does not
  3. Bugzilla 19412: std.algorithm.cmp with default ordering can use memcmp for all size 1 unsigned types (instead of just char)
  4. Bugzilla 19686: sgn is too greedy

Druntime regressions

  1. Bugzilla 18530: [Reg 2.079] src/rt/tracegc.d(43): Deprecation: The delete keyword has been deprecated
  2. Bugzilla 19796: druntime PR#1982 broke array ops on double[] due to wrong assumption of integral element type

Druntime bugs

  1. Bugzilla 19723: wrong time values in GC.profileStats
  2. Bugzilla 19810: destroy does not work for C++ classes without destructor
  3. Bugzilla 19830: core.memory.__delete destructs arrays of structs in the wrong order

dlang.org bugs

  1. Bugzilla 11161: Document the default struct equality comparison and operator overloading
  2. Bugzilla 19621: The specification is self-contradictory on immutability

Installer regressions

  1. Bugzilla 18522: [REG 2.079-b2] MinGW import libraries interfere with platform SDK
)

Contributors to this release (55)

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

previous version: 2.085.0