Bug 22968 – "Need this of type X" error message is confusing
Status
RESOLVED
Resolution
FIXED
Severity
enhancement
Priority
P4
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2022-04-02T18:23:56Z
Last change time
2023-07-27T20:09:15Z
Keywords
diagnostic
Assigned to
No Owner
Creator
Steven Schveighoffer
Comments
Comment #0 by schveiguy — 2022-04-02T18:23:56Z
When a non-static method is called without an instance, the error message relates more to how the compiler is viewing the call, rather than how the user called it.
Considering that in many cases, the `this` parameter is implied (on account of being inside a type method), or is not even present. Telling the user about their bad `this` argument is confusing.
An example:
```d
struct S
{
void foo();
}
void main()
{
S s;
S.foo(); // oops, used the wrong case
}
```
The error message in the above is:
```
onlineapp.d(9): Error: need `this` for `foo` of type `void()`
```
A more robust message would identify that the user did not call a method that requires the `this` parameter on a correct object. I'd prefer to see a message like:
```
Error: `S.foo` should only be called on an instance of `S`.
```
Optionally, you could identify that they were really trying to call it on the type `S`.
When inside a *different* type, the error message is slightly more esoteric:
```d
struct S
{
void foo();
}
struct T
{
S s;
void bar()
{
S.foo(); // oops again!
}
}
```
And the result:
```
onlineapp.d(11): Error: `this` for `foo` needs to be type `S` not type `T`
```
This is confusing because the user didn't explicitly pass the `this` parameter of T. While I understand how the machinery works, the compiler should hide how it is doing things here. I'd prefer a similar message change:
```
Error: `S.foo` should only be called on an instance of `S`. When calling from inside `T.bar`, `this` is of type `T`.
```
In general, trying to diagnose the code that was written rather than what the compiler sees is more helpful as an error message.
Note that there are valid uses of specifying a function to call statically instead of on an instance. Notably calling a superclass implementation:
```d
class C
{
void foo() {writeln("inside C");}
}
class D : C
{
override void foo() {writeln("inside D");}
void bar() {C.foo();} // prints "inside C"
}
```
So the feature cannot really be flagged without checking if the call is valid first.