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

previous version: 2.073.2 – next version: 2.074.1

Download D 2.074.0
released Apr 10, 2017

List of all bug fixes and enhancements in D 2.074.0.

Runtime changes

  1. TypeInfo.init has been @disabled.

    TypeInfo.init has been @disabled. Use TypeInfo.initializer instead.

    TypeInfo.init is a legacy alias of the method that is now called TypeInfo.initializer. The name change is necessary because the name "init" clashes with the type property of the same name (init).

    The legacy alias has been deprecated since 2.072.0. It's going to be removed in 2.075.0.

Library changes

  1. Added std.range.bitwise to create a bitwise adapter over an integral type range, consuming the range elements bit by bit.

    std.range.bitwise creates a bit by bit adapter over an integral type range:

    import std.range : bitwise;
    ubyte[] arr = [3, 9];
    auto r = arr.bitwise;
    r[2] = 1;
    assert(arr[0] == 7);
  2. Allow a generic function for std.variant.visit.

    If a lambda with a single generic parameter is provided as a handler to std.variant.visit, it is invoked for any type contained in the Algebraic which does not have a handler for that type.

    This allows something like:

    // Assume Circle, Square, and Triangle all define center()
    Algebraic!(Circle, Square, Triangle) someShape;
    auto center = someShape.visit!(x =>;

    This may be combined with explicitly typed handlers and a single fallback handler for an empty variant:

    Algebraic!(int, float, string) something;
    something.visit!((string s) => s.length, // called for string
                     x          => x,        // called for int/float
                     ()         => 0);       // called if empty
  3. Added std.utf.decodeBack which decodes the last UTF code point of given character range.
     import std.utf : decodeBack;
     string text = "サイト";
     assert(decodeBack(text) == 'ト');
     assert(decodeBack(text) == 'イ');
     assert(decodeBack(text) == 'サ');
  4. Performance improvements for std.algorithm.searching.{min,max}Element

    std.algorithm.searching.minElement and std.algorithm.searching.maxElement are now considerably faster (almost 2x in microbenchmarks) as a special path for the identity case is provided. This allows the compiler to make use of SSE instructions.

    The exact improvements are:

    % dmd -release -O test.d && ./test
    extremum.before = 54 secs, 12 ms, 347 μs, and 9 hnsecs
    extremum.after  = 29 secs, 521 ms, 896 μs, and 5 hnsecs

    % ldc -release -O3 test.d && ./test
    extremum.before = 13 secs, 186 ms, 176 μs, and 4 hnsecs
    extremum.after  = 2 secs, 241 ms, 454 μs, and 9 hnsecs

    See the benchmark code.

  5. std.format.formattedWrite now accepts a compile-time checked format string

    std.format.formattedWrite and related functions now have overloads to take the format string as a compile-time argument. This allows the format specifiers to be matched against the argument types passed. Any mismatch or orphaned specifiers/arguments will cause a compile-time error:

    import std.format, std.stdio;
    auto s = format!"%s is %s"("Pi", 3.14);
    assert(s == "Pi is 3.14");
    writefln!"%c is %s"('e', 1.61);
    static assert(!__traits(compiles, {s = format!"%l"();}));     // missing arg
    static assert(!__traits(compiles, {s = format!""(404);}));    // surplus arg
    static assert(!__traits(compiles, {s = format!"%d"(4.03);})); // incompatible arg
  6. New: Checked, a lightweight and highly configurable checked integral

    std.experimental.checkedint.Checked is a wrapper around any integral type that inserts checks against common sources of bugs: overflow in operators, mixed-sign comparisons, and casts that lose information.

    The example below illustrates the basic use of the facility:

    void main()
        import std.experimental.checkedint, std.stdio;
        writeln((checked(5) + 7).get); // 12
        writeln((checked(10) * 1000 * 1000 * 1000).get); // Overflow

    By default, all checks are enabled and the program is aborted if any check fails. An implementation based on hooks discoverable by using Design by Introspection allows unbounded customizations of both the checks to do, and the enforcement policy.

  7. Added std.traits.hasStaticMember to check whether a symbol is a static member of a type.
    import std.traits : hasStaticMember;
    struct S
        static int staticVar;
        int nonstaticVar;
    assert( hasStaticMember!(S, "staticVar"));
    assert(!hasStaticMember!(S, "nonstaticVar"));
  8. std.experimental.ndslice has been removed

    The synchronization between Phobos and Mir turned out to be a high amount of work with little gain. Users of std.experimental.ndslice are advised to switch to the upstream mir-algorithm package.

    It comes with a lot of new features

    ndslice design was changed. New ndslices can be created on top of random access iterators including pointers. There are three kinds of ndslice:

    • Contiguous - Contiguous in memory representation. It does not store strides and can be always flattened to 1 dimensional ndslice on top of the same iterator type.
    • Canonical - BLAS like. Stride for row dimension assumed to be equal to 1.
    • Universal - Numpy like. Each dimension has strides. All dimensions can be exchanged without reallocation. The old ndslice ABI corresponds to to the Universal ndslice.

  9. std.format.formattedRead now accepts ref parameters as input arguments.

    When std.format.formattedRead is used with ref parameters it is @safe. For compatibility it's still possible to use std.format.formattedRead with pointers:

    import std.format;
    void main() {
        string text = "1 2 3";
        int a, b, c;
        formattedRead(text, "%d %d %d", a, b, c);
        // pointers can still be used
        formattedRead(text, "%d %d %d", &a, &b, &c);
        // and even combined:
        formattedRead(text, "%d %d %d", a, &b, c);
  10. std.stdio.readf now accepts ref parameters as input arguments.
    import std.stdio : readf;
    void main() {
        // assume every line from stdin is similar to "1 2 3";
        int a, b, c;
        readf(" %d %d %d", a, b, c);
        // pointers can still be used
        readf(" %d %d %d, &a, &b, &c);
        // and even combined:
        readf(" %d %d %d, a, &b, c);
  11. MersenneTwisterEngine has been updated so that its template signature matches the C++11 standard.

    MersenneTwisterEngine has been updated so that its template signature matches the C++11 standard (adding two new template parameters, an extra tempering parameter d and the initialization multiplier f).

    Handling of the word size w has been fixed so that the generator will now properly handle cases where it is less than the number of bits in the chosen UIntType. This has been validated against the behaviour of a widely-used implementation of the C++11 standard.

    For anyone using the standard template instantiation Mt19937 this will have no noticeable effect. However, these will be breaking changes for anyone using the MersenneTwisterEngine template directly.

    The internal implementation has been reworked to use Ilya Yaroshenko's highly optimized algorithm from mir-random. This should have a very noticeable positive effect for anyone who cares about generating a lot of random numbers quickly.

    A new Mt19937_64 template instantiation has been added, corresponding to the standard 64-bit implementation of the algorithm (MT19937-64). This fixes

List of all bug fixes and enhancements in D 2.074.0:

DMD Compiler regressions

  1. Bugzilla 15947: [REG 2.069.0?] simple multithreaded program + "-profile=gc" = crash
  2. Bugzilla 16680: dmd doesn't use druntime optimized versions of subtraction array operations
  3. Bugzilla 17117: [REG2.073] erroneous "escaping reference to local variable"
  4. Bugzilla 17123: [REG 2.073] Issues with return @safe inference
  5. Bugzilla 17291: [REG 2.074-b1] windows: invalid relocation entries
  6. Bugzilla 17292: [REG 2.069] Windows: dmd causes "out of memory" when using less than 2GB of memory

DMD Compiler bugs

  1. Bugzilla 6400: opDispatch with WithStatement
  2. Bugzilla 15428: __traits(compiles, super()) cause error "multiple constructor calls" later
  3. Bugzilla 15616: missing candidate in error message
  4. Bugzilla 15676: The compiler does not preserve @disable while generating .di files
  5. Bugzilla 16083: AliasSeq loses type of enums that have the same value
  6. Bugzilla 16245: the message emitted when a const function mutates members is misleading
  7. Bugzilla 16346: Enum used as a constructor evaluates to the underlying type, not to the enum type.
  8. Bugzilla 16355: __xpostblit incorrectly generated for a struct with a zero-length static array
  9. Bugzilla 16382: Passing &this as a CT parameter seg faults dmd
  10. Bugzilla 16483: ICE in expression.d from typeof
  11. Bugzilla 17049: [scope] member methods not escape checked like free functions
  12. Bugzilla 17057: trait "allMembers" incorrectly includes imports
  13. Bugzilla 17076: [scope] compiling identity function template with -dip1000 causes error
  14. Bugzilla 17086: DMD segfault with multiple template matches and invalid code
  15. Bugzilla 17255: Warning when compiling ddmd.backend/ptrntab.c about type-punning

DMD Compiler enhancements

  1. Bugzilla 14859: static declared array with more than 16MB size should be allowed in struct and class declaration
  2. Bugzilla 16513: Speed up TemplateInstance.findExistingInstance hash
  3. Bugzilla 16697: Extend IsExpression to accept __vector as a TypeSpecialization
  4. Bugzilla 17111: DMD accepts switch statement with non-const case variables

Phobos regressions

  1. Bugzilla 17282: [REG 2.074.0-b1] std.conv.parse throws with -debug

Phobos bugs

  1. Bugzilla 8260: * used three or more times on an array inside std.format.formattedRead and not guarded by template constraint
  2. Bugzilla 8471: std.stdio.readf should be @trusted
  3. Bugzilla 9615: std.conv.parse!(T[]) fails on trailing comma
  4. Bugzilla 11703: Typedef properties should not be of the original type
  5. Bugzilla 13619: std.container.array capacity not updated when length increases
  6. Bugzilla 16342: std.algorithm.fill can't fill a char[]?
  7. Bugzilla 16442: FrontTransversal fails with empty ranges
  8. Bugzilla 16564: KRRegion.empty sometimes returns
  9. Bugzilla 16642: byCodeUnit doesn't work AutodecodableStrings unless they're actually strings or alias a variable that's a string
  10. Bugzilla 16824: std.experimental.allocator.dispose leaks memory for arrays of more than 1 dimension
  11. Bugzilla 17075: ctRegex BacktrackingMatcher.prevStack: free(): invalid pointer
  12. Bugzilla 17102: std.write.file generates a segmentation fault when the file name is a string with a default value
  13. Bugzilla 17116: std.typecons.ReplaceType is not able to process const delegate
  14. Bugzilla 17153: std.container.array.Array cannot be used in @nogc code
  15. Bugzilla 17154: std.conv.toChars doesn't support $ in slicing
  16. Bugzilla 17157: ctRegex.matchAll doesn't set last item in Captures
  17. Bugzilla 17177: AutoImplement fails on function overload sets with "cannot infer type from overloaded function symbol"
  18. Bugzilla 17217: doesn't work with non char arrays
  19. Bugzilla 17229: File.byChunk (ubyte) w/ stdout.lockingTextWriter corrupts utf-8 data (and is very slow)
  20. Bugzilla 17243: std.math.{FloatingPointControl,ieeeFlags} don't work on x86_64
  21. Bugzilla 17247: should not assume sliceable range is assign-copyable to ubyte[].

Phobos enhancements

  1. Bugzilla 10900: Mersenne Twister should have a 64-bit (ulong) version
  2. Bugzilla 13017: opEquals for null std.typecons.Nullable
  3. Bugzilla 16281: std.format.formattedRead should use ref instead of requiring pointers
  4. Bugzilla 16323: std.utf.decodeBack
  5. Bugzilla 16736: Retrieving cUrl time values is quite cumbersome

Druntime regressions

  1. Bugzilla 17130: [Reg 2.074] ambiguous implicit super call when inheriting core.sync.mutex.Mutex

Druntime bugs

  1. Bugzilla 16470: Segfault with negative array length

Druntime enhancements

  1. Bugzilla 8411: core.time: No easy way to check if Duration is empty bugs

  1. Bugzilla 17115: [404 Not Found] std.concurrencybase enhancements

  1. Bugzilla 16991: Make writeln documentation palatable

Tools bugs

  1. Bugzilla 17139: [BLOCKING] dscanner needs to handle 'scope' function attributes
previous version: 2.073.2 – next version: 2.074.1