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

previous version: 2.086.1 – next version: 2.087.1

Download D 2.087.0
released Jul 01, 2019

2.087.0 comes with 22 major changes and 44 fixed Bugzilla issues. A huge thanks goes to the 63 contributors who made 2.087.0 possible.

List of all bug fixes and enhancements in D 2.087.0.

Compiler changes

  1. A new syntax is available to declare an alias to a function type

    It's now possible to declare an alias to a function type using the alias syntax based on the assignment operator. The declaration consists of the return type, followed by parameters and ends with optional (member) function attributes. See the AliasDeclarationY rule for more details.


    alias int OldStyleFunAlias(string);
    alias NewStyleFunAlias = int(string);
    int fun(string p){return 0;}
    static assert(is(typeof(fun) == NewStyleFunAlias));

    Note that an advantage compared to the old syntax is that the new allows a shortcut to function template types:

    alias SetterProto(T) = void(T t);
    alias GetterProto(T) = T() const;
  2. Add Markdown-inspired features to Ddoc

    With the -preview=markdown flag to dmd, Ddoc now supports Markdown features like headings, emphasized text, links and more. The full list of features is described in the Ddoc documentation page.

    Use the -transition=vmarkdown flag together with the -preview=markdown flag to log all instances of Markdown features as they're processed in your documentation.

  3. scope as a type constraint on class declarations is deprecated.

    scope as a type constraint on class declarations has been deprecated for quite some time. However, starting with this release, the compiler will emit a deprecation warning if used.

    scope class C { }  // Deprecation: `scope` as a type constraint is deprecated.  Use `scope` at the usage site.

    Note that this does not apply to structs. Deprecation of scope as a type constraint on structs is still awaiting a decision.

  4. Usage of this and super as types is obsolete

    Prior to this release, this and super could be used as both data or types depending on the context, but was deprecated about a year ago. Starting with this release using this or super as a type will result in a compiler error.

    class C
        shared(this) x;    // Error: Using `this` as a type is obsolete. Use `typeof(this)` instead
    class D : C
        shared(super) a;   // Error: Using `super` as a type is obsolete. Use `typeof(super)` instead
        super b;           // Error: Using `super` as a type is obsolete. Use `typeof(super)` instead

    Use typeof(super) or typeof(this) instead.

    class C
        shared(typeof(this)) x;
    class D : C
        shared(typeof(super)) a;
        typeof(super) b;
  5. Turn deprecation into error for some invalid integer literals.

    With this release DMD will issue an error when some invalid integer literals like 0b or 0x are used. Example:

    auto a = 0b;  // Error: `0b` isn't a valid integer literal, use `0b0` instead
    auto a = 0x;  // Error: `0x` isn't a valid integer literal, use `0x0` instead
  6. fix Issue 16002 - Add is(sym == module) and is(sym == package)

    This enhancement adds two new forms of the is(), expression, which determine whether a given symbol represents a module or package.

    It also adds __traits(isModule, sym) and __traits(isPackage, sym), which do the same thing.

  7. Local templates can now receive local symbols.

    With this release local and member templates can be instantiated with local symbols.

    struct S
        private int _m;
        void exec(alias fun)()
        int localVar;
        void set(int i)
            localVar = i;
        auto obj = S(10);
        assert(localVar == 10);

    This was a long-standing limitation that disturbed the metaprograming experience.

    See issue 5710.

  8. Windows: The mingw based runtime and platform import libraries can now be selected explicitly

    When specifying -mscrtlib=msvcrt100 explicitly on the command line to dmd, detection of a Visual Studio installation is skipped and the redistributable VC2010 dynamic runtime library and mingw based platform import libraries will be used unconditionally. The LLD linker (provided by the LLVM project) will be invoked instead of the Microsoft linker.

  9. Floating point types now use a quiet nan as the .init value

    Prior to this release, float.init, double.init and real.init used a signalling nan. They now use a quiet nan, which is the same as the corresponding .nan value.

    Old behaviour:

    double a = double.init, b = double.nan;
    writefln("%x",*cast(ulong*)&a); // 7ff4000000000000
    writefln("%x",*cast(ulong*)&b); // 7ff8000000000000

    New behaviour:

    double a = double.init, b = double.nan;
    writefln("%x",*cast(ulong*)&a); // 7ff8000000000000
    writefln("%x",*cast(ulong*)&b); // 7ff8000000000000
  10. Class allocators and deallocators are now obsolete

    Starting with this release any use of class allocators or deallocators will result in a compilation error.

    See the deprecated features page for more information.

  11. The deprecation phase for access checks is finished

    The -transition=import and -transition=checkimports switches no longer have an effect and are now deprecated. Symbols that are not visible in a particular scope will no longer be found by the compiler.

  12. Initialization of immutable global data from static this is deprecated

    Prior to this release, the following code was possible:

    module foo;
    immutable int bar;
    static this()
        bar = 42;

    However, module constructors (static this) run each time a thread is spawned, and immutable data is implicitly shared, which led to immutable value being overriden every time a new thread was spawned. The simple fix for this is to use shared static this over static this, as the former is only run once per process.

  13. Struct constructors with all-default parameter will now error

    Since 2.070.0, the following code has been giving deprecations:

    struct Oops
        this (int universe = 42) {}

    It will now error out.

  14. Template alias parameters now match basic types as a conversion.

    With this release, templates with alias parameters can be instantiated with basic types, such as int or void function().

    template Example(alias A) { alias Example = A[]; }
    alias IntArray = Example!int;
    template MatchType(T) { enum MatchType = "type"; }
    template MatchType(alias A) { enum MatchType = "alias"; }
    // alias matches, but type matches take priority.
    static assert (MatchType!int == "type");

    Templates with alias parameters already matched named types, lambdas, and even value literals. Templates with variadic parameters already matched basic types. This led to strange replacements for alias such as template Template(T...) if (T.length == 1). Those replacements are no longer necessary.

    As a consequence, in some cases templates will match that did not used to. For instance, a template may have falsely relied on alias parameters being "something callable" vs. type parameters being "the type of something callable", such as

    void fun(T...)(T callable) { ... }
    void fun(alias A)() { ... }

    Such overloads may now need to explicitly check whether A is callable in the second case:

    void fun(alias A)() if (__traits(compiles, A())) { ... }
    // shorter, but may miss cases like structs with a static opCall
    void fun(alias A)() if (!isType!A) { ... }
  15. 32 Bit Linux now uses XMM registers for float and double rather than the x87.

    This should substantially speed up routine float and double processing. SIMD vector operations, however, are still not support on 32 bit Linux code because of issues with 16 byte stack alignment.

    This means that generated code will no longer work on older x86 processors that do not have XMM registers. If this is an issue, please file a bug report.

