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

Download D 2.080.0
released May 01, 2018


List of all bug fixes and enhancements in D 2.080.0.

Compiler changes

  1. Class allocators and deallocators have been deprecated

    Class allocators and deallocators have been planned for deprecation for years. Starting with this release the following code will emit deprecation messages.

    class C
    {
        new(size_t size)         // deprecation message
        {
            return malloc(size);
        }
    
        delete(void* obj)        // deprecation message
        {
            free(obj);
        }
    }
    

    See the Deprecated Features for more information.

    Many alternatives for class allocators/deallcators exist. Among them is the generic std.experimental.allocator.make and std.experimental.allocator.dispose from the allocator package. For other alternatives, see the recent article about memory allocation on the DBlog and the D Wiki memory management article.

    Users have leveraged allocators in order to disable GC allocation, as illustrated in the following example:

    class C
    {
        @disable new(size_t size);
    }
    
    void main()
    {
        auto c = new C();  // Error: allocator `new` is not callable because it is annotated with `@disable`
    }
    

    That idiom will remain, but has been enhanced with this release to no longer require the size_t argument. That is, starting with this release, the following syntax is also permitted:

    class C
    {
        @disable new();
    }
    
    void main()
    {
        auto c = new C();  // Error: allocator `new` is not callable because it is annotated with `@disable`
    }
    
  2. Deprecate double initialization of immutable fields inside constructor

    Inside a constructor scope, assigning to aggregate declaration (class/struct) members is done by considering the first assignment as initialization and subsequent assignments as modifications of the initially constructed object. For const/immutable fields the initialization is accepted in the constructor, but subsequent modifications are not. Example:

    struct A
    {
        int a;
        immutable int b;
        this(int a, int b)
        {
            this.a = a;
            this.b = b;
    
            this.a = 7; // OK, a is mutable
            this.b = 9; // Error: immutable field b initialized multiple times
        }
    }
    

    However, Bugzilla 18719 shows that this rule does not apply when inside a constructor scope there is a call to a different constructor:

    struct A
    {
        immmutable int a;
        this()
        {
            this(42);
            this.a = 5;  // second initialization of immutable field
        }
    
        this(int a)
        {
            this.a = a;
        }
    }
    

    The above code wrongfully compiled succesfully before this patch, accepting the double initialization of the immutable field a. After this patch, this.a = 5 will issue a deprecation warning stating that a is initialized multiple times.

  3. Issue 18736 - constructor calls allowed after case labels

    Delegating constructor calls are not allowed after labels, but case labels and default labels should also count as labels.

    class A
    {
        this(char c) { }
    
        this(int i)
        {
            switch (i)
            {
                case 1:  break;
                default: break;
            }
            this('c'); // now gives an error
        }
    }
    

    This is necessary so the compiler can guarantee that each field is initialized exactly once. To get code like the above to pass the compiler, replace it with an if-then sequence.

  4. fix Issue 5227 - X ^^ FP at compile-time

    The pow operator ^^ can now be used by CTFE.

    Adds these std.math functions to those that can be used by CTFE:

    round floor ceil trunc log log2 log10 pow expm1 exp2 fmin fmax copysign fma

  5. add __traits(isReturnOnStack, func)

    Determines if a function's return value is placed on the stack, or is returned via registers. For more details, see isReturnOnStack.

  6. Support for calling Objective-C class (static) methods has been added.

    Previously to call an Objective-C class method it was necessary to make explicit calls to the Objective-C runtime. The following code is an example of the old way to call a class method:

    extern (C) Class objc_lookUpClass(in char* name);
    
    extern (Objective-C)
    interface Class
    {
        NSObject alloc() @selector("alloc");
    }
    
    extern (Objective-C)
    interface NSObject
    {
        NSObject init() @selector("init");
    }
    
    void main()
    {
        auto cls = objc_lookUpClass("NSObject");
        auto o = cls.alloc().init();
    }
    

    The above code can now be replaced with the following:

    extern (Objective-C)
    interface NSObject
    {
        static NSObject alloc() @selector("alloc");
        NSObject init() @selector("init");
    }
    
    void main()
    {
        auto o = NSObject.alloc().init();
    }
    

    Note the use of the static attribute in the method declaration.

  7. Deprecate the use of a const/immutable/shared postblit

    Before this patch, if a postblit was declared const/immutable/shared the compiler would have accepted the declaration but there would have been no way of calling the postblit succesfully, except for const due to the implicit conversion mutable -> const. Even though calling a const posblit is possible, there is no way to modify the fields of the newly copied struct:

    struct S
    {
        int n
        this(this) const
        {
            ++n;   // Error: cannot modify this.n in const method
        }
    }
    
    void main()
    {
        S a;
        auto a2 = a;
    }
    

    With this release, if a postblit contains const/immutable/shared in its signature, a deprecation message will be emitted.

  8. The deprecation for read-modify-write operations on shared variables has ended

    Read-modify-write operations are not allowed for shared variables:

    shared int i;
    i++; // Error: read-modify-write operations are not allowed for shared variables
    

    Use core.atomic.atomicOp instead:

    import core.atomic : atomicOp;
    shared int i;
    atomicOp!"+="(i, 1);
    
  9. The deprecation for switch cases which skip the declaration of a variable has ended

    Usage of a variable which is declared in another switch case now results in an error.

    int i = 2;
    switch (i)
    {
        case 1:
        {
            int j;
        case 2:
            j++;
            j.writeln; // BUG: j is not initialized and e.g. prints -321532879
            break;
        }
        default:
            break;
    }
    

    If this behavior is wanted, it can explicitly requested by using void initialization:

    int i = 2;
    switch (i)
    {
        case 1:
        {
            int j = void;
        case 2:
            j = 2;
            j.writeln;
            break;
        }
        default:
            break;
    }
    

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
    }
    
  2. std.math.rndtonl has been deprecated

    std.math.rndtonl is a rounding function only available when using the Digital Mars C Runtime on Windows. As this function is not cross-platform, it has been deprecated, and will be removed on version 2.089. Please use std.math.round instead.

  3. Added the SharedBitmappedBlock, as the thread-safe version of the regular BitmappedBlock.

    The new std.experimental.allocator.building_blocks.bitmapped_block.SharedBitmappedBlock and its single-threaded version can now be instantiated with Yes.multiblock or No.multiblock. If instantiated with Yes.multiblock (the default behavior), each allocation can return an arbitrary number of blocks. With No.multiblock however, any allocation request can't exceed the block size. This allows for greater performance on both single and multithreaded environments.

    // The 'BitmappedBlock' is implicitly instantiated with Yes.multiblock
    auto a = BitmappedBlock!(blockSize, 8, Mallocator, Yes.multiblock)(numBlocks * blockSize);
    
    // Instantiated with Yes.multiblock, can allocate more than one block at a time
    void[] buf = a.allocate(2 * blockSize);
    assert(buf.length == 2 * blockSize);
    assert(a.deallocate(buf));
    
    // Instantate the 'BitmappedBlock' with No.multiblock
    auto a = BitmappedBlock!(blockSize, 8, Mallocator, No.multiblock)(1024 * blockSize);
    
    // Since instantiated with No.multiblock, can only allocate at most the block size
    void[] buf = a.allocate(blockSize + 1);
    assert(buf is null);
    

    For shared the same rules apply, we only need to replace BitmappedBlock with SharedBitmappedBlock.

  4. Implemented a new allocator, AlignedBlockList and its thread-safe version SharedAlignedBlockList

    std.experimental.allocator.building_blocks.aligned_block_list.AlignedBlockList represents a list of allocators which allows for deallocations in constant time. Although allocations are in theory served in linear searching time, deallocate calls take Ο(1) time, by using aligned allocations. The ParentAllocator must implement alignedAllocate.

    std.experimental.allocator.building_blocks.aligned_block_list.SharedAlignedBlockList has the same semantics as its single threaded version, however the internal allocators must be in addition marked as shared.

  5. std.exception.enforceEx was deprecated in favor of std.exception.enforce

    With 2.079 std.exception.enforce became a complete super set of std.exception.enforceEx

    Corrective action

    Replace:

    import std.exception;
    alias enf = enforceEx!Exception;
    assertNotThrown(enf(true));
    assertThrown(enf(false, "blah"));
    

    with:

    import std.exception;
    alias enf = enforce!Exception;
    assertNotThrown(enf(true));
    assertThrown(enf(false, "blah"));
    
  6. Fixed digits grouping for floating point number without decimal part

    std.format.formatValue now correctly groups digits in the output string by inserting a group separator character (,) every n characters specified by the Separator grammar rule in cases with zero decimal precision specified in the format string for floating point numbers.

    No group separators at all are inserted for floating point numbers when formatted with zero precision (i.e. no decimal digits) in Phobos before this fix, regardless of the respective decimal part of the formatted number.

    import std.format;
    
    assert(format("%,3.2f", 1172.009) == "1,172.01");
    assert(format("%,3.0f", 1172.009) == "1,172");
    assert(format("%#,3.4f", 1303.2508) == "1,303.250,8");
    assert(format("%#,3.0f", 1303.2508) == "1,303.");
    
    // original (buggy) behaviour before this fix
    //assert(format("%,3.0f", 1303.2508) == "1303");
    //assert(format("%,3.0f", 1303.) == "1303");
    
    // original (correct) behaviour before this fix
    //assert(format("%,3.1f", 1303.2508) == "1,303.3");
    //assert(format("%,3.2f", 1303.) == "1,303.00");
    //assert(format("%,3f", 1303.) == "1,303.000,000");
    
  7. std.functional.binaryReverseArgs was deprecated in favor of std.functional.reverseArgs

    std.functional.reverseArgs is a full super set of std.functional.binaryReverseArgs.

    Correct action: replace binaryReverseArgs with reverseArgs.

  8. apply was added to std.typecons.

    apply is an operation for std.typecons.Nullable values that "unpacks" the Nullable, performs some operation (that is passed as a template parameter), then packs the result into another Nullable if necessary. When the initial Nullable is null, the resulting Nullable is also null and the function is not called.

    Nullable!int n;
    alias square = i => i * i;
    n = n.apply!square; // does nothing if isNull
    assert(n.isNull);
    n = 2;
    assert(n.apply!square.get == 4);
    

