opCast in class prevents destroy

Paul Backus snarwin at gmail.com
Tue Mar 1 16:40:50 UTC 2022


On Tuesday, 1 March 2022 at 04:59:49 UTC, Mike Parker wrote:
> On Tuesday, 1 March 2022 at 04:29:56 UTC, cc wrote:
>> ```d
>> struct A {}
>> class B {
>> 	A opCast(T : A)() {
>> 		return A();
>> 	}
>> }
>> void main() {
>> 	auto b = new B();
>> 	destroy(b);
>> }
>> ```
>> fails with
>> ```
>> dmd2\windows\bin\..\..\src\druntime\import\object.d(4209): 
>> Error: template instance `opCast!(void*)` does not match 
>> template declaration `opCast(T : A)()`
>> main.d(9): Error: template instance `object.destroy!(true, B)` 
>> error instantiating
>> ```
>>
>> Looks like a similar bug has been reported: 
>> https://issues.dlang.org/show_bug.cgi?id=22635
>
> Is it a bug? It's not documented in the `opCast` documentation, 
> but it looks like when you define an `opCast` it completely 
> replaces the default behavior, i.e., whatever type you define 
> as the target type becomes the only type to which you can 
> attempt to cast.

It's a bug in druntime. `destroy` needs to reinterpret the class 
reference as a `void*` to pass it to `rt_finalize`:

https://github.com/dlang/druntime/blob/v2.098.1/src/object.d#L4209

However, `cast(void*)` is not the correct way to do this, because 
it fails in the presence of `opCast`.


More information about the Digitalmars-d-learn mailing list