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

go/types: include import path in type error messages #35895

Closed
stapelberg opened this issue Nov 28, 2019 · 10 comments
Closed

go/types: include import path in type error messages #35895

stapelberg opened this issue Nov 28, 2019 · 10 comments
Labels
FrozenDueToAge NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made.
Milestone

Comments

@stapelberg
Copy link
Contributor

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

$ go version
go version go1.13.4 linux/amd64

Does this issue reproduce with the latest release?

Yes.

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

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/usr/local/google/home/stapelberg/.cache/go-build"
GOENV="/usr/local/google/home/stapelberg/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/tmp/bug"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/lib/google-golang"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/google-golang/pkg/tool/linux_amd64"
GCCGO="/usr/bin/gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
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 -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build918009785=/tmp/go-build -gno-record-gcc-switches"

What did you do?

I have the following Go source files (directory structure is relevant, so no play.golang.org link):

% head -100 pkg1/pkg1.go nested/pkg1/pkg1.go third/third.go demo/demo.go ast/ast.go
==> pkg1/pkg1.go <==
package pkg1

type Client struct{}

==> nested/pkg1/pkg1.go <==
package pkg1

type Client struct{}

==> third/third.go <==
package third

import "pkg1"

func Something(*pkg1.Client) {}

==> demo/demo.go <==
package main

import (
	"nested/pkg1"
	"third"
)

func main() {
	h := &pkg1.Client{}
	third.Something(h)
}

==> ast/ast.go <==
package main

import (
	"fmt"
	"os"

	"golang.org/x/tools/go/packages"
)

func main() {
	cfg := &packages.Config{
		Mode: packages.NeedFiles | packages.NeedSyntax | packages.NeedImports | packages.NeedTypes,
	}
	pkgs, err := packages.Load(cfg, "demo")
	if err != nil {
		fmt.Fprintf(os.Stderr, "load: %v\n", err)
		os.Exit(1)
	}
	if packages.PrintErrors(pkgs) > 0 {
		os.Exit(1)
	}
	fmt.Printf("pkgs: %v", pkgs)
}

When using go run demo.go, I get:

./demo.go:10:17: cannot use h (type *"nested/pkg1".Client) as type *"pkg1".Client in argument to third.Something

However, when using go run ast.go, I get:

/tmp/bug/src/demo/demo.go:10:18: cannot use h (variable of type *pkg1.Client) as *pkg1.Client value in argument to third.Something

The latter message does not include the import path, only the package, and is hence very confusing especially for newcomers to the language: the two *pkg1.Client look exactly the same, so the error message looks non-sensical.

The message is produced by the go/types package in

check.errorf(x.pos(), "cannot use %s as %s value in %s", x, T, context)

Note that some users in some environments might be exposed to error messages from go/types before they see the error message from the Go compiler because of how IDE integration works.

Could we include the import path in the error messages produced by go/types as well please?

@mvdan
Copy link
Member

mvdan commented Dec 1, 2019

Same issue, but for runtime errors: #11634

@dmitshur dmitshur added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Dec 2, 2019
@dmitshur
Copy link
Contributor

dmitshur commented Dec 2, 2019

/cc @griesemer per owners.

@griesemer griesemer self-assigned this Dec 2, 2019
@griesemer griesemer added the NeedsFix The path to resolution is known, but the work has not been done. label Dec 2, 2019
@gopherbot gopherbot removed the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Dec 2, 2019
@griesemer griesemer added this to the Go1.14 milestone Dec 2, 2019
@griesemer
Copy link
Contributor

Marking tentatively for 1.14 since this only affects an error message.

@gopherbot
Copy link
Contributor

Change https://golang.org/cl/209578 mentions this issue: go/types: print full package path for imported packages in error messages

@griesemer
Copy link
Contributor

The fix is trivial (https://golang.org/cl/209578) but may have implications for client code that parses error messages. Also, we're currently in the 1.14 freeze and this may cause needless instability. Marking NeedsDecision for input from others.

@griesemer griesemer added NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. and removed NeedsFix The path to resolution is known, but the work has not been done. labels Dec 2, 2019
@dmitshur
Copy link
Contributor

dmitshur commented Dec 3, 2019

may have implications for client code that parses error messages

/cc @neild who worked on defining an internal policy related to that, which can be helpful when making decisions about changing error messages.

I'm okay with either, but I think it makes sense to leave to 1.15, since it's not fixing an existing bug.

@rsc
Copy link
Contributor

rsc commented Dec 4, 2019

Note that the compiler only prints the full import path when it sees ambiguity (same package name in multiple imports, I think).

@ianlancetaylor
Copy link
Contributor

The relevant code for the compiler is in cmd/compile/internal/gc/fmt.go:

			// If the name was used by multiple packages, display the full path,
			if s.Pkg.Name != "" && numImport[s.Pkg.Name] > 1 {
				return fmt.Sprintf("%q.%s", s.Pkg.Path, s.Name)
			}
			return s.Pkg.Name + "." + s.Name

@griesemer
Copy link
Contributor

The latest CL now matches the behavior of the compiler.

@stapelberg
Copy link
Contributor Author

Thanks for fixing this so quickly! This will eliminate a common issue for people learning Go in my class :)

@golang golang locked and limited conversation to collaborators Dec 5, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made.
Projects
None yet
Development

No branches or pull requests

7 participants