Runtime changes

  1. Convert FreeBSD's sys/ttycom.h into core.sys.posix.sys.ttycom

    In FreeBSD, as in OSX, the tty part of ioctl is defined in sys/ttycom.h which is included by sys/ioctl.h. In druntime, there were OSX part of definitions in ttycom.d, but there were no FreeBSD equivalent. This change implements FreeBSD part of ttycom.d and ioccom.d, and public import core.sys.posix.sys.ttycom in ioctl.d. The OSX users and FreeBSD users can now use full ioctls related to tty by importing core.sys.posix.sys.ioctl, like including sys/ioctl.h in C language. (For example, TIOCGWINSZ ioctl was not provided in FreeBSD.) Since there are only version(OSX) and version(FreeBSD) part in ttycom.d, public import'ing core.sys.posix.sys.ttycom from ioctl.d will make no harm to other platforms.

  2. GC now marks the heap with multiple threads

    The garbage collector now uses available CPU cores to mark the heap faster. This reduces pause times for a collection considerably.

    By default, the GC uses all available logical cores of your CPU. This might affect your application if it has threads that are not suspended during the mark phase of the collection. You can configure the number of additional threads used for marking by DRT option parallel to the GC configuration, e.g. by passing --DRT-gcopt=parallel:2 on the command line. A value of 0 disables parallel marking completely.

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

    extern(C) __gshared string[] rt_options = [ "gcopt=parallel:0" ];
  3. Add the clone and unshare functions to core.sys.linux.sched

    clone(2) and unshare(2) are Linux-specific system calls. Bindings have been added to the corresponding D module, as well as the CLONE_* constants that are used as flags to these functions.

Library changes

  1. Added a table of control characters in ASCII table

    There is a new enumerated type std.ascii.ControlChar. It has values for every control character in ASCII table and has a base type of char, allowing for alternative markup of strings with control characters:

    import std.ascii, std.conv;
    with (ControlChar) assert(text("Phobos", us, "Deimos", us, "Tango", rs) == "Phobos\x1FDeimos\x1FTango\x1E");
  2. Count processors via sched_getaffinity on Linux

    On GNU/Linux usable number of processors may be restricted if a process runs in containers. In case it's better to use sched_getaffinity(2).

    import std.parallelism;
    writeln(totalCPUs); // 4
    writeln(totalCPUs); // 1: runs on `taskset -c 0`
  3. Add overload std.algorithm.sorting.schwartzSort!(alias transform, SwapStrategy ss, R)

    std.algorithm.sorting.schwartzSort now has an overloaded version that can be used to provide a SwapStrategy without also explicitly specifying the predicate to sort by.

    auto s1 = a.schwartzSort!(abs, SwapStrategy.stable);
    // The old syntax still works.
    auto s2 = a.schwartzSort!(abs, "a < b", SwapStrategy.stable);
  4. Phobos is now compiled with -preview=dip1000

    Phobos and Druntime are now compiled with -preview=dip1000.

    This is a major milestone in the transition to DIP1000. Hence, end users can now start using -preview=dip1000 in their own code bases.

    As always, any encountered issue should be reported to the issue tracker.

