Change Log: 2.098.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
Compiler changes
- Deprecation period for ambiguous ternary expressions has ended
- Usage of the body keyword has been deprecated
- Deprecate a case of using fully-qualified names to bypass imports
- Explicit package visibility attribute is now always applied to new scopes
- pragma(mangle) can now be applied to aggregates
- Complex and imaginary types are now deprecated
- while (auto n = expression) is now supported
Library changes
- Centering formatted output.
- AllImplicitConversionTargets replaces ImplicitConversionTargets
- Formatting integers with %e, %f, %g and %a is now possible.
- Implementation of pow(f, -2) and f ^^ -2 changed
- Deprecate std.format : enforceValidFormatSpec
- Deprecate std.format : formatElement
- Deprecate std.format : unformatElement
- FieldnameTuple now returns an empty tuple for interfaces
- Fields (formerly FieldTypeTuple) now returns an empty tuple for interfaces
- Floating point numbers can be formatted at compile time
- Formatting floating point numbers don't allocate with the GC anymore.
- Some reals will be downcast to double when used with std.format.
- std.typecons.Nullable: Remove deprecated alias get this.
- Documentation of std.format has been completely reworked.
- Module std.format has been split into smaller modules
- Module std.math has been split into smaller modules
- splitWhen added to std.algorithm.iteration
- The old benchmarking functionality in std.datetime has been removed.
- std.exception.enforceEx has been removed.
- New module: std.sumtype
- std.range.Transposed: Remove deprecated member save
Dub changes
List of all upcoming bug fixes and enhancements in D 2.098.0.
Compiler changes
- Deprecation period for ambiguous ternary expressions has ended
In D, the ternary operator (?:) has a higher precedence than the assignment operator (=), hence:
true ? stt = "AA" : stt = "BB"
actually means:
(true ? (stt = "AA") : stt) = "BB",
This is in line with C, and many other languages (except C++), but comes at a surprise to many, which is why this specific combination of ternary and assignment was deprecated in v2.082.0 (2018-09-01).
The deprecation instructs the user to use parenthesis to make the intent explicit, so the above snippet should read as:
true ? (stt = "AA") : (stt = "BB")
This deprecation period has now ended and the compiler will now issue an error for ambiguous code.
- Usage of the body keyword has been deprecated
Using body to indicate the body of a function or method in the presence of contracts is now deprecated. Any leftover usage of body can be replaced with do. This replacement, introduced by DIP1003, has been available since DMD v2.075.0 (July 2017).
- Deprecate a case of using fully-qualified names to bypass imports
Since v2.084 it is no longer possible to bypass private imports by using fully-qualified names, this was deprecated in v2.071 but when fully-qualified names are used as a type (vs an expression) the code is accepted without any warning.
Starting with this release the compiler will now properly deprecate the previous omitted case.
The issue is best described in the following example:
import std.algorithm; // deprecated in v2.071, error since v2.084 auto a = std.range.Take!(int[]); // Error: undefined identifier `range` in package `std`... // now it's deprecated, will be error from v2.106 std.range.Take!(int[]) s;
- Explicit package visibility attribute is now always applied to new scopes
If a less restrictive package attribute appeared within the scope of another package attribute, the more restrictive parent would override any explicit child visibility.
Example:
module pkg.foo; package(pkg.foo): // analogous to "private" or plain "package" package(pkg) int bar(); // package(pkg) was being ignored
Starting from this version, the package visibility attribute is now always applied as long as it is valid. In the given example, this allows any module in the package pkg to import and use the symbol bar.
- pragma(mangle) can now be applied to aggregates
The syntax is pragma(mangle, str_or_decl [, str] ) declaration; where str_or_decl is either: a string expression to substitute the name of declaration; or a class, struct, or union declaration or template instance to use instead of declarations for mangling. If the optional second argument is present, use that as a name instead but keep the namespaces and template parameters of str_or_decl (if any).
This enables binding with functions that take classes by value or reference and to classes that are D keywords.
To bind C++'s std::function by value:
extern(C++, "std") { template std_function(F) { pragma(mangle, "function") class std_function { // member variables and functions } } } template ScopeClass(C , string name) { enum ns = __traits(getCppNamespaces,C); extern(C++, class) extern(C++,(ns)) { pragma(mangle, C, name) struct ScopeClass { char[__traits(classInstanceSize, C)] buffer; // member variables and functions } } } alias FuncType = void function(int); alias RawFuncType = typeof(*FuncType.init); // Mangles as `void funk(std::function<void(int)> a)` extern(C++) void funk( ScopeClass!(std_function!(RawFuncType)),"function") a );
- Complex and imaginary types are now deprecated
D previously supported complex and imaginary versions of all floating point types as part of the language.
float a = 2; ifloat b = 4i; cfloat c = a + b; assert(c == 2 + 4i);
However these types are too specialized to be a part of the core language, and the same functionalities can be implemented as part of a library type. As such, older versions of DMD provided the -transition=complex switch to warn when those builtin types were used. This transition phase has finished, and those deprecations are now turned on by default.
Users should use std.complex.Complex instead.
import std.complex; float a = 2; float b = 4; auto c = complex(a, b); assert(c == complex(2, 4));
The -transition=complex switch that previously turn on deprecation warnings no longer has an effect and has also been deprecated.
- while (auto n = expression) is now supported
Up until this release, while (auto n = expression) was not supported, although the if counterpart: if (auto n = expression) compiled succesfully. Starting with the current compiler version, while (auto n = expression) is accepted, having the exact same semantics as:
while (true) { if (auto n = expression) { /* loop body */ } else { break; } }
Library changes
- Centering formatted output.
A new flag '=' has been added to the format specifier, which allows to center the output:
assert(format!"|%=8d|"(1234) == "| 1234 |");
In case the output cannot be centered exactly it is moved slightly to the left if '-' flag is present too and to the right else:
assert(format!"|%=-8d|"(123) == "| 123 |"); assert(format!"|%=8d|"(123) == "| 123 |");
- AllImplicitConversionTargets replaces ImplicitConversionTargets
The function ImplicitConversionTargets in module std.traits has a design flaw: The list of conversion targets contains some, but not all unsafe conversion targets. To overcome this, a new function AllImplicitConversionTargets has been added and ImplicitConversionTargets has been deprecated.
- Formatting integers with %e, %f, %g and %a is now possible.
The formatting posibilities of integers have been expanded to the specifiers that are typical for floating point numbers: Integers can now be formatted using %e, %f, %g and %a. The result is similar to the result expected for the corresponding floating point value.
assert(format!"%.3e"(ulong.max) == "1.845e+19"); assert(format!"%.3,3f"(ulong.max) == "18,446,744,073,709,551,615.000"); assert(format!"%.3g"(ulong.max) == "1.84e+19"); assert(format!"%.3a"(ulong.max) == "0x1.000p+64");
- Implementation of pow(f, -2) and f ^^ -2 changed
We noticed that the implementation of pow(f, -2) and f ^^ -2 with f being a floating point value, was buggy for some values of f. Unfortunately the fix implies small changes for other values for f (with exponent -2) too: The least significant bits of the result might differ from the current implementation. (This is due to the peculiarities of floating point numbers and cannot be avoided with reasonable means.)
To avoid problems, make sure, that your algorithms do not rely on the least significant bits of floating point calculations, for example by using isClose instead of ==.
- Deprecate std.format : enforceValidFormatSpec
enforceValidFormatSpec from std.format has been accidentally made public and will be removed from public view in 2.107.0.
- Deprecate std.format : formatElement
formatElement from std.format has been accidentally made public and will be removed from public view in 2.107.0.
Please use instead of formatElement(sink, value, fmt):
import std.range : only; sink.put(format!("%("~fmt~"%)")(only(value)));
- Deprecate std.format : unformatElement
unformatElement from std.format has been accidentally made public and will be removed from public view in 2.107.0.
Please use instead for strings and characters parseElement from std.conv and for all else unformatValue from std.format.read.
- FieldnameTuple now returns an empty tuple for interfaces
Previously FieldNameTuple returned AliasSeq!"" for interfaces as done for non-aggregate types like int, char*, ... . This behaviour was surprising because an instance of that interface may have members that just are not known at compile time.
FieldNameTuple will now return an empty AliasSeq!() for interfaces.
- Fields (formerly FieldTypeTuple) now returns an empty tuple for interfaces
Previously Fields returned AliasSeq!(Interface) for interfaces as done for non-aggregate types like int, char*, ... . This behaviour was surprising because an instance of an interface may have members that just are not known at compile time.
Fields will now return an empty AliasSeq!() for interfaces.
- Floating point numbers can be formatted at compile time
Example:
import std.format : format; import std.math : sqrt; enum pi = format!"%s"(3.1415926f); static assert(pi == "3.14159"); enum golden_ratio = format!"|%+-20.10E|"((1 + sqrt(5.0)) / 2); static assert(golden_ratio == "|+1.6180339887E+00 |");
- Formatting floating point numbers don't allocate with the GC anymore.
The implementation of formatting floating point numbers has been reworked. We made sure that working examples never allocate with the GC, however, we are still using exceptions which are GC managed. Therefore, code that uses formatting correctly will never allocate, but in the case of exceptions, the GC will be used to allocate the exception. We are working on DIP 1008 to solve this issue.
- Some reals will be downcast to double when used with std.format.
In the internals of std.format we replaced a call to snprintf of libc with routines written in D for formatting floating point values. These functions only work for floats, doubles, 64-bit-reals and 80-bit-reals (x87-reals) yet.
All other reals are handled by downcasting them to doubles before being formatted. This might result in a loss of precision in the output. Further, numbers larger than double.max will be formatted like double.max and numbers large than zero but smaller than the smallest positive double will be formatted like the smallest positive double. Likewise for negative values.
- std.typecons.Nullable: Remove deprecated alias get this.
Nullable no longer implicitly converts to its member. This feature was problematic because a simple use of a value could invisibly cause an assertion due to type conversion. To restore the previous behavior, replace uses of a Nullable value n with n.get.
- Documentation of std.format has been completely reworked.
In the last years, the documentation of std.format was outdated little by little and therefore needed a complete rework. The whole package was reviewed and all documentations, including examples, improved and extended.
Some highlights:
- The grammar of the format string was updated.
- A detailed description of format specifiers was provided.
- Several examples on how to use the functions and the format strings were added.
- Module std.format has been split into smaller modules
The module std.format has been split into submodules:
- std.format.spec: Symbols concerning the format string, mainly the struct FormatSpec and the template singleSpec
- std.format.read: Symbols concerning reading input, mainly the template formattedRead and the template unformatValue
- std.format.write: Symbols concerning writing output, mainly the template formattedWrite and the template formatValue
All public symbols are still accessible using std.format as usual.
- Module std.math has been split into smaller modules
The module std.math has been split into submodules:
- std.math.constants: Mathematical constants, like PI.
- std.math.algebraic: Basic algebraic functions, like abs and sqrt.
- std.math.trigonometry: Trigonometric functions, like sin and cos.
- std.math.rounding: Functions concerned about rounding, like ceil and floor.
- std.math.exponential: Exponential and logarithmic functions, like pow, exp and log.
- std.math.remainder: Function calculating the remainder, like fmod.
- std.math.operations: Floating-point operations, like isClose, nextUp and fmin.
- std.math.traits: Floating-point introspection, like isNaN and isSubnormal.
- std.math.hardware: Hardware control: IeeeFlags and FloatingPointControl.
All public symbols are still accessible using std.math as usual.
- splitWhen added to std.algorithm.iteration
std.algortihm.iteration.splitWhen is a variant of the existing std.algortihm.iteration.chunkBy function that does not require its predicate to be an equivalence relation, allowing it to be used in ways that chunkBy cannot. For example:
// Grouping by maximum adjacent difference: import std.math : abs; import std.algorithm; auto r3 = [1, 3, 2, 5, 4, 9, 10].splitWhen!((a, b) => abs(a-b) >= 3); assert(r3.equal!equal([ [1, 3, 2], [5, 4], [9, 10] ]));
This would have an undefined result with chunkBy, because it requires that if pred(a,b) and pred(b,c) return true, pred(a,c) must also return true.
- The old benchmarking functionality in std.datetime has been removed.
It had been deprecated in 2.077.0 in favor of std.datetime.stopwatch, which uses core.time.MonoTime and core.time.Duration.
- std.exception.enforceEx has been removed.
It had been deprecated in 2.079 in favor of std.exception.enforce.
- New module: std.sumtype
The sumtype package from code.dlang.org has been added to the standard library as std.sumtype.
It provides SumType, a generic discriminated union implementation that uses design-by-introspection to generate safe and efficient code, and is intended to serve as a replacement for the legacy std.variant.Algebraic.
Features of SumType include:
- Pattern matching.
- Support for self-referential types.
- Full compatibility with pure, @safe, @nogc, nothrow, and scope.
- No dependency on runtime type information (TypeInfo).
- Compatibility with BetterC.
Example usage:
import std.sumtype; import std.math : isClose; struct Fahrenheit { double degrees; } struct Celsius { double degrees; } struct Kelvin { double degrees; } alias Temperature = SumType!(Fahrenheit, Celsius, Kelvin); // Construct from any of the member types. Temperature t1 = Fahrenheit(98.6); Temperature t2 = Celsius(100); Temperature t3 = Kelvin(273); // Use pattern matching to access the value. Fahrenheit toFahrenheit(Temperature t) { return Fahrenheit( t.match!( (Fahrenheit f) => f.degrees, (Celsius c) => c.degrees * 9.0/5 + 32, (Kelvin k) => k.degrees * 9.0/5 - 459.4 ) ); } assert(toFahrenheit(t1).degrees.isClose(98.6)); assert(toFahrenheit(t2).degrees.isClose(212)); assert(toFahrenheit(t3).degrees.isClose(32)); // Use ref to modify the value in place. void freeze(ref Temperature t) { t.match!( (ref Fahrenheit f) => f.degrees = 32, (ref Celsius c) => c.degrees = 0, (ref Kelvin k) => k.degrees = 273 ); } freeze(t1); assert(toFahrenheit(t1).degrees.isClose(32)); // Use a catch-all handler to give a default result. bool isFahrenheit(Temperature t) { return t.match!( (Fahrenheit f) => true, _ => false ); } assert(isFahrenheit(t1)); assert(!isFahrenheit(t2)); assert(!isFahrenheit(t3));
- std.range.Transposed: Remove deprecated member save
Transposed never worked as forward range.
Dub changes
- Builds dynamicLibrary targets as dynamic libraries instead of static libraries.
Dub will no longer build dynamicLibrary targetType's as staticLibrary.
Except for x86_omf. This has been disabled due to numerous issues that will lead this to not doing what is expected of it.
No compiler or linker flags have been added at this time, you will need to specify the relevant flag to get the compiler to link dynamically against Phobos.
- The $DUB_BUILD_PATH variable was added
The $DUB_BUILD_PATH variable is now defined inside the postBuildCommands section. It contains the absolute path in which the package was built, and can be used to copy by-products of the build process to their intended locations.
For example, if an executable exports symbols, you will want to make the resulting import library and symbols export file available somewhere. That can be done with a dub.json section like this:
"postBuildCommands-windows": [ "copy /y $DUB_BUILD_PATH\\$DUB_TARGET_NAME.lib $PACKAGE_DIR\\lib" "copy /y $DUB_BUILD_PATH\\$DUB_TARGET_NAME.exp $PACKAGE_DIR\\lib" ],
- Command environment variable substitution changed
Now users can use the documented predefined variables inside custom command directives without the need for a wrapper shell script.
Before this would have failed:
"preBuildCommands": ["$DC -run foo.d"]
unless DC was defined as environment variable outside DUB.
It was before possible to run a script that used the $DC environment variable or on POSIX escape the $ with $$DC to make the shell substitute the variable. These workarounds are no longer needed now.
API change: none of the different command directives are no longer substituted with the process environment variables. You now access the raw commands as provided by the user in the recipe. dub describe has been adjusted and now also processes the predefined environment variables as well as the process environment variables.
List of all bug fixes and enhancements in D 2.098.0:
DMD Compiler regression fixes
- Bugzilla 13009: [REG2.064] inout overload conflicts with non-inout when used via alias this
- Bugzilla 21238: -deps considers only the first instantiation site of a template for dependencies
- Bugzilla 21850: [REG2.093] Template inference of pure not working
- Bugzilla 22035: [REG 2.097][ICE] Segmentation fault parsing invalid case statement
- Bugzilla 22048: [REG2.095] alias a = int p; compiles
- Bugzilla 22054: Referencing a fwd-declared field results in many error messages
- Bugzilla 22075: [Reg 2.068] "AA key type S should have 'size_t toHash() const nothrow @safe' if opEquals defined" is not triggered if any field of S has its own 'alias this'
- Bugzilla 22084: [REG 2.097] Segmentation fault passing non-pod struct as variadic argument
- Bugzilla 22086: importC: RangeError@src/dmd/dscope.d(469): Range violation
- Bugzilla 22118: Const union causes false multiple-initialization error in constructor
- Bugzilla 22121: [REG 2.097][ICE] Segmentation fault in in dmd.dsymbol.ScopeDsymbol.addAccessiblePackage
- Bugzilla 22122: [REG 2.097][ICE] Segmentation fault in in dmd.access.hasPackageAccess
- Bugzilla 22133: [REG2.097] Breaking change in DotTemplateExp type semantics leading to e.g. isInputRange regression
- Bugzilla 22157: Bad diagnostic for static/non-static overload resolution conflict
- Bugzilla 22170: interface thunk doesn't set EBX to GOT
- Bugzilla 22196: importC: Error: found const when expecting )in __attribute__
- Bugzilla 22205: catch(Exception) not longer working in debug blocks
- Bugzilla 22214: Regression 2.097.0: __traits(compiles) doesn't notice invalid getMember that yields type
- Bugzilla 22224: [REG 2.097.0] compiler segfaults with -profile
- Bugzilla 22226: [REG 2.095.1] __ctfe + function call in conditional expression used to initialize struct member in constructor causes ICE
- Bugzilla 22228: [CTFE] taking address of immutable in frame function causes ICE on Unix platforms
- Bugzilla 22292: REG[2.084.1] Recursive class literal segfaults compiler
DMD Compiler bug fixes
- Bugzilla 13165: Using -profile does extra control flow analysis, leading to spurious statement is not reachable warning
- Bugzilla 14064: Error message about @ attributes incomplete.
- Bugzilla 15631: gdb: Parent's scope not considered for symbol lookup
- Bugzilla 16274: The curses of debugging: short argument passed in 16-bit register, against ABI
- Bugzilla 17041: foreach-ref can't use to static array's AliasSeq
- Bugzilla 20150: -dip1000 defeated by pure
- Bugzilla 20245: DIP1000: Should infer scope when taking address of ref
- Bugzilla 21209: scope attribute inference with does not work well with foreach
- Bugzilla 21868: DIP1000 doesn't catch pointer to struct temporary
- Bugzilla 21905: case of IFTI failure when combining ref, and alias this on a static instance
- Bugzilla 21912: delegate assigned to return scope variable needs closure
- Bugzilla 21928: Wrong location for "array literal in @nogc function main may cause GC allocation" error
- Bugzilla 21931: importC: 'alias time_t = time_t;' cannot alias itself, use a qualified name to create an overload set
- Bugzilla 21932: importC: enum 'ENUM' conflicts with enum 'ENUM'
- Bugzilla 21933: importC: struct parameters: AssertError@src/dmd/typesem.d(1890): Assertion failure
- Bugzilla 21934: importC: Support asm labels to specify the assembler name to use for a C symbol
- Bugzilla 21937: importC: Support parsing __attribute specifiers
- Bugzilla 21939: Duplicate error messages for wrong aggregate in 'static foreach'
- Bugzilla 21942: importC: Support parsing __inline__ keyword
- Bugzilla 21944: importC: Support parsing # line marker directive extensions
- Bugzilla 21945: importC AssertError@src/dmd/dsymbolsem.d(4787): Assertion failure
- Bugzilla 21946: importC: Support parsing __extension__ keyword
- Bugzilla 21948: importC: Support declaring local variables of typedef types
- Bugzilla 21949: noreturn doesn't follow covariance rules
- Bugzilla 21951: Segfault on noreturn.init
- Bugzilla 21962: importC: Empty enums are accepted as valid code
- Bugzilla 21963: importC: Support declaring union types
- Bugzilla 21965: importC: Anonymous top-level struct or union triggers [email protected](4787)
- Bugzilla 21967: importC: Error function without 'this' cannot be 'const'
- Bugzilla 21968: importC: struct fields: AssertError@src/dmd/typesem.d(1890): Assertion failure
- Bugzilla 21970: importC: Error: variable extern symbols cannot have initializers
- Bugzilla 21973: importC: AssertError@src/dmd/dsymbolsem.d(4307): Assertion failure
- Bugzilla 21976: importC: does not distinguish between cast-expression and unary-expression correctly
- Bugzilla 21977: importC: Global declarations are thread-local by default
- Bugzilla 21982: importC: Error: variable no definition of struct
- Bugzilla 21985: "goto" errors with unexistent label report wrong/misleading line
- Bugzilla 21992: importC: Error: variable is used as a type
- Bugzilla 21993: Cannot cast to noreturn
- Bugzilla 21994: (char*)"string" fails to compile
- Bugzilla 22005: ICE: Segmentation fault with static foreach and -betterC
- Bugzilla 22006: static foreach and foreach over tuple doesn't work on 16-bit
- Bugzilla 22007: static foreach: cannot implicitly convert expression Tuple4(0LU, 1) of type Tuple4 to int
- Bugzilla 22019: case 1,: allowed by grammar but not DMD
- Bugzilla 22028: importC: Parser accepts initializers for struct members
- Bugzilla 22029: importC: Parser accepts storage-class specifiers for fields
- Bugzilla 22030: importC: Wrong error with bad declarator
- Bugzilla 22032: importC: infinite loop: illegal combination of type specifiers
- Bugzilla 22053: catch { not rejected while in a template
- Bugzilla 22060: importC: Multiple forward declarations result in error struct conflicts with struct
- Bugzilla 22063: importC: Error: undefined identifier 'var' with pointer-to-typedef type
- Bugzilla 22066: importC: Error: expression expected, not ';' using (postfix-expression)++
- Bugzilla 22067: importC: cast-expression accepted as lvalue in assignment-expression
- Bugzilla 22068: importC: cast-expression accepted as lvalue in unary-expression
- Bugzilla 22069: importC: Error: found '&' instead of statement
- Bugzilla 22070: importC: Error: string literal is not an lvalue
- Bugzilla 22071: importC: Error: struct literal is not an lvalue
- Bugzilla 22073: importC: Error: found '.' when expecting ';' following compound literal
- Bugzilla 22079: importC: Error: '=', ';' or ',' expected taking sizeof compound literal
- Bugzilla 22080: ImportC: Error: cannot implicitly convert expression of type 'extern(C) function' to 'function'
- Bugzilla 22088: ImportC: C11 6.3 semantics on implicit conversions is not implemented
- Bugzilla 22102: importC: Error: function is used as a type
- Bugzilla 22103: importC: Parser accepts wrong syntax for array declarators
- Bugzilla 22106: importC: Error: variable 'var' no definition of struct 'type'
- Bugzilla 22126: -checkaction=context should not print overlapped struct members
- Bugzilla 22144: ICE(dcast.d): Floating point exception in castTo::CastTo::visit(Expression*) at dmd/dcast.d:1702
- Bugzilla 22149: TypeInfo_Struct names aren't unique, leading to botched equality semantics
- Bugzilla 22150: TypeInfo_Class names aren't unique, leading to botched equality semantics
- Bugzilla 22160: importC: Error: redeclaring module test as struct test
- Bugzilla 22179: core.stdcpp.utility is missing in dmd binary dist
- Bugzilla 22180: .alignof not working for globals
- Bugzilla 22182: importC: Error: expression expected, not ) when casting pointer with redundant parens.
- Bugzilla 22209: NRVO variable detection ignoring alias this conversion => segfaults
- Bugzilla 22246: importC: C11 does not allow _Alignof (expression)
- Bugzilla 22250: ImportC: Array subscripts do not comply with C standard.
- Bugzilla 22252: ImportC: Array, Function parameter types should be converted to pointers
- Bugzilla 22253: ImportC expressions inadvertently supporting D properties
- Bugzilla 22262: importC: Error: incompatible types for '(buf) is (0)': 'ubyte*' and 'int'
- Bugzilla 22263: ImportC: function and variable re-declarations should be allowed
- Bugzilla 22264: importC: Error: '=', ';' or ',' expected using K&R function syntax
- Bugzilla 22265: importC: Error: cannot modify 'const' expression
- Bugzilla 22274: importC: [ICE]: 4 identifiers does not match 3 declarations using K&R syntax
- Bugzilla 22275: importC: Error: incompatible types for (dest) !is (buf): char* and char[1]
- Bugzilla 22286: importC: (identifier)(other_identifier) incorrectly parsed as a cast-expression
- Bugzilla 22294: importC: enums aren’t placed in surrounding namespace.
- Bugzilla 22303: ImportC: pragma directives should be ignored
- Bugzilla 22304: importC: parsing gnu-style attributes fails if return type is pointer
- Bugzilla 22312: importC: redundant typedefs are rejected
- Bugzilla 22313: ImportC: account for ( ) when doing lookahead on assignment-expressions
- Bugzilla 22314: ImportC: fails to parse gnu attributes on enum members
- Bugzilla 22321: ImportC: non-static arrays can’t be initialized by an initializer list.
- Bugzilla 22322: ImportC: struct with floating point members causes problems with generated toHash() function
- Bugzilla 22326: ImportC: struct with flexible array member is incorrectly handled
- Bugzilla 22329: DMD and LDC2 Segumentation Faults due to alias this on private field + special names
- Bugzilla 22333: ImportC: fails to parse enumerators with = and gnu attributes
- Bugzilla 22373: Glue layer rejects cast from noreturn to other type
DMD Compiler enhancements
- Bugzilla 15889: Array bounds check should report index and length
- Bugzilla 16001: Lambda syntax: forbid use with FunctionLiteralBody: (x) => {assert(x);}
- Bugzilla 16689: Errors in instantiated mixin templates should show instantiation point
- Bugzilla 17400: put a new line before "candidates are:" in error messages
- Bugzilla 18907: Support cross-compiling
- Bugzilla 21885: Bad diagnostic: struct is not copyable because it is annotated @disable
- Bugzilla 21997: CTFE should allow function pointer casts with different attributes
- Bugzilla 22038: final switch error message should report all missing enum members
- Bugzilla 22115: Optimize if (s.a == 3 ? s : null) to if (s.a == 3)
- Bugzilla 22138: foreach cannot declare the loop variables as scope
- Bugzilla 22227: if (scope f = x()) and while (scope f = x()) do not parse
Phobos regression fixes
- Bugzilla 21920: [REG master] Error: auto can only be used as part of auto ref for template function parameters
- Bugzilla 22056: [Reg 2.074] std.traits.isFloatingPoint, isNumeric, isUnsigned, & isSigned should never be true for SIMD vectors
- Bugzilla 22057: [Reg 2.074] std.traits.isNumeric & isUnsigned should not be true for enum types with character base types
- Bugzilla 22058: [Reg 2.074] std.traits.isNumeric & isSigned should not be true for complex or imaginary types
- Bugzilla 22093: [Reg 2.097] std.typecons.RefCounted!T for struct T without an explicit toString or alias this previously could be converted to string even when uninitialized but now cannot be
- Bugzilla 22125: std.process.Config was changed to a struct but miss operator overloads, leading to user code breakage.
- Bugzilla 22176: Nullable creates autogenerated opAssign, triggering invariants
Phobos bug fixes
- Bugzilla 19727: std.algorithm.endsWith fails to compile while startsWith succeeds
- Bugzilla 20393: formattedRead accepts input, that should be rejected
- Bugzilla 20937: std.range.array of a lengthless range with indirection is not @safe
- Bugzilla 21916: Error message is obfuscated when using wrong format specifier at compile-time
- Bugzilla 22001: Equality of std.conv.toChars() results for radix 10 depends on uninitialized bytes
- Bugzilla 22077: std.sumtype support for copy constructors is incomplete
- Bugzilla 22101: Nullable.get(fallback) cannot be used with non-@safe/pure/nothrow types
- Bugzilla 22110: isCallable fails for template opCall without any templated argument
- Bugzilla 22140: FunctionTypeOf fails for template opCall without any templated argument
- Bugzilla 22146: std.algorithm.searching.findAdjacent() can fall off end of function
- Bugzilla 22222: Custom unittest runner on phobos fails due to segfault on fork() exiting
Phobos enhancements
- Bugzilla 16210: std.utf.byUTF can be made into a bidirectional range
- Bugzilla 16218: Windows std.file.readImpl should be marked @system
- Bugzilla 18632: enable use of fromStringz with char[n]
- Bugzilla 20665: std.concurrency.spawn should document not working with delegates
- Bugzilla 21926: Allow leading zeros in std.conv.octal
- Bugzilla 22100: Support chained assignment of Nullable
- Bugzilla 22225: SumType: Some assignments should be able to execute in safe code
Druntime regression fixes
- Bugzilla 21110: OOB memory access, safety violation
- Bugzilla 22178: [REG 2.097] Compilers do not compile on Musl Libc
Druntime bug fixes
- Bugzilla 9799: Missing aliases and enums in druntime imports
- Bugzilla 14439: aa's keys, values not usable in @safe context
- Bugzilla 21550: core.memory.__delete does not actually work
- Bugzilla 21983: dup leaves a partially constructed array if postblit/copy ctor throws
- Bugzilla 21996: -checkaction=context triggers InvalidMemoryOperationError in finalizer
- Bugzilla 22024: hashOf does not work on enum types whose base type is a SIMD vector
- Bugzilla 22026: checkaction=context: Exception thrown by toString hides assertion failures
- Bugzilla 22076: hashOf(S) can segfault if S.toHash is forwarded via 'alias this' to a receiver which may be null
- Bugzilla 22081: DWARF v5 support is utterly broken - 'illegal instruction' when throwing exceptions
- Bugzilla 22085: checkaction=context doesn't support extern(C++) classes
- Bugzilla 22107: [scope][dip1000] Can't .dup an array of structs with impure copy constructor
- Bugzilla 22143: Throwable ctor doesn't increment chained exception's ref count
- Bugzilla 22166: On OpenBSD and Android make core.sys.posix.arpa.inet: htonl, htons, ntohl, & ntohs work correctly on big endian architectures
- Bugzilla 22167: OpenBSD core.sys.posix.semaphore: sem_t should be a pointer to an opaque struct
- Bugzilla 22168: Fix non-compiling ELF32_M_INFO & ELF64_M_INFO in core.sys..sys.elf32 & core.sys..sys.elf64 for DragonFlyBSD, FreeBSD, NetBSD, & OpenBSD
- Bugzilla 22218: Dynamic casts across binary boundaries can easily fail
Druntime enhancements
- Bugzilla 22169: Mark as pure core.sys.posix.string: memccpy, stpcpy, stpncpy, strnlen
dlang.org bug fixes
- Bugzilla 3345: Static and nonstatic methods with the same name should be allowed
- Bugzilla 20557: Spec does not allow StringPostfix after DelimitedString or TokenString while implementation does
- Bugzilla 21125: Typo in std.range.refRange documentation for opIndex
- Bugzilla 21906: obscure sentence in the introduction to phases of compilation
- Bugzilla 21935: Broken Link in Lazy Evaluation Article
- Bugzilla 22229: Struct initialization via constructor missing from language spec
dlang.org enhancements
- Bugzilla 21495: File.readf documentation does not state what what is returned.
- Bugzilla 21600: Regex.namedCaptures is undocumented
Installer bug fixes
- Bugzilla 21488: Bundled 32-bit dlang tools (ddemangle, dustmite, rdmd) segfault on startup
Contributors to this release (62)
A huge thanks goes to all the awesome people who made this release possible.
- Adam D. Ruppe
- aG0aep6G
- Airbus5717
- Andrei Alexandrescu
- Andrei David
- Andrej Petrović
- Ate Eskola
- Atila Neves
- avaj
- Basile Burg
- Ben Jones
- berni44
- Boris Carvajal
- Brandon Mitchell
- Brian Callahan
- Cameron Ross
- Carsten Schlote
- Craig Barnes
- dandrei279
- Dennis
- dkorpel
- DoctorNoobingstoneIPresume
- drug007
- Etienne Brateau
- Florian
- Hiroki Noda
- Iain Buclaw
- Johan Engelen
- John Colvin
- João Lourenço
- linkrope
- lucica28
- Luís Ferreira
- Martin Kinkelin
- Martin Nowak
- Mathias Lang
- Mathis Beer
- Max Haughton
- Mike Parker
- MoonlightSentinel
- Nathan Sashihara
- Nicholas Wilson
- nordlow
- Paul Backus
- Per Nordlöw
- Rainer Schuetze
- Ramanuj
- Razvan Nitu
- Richard Manthorpe
- RUSshy
- Sebastian Wilzbach
- Simen Kjærås
- Sinisa Susnjar
- Stefan Koch
- Teodor Dutu
- Tomoya Tanjo
- TungstenHeart
- vladchicos
- Vladimir Panteleev
- Walter Bright
- Walter Waldron
- Witold Baryluk