Bug 17297 – Object.~this not being @nogc is severely limiting @nogc applicability

Status
RESOLVED
Resolution
DUPLICATE
Severity
normal
Priority
P1
Component
druntime
Product
D
Version
D2
Platform
All
OS
All
Creation time
2017-04-04T10:02:55Z
Last change time
2020-03-21T03:56:37Z
Assigned to
No Owner
Creator
ponce

Comments

Comment #0 by aliloko — 2017-04-04T10:02:55Z
destroy() infers it's "@nogc"-ness from rt_finalize which is not nothrow and not @nogc: https://github.com/dlang/druntime/blob/5a94816c8f1d5c225e560151cebe0a09949896a5/src/object.d#L16 I guess the rationale is that rt_finalize call Object.~this() and that may GC allocate, and throw. In turn this cause every wrapper using emplace+destroy to not be @nogc. Current programs which run without the runtime must currently break the type system in order to call destroy() anyway. https://www.auburnsounds.com/blog/2016-11-10_Running-D-without-its-runtime.html
Comment #1 by b2.temp — 2017-04-06T12:47:09Z
> Object.~this not being @nogc is severely limiting @nogc applicability I agree. There's two main reasons for the problem: 1/ OOP nature. One may call `destroy()` from an instance that's casted to a base type 2/ (the biggest issue IMO) destructors are not called by inheritance (like `super()` for constructors). destructors are found, from the most derived to the base using the `TypeInfo_Class` of each generation (indeed in `rt_finalize2()`). The TI just stores a pointer to a `void function()` and not to a `@nogc void function()`. A workaround (that works since i currently use it) is not to use `destroy()` but create your own equivalent, templatized, able to infer `@nogc`. To solve the first issue you have to assume that the instance that passed to the custom `destroy()` function is the most derived (i.e the traits to get `__xdtor` doesn't return an ancestor `__xdtor`). Then to solve the second issue the `__xdtor` in the ancestors must be called by inheritance, which can be done by mixing a template at each generation. There would also be the idea of an `@assumenogc` attribute. I remember that someone else needed it for the `IAllocator` interface.
Comment #2 by Marco.Leise — 2017-04-07T16:13:42Z
A previous bug report about rt_finalize and @nogc is issue 15246. It takes a look from a different angle, but boils down to the same fundamental issues. Points 1/ (OOP nature) and 2/ (non-inheritance of ~this) from my previous commentator are also discussed there and I gave an example of an "OOP nature" case that I would like to cross post here for illustration purposes... Quote: If we did in fact have virtual destructors like C++, the general rule with inheritance applies: The derived thing must be usable everywhere the base class is used. That disallows the removal of attributes on virtual function overrides: class C { ~this() @safe } class D { override ~this(); // @system } void foo(C c) @safe { // Destroying D is unsafe, but we can't statically check, // because for all we know it is at least a C. destroy(c); } void main() { foo(new D); }
Comment #3 by simen.kjaras — 2018-02-07T12:51:17Z
*** This issue has been marked as a duplicate of issue 15246 ***