The compiler swallows opDispatch errors
Steven Schveighoffer
schveiguy at gmail.com
Fri Aug 27 16:08:37 UTC 2021
This bit me again:
```d
struct S
{
void opDispatch(string s)() {
writeln("you called " ~ s);
}
}
void main()
{
S s;
s.foo();
}
```
The result?
```
onlineapp.d(11): Error: no property `foo` for type `onlineapp.S`
onlineapp.d(11): potentially malformed `opDispatch`. Use an
explicit instantiation to get a better error message
```
What? I have to tell the compiler to *explicitly instantiate opDispatch*
in order for it to tell me the actual message?
What I expected is something like:
Error: no symbol `writeln`, please import std.stdio
What is happening here is that if `opDispatch` doesn't compile *for any
reason*, it's not considered a valid instantiation.
This is not how any other functions templates work. If you call a
function or template, and it doesn't compile, it tells you *why* it
didn't compile and gives an error. With `opDispatch`, it implicitly is
adding one of the worst template constraints `if (__traits(compiles,
<function body>))`. This hides so much stuff, and makes it really hard
to find out why something doesn't work, or results in calling very
surprising UFCS functions.
Let's make it even more obscure!
```d
s.get();
```
```
onlineapp.d(11): Error: template `object.get` cannot deduce function
from argument types `!()(S)`, candidates are:
/dlang/dmd/linux/bin64/../../src/druntime/import/object.d(3077):
`get(K, V)(inout(V[K]) aa, K key, lazy inout(V) defaultValue)`
/dlang/dmd/linux/bin64/../../src/druntime/import/object.d(3084):
`get(K, V)(inout(V[K])* aa, K key, lazy inout(V) defaultValue)`
```
Yeah, can we please fix this? `opDispatch` should use the *same rules*
as any other function template -- if it matches, compile. No implicit
"compilation must succeed" BS.
-Steve
More information about the Digitalmars-d
mailing list