Skip to content

x/tools/cmd/stringer cannot run on a file containing imports #52710

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

Closed
0xjac opened this issue May 4, 2022 · 10 comments
Closed

x/tools/cmd/stringer cannot run on a file containing imports #52710

0xjac opened this issue May 4, 2022 · 10 comments
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. Tools This label describes issues relating to any tools in the x/tools repository.
Milestone

Comments

@0xjac
Copy link

0xjac commented May 4, 2022

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

$ go version
go version go1.18 linux/amd64

Does this issue reproduce with the latest release?

Yes, and with all available versions of golang.org/x/tools from v0.1.0 to v.0.1.10 included.

What operating system and processor architecture are you using (go env)?

go env Output
$ go env

GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="$HOME/.cache/go-build"
GOENV="$HOME/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="$HOME/go/pkg/mod"
GONOPROXY="[REDACTED]"
GONOSUMDB="[REDACTED]"
GOOS="linux"
GOPATH="$HOME/go"
GOPRIVATE="[REDACTED]"
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/lib/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.18"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/dev/null"
GOWORK=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build1257915923=/tmp/go-build -gno-record-gcc-switches"

What did you do?

stringer fails to generate a String method for a type located in a file which contains (unrelated) valid imports.

Consider the following pill.go file taken from the stringer documentation, with an extra silly Print function whose sole purpose here is to add an import statement (fmt):

package pill

import (
	"fmt"
)

type Pill int

const (
	Placebo Pill = iota
	Aspirin
	Ibuprofen
	Paracetamol
	Acetaminophen = Paracetamol
)

func Print(pill Pill) {
	fmt.Printf("%v", pill)
}

This needs to be placed in a go module, the simplest reproducible example is to put the file above alongside a simple go.mod file in a pill directory such as:

./pill
├── go.mod
└── pill.go

The go.mod file can be created with go mod init pill.

Simply run the stringer command as documented:

stringer -type=Pill

What did you expect to see?

A correctly generated file: pill_string.go which contains the implementation of the String method for the type Pill defined in the file pill.go (above) as per the stringer documentation.

What did you see instead?

When running the command on the file above, no pill_string.go file is generated. Instead we get the following error message:

stringer: internal error: package "fmt" without types was imported from "pill"

Note this is most likely a consequence of #37617.

@dr2chase
Copy link
Contributor

dr2chase commented May 4, 2022

I tried to reproduce this, including with the latest version of stringer

go install golang.org/x/tools/cmd/stringer@latest
go: downloading golang.org/x/sys v0.0.0-20211019181941-9d821ace8654

and got some errors that were even more mystifying

stringer -type=Pill
stringer: checking package: pill.go:4:2: could not import fmt (cannot find package "fmt" in any of:
	/.../home/drchase/work/go-ssa/src/fmt (from $GOROOT)
	/.../home/drchase/go/src/fmt (from $GOPATH))

but there is no "GO"-anything in my environment, nor is there any mention of "ssa" and the error persisted after go clean -cache.

@dr2chase dr2chase added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label May 4, 2022
@dr2chase dr2chase added this to the Backlog milestone May 4, 2022
@dr2chase
Copy link
Contributor

dr2chase commented May 4, 2022

@golang/tools-team can you give this a look?

@findleyr
Copy link
Member

findleyr commented May 4, 2022

Hi, can you please try go clean -cache, and check if the problem persists?

@0xjac
Copy link
Author

0xjac commented May 4, 2022

@findleyr I've just tried with both go clean -cache and go clean -modcache and the result stays the same:

stringer: internal error: package "fmt" without types was imported from "pill"

Even more interesting, I've cloned the tools repo, checked out v0.1.10 (6799a7ae) and ran stringer from there.

From my pill module, adjacent to go tools if I build stringer.go and there run it from my pill, it works. I get no output but the string file is generated correctly!?

$ pushd ../go-tools/cmd/stringer/; go build stringer.go; popd; ../go-tools/cmd/stringer/stringer -type=Pill
$ head -n 1 pill_string.go
// Code generated by "stringer -type=Pill"; DO NOT EDIT.

This is reaching my limit of go knowledge... I don't understand why the version of stringer built locally with go build (no option) works, but the version installed via go get golang.org/x/tools/cmd/stringer does not...

Note that together with go build, I tried go install (from tools/cmd/stringer) to replace the stringer binary installed via go get with the one built locally and that also result in a working binary.

This all seems rather confusing but I hope someone can make sense of it. I'm happy to help debug further if needed.

@findleyr
Copy link
Member

findleyr commented May 4, 2022

I can't reproduce. How are you installing stringer?

Heres what I've done:

> go install golang.org/x/tools/cmd/stringer@latest
> go version
go version devel go1.19-61a585a32c Tue May 3 16:29:56 2022 +0000 linux/amd64
> stringer -type=Pill
> ls
go.mod  pill.go  pill_string.go
> go1.18beta1 install golang.org/x/tools/cmd/stringer@latest
> stringer -type=Pill
> ls
go.mod  pill.go  pill_string.go
> nvim pill_string.go

