Change Log: 2.095.0
Download D 2.095.0
released Jan 01, 2021
Compiler changes
- Deprecate bypassing of symbol visibility when doing overload resolution
- Deprecation triggered inside of templates now show instantiation trace
- Improvements for the C++ header generation
- Diagnostics for conflicting function definitions within a module
- extern(Pascal) has been removed
- The compiler now accepts -extern-std=c++20
- C++ compability standard now c++11 by default
- Add -preview=inclusiveincontracts: in contracts must be an explicit superset of the parent in contracts.
- Add support for Objective-C protocols
- Allow any compile-time argument in pragma(inline)
- Add __traits(getCppNamespaces, symbol) to retrieve the C++ namespaces a symbol resides in.
Library changes
Dub changes
- All commands now accept a version specification
- Dub will now automatically exclude mainSourceFile from other configurations
- Add support for -betterC compiler flag to the visuald project generator
- Caching of generated unittest runner (dub test)
- Allow custom build settings to be defined for dependencies
- DFLAGS and LFLAGS no longer propagate to nested dub invocations
- Use DC environment variable as default D compiler
- Fix #2051 "Running unit tests from DUB single file packages fails"
- Improve ldc cross compilation
- Filter ability for list command
- Support for .netrc file added
List of all bug fixes and enhancements in D 2.095.0.
Compiler changes
- Deprecate bypassing of symbol visibility when doing overload resolution
If an aggregate declaration contains a private method and a public method in the same overload set it is possible to call the private method from a different module.
Example:
============================== module foo; struct Foo { import std : writeln; private int _x; private ref int x() return { writeln("ref int"); return _x; } int x() const { writeln("int"); return _x; } } ============================ ---
Starting from this version a deprecation message will be issued in such situations.module main;
void main() { import std : writeln; import foo : Foo;
auto f = Foo(); f.x = 3; // ok to call private method writeln(f); } ===========================
- Deprecation triggered inside of templates now show instantiation trace
A common issue when dealing with deprecations is to have it trigger in library code, for example having a deprecated alias this, or a hook (opApply, range primitives...) being called by a function deeply nested inside Phobos.
In such cases, finding out where the instantiation comes from can be quite tedious. From this release, if a deprecation is triggered inside a template, the compiler will show the template instantiation trace, just like it already does on error. The same limit apply (6 frames, recursive templates are compressed), and -v can be used to lift it.
- Improvements for the C++ header generation
The following features/bugfixes/improvements were implemented for the experimental C++ header generator:
- Enums are no longer emitted in macros and enum class is used when the C++ standard set from -extern-std= is c++11 or later.
- Forward referenced declarations are now properly indented.
- Default functions parameters are properly emitted
- Tuple members/parameters/variables are emitted as individual variables using the compiler internal names instead of causing an assertion failure.
- Interfaces are now emitted as base classes.
- Aggregate members will be emitted with proper protection levels
- Protected enums in aggregates are emitted again
- Private member methods are no longer emitted
- No auto-generated default constructor for unions
- No longer ignores declarations nested inside an extern block, e.g. extern(D) extern(C++) void foo() {}
- Opaque enums no longer cause segfaults & are properly exported for C++ 11
- C++11 constructs are avoided when compiling with -extern-std=c++98.
- Using typeof(null) type no longer causes an assertion failure.
- The base type of floating point literals is propagated into the header
- NaN, Infinity are emitted using NAN/INFINITY from math.h.
- Final classes are marked as final
- immutable is emitted as const instead of mutable
- Identifier chains in templates are printed completely
- Proper vtable layout is ensured by emitting hidden placeholders for virtual functions that are not extern(C|C++).
- Fixed missing const for class members/methods
- Templated class declarations are now emitted
- Manifest constants that are not extern(C|C++) are no longer emitted.
Note: The header generator is still considerer experimental, so please submit any bugs encountered to the bug tracker.
- Diagnostics for conflicting function definitions within a module
Previously, multiple definitions of identical functions within a module were not recognized, although they have the same mangling. This was problematic because a binary cannot contain multiple definitions of a symbol, which caused undefined behavior depending on the compiler backend.
DMD will now raise an error message if there are conflicting implementations within a single module:
void foo() {} void foo() {} // error
Multiple declarations are still allowed as long as there is at most one definition:
void bar(int); void bar(int) { } void bar(int);
DMD will issue a deprecation for mangling schemes that don't support overloading (extern(C|Windows|System)):
extern(C): void foo(int) { } void foo(double) { } // deprecation
This deprecation will become an error in 2.105.
- extern(Pascal) has been removed
This unused linkage was deprecated in v2.084.0 and has now been removed.
- The compiler now accepts -extern-std=c++20
The compiler now accepts c++20 as a supported standard for -extern-std=. Currently this only changes the value of __traits(getTargetInfo, "cppStd"), though new types may be added in the future.
- C++ compability standard now c++11 by default
The default setting for -extern-std= has been updated to c++11.
Declarations with extern(C++) linkage are no longer guaranteed to link with code compiled by a C++98 compiler. Additionally, C++ headers generated by -HC will use constructs only available from C++11 onwards.
If compatibility with older C++ compilers is required, you must now pass -extern-std=c++98 on the command-line.
- Add -preview=inclusiveincontracts: in contracts must be an explicit superset of the parent in contracts.
As per Liskov, in contracts can only loosen the conditions placed on the method they appear on. Currently this is enforced by automatically "oring" together the in contract with the in contract on the parent method, creating a combined contract that is necessarily looser than the parent.
However, this leads to odd behavior like this code passing:
class A { void foo(int i) in (i > 0) { } } class B : A { void foo(int i) in (i < 0) { } } unittest { (new B).foo(5); }
That is because the in contract of B.foo is implicitly super.in() || i < 0, ie. i > 0 || i < 0
With -preview=inclusiveincontracts, this code will now fail with an AssertError. To reach the previous behavior, you would have to write out in (i > 0 || i < 0); that is, you explicitly include the parent's in contract in the child's.
- Add support for Objective-C protocols
It's now possible to declare [Objective-C protocols][objc_protocol]. In D, this is declared using the interface keyword.
To match the behavior of protocols in Objective-C, some additional changes have been made:
- It's possible to declare optional methods in an interface. This is done
- It's possible to have static methods in an interface. This method is
Example:
import core.attribute : optional, selector; import std.stdio : writeln; struct objc_selector; alias SEL = objc_selector*; extern (C) SEL sel_registerName(in char* str); extern (Objective-C) extern class NSObject { static NSObject alloc() @selector("alloc"); NSObject init() @selector("init"); } extern (Objective-C) interface Foo { bool respondsToSelector(SEL sel) @selector("respondsToSelector:"); void foo() @selector("foo"); // this is an optional method @optional void bar() @selector("bar"); } extern (Objective-C) class Bar : NSObject, Foo { override static Bar alloc() @selector("alloc"); override Bar init() @selector("init"); bool respondsToSelector(SEL sel) @selector("respondsToSelector:"); void foo() @selector("foo") { writeln("foo"); } } void main() { Foo f = Bar.alloc.init; // check, at runtime, if the instance `f` implements the method `bar` if (f.respondsToSelector(sel_registerName("bar"))) f.bar(); else f.foo(); }
[objc_protocol][https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/WorkingwithProtocols/WorkingwithProtocols.html]
- Allow any compile-time argument in pragma(inline)
Previously only true or false literals were allowed (the spec stated that integers worked, but they did not).
Now the pragma can receive any compile-time expression convertible to bool, this expression will be evaluated only when the target function is actually used.
For example, in the following code all three functions should be inlined:
pragma(inline, canInline("func1")) void func1() {} void func2() { pragma(inline, canInline(__traits(identifier, __traits(parent, {})))); } pragma(inline, canInline("func3") || true) void func3() {} int canInline(string fname) { switch (fname) { case "func1": case "func2": return 1; default: return 0; } } void main() { func1(); func2(); func3(); }
- Add __traits(getCppNamespaces, symbol) to retrieve the C++ namespaces a symbol resides in.
This new trait returns a tuple of strings representing the namespace(s) the symbol resides in. This enables determining what namespaces a given symbol resides in for use in reflection, and can be used directly with an extern(C++) declaration as demonstrated below.
extern(C++, "ns") struct Foo {} static assert(__traits(getCppNamespaces, Foo)[0] == "ns"); struct Bar {} static assert(!__traits(getCppNamespaces, Foo).length); extern(C++, __traits(getCppNamespaces, Foo)) struct Baz {} static assert(__traits(getCppNamespaces, Foo) == __traits(getCppNamespaces, Baz));
Runtime changes
- Variables suspendSignalNumber and resumeSignalNumber are now private
These variables, which are in core.thread.osthread, were accidentally exposed. They shouldn't be accessed directly and have been made private. In order to set GC signals, one should call thread_setGCSignals instead.
Library changes
- Return the number of characters consumed by std.conv.parse
By setting the flag doCount to Yes.doCount, the function returns a named tuple. The tuple contains the fields data and count. The field data is of type Target and it contains the result of the original function. The field count is of type size_t and it contains the number of characters consumed. The function is keeping its original behaviour otherwise. Example:
import std.typecons : Flag, Yes, No; string s1 = "123"; auto a1 = parse!(int, string, Yes.doCount)(s1); assert(a1.data == 123 && a1.count == 3);
- Deprecate std.stdio.getdelim and std.stdio.getline
The publicly available extern(C) bindings for getdelim and getline in std.stdio have been deprecated. Any code that still needs it can import the symbol from core.sys.posix.stdio in druntime instead.
- Add integer conversions in JSONValue.get
JSONValue.get now allows to convert a stored uinteger or integer into any signed or unsigned integer. The conversion is performed with std.conv.to, and throws a ConvException in case of an integer overflow;
auto json = parseJSON(`{"a": 123}`); writeln(json["a"].get!ubyte);
Dub changes
- All commands now accept a version specification
Before this release dub could only get an exact version for some commands (describe, generate, fetch, etc...). All commands now accept a version specification, such as can be found in dub.json / dub.sdl:
dub fetch 'foo@>0.2.0' dub describe foo@'>=0.3.0 <1.0.0'
Note that commands such as describe will still not fetch from the network.
- Dub will now automatically exclude mainSourceFile from other configurations
By default, Dub uses all files it can find under its sourcePaths. However, a common pattern when dealing with multiple targets is to use configurations to represent said targets. In the case those targets are executables, users would be forced to add main files from other configurations to the excludedSourceFiles list, or store the main in a different directory outside of the sourcePaths.
To simplify this workflow, Dub will now exclude files listed in mainSourceFile for other configuration. In case this is not desirable, the files need to be manually added to the sourceFiles list.
- Add support for -betterC compiler flag to the visuald project generator
If betterC is specified in the buildOptions, visuald project files will also be configured to use betterC.
- Caching of generated unittest runner (dub test)
For projects without a user-defined unittest configuration dub test generates a main file automatically. This main file is now being cached and won't be regenerated won subsequent runs without file changes.
- Allow custom build settings to be defined for dependencies
For example:
{ "name": "example", "dependencies": { "vibe-d": { "version" : "~>0.9.2", "dflags" : ["-preview=in"] } } }
In this example, -preview=in will be applied to vibe-d and all of its dependencies. Any https://dub.pm/package-format-json.html#build-settings field will be parsed, however only dflags is taken into account when compiling for now.
- DFLAGS and LFLAGS no longer propagate to nested dub invocations
DFLAGS and LFLAGS will no longer be exported as environment variables by default when invoking pre-generate, pre-build, pre-run, post-generate, post-build, or post-run commands.
If the previous behavior is still desired, they can be accessed using $DFLAGS and $LFLAGS in dub.json E.g.: preGenerateCommands : ["DFLAGS=$DFLAGS env | grep DFLAGS"]
will output DFLAGS environment variable with all the dflags used.
- Use DC environment variable as default D compiler
dub now respects the DC environment variable, meaning that DC=ldc2 dub build will behave as dub build --compiler=ldc2. In case both are supplied, the --compiler switch still has priority. Note that when DUB recursively invokes itself, for example in preGenerateCommands, it sets the DC variable to the compiler it is using, meaning that nested dub invocation will now use the same compiler.
- Fix #2051 "Running unit tests from DUB single file packages fails"
Now dub is capable run test command in single mode like: dub test --single yoursinglefile.d
- Improve ldc cross compilation
Enables co-existence and parallel compilation of the same project with different settings (e.g. cross compilation) by moving .dub/obj to $DUB_TARGET_PATH/obj.
- Filter ability for list command
For list command added optional filtration by name and version specification:
dub list foo dub list foo@'>=0.1.0 <1.0.0'
- Support for .netrc file added
Basic authentication credentials defined in .netrc file will now be taken into account while connecting to secured repositories.
List of all bug fixes and enhancements in D 2.095.0:
DMD Compiler regressions
- Bugzilla 20608: [REG2.087] Cannot pass tuple.expand to auto ref T... template argument pack
- Bugzilla 21282: mixin of AliasSeq "cannot alias an expression"
- Bugzilla 21294: [REG 2.095]: DMD fails to link since PR11743
- Bugzilla 21312: [REG 2.095] Newly triggered
is not an lvalue and cannot be modified - Bugzilla 21325: Flags not set for ?: evaluation with floating point operands
- Bugzilla 21328: Forwarding static float array element inside a lambda crashes dmd backend
- Bugzilla 21357: [REG2.093] postblit aliases old and new struct pointers
- Bugzilla 21364: Improperly aligned struct when one member is a GPR and the other is an XMM
DMD Compiler bugs
- Bugzilla 3713: Tail call optimization not enabled with the ?: operator
- Bugzilla 8156: Very slow compilation with string-imported file ~100 MiB
- Bugzilla 10664: Win64: exception handling does not work with COMDAT folding
- Bugzilla 11049: array bounds error uses module file name rather than file name modified by #line directive
- Bugzilla 11435: Pushing indirect ref to byte or short can read beyond edge of valid memory
- Bugzilla 14708: destructor for temporary not called during stack unwinding
- Bugzilla 15909: Duplicate case error reports characters as numbers
- Bugzilla 19754: cast() sometimes yields lvalue, sometimes yields rvalue
- Bugzilla 19970: [CTFE] 0 ptr is not null
- Bugzilla 20195: -preview=nosharedaccess has some access problems
- Bugzilla 20604: [ICE] dtoh ICE with nested template structs (and probably most templates
- Bugzilla 20652: extern(C++) doesn't seem to mangle the types in core.simd right
- Bugzilla 20714: Struct with postblitting member does not call it's copy constructor
- Bugzilla 20716: Wrong code/ABI for extern(C++) interface method that returns non-POD
- Bugzilla 20916: hard to find where a deprecation comes from
- Bugzilla 20965: Implicitly generated postblit overrides disabled copy ctor
- Bugzilla 20970: Test Suite Azure Pipelines Windows_LDC_Debug x64-debug-ldc failed due to heisenbug
- Bugzilla 21218: dtoh: protection attributes should be emitted to headers
- Bugzilla 21227: import(".\file") doesn't work on Windows
- Bugzilla 21234: Import expression can read files outside of -J path in case of symlink/hardlink
- Bugzilla 21246: Compiler must show mismatching types when functions do not properly override
- Bugzilla 21255: "overload alias ... forward declaration" when overload set of imported template functions is passed to alias template parameter
- Bugzilla 21271: C++ header generation ignores extern(D) class methods affecting vtable layout
- Bugzilla 21283: [C++] Wrong mangling for ref of parameter pack
- Bugzilla 21293: dtoh: segfault when encountering opaque enum
- Bugzilla 21299: [LINK] undefined reference to dmd.root.stringtable.StringValue!(Type).StringValue.lstring()
- Bugzilla 21300: C++ header generation produce nonsense code on enum with enum as parent
- Bugzilla 21320: @live mistakes borrowed pointer for owner in parameter
- Bugzilla 21424: Variable is incremented twice
- Bugzilla 21464: Superfluous module-level import affects attribute inference
- Bugzilla 21479: ternary operator returns wrong val with ref return
- Bugzilla 21514: [ICE] cod1.d:4015: Assertion `retregs || !*pretregs' failed with -m32
DMD Compiler enhancements
- Bugzilla 8044: Print names, not casted values when using enum template parameter
- Bugzilla 21204: Error in generated copy constructor gives confusing message
- Bugzilla 21259: struct initialization with deprecated fields should issue deprecation warnings
- Bugzilla 21275: Overload resolution bypasses private access
- Bugzilla 21340: extern(C++,(emptyTuple)) should result in no namespace not an error
Phobos bugs
- Bugzilla 13930: std.concurrency can't send immutable AA to another thread
- Bugzilla 15425: std.traits.hasIndirections fails to recognize nested structs
- Bugzilla 18789: std.stdio messes up UTF conversions on output
- Bugzilla 18801: std.stdio.File doesn't work with MSVCRT's UTF-8 mode
- Bugzilla 20924: std.numeric.gcd cannot be used with const BigInt
- Bugzilla 21231: Unreachable warning for empty struct in VariantN with preview=fieldwise
- Bugzilla 21249: clamp() is not stable and is not constrained
- Bugzilla 21253: Can't compile Variant.visit!(...) with generic function
- Bugzilla 21296: std.variant.Variant cannot be initialized with immutable AA
- Bugzilla 21302: std.uni's documentation contains a dead link to its source file
- Bugzilla 21452: isCallable erroneously returns false on function templates
Phobos enhancements
- Bugzilla 6484: compose can't take multi arg functions
- Bugzilla 20869: std.algorithm.mutation : move is overly trusting of opPostMove
- Bugzilla 20980: std.bigint.BigInt: special case x & non-negative int to avoid unnecessary allocation
- Bugzilla 21233: std.conv.parse doesn't report the number of characters consumed
- Bugzilla 21237: isLvalueAssignable and isRvalueAssignable should be public
- Bugzilla 21347: std.functional.adjoin should work in BetterC
- Bugzilla 21407: Make std.math.NaN and std.math.getNaNPayload work in CTFE
- Bugzilla 21408: Make std.math.nextUp and nextDown and nextafter work in CTFE for extended-precision real
- Bugzilla 21430: Add const to front, save, & length properties of range returned by std.bitmanip.bitsSet
Druntime bugs
- Bugzilla 14226: invalid Runtime.traceHandler setup
- Bugzilla 21421: core.stdcpp.new_.cpp_delete does not work with classes
- Bugzilla 21441: TypeInfo_Enum.destroy and TypeInfo_Enum.postblit not calling destroy and postblit of base type
- Bugzilla 21442: Calling AA.remove from a destructor might lead to InvalidMemoryOperationError
- Bugzilla 21468: Inscrutable template error when core.stdcpp.vector of a struct with a core.stdcpp.vector field is referenced before the struct's definition
- Bugzilla 21484: Infinite recursion in core.memory : GC.{get,set,clr}Attr(const scope void*...)
Druntime enhancements
- Bugzilla 21030: Reduce template function instantiations related to array equality
- Bugzilla 21417: core.stdcpp.new_.cpp_delete unnecessarily requires destruction to be @nogc
- Bugzilla 21426: dup, idup for arrays plus keys, values for associative arrays: call postblits directly instead of via TypeInfo function pointer
dlang.org bugs
- Bugzilla 21189: Plain Old Data and copy constructors
- Bugzilla 21273: [spec] Inexistent contrast for shell snippets make them unreadable (CSS)
Installer bugs
- Bugzilla 21433: "bash: line 952: --list-keys: command not found" when running install.sh on Catalina
- Bugzilla 21439: install.sh is disabled for LDC on FreeBSD
Contributors to this release (61)
A huge thanks goes to all the awesome people who made this release possible.
- Adela Vais
- aG0aep6G
- Andrei Alexandrescu
- Andrey Zherikov
- Atila Neves
- Bastiaan Veelo
- Ben Jones
- Boris Carvajal
- Brian Schott
- Crom (Thibaut CHARLES)
- Daniel Graczer
- Denis Feklushkin
- Dimitar Nestorov
- Ernesto Castellotti
- Ezneh
- godmyoh
- Guillaume Piolat
- H. S. Teoh
- Harry T. Vennik
- Iain Buclaw
- Imperatorn
- Jacob Carlborg
- James Gray
- James Thompson
- jmh530
- Johan Engelen
- K
- Lio李歐
- Lorenzo Gabriele
- Luhrel
- Luís Ferreira
- Martin Kinkelin
- Martin Nowak
- Mathias Lang
- Mathis Beer
- Mihaela Chirea
- Mike Parker
- MoonlightSentinel
- Nathan Sashihara
- Nicholas Wilson
- nordlow
- Panke
- Paul Backus
- Petar Kirov
- phebert5009
- Quirin F. Schroll
- Rainer Schuetze
- Razvan Nitu
- Remi Thebault
- Roman Chistokhodov
- Sebastian Wilzbach
- Simen Kjærås
- Simon Naarmann
- starcanopy
- Tobias Pankrath
- Tomoya Tanjo
- Tomáš Chaloupka
- Vladimir Panteleev
- Walter Bright
- Yanis Zafirópulos
- Ömer Faruk IRMAK