purge changelog

This commit is contained in:
Dennis Korpel 2025-03-31 13:33:57 +02:00
parent c403accecf
commit c6863be720
31 changed files with 0 additions and 673 deletions

View file

@ -1,19 +0,0 @@
Storage classes `ref` and `auto ref` can now be applied to local, static, extern, and global variables
For example, one can now write:
```
struct S { int a; }
void main()
{
S s;
ref int r = s.a;
r = 3;
assert(s.a == 3);
auto ref x = 0;
auto ref y = x;
static assert(!__traits(isRef, x));
static assert( __traits(isRef, y));
}
```

View file

@ -1,18 +0,0 @@
Keywords `auto` and `ref` must be adjacent
It's now deprecated to declare `auto ref` parameters without putting those two keywords next to each other.
This way it's clear that `auto ref` semantics are intended, rather than `ref` and `auto` semantics separately.
For the newly introduced $(RELATIVE_LINK2 dmd.reflocal, `ref` local / global variables), it's an error immediately.
---
void t()(ref const auto int x) // Deprecation
{
ref auto y = x; // Error
}
// Correction:
void t()(auto ref const int x)
{
auto ref y = x;
}
---

View file

@ -1,23 +0,0 @@
The `align` attribute now allows specifying `default` explicitly
A lone `align` sets the alignment to the types default.
To be more explicit, `align(default)` does the same.
```
struct S
{
align(4)
{
byte x;
align(default) long y;
long z;
}
}
void main()
{
pragma(msg, S.x.alignof); // 4
pragma(msg, S.y.alignof); // 8
pragma(msg, S.z.alignof); // 4
}
```

View file

@ -1,15 +0,0 @@
Remove `delete` as a keyword
After being superseded by `destroy()`, deprecated, and turned into an error, `delete` can now be used as an identifier:
---
enum Action
{
add, delete
}
void delete(T)(T obj)
{
}
---

View file

@ -1,18 +0,0 @@
Case fallthough for multivalued cases is an error now
This used to give a deprecation and now gives an error:
```
int i;
switch (0)
{
case 0, 1: i = 20;
default: assert(0); // Error: switch case fallthrough - use 'goto default;' if intended
}
switch (0)
{
default:
case 0, 1: i = 20;
case 2, 3: i = 30; // Error: switch case fallthrough - use 'goto case;' if intended
}
```

View file

@ -1,32 +0,0 @@
An error is now given for constructors when a field's destructor has stricter attributes
```
struct HasDtor
{
~this() {}
}
struct Pure
{
HasDtor member;
this(int) pure {} // Error: `this` has stricter attributes than its destructor (`pure`)
}
struct Nothrow
{
HasDtor member;
this(int) nothrow {} // Error: `this` has stricter attributes than its destructor (`nothrow`)
}
struct NoGC
{
HasDtor member;
this(int) @nogc {} // Error: `this` has stricter attributes than its destructor (`@nogc`)
}
struct Safe
{
HasDtor member;
this(int) @safe {} // Error: `this` has stricter attributes than its destructor (`@safe`)
}
```

View file

@ -1,16 +0,0 @@
Initializing a field with itself has been deprecated
This is to prevent a common mistake when a field and a parameter ought to have the same name,
but one is misspelled where it's declared:
---
struct S
{
int field;
this(int feild) // supposed to be: this(int field)
{
this.field = field; // equal to this.field = this.field
}
}
---

View file

@ -1,11 +0,0 @@
An error is now given for subtracting pointers of different types
The following code now gives errors:
```
static assert(cast(void*)8 - cast(int*) 0 == 2L);
static assert(cast(int*) 8 - cast(void*)0 == 8L);
void test()
{
auto foo = (ushort*).init - (ubyte*).init;
}
```

View file

@ -1,17 +0,0 @@
An error is now issued for `in`/`out` contracts of `nothrow` functions that may throw
This used to issue a deprecation, it is now an error:
```
void test() nothrow
in
{
throw new Exception(null); // Error: `in` contract may throw but function is marked as `nothrow`
}
out
{
throw new Exception(null); // Error: `out` contract may throw but function is marked as `nothrow`
}
do
{
}
```

View file

