On Thursday, 10 March 2016 at 01:25:44 UTC, Nicholas Wilson wrote:
struct Bar_T; // opaque
alias Bar = Bar_T*;
void someFuncIWantWrapped(Bar* bar)
{
}
struct Foo
{
    Bar bar;
    alias bar this;
}
void someFunc(Foo* foo)
{
   someFuncIWantWrapped(foo);
}

gives
Error: function someFuncIWantWrapped (Bar_T** bar) is not callable using argument types Foo*

I feel like this should work.

Yes I realise that I can fix it by
void someFunc(Foo foo)
{
   someFuncIWantWrapped(&foo.bar);
}

but I'm generating this and the name of bar changes and in generated from multiple code paths.

Should I report this as a bug?

I see no bugs here. Just because type T can be implicitly converted to type U doesn't mean that T* can be implicitly converted to U* - e.g. int* can't be safely converted to long* in the general case. There are some cases where it can be done in @system code if the programmer knows what they're doing but not in @safe code - and regardless, it's done by reinterpreting the bytes, not by the kind of conversion that alias this is doing. You're asking for the compiler to somehow take T* and convert it to a completely unrelated type U* just because the programmer has provided a way to convert T to U. But since that conversion is not done be reinterpreting the bytes, there's no way to do that even in @system code, let alone implicitly in @safe code.

Regardless, Foo defined the alias this, not Foo*, so alias this isn't going to work with Foo*. Foo* may point to a Foo, but isn't a Foo, and it doesn't follow the same conversion rules.

- Jonathan M Davis

Reply via email to