Code:
------
class C { }
struct S
{
C c;
alias c this;
}
Nullable!S s;
struct Nullable(T) // reduced from std.typecons.Nullable
{
union U
{
T t;
}
U u = U.init;
size_t toHash() const @safe nothrow
{
static if (__traits(compiles, .hashOf(u.t))) {}
return 0;
}
}
------
Compiler output:
------
Warning: struct S has method toHash, however it cannot be called with const(S) this.
------
This warning is spurious, because the whole point of the static if is to check for exactly this case, and to provide workaround code for it. As things stand, it is impossible to avoid the warning, even if there is workaround code for it.
Related to issue #18682 that introduced .toHash to std.typecons.Nullable. The bug here, however, is related the compiler, and appears to be related to the compiler confusing Nullable.toHash with S.c.toHash because of the `alias this`.
Comment #1 by s.naarmann — 2019-01-16T00:03:32Z
Right, this has nothing to do with Nullable in particular. This warning appeared in my existing codebase after I switched from DMD 2.083.2 to 2.084.0, and the codebase doesn't use Nullable.
The workaround is to remove the 'alias this' in S.
But it's very common to wrap class references in structs and then alias-this to the class. Would love to see a quick fix!
Comment #2 by hsteoh — 2020-07-13T18:49:11Z
Found this (partial) workaround:
------
class C { /* ... */ }
struct S
{
C c;
auto opDispatch(string field)() inout
{
return mixin("c."~field);
}
}
------
The key here is the `inout`.
This works as long as you don't expect to implicitly convert S to C. You can access class fields as if they were fields in S.
For implicit conversion, though, I haven't come up with a good workaround yet.
Comment #3 by robert.schadek — 2024-12-13T19:01:46Z