@ -1,40 +0,0 @@
Typesafe variadic class parameters have been deprecated
This obscure feature allowed a limited form of implicit construction:
---
void check(bool x, Exception e...)
{
if (!x)
throw e;
}
void main(string[] args)
{
check(args.length > 1, "missing argument");
}
---
However, few uses of this feature have been found, and one project was actually mistakenly using it instead of the more common Typesafe variadic array parameter.
Considering D doesn't support implicit construction and already has a confusing amount of different variadic parameter forms, it was decided to remove this feature.
As a corrective action, either call the constructor in the callee:
---
void check(string msg)
{
if (!x)
throw new Exception(msg);
}
---
Or let the caller construct the class instance:
---
void check(bool x, Exception e);
void main(string[] args)
{
check(args.length > 1, new Exception("missing argument"));
}
---

View file

@ -1,5 +0,0 @@
Integers in `debug` or `version` statements have been removed from the language
These were deprecated in 2.101.
Use `-debug=identifier` and `-version=identifier` instead for versions set on the command line,
and likewise `version = identifier;` and `debug = identifier;` for versions set in code at global scope.

View file

@ -1,123 +0,0 @@
Many error messages have changed
Some changes have been made without being associated to a reported issue:
Error messages for `@safe` violations now consistently mention they are related to `@safe` functions (or default functions with `-preview=safer`).
In general, function attributes that failed to infer have a more compact error message:
Before:
$(CONSOLE
app.d(8): Error: function `attributediagnostic_nothrow.gc1` is not `nothrow`
app.d(2): which wasn't inferred `nothrow` because of:
app.d(2): `object.Exception` is thrown but not caught
)
After:
$(CONSOLE
app.d(8): Error: function `attributediagnostic_nothrow.gc1` is not `nothrow`
app.d(2): and `object.Exception` being thrown but not caught makes it fail to infer `nothrow`
)
Function literals are now referred to by their (truncated) function body, instead of the internal `__lambda` name.
---
/*
BEFORE:
../test/test_.d(3): Error: function literal `__lambda1()` is not callable using argument types `(int)`
(() => 42)(1);
^
AFTER:
../test/test_.d(3): Error: function literal `() => 42` is not callable using argument types `(int)`
(() => 42)(1);
^
*/
---
Match levels are now mentioned on ambiguous overloads: [#20637](https://github.com/dlang/dmd/pull/20637)
Before:
$(CONSOLE
Error: `app.bar` called with argument types `(string)` matches both:
)
After:
$(CONSOLE
Error: `app.bar` called with argument types `(string)` matches multiple overloads after implicit conversions:
)
Error messages related to operator overloading have been improved.
When the related template functions (`opUnary`, `opBinary`, `opBinaryRight`, `opOpAssign`, `opIndex`, `opSlice`)
are missing, a suggestion to implement them is given.
When they do exist but fail to instantiate, the error from instantiation is shown.
There's no longer a need to manually e.g. rewrite `s + 1` to `s.opBinary!"+"(1)` to diagnose the error.
---
struct S {}
void main()
{
S s;
const x = s[3 .. "4"];
}
---
Before:
$(CONSOLE
app.d(6): Error: no `[]` operator overload for type `S`
)
After:
$(CONSOLE
app.d(6): Error: no `[3.."4"]` operator overload for type `S`
app.d(1): perhaps define `auto opSlice(int lower, string upper) {}` for `app.S`
)
---
struct Str {}
struct Number
{
int x;
int opBinary(string op : "+")(int rhs) => this.x + x;
}
void f(Str str, Number number)
{
const s = str ~ "hey";
const n = number + "oops";
}
---
Before:
$(CONSOLE
app.d(12): Error: incompatible types for `(str) ~ ("hey")`: `Str` and `string`
const s = str ~ "hey";
^
app.d(13): Error: incompatible types for `(number) + ("oops")`: `Number` and `string`
const n = number + "oops";
)
After:
$(CONSOLE
app.d(12): Error: operator `~` is not defined for type `Str`
const s = str ~ "hey";
^
app.d(2): perhaps overload the operator with `auto opBinary(string op : "~")(string rhs) {}`
struct Str {}
^
app.d(13): Error: function `test_.Number.opBinary!"+".opBinary(int rhs)` is not callable using argument types `(string)`
const n = number + "oops";
^
app.d(13): cannot pass argument `"oops"` of type `string` to parameter `int rhs`
app.d(7): `opBinary` defined here
int opBinary(string op : "+")(int rhs) => this.x + x;
^
)
Furthermore:
- D1 operator overloading functions (`opAdd`, `opDot`) are completely removed and no longer mentioned in error messages specifically.
- Class allocators (`auto new() {}`) are not only a semantic error, but no longer parse.

View file

@ -1,4 +0,0 @@
The compiler now accepts `-extern-std=c++23`
The compiler now accepts c++23 as a supported standard for `-extern-std=`.
Currently this only changes the value of `__traits(getTargetInfo, "cppStd")`.

View file

@ -1,16 +0,0 @@
Build time profiling has been added to DMD
The `-ftime-trace` switch that the LDC compiler already has, is now also available in dmd.
It can be used to figure out which parts of your code take the longest to compile, so you can optimize your build times.
$(CONSOLE
dmd -ftime-trace app.d
)
This will output `app.o.time-trace`.
A different output file can be selected with `-ftime-trace-file=trace.json`.
The output is in Google Chrome's profiler format, which can be viewed in an interactive viewer like [ui.perfetto.dev](https://ui.perfetto.dev).
See also the YouTube tutorial [*Easily Reduce Build Times by Profiling the D Compiler*](https://www.youtube.com/watch?v=b8wZqU5t9vs).

View file

@ -1,16 +0,0 @@
New traits `getBitfieldOffset` and `getBitfieldWidth` for built-in bitfields
This completes the introspection capabilities of built-in bitfields. For example:
---
struct S
{
int a,b;
int :2, c:3;
}
static assert(__traits(getBitfieldOffset, S.b) == 0);
static assert(__traits(getBitfieldOffset, S.c) == 2);
static assert(__traits(getBitfieldWidth, S.b) == 32);
static assert(__traits(getBitfieldWidth, S.c) == 3);
---

View file

@ -1,3 +0,0 @@
Using the compiler flag `-i` will now properly pick up C source files
Previously, you needed to manually include `*.c` source files, it now works just like with D files.

View file

@ -1,25 +0,0 @@
A pragma for ImportC allows to set `nothrow`, `@nogc` or `pure`
The following new pragma for ImportC allows to set default storage
classes for function declarations:
```c
#pragma attribute(push, [storage classes...])
```
The storage classes `nothrow`, `nogc` and `pure` are supported.
Unrecognized attributes are ignored.
Enabling a default storage class affects all function declarations
after the pragma until it is disabled with another pragma.
Declarations in includes are also affected.
The changed storage classes are pushed on a stack. The last change can
be undone with the following pragma.
The following example
enables `@nogc` and `nothrow` for a library:
```c
#pragma attribute(push, nogc, nothrow)
#include <somelibrary.h>
#pragma attribute(pop)
```
This can also disable multiple default storage classes at the same time,
if they were enabled with a single `#pragma attribute(push, ...)` directive.

View file

@ -1,8 +0,0 @@
Mixin templates can now use assignment syntax
Previously, giving a name to a mixed-in mixin template instance required putting the name at the end.
Now, it can also go in front of the instantiation using assignment syntax.
---
mixin MyMixinTemplate!(Args) myName; // old style
mixin myName = MyMixinTemplate!(Args); // new style
---

View file

@ -1,6 +0,0 @@
Object file extensions `.o` and `.obj` are now accepted on all platforms
Accepting `.o` and `.obj` file extensions on all platforms makes DMD behave
like Clang and other modern compilers. There is no point in
discarding `*.o` or `*.obj` depending on the current operating system, as both extensions
unambiguously denote object file.

View file

@ -1,38 +0,0 @@
Objective-C selectors are now automatically generated when not specified with `@selector`.
Additionally, the Objective-C selector generation rules have changed, following these steps:
1. Functions marked with `@property` will generate `setXYZ:` for the setters.
2. For property functions with names starting with `is`, that prefix will be stripped off in the setter.
3. Selector generation now uses the names of the function parameters instead of their D-mangled types.
Selectors may still be specified with the `@selector` UDA, in which case it takes precedence over the
automatically generated selectors.
These new rules apply both for `extern` and non-`extern` Objective-C classes and protocols.
---
extern(Objective-C)
extern class NSObject {
static NSObject alloc(); // Generates as `alloc`
NSObject init(); // Generates as `init`
}
extern(Objective-C)
class Fox : NSObject {
bool fluffy;
@property bool isFluffy() => fluffy; // `isFluffy`
@property void isFluffy(bool value) { fluffy = value; } // `setFluffy:`
void yip(int a) @selector("bark:") { // `bark:`
// ...
}
void doSomething(int a, int b, int c) { // `doSomething:b:c:`
// ...
}
}
---
These changes should not break any existing code because the automatic selector generation
was not present before. And automatic selector generation only applies to `extern(Objective-C)` methods.

View file

@ -1,15 +0,0 @@
New compiler switch `-oq` for DMD
The switch gives fully qualified names to object files, preventing name conflicts when using the switch `-od`
while compiling multiple modules with the same name, but inside different packages.
The switch already existed in LDC, but is now in dmd as well.
Example:
$(CONSOLE
dmd -c -oq -od=. app.d util/app.d misc/app.d
)
This will output `app.obj`, `util.app.obj`, and `misc.app.obj`, instead of just `app.obj`.
The switch `-oq` also applies to other outputs, such as Ddoc (`-D -Dd=.`) and `.di` header generation (`-H -Hd=.`).

View file

@ -1,20 +0,0 @@
Added Placement New Expression
Placement `new` explicitly provides the storage for `new` expression to initialize
with the newly created value, rather than using the GC.
---
struct S
{
float d;
int i;
char c;
}
void main() @system @nogc
{
S s;
S* p = new (s) S(3.14, 42, 'X'); // place new object into s
assert(p.i == 42 && p.c == 'X');
}
---

View file

@ -1,13 +0,0 @@
Postfix type qualifier method attributes for `-H` and `-D`
The `.di` interface file generation and Ddoc output will now have type qualifier
attributes placed after the parameter list for methods (and constructors).
This avoids confusion with the return type.
---
struct S
{
const int f(); // before
int f() const; // now
}
---

View file

@ -1,8 +0,0 @@
The folder *samples* has been removed from DMD installations
Every DMD release has included a folder with small D code examples.
These examples are quite old, and not a good representation of modern D.
They're also hard to discover, since D compilers are often installed through an installer or package manager.
Since there are better resources available online nowadays, these samples have
been moved to the [undeaD](https://github.com/dlang/undeaD) repository.

View file

@ -1,40 +0,0 @@
New keyword `__rvalue`
The newly added primary expression of the form `__rvalue(expression)`
evaluates to `expression`, except that it is treated as an rvalue,
even if would be an lvalue otherwise.
Overloads on `ref`:
```
foo( S s); // selected if the argument is an rvalue
foo(ref S s); // selected if the argument is an lvalue
S s;
S bar();
...
foo(s); // selects foo(ref S)
foo(bar()); // selects foo(S)
```
With this change:
```
foo(__rvalue(s)); // selects foo(S)
```
This also applies to constructors and assignments, meaning move constructors and
move assignments are enabled. Moving instead of copying can be much more resource
efficient, as, say, a string can be moved rather than copied/deleted.
A moved object will still be destructed, so take that into account when moving
a field - set it to a benign value that can be destructed.
`__rvalue` may also be used as an attribute on a function which returns by ref
to declare that the result should be treated as an rvalue at the callsite:
```
ref T move(T)(return ref T source) __rvalue
{
return source;
}
S s;
S t = move(s); // call expression rewritten as: S t = __rvalue(move(s))
```
This is used as an internal tool to implement library primitives such as `move` and `forward`.

View file

@ -1,22 +0,0 @@
Add `-preview=safer` switch for safety checking on unattributed functions
All the checks currently enabled in `@safe` code, that are easily fixed (as in
the fix is constrained to the function), will be enabled in `-preview=safer` code.
Code not easily fixed, such as calls to `@system` or unattributed functions, will
be allowed as before.
---
void f();
@system void g();
void main()
{
int* p;
p++; // Error, pointer arithmetic
f(); // allowed
g(); // allowed
}
---
For more information, see [this document](https://github.com/WalterBright/documents/blob/38f0a846726b571f8108f6e63e5e217b91421c86/safer.md).

View file

@ -1,18 +0,0 @@
Shortened method syntax can now be used in constructors
This used to raise an error (cannot return expression from constructor), but is now supported:
---
struct Number
{
int x;
void vf(int);
this(int x) => vf(x);
this(float x) => this(cast(int) x);
}
---
The expression body must be a `this`/`super` call or have type `void`.
Postblits and destructors already supported shortened method syntax because they return `void`.

View file

@ -1,7 +0,0 @@
Add Windows BCrypt bindings under `core.sys.windows.bcrypt`
Adds full [BCrypt API](https://learn.microsoft.com/en-us/windows/win32/api/bcrypt/) bindings
to the Windows-specific system bindings.
The Windows-specific bindings under `core.sys.windows.sdkddkver` and `core.sys.windows.w32api`
have also been updated in order to facilitate the creation of the BCrypt bindings.

View file

@ -1,5 +0,0 @@
Remove `criticalRegionLock`
The `criticalRegionLock` feature suffer from a serious design flaw: $(LINK https://issues.dlang.org/show_bug.cgi?id=24741)
It turns out it is not used, so rather than fixing the flaw, the feature was removed.

View file

@ -1,7 +0,0 @@
Adds `expect`, `likely`, `unlikely`, and `trap` to `core.builtins`
Adds the functions `expect` and `likely`/`unlikely` for branch and value hints for the LDC/GDC compilers.
DMD ignores these hints.
Adds the function `trap` to be lowered to the target-dependent trap instruction.
If the target does not have a trap instruction, this intrinsic will be lowered to a call of the `abort` function.

View file

@ -1,65 +0,0 @@
New segfault handler showing backtraces for null access / call stack overflow on linux
While buffer overflows are usually caught by array bounds checks, there are still other situations where a segmentation fault occurs in D programs:
- `null` pointer dereference
- Corrupted or dangling pointer dereference in `@system` code
- Call stack overflow (infinite recursion)
These result in an uninformative runtime error such as:
$(CONSOLE
[1] 37856 segmentation fault (core dumped) ./app
)
In order to find the cause of the error, the program needs to be run again in a debugger like GDB.
There is the `registerMemoryErrorHandler` function in `etc.linux.memoryerror`, which catches `SIGSEGV` signals and transforms them into a thrown `InvalidPointerError`, providing a better message.
However, it doesn't work on call stack overflow, because it uses stack memory itself, so the segfault handler segfaults.
It also relies on inline assembly, limiting it to the x86 architecture.
A new function `registerMemoryAssertHandler` has been introduced, which does handle stack overflow by setting up an [altstack](https://man7.org/linux/man-pages/man2/sigaltstack.2.html).
It uses `assert(0)` instead of throwing an `Error` object, so the result corresponds to the chosen `-checkaction` setting.
Example:
---
void main()
{
version (linux)
{
import etc.linux.memoryerror;
registerMemoryAssertHandler();
}
int* p = null;
int* q = cast(int*) 0xDEADBEEF;
// int a = *p; // segmentation fault: null pointer read/write operation
// int b = *q; // segmentation fault: invalid pointer read/write operation
recurse(); // segmentation fault: call stack overflow
}
void recurse()
{
recurse();
}
---
Output with `dmd -g -run app.d`:
$(CONSOLE
core.exception.AssertError@src/etc/linux/memoryerror.d(82): segmentation fault: call stack overflow
$(NDASH)$(NDASH)$(NDASH)$(NDASH)$(NDASH)$(NDASH)$(NDASH)$(NDASH)$(NDASH)$(NDASH)
src/core/exception.d:587 onAssertErrorMsg [0x58e270d2802d]
src/core/exception.d:803 _d_assert_msg [0x58e270d1fb64]
src/etc/linux/memoryerror.d:82 _d_handleSignalAssert [0x58e270d1f48d]
??:? [0x7004139e876f]
./app.d:16 void scratch.recurse() [0x58e270d1d757]
./app.d:18 void scratch.recurse() [0x58e270d1d75c]
./app.d:18 void scratch.recurse() [0x58e270d1d75c]
./app.d:18 void scratch.recurse() [0x58e270d1d75c]
./app.d:18 void scratch.recurse() [0x58e270d1d75c]
...
...
...
)