Tools changes

  1. rdmd can now be used as a shell in makefiles

    With gnu make(3.82 or higher), rdmd can now be used in makefiles. This is accomplished by setting the SHELL and .SHELLFLAGS to /usr/bin/rdmd and --eval respectively.

    .ONESHELL:
    SHELL = /usr/bin/rdmd
    .SHELLFLAGS = --eval
    hello.txt:
    	import std.file;
    	write("$@","hello world\n");
    

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
  2. Bugzilla 18197: [REG2.073] Internal error: backend\cgcod.c 1659
  3. Bugzilla 18489: [REG 2.073]Internal error: dmd/backend/cgcod.c 1688

DMD Compiler bugs

  1. Bugzilla 5212: no escape analysis for typesafe variadic function arguments
  2. Bugzilla 5227: X ^^ FP at compile-time
  3. Bugzilla 9433: Deprecate delete
  4. Bugzilla 12486: Function returning struct isn't called if enum of its result is accessed
  5. Bugzilla 14997: __ctor present in error message
  6. Bugzilla 15653: IFTI fails for immutable parameter
  7. Bugzilla 15660: break immutable with pure function and mutable reference params
  8. Bugzilla 16107: [ICE] - Internal error: backend/cgcod.c 2297
  9. Bugzilla 16189: Optimizer bug, with simple test case
  10. Bugzilla 16555: Stack corruption when calling multi-parameter outer function from nested function
  11. Bugzilla 16578: bogus deprecation - switch skips declaration of variable
  12. Bugzilla 17284: Template function attribute inference wrongly infers @safe for accessing overlapping pointer fields in unions
  13. Bugzilla 17423: pointer assignment to this in member function is not accounted for
  14. Bugzilla 17874: Segmentation fault when constructing a struct with a static array of structs containing floats
  15. Bugzilla 17892: Scope analysis with -dip1000 fails for templated structs
  16. Bugzilla 17918: [Reg 2.072] ICE with unknown symbol in base class
  17. Bugzilla 17959: [DIP1000] Can store scope delegate in non-scope member
  18. Bugzilla 17991: ICE with imports without module
  19. Bugzilla 18000: [scope] auto-generated opAssign not scope aware
  20. Bugzilla 18034: SIMD optimization issues
  21. Bugzilla 18130: ICE on zero-length out array parameter
  22. Bugzilla 18199: Error with lambda in struct initializer
  23. Bugzilla 18242: DMD Segmentation fault.
  24. Bugzilla 18282: [Scope][DIP1000]Assignment of local variable to scope variable not recognized by compiler
  25. Bugzilla 18459: The static array ABI doesn't match the struct ABI
  26. Bugzilla 18461: codegen bug - OPbt expressions and assignments to ambiguous symbols
  27. Bugzilla 18474: Postblit not working in shared structs
  28. Bugzilla 18484: [dip1000] Subtype allows reference to escape with implicit casting
  29. Bugzilla 18504: Assert in synchronized crashes with SIGILL on exit
  30. Bugzilla 18505: delete deprecation message is misleading
  31. Bugzilla 18534: Wrong code for ?: operator when compiling with -O
  32. Bugzilla 18553: Inline assembler: CR2, CR3 control registers not available in 64-bit code
  33. Bugzilla 18554: tupleof ignoring private shouldn't be accepted in @safe code
  34. Bugzilla 18568: partially overlapping assignments have undefined behavior but are accepted in @safe code
  35. Bugzilla 18575: making delegate from member function can lead to unsafe code
  36. Bugzilla 18576: Compiler not doing RVO with auto returns
  37. Bugzilla 18597: more unsafe unaligned pointer errors
  38. Bugzilla 18607: using labelled continue in tuple foreach can break pure and @safe
  39. Bugzilla 18644: [dip1000] escape of outer local not detected
  40. Bugzilla 18661: auto ref and return attribute inference
  41. Bugzilla 18708: Flow analysis in constructors not done correctly for if, ||, &&
  42. Bugzilla 18719: Doubly-called constructor against member when using forwarding constructors
  43. Bugzilla 18736: constructor calls allowed after case labels
  44. Bugzilla 18737: An assert(0) should be a leaf in constructor flow analysis
  45. Bugzilla 18753: chunkBy compile error causes ICE
  46. Bugzilla 18762: DMD should use a unique path/filename for __stdin.o

