Bug 13531 – Destructor attributes don't take member destructor attributes into account

Status
NEW
Severity
minor
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-09-25T09:57:58Z
Last change time
2024-12-13T18:29:36Z
Keywords
diagnostic
Assigned to
No Owner
Creator
monarchdodra
Moved to GitHub: dmd#18891 →

Comments

Comment #0 by monarchdodra — 2014-09-25T09:57:58Z
If you have "S" with completely unsafe destructor, and you aggregate it into "SS": //---- struct S { ~this() //not nothrow, system, impure, gc etc... {} } struct SS { S s; ~this() @safe pure nothrow @nogc {} } //---- This compiles. This may or may not be wrong, depending on your point of view: The "code content" of the destructor is indeed actually safe etc... The issue comes if you actually do try to use it in a safe context: //---- void main() @safe pure nothrow @nogc { SS ss; } //---- Here is the error message: //---- Error: pure function 'D main' cannot call impure function 'main.SS.~this' Error: safe function 'D main' cannot call system function 'main.SS.~this' Error: @nogc function 'D main' cannot call non-@nogc function 'main.SS.~this' Error: 'main.SS.~this' is not nothrow Error: function 'D main' is nothrow yet may throw //---- The issue here is that it clearly states that "SS.~this" is the one that is unsafe, yet it is clearly marked as such. IMO, the bug is that it should have never been legally marked as @safe to begin with.
Comment #1 by bugzilla — 2014-11-13T11:20:01Z
What's happening here is that there are actually two destructors for SS - the one for the s field, and the ~this(). The compiler combines all such destructors into one aggregate destructor. The aggregate destructor contains the most permissive combination of the attributes of all the aggregated destructors. The error message is for the generated aggregated destructor. Perhaps the error message could be better, but the feature is working as designed. Reducing this issue to minor as the only problem is the error message.
Comment #2 by stanislav.blinov — 2021-12-08T18:00:46Z
Nowadays the error message is... better, for a conservative definition of "better". But it's __very__ verbose and most of all, wrong. It's referring to SS.~this, which is not at all the destructor in question - SS.__xdtor is. It's even referring to the line where SS.~this is declared! SS.~this has the attributes, and the error message shouldn't indicate that it doesn't. main.d(16): Error: `pure` function `D main` cannot call impure destructor `SS.~this` main.d(10): generated `SS.~this` is impure because of the following field's destructors: main.d(9): - S s main.d(3): impure `S.~this` is declared here main.d(16): Error: `@safe` function `D main` cannot call `@system` destructor `SS.~this` main.d(10): `SS.~this` is declared here main.d(10): generated `SS.~this` is @system because of the following field's destructors: main.d(9): - S s main.d(3): @system `S.~this` is declared here main.d(16): Error: `@nogc` function `D main` cannot call non-@nogc destructor `SS.~this` main.d(10): generated `SS.~this` is non-@nogc because of the following field's destructors: main.d(9): - S s main.d(3): non-@nogc `S.~this` is declared here main.d(16): Error: destructor `SS.~this` is not `nothrow` main.d(10): generated `SS.~this` is not nothrow because of the following field's destructors: main.d(9): - S s main.d(3): not nothrow `S.~this` is declared here main.d(14): Error: `nothrow` function `D main` may throw Add more fields to SS, and this gets even longer. With this code: struct S { ~this() //not nothrow, system, impure, gc etc... {} } struct S2 { ~this() {} } struct SS { S s; ~this() @safe pure nothrow @nogc {} } struct SSS { SS ss; ~this() @safe pure nothrow @nogc {} } void main() @safe pure nothrow @nogc { SSS ss; } ...errors are page long :\ Suggested change: main.d(16): Error: `@safe pure nothrow @nogc` function `D main` cannot call impure @system throwing GC-using generated destructor for `SS` main.d(9): Generated destructor for `SS` is impure @system throwing GC-using because of destructor of field `s` main.d(3): impure @system throwing GC-using destructor of field `s` is declared here ...with one relevant line per field, correctly distinguishing generated destructors and user-defined destructors.
Comment #3 by robert.schadek — 2024-12-13T18:29:36Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/18891 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB