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/vet: false positive about recursive call to String method #23550

Closed
marat-rkh opened this issue Jan 25, 2018 · 9 comments
Closed

cmd/vet: false positive about recursive call to String method #23550

marat-rkh opened this issue Jan 25, 2018 · 9 comments
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@marat-rkh
Copy link

Please answer these questions before submitting your issue. Thanks!

What version of Go are you using (go version)?

go1.9.3 darwin/amd64

Does this issue reproduce with the latest release?

Yes

What did you do?

Run go vet and go run on the following file:

package main

import "fmt"

type X string
func (x *X) String() string { return fmt.Sprint(">> ", &x) }

func main() {
	var x X = ""
	fmt.Println(x.String())
}

What did you expect to see?

go vet reports no errors as program runs without problems, prints pointer address and exits normally.

What did you see instead?

go vet reports arg &x in Sprint call causes recursive call to String method.

@mvdan mvdan self-assigned this Jan 25, 2018
@mvdan mvdan added the NeedsFix The path to resolution is known, but the work has not been done. label Jan 25, 2018
@mvdan mvdan added this to the Go1.11 milestone Jan 25, 2018
@mvdan
Copy link
Member

mvdan commented Jan 25, 2018

This might be because, until recently, vet did not always have type information. Should be fairly easy to make the check precise.

@marat-rkh
Copy link
Author

As far as I understand, check for print functions will be executed by default before tests in go 1.10. Check results will be treated as errors. Can this be a reason to fix this before 1.10 or, at least, disable the check for this particular case?

@mvdan
Copy link
Member

mvdan commented Jan 25, 2018

That's a good point. Not a regression in vet, but could qualify as a regression in test. /cc @rsc

@mvdan
Copy link
Member

mvdan commented Jan 28, 2018

Actually, I'm not 100% sure if fmt is right here. I know that the program does run, but I don't follow the logic as to why it doesn't crash with an infinite recursion. /cc @robpike

@jimmyfrasche
Copy link
Member

@mvdan the address is taken twice (once implicitly then once explicitly) so it's a **X which has no method set

@robpike
Copy link
Contributor

robpike commented Jan 28, 2018

Vet should not complain here. The code is legal and should (and does) print the address of x, of type **X. The argument to Sprint has no method set.

@mvdan
Copy link
Member

mvdan commented Jan 29, 2018

Thank you both. I do understand the double pointer - what still confuses me at times is what rules apply when a method of *T can be called on T (and vice versa). Thanks for confirming that the code is right before I looked into a fix.

@mvdan
Copy link
Member

mvdan commented Jan 29, 2018

Indeed - the problem is that vet tracked only the types that had a String() string method declared on them, but it did not track whether the receiver in the method had a pointer type. With that extra information, we can now fix this false positive.

@gopherbot
Copy link

Change https://golang.org/cl/90417 mentions this issue: cmd/vet: **T is not Stringer if *T has a String method

@ianlancetaylor ianlancetaylor modified the milestones: Go1.11, Go1.10 Jan 29, 2018
@golang golang locked and limited conversation to collaborators Jan 30, 2019
@rsc rsc unassigned mvdan Jun 23, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

6 participants