DMD Compiler enhancements

  1. Bugzilla 15624: opApply with @safe and @system variants can't be used with foreach syntax
  2. Bugzilla 16037: assigning delegate to a scope variable shouldn't allocate closure
  3. Bugzilla 17784: [scope][DIP1000] Confusing error message for escaping local via new-expression
  4. Bugzilla 18417: Make const and immutable postblit constructors illegal
  5. Bugzilla 18460: Improve error message for missing 'new' for class instantiation
  6. Bugzilla 18503: Confusing error message for erroneous postblit
  7. Bugzilla 18551: Improve hint for "does not override any function
  8. Bugzilla 18574: Unclear error message when trying to inherit from multiple classes
  9. Bugzilla 18578: First enum value assigned 0 instead of EnumBaseType.init
  10. Bugzilla 18591: DMD should allow access to mixin template declarations
  11. Bugzilla 18694: pure functions using static/global structs with no fields should pass compilation
  12. Bugzilla 18767: __xtoHash memberwise hashing shouldn't just sum the member hashes

Phobos regressions

  1. Bugzilla 17961: std.uni does not compile with -unittest -dip1000
  2. Bugzilla 18800: [REG2.080.0-beta.1] Array.length setter segfaults for payloads with indirections

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 15768: std.stdio.File does not support __gshared semantics of stdout/err/in
  4. Bugzilla 17862: std.random.XorshiftEngine.min is wrong when bits == 32
  5. Bugzilla 17982: Support for const(Class) in algorithm.searching.extremum
  6. Bugzilla 18133: BitArray constructors are poorly documented.
  7. Bugzilla 18134: BitArray >>= broken when length % (8 * size_t.sizeof) == 0
  8. Bugzilla 18452: std.zip has size limit of 2 GB
  9. Bugzilla 18524: std.range.Zip.moveBack instead performs moveFront
  10. Bugzilla 18579: No group separators for floating point number formatted with zero decimal digits
  11. Bugzilla 18615: Rebindable!A doesn't use class A's opEquals (returns a is b instead)
  12. Bugzilla 18634: std.container.rbtree does not work with delegate comparators
  13. Bugzilla 18663: std.random.isSeedable has false positives
  14. Bugzilla 18669: isNestedFunction does not check if parameter is a function
  15. Bugzilla 18689: std.format should always throw FormatException on bad specs/arguments
  16. Bugzilla 18704: std/datetime/stopwatch.d(452) assertion failure on auto-tester
  17. Bugzilla 18714: Phobos calls localtime, which is not threadsafe

