Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/compile: recommend fix when "method has pointer receiver" #44201

Open
kstenerud opened this issue Feb 10, 2021 · 4 comments
Open

cmd/compile: recommend fix when "method has pointer receiver" #44201

kstenerud opened this issue Feb 10, 2021 · 4 comments
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made.
Milestone

Comments

@kstenerud
Copy link

Go's diagnostic message when passing a non-pointer to a function taking an interface is confusing because it doesn't explain very well what the problem is.

Example (https://play.golang.org/p/MXm6RG5fYPy):

package main

import (
	"fmt"
)

type Widget interface {
	DoStuff()
}

type MyWidget struct{}

func (w *MyWidget) DoStuff() {
	fmt.Println("Doing stuff")
}

func doStuffWithWidget(w Widget) {
	w.DoStuff()
}

func main() {
	w := MyWidget{}
	doStuffWithWidget(w)
}

This produces the diagnostic:

./prog.go:23:19: cannot use w (type MyWidget) as type Widget in argument to doStuffWithWidget:
	MyWidget does not implement Widget (DoStuff method has pointer receiver)

... which is only half the story, and makes it difficult to see what's actually wrong. A better diagnostic would be:

./prog.go:23:19: cannot use w (type MyWidget) as type Widget in argument to doStuffWithWidget:
	MyWidget does not implement Widget (DoStuff method has pointer receiver). Passing &w would work here.
@seankhliao seankhliao changed the title Confusing error diagnostic: "method has pointer receiver" cmd/compile: recommend fix when "method has pointer receiver" Feb 10, 2021
@seankhliao seankhliao added the NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. label Feb 10, 2021
@ALTree
Copy link
Member

ALTree commented Feb 10, 2021

The

(DoStuff method has pointer receiver)

part explains clearly what the problem is, so the diagnostic is complete. You propose adding a sentence that also suggests a possible solution, which is a different thing.

Not many errors in Go do that, because it makes every error message more verbose. This style of diagnostic is useful in complex languages, where it may not be obvious at all how to fix an issue, but I'm not sure this is the case. In my experience, after you've seen the "has pointer receiver" error once or twice, you quickly learn what it means (and how to fix it).

@jmaister
Copy link

What seems confusing to me is that the method doStuffWithWidget is expecting a Widget and not a *Widget.

So, why the parameter must be sent as a pointer with doStuffWithWidget(&w) instead of doStuffWithWidget(w)?

@gazerro
Copy link
Contributor

gazerro commented Jul 13, 2021

I think that (DoStuff method has pointer receiver) already suggest a possible solution but it can be unclear.

In addition to this, if the argument is replaced with a pointer value, its type does not necessarily implement the interface. For example if the interface is

type Widget interface {
	DoStuff()
        None()
}

the error message is the same but *MyWidget does not implement Widget either.

If the corresponding pointer type (*MyWidget in this example) does not implement the interface, the error should, possibly, not refer to an interface method that *MyWidget does not implement.

If instead *MyWidget implements the interface, the error should suggest *MyWidget implements Widget, as in

./prog.go:23:19: cannot use w (type MyWidget) as type Widget in argument to doStuffWithWidget:
	MyWidget does not implement Widget (*MyWidget implements Widget)

@bklaubos
Copy link

bklaubos commented Oct 9, 2021

./prog.go:23:19: cannot use w (type MyWidget) as type Widget in argument to doStuffWithWidget:
MyWidget does not implement Widget (DoStuff method has pointer receiver)

I agreed that its confusing to say the least. A better message would be:

./prog.go:23:19: cannot use w (type MyWidget) as type Widget in argument to doStuffWithWidget:
MyWidget does not implement Widget (DoStuff method expects pointer receiver)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made.
Projects
Status: Triage Backlog
Development

No branches or pull requests

7 participants