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 makes sense to me, and I would say the bug is that it's not
documented.
As a workaround, adding an additional opCast:
```d
class B {
A opCast(T : A)() {
return A();
}
auto opCast(T)() {
return cast(T)super;
}
}
```
SEEMS to work. Is that safe? Or are consequences not what I'm
intending?
So what you've done here is specialized on anything convertible
to `A` and then reenabled casts to all other types, i.e., the
default behavior, but with a special exception for `T:A`.
You could also specialize on `void*`, as that's the type that was
failing to compile. Then you're restricted to `void*` and
anything convertible to `A`.