Phobos enhancements

  1. Bugzilla 4591: Concat of std.typecons.Tuples
  2. Bugzilla 8341: topN(zip()) too?
  3. Bugzilla 10828: datetime toString functions should accept sink
  4. Bugzilla 13880: nothrow @nogc std.algorithm.reduce on fixed-size arrays
  5. Bugzilla 14637: Array operations should work on tuples
  6. Bugzilla 18158: std.file.getcwd should be usable in @safe
  7. Bugzilla 18166: std.array.replace should be usable in @safe for dstrings
  8. Bugzilla 18168: std.base64.encode for output ranges should be usable in @safe
  9. Bugzilla 18174: std.math.equalsDigit should be usable in @safe
  10. Bugzilla 18182: std.uri should be usable in @safe
  11. Bugzilla 18223: std.experimental.allocator uninitializedFillDefault could use memset
  12. Bugzilla 18438: hasStaticMember fails with a T* while hasMember passes
  13. Bugzilla 18501: randomShuffle and partialShuffle should return their input argument
  14. Bugzilla 18596: std.random.unpredictableSeed could use something better than MinstdRand0
  15. Bugzilla 18600: Regex performance enhancement for repeated matchFirst calls
  16. Bugzilla 18638: The main override of std.range.zip could infer @nogc and nothrow

Druntime regressions

  1. Bugzilla 18652: hashOf example doesn't compile

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

dlang.org bugs

  1. Bugzilla 18602: [Better C] docs
  2. Bugzilla 18603: Illegal instruction: 4 on Mac OS 10.7.5 Leopard
  3. Bugzilla 18702: FAQ item "What does D have that C++ doesn't?" comparison link (https://dlang.org/articles/comparison.html) returns 404
  4. Bugzilla 18709: DDOC_AUTO_PSYMBOL and friends are wrong
  5. Bugzilla 18747: [Structs, Unions]

Installer bugs

  1. Bugzilla 18649: curl on Ubuntu 18.04 depends on libcurl4, .deb installer depends on libcurl3

Contributors to this release (65)

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

previous version: 2.079.1