i.e. with both the go1.18 beta and a recent go1.19 build, installing the latest version of stringer works fine.

@seankhliao
Copy link
Member

@0xjac output of go version -m /path/to/stringer please
also go get shouldn't be installing anything.

@0xjac
Copy link
Author

0xjac commented May 4, 2022

@seankhliao thanks for your comment, I am not sure why go get seemed to have executed successfully and silently if it is not supposed to install anything.

I believe this might have been user error on my part, where go get -u golang.org/x/tools/cmd/stringer only updated the dependency in my module but did not update the stringer binary. And I must have had an old version of stringer back from when it was installed with go get instead of go install. I've manually removed the stringer manually, cleaned the cache and reinstalled it with go install and with v0.10.0 it now works.

I've checked old versions and if I downgrade to v0.1.7 then I get the error message. Most likely that issue was fixed for v0.1.8 so that's on me...

With the latest version (v0.1.10) of stringer, the output of go version -m `which stringer` is:

/home/jac/go/bin/stringer: go1.18
	path	golang.org/x/tools/cmd/stringer
	mod	golang.org/x/tools	v0.1.10	h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20=
	dep	golang.org/x/mod	v0.6.0-dev.0.20220106191415-9b9b3d81d5e3	h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o=
	dep	golang.org/x/sys	v0.0.0-20211019181941-9d821ace8654	h1:id054HUawV2/6IGm2IV8KZQjqtwAOo2CYlOToYqa0d0=
	dep	golang.org/x/xerrors	v0.0.0-20200804184101-5ec99f83aff1	h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
	build	-compiler=gc
	build	CGO_ENABLED=1
	build	CGO_CFLAGS=
	build	CGO_CPPFLAGS=
	build	CGO_CXXFLAGS=
	build	CGO_LDFLAGS=
	build	GOARCH=amd64
	build	GOOS=linux
	build	GOAMD64=v1

For me this is solved, with my apology for anyone's time being wasted and a special thanks to @seankhliao who made me realize where I got it wrong. 😉

The issue of @dr2chase remains however. But I can't reproduce it. As I started this I am happy to help solve it. @dr2chase did you put the pill.go file in its own directory alongside a go.mod file to make it a module?

@findleyr findleyr changed the title affected/package: golang.org/x/tools/cmd/stringer cannot run on a file containing imports x/tools/cmd/stringer cannot run on a file containing imports May 10, 2022
@gopherbot gopherbot added the Tools This label describes issues relating to any tools in the x/tools repository. label May 10, 2022
@findleyr
Copy link
Member

Closing as I think the issue @dr2chase is encountering is a separate problem, perhaps related to his environment.

@AdwindOne
Copy link

go version 1.18.5 success but 1.20 has the same error

@adonovan
Copy link
Member

I can't reproduce the problem at 1.20 or at tip:

dummy$ pwd
/Users/adonovan/w/dummy
dummy$ ls
go.mod	pill.go
dummy$ head -999 * 
==> go.mod <==
module dummy.com

go 1.19

==> pill.go <==
package dummy

import (
"fmt"
)

type Pill int

const (
	Placebo Pill = iota
	Aspirin
	Ibuprofen
	Paracetamol
	Acetaminophen = Paracetamol
)

func Print(pill Pill) {
	fmt.Printf("%v", pill)
}
dummy$ go1.20 run golang.org/x/tools/cmd/stringer@latest -type=Pill 
dummy$ ls
go.mod		pill.go		pill_string.go
dummy$ cat pill_string.go 
// Code generated by "stringer -type=Pill"; DO NOT EDIT.

package dummy

import "strconv"

func _() {
	// An "invalid array index" compiler error signifies that the constant values have changed.
	// Re-run the stringer command to generate them again.
	var x [1]struct{}
	_ = x[Placebo-0]
	_ = x[Aspirin-1]
	_ = x[Ibuprofen-2]
	_ = x[Paracetamol-3]
}

const _Pill_name = "PlaceboAspirinIbuprofenParacetamol"

var _Pill_index = [...]uint8{0, 7, 14, 23, 34}

func (i Pill) String() string {
	if i < 0 || i >= Pill(len(_Pill_index)-1) {
		return "Pill(" + strconv.FormatInt(int64(i), 10) + ")"
	}
	return _Pill_name[_Pill_index[i]:_Pill_index[i+1]]
}
dummy$ 

@AdwindOne Is your go.mod file valid? Can you provide the output of go1.20 list -json . in the pill directory?

benhoyt added a commit to benhoyt/goawk that referenced this issue Jun 20, 2023
Also update stringer version, as I was getting this error with the
current version for some reason:
golang/go#52710
benhoyt added a commit to benhoyt/goawk that referenced this issue Jun 20, 2023
Also update stringer version, as I was getting this error with the
current version for some reason:
golang/go#52710
@golang golang locked and limited conversation to collaborators Apr 16, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. Tools This label describes issues relating to any tools in the x/tools repository.
Projects
None yet
Development

No branches or pull requests

7 participants