List of all bug fixes and enhancements in D 2.087.0:

DMD Compiler regressions

  1. Bugzilla 19661: DMD 2.084.0 SIGSEGV in std.traits.isFunction
  2. Bugzilla 19758: (0x01 & 0xFF) == 0 by dmd 2.085.0(-m64) on Windows

DMD Compiler bugs

  1. Bugzilla 711: combining mixins and overriding causes inifite loops
  2. Bugzilla 1170: Cannot forward reference a type defined in a MixinStatement
  3. Bugzilla 4923: immutable module variables are modifiable in non-shared module constructors
  4. Bugzilla 5710: cannot use delegates as parameters to non-global template
  5. Bugzilla 6541: using synchronized on a templated method crashes the compiler
  6. Bugzilla 9029: Built-in types treated specially for alias parameters
  7. Bugzilla 10739: Struct defined by template mixin leads to order-sensitivity of declarations
  8. Bugzilla 13471: CTFE glitch when executing std.digest.crc.crc32Of() and checking the result with enforce(). (keyword: uninitialized variable)
  9. Bugzilla 13848: overlapping initialization for r
  10. Bugzilla 17141: Type Inference Incorrectly Converts Characters to Integers
  11. Bugzilla 18794: Compiling with -O causes runtime segfault
  12. Bugzilla 18958: extern(C++) wchar, dchar mangling not correct
  13. Bugzilla 19234: betterC TypeInfo error when using slice copy on Structs
  14. Bugzilla 19813: Generated bt instruction seg faults, high 32 bits of register is garbage
  15. Bugzilla 19814: Nested code blocks in Ddoc break formatting
  16. Bugzilla 19829: __traits(isSame) returns true for some non-local delegate lambdas even when they are different
  17. Bugzilla 19870: Generated Copy Constructor disables default construction
  18. Bugzilla 19890: ICE: Segmentation fault with negative array size
  19. Bugzilla 19891: Confusing error message for auto ref parameters with default values
  20. Bugzilla 19893: extern(C++, "ns") should count as module scope for version declarations
  21. Bugzilla 19905: Floating point .init should be bitwise identical to .nan
  22. Bugzilla 19920: __trait(parent, ...) broken with extern(C++,"ns") nested in scopes
  23. Bugzilla 19971: wrong string literals in "cannot pass argument" errors
  24. Bugzilla 19995: parameter attributes are accepted in parameter-less functions

DMD Compiler enhancements

  1. Bugzilla 10665: The documentation produced by ddoc should clearly list all public imports of a module
  2. Bugzilla 16002: Add __traits(isModule) and __traits(isPackage)
  3. Bugzilla 16020: Allow AliasDeclarationY to express function types
  4. Bugzilla 19856: [aApplycd2]: foreach (int) doesn't work on BigEndian targets

Phobos regressions

  1. Bugzilla 17358: [REG 2.074.0] std.stdio.File.lockingTextWriter.put no longer accepts chains of characters
  2. Bugzilla 19740: Incorrect result of BigInt * BigInt

Phobos bugs

  1. Bugzilla 11061: std.variant.Variant equality comparison always returns false for static array literals.
  2. Bugzilla 19226: std.typecons.Nullable(T, T nullValue) doesn't fully handle non-self-equal nullValue
  3. Bugzilla 19781: etc.c.zlib should be @nogc
  4. Bugzilla 19836: Excessive probability of UUID collisions in std.uuid.randomUUID
  5. Bugzilla 19883: Cyclic constructor call for BigInt(dstring)
  6. Bugzilla 19899: std.bitmanip.bitsSet should accept const arguments
  7. Bugzilla 19939: std.format %13,3.2f does not count width correctly

Phobos enhancements

  1. Bugzilla 6657: dotProduct overload for small fixed size arrays
  2. Bugzilla 13965: More handy schwartzSort
  3. Bugzilla 19513: Use sched_getaffinity(2) to get the number of CPU cores if available
  4. Bugzilla 19892: Add CTFE support for std.bitmanip: nativeToBigEndian, bigEndianToNative, littleEndianToNative, nativeToLittleEndian

Druntime bugs

  1. Bugzilla 19861: core.cpuid reports the wrong number of threads

Contributors to this release (63)

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

previous version: 2.086.1 – next version: 2.087.1