Navigation Menu

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: new embedded interface behavior (possible regression) #29029

Closed
ccbrown opened this issue Nov 30, 2018 · 6 comments
Closed

go/types: new embedded interface behavior (possible regression) #29029

ccbrown opened this issue Nov 30, 2018 · 6 comments
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. release-blocker
Milestone

Comments

@ccbrown
Copy link

ccbrown commented Nov 30, 2018

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

$ go version
go version go1.11.2 darwin/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
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/chris/Library/Caches/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/chris/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
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=/var/folders/x1/md855yzx0lg2yqccxnvnb5lw0000gn/T/go-build287116670=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

I type-checked and printed definitions from a package with a test file that embeds a non-test interface into another interface.

What did you expect to see?

The interface method with the correct receiver type:

func (github.com/ccbrown/go-interface-method-type-bug/thepackage.A).Foo()

What did you see instead?

The receiver type was overwritten based the contents of the test file:

func (interface).Foo()

Demo project

Check out this program: https://github.com/ccbrown/go-interface-method-type-bug

Run go run main.go. With Go 1.10, you get the output I would expect. With Go 1.11, you get different output.

This makes tooling such as @dominikh's unused tool break in Go 1.11 for certain cases where tests define interfaces that embed other interfaces.

@agnivade agnivade added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Nov 30, 2018
@agnivade
Copy link
Contributor

/cc @griesemer

@griesemer griesemer self-assigned this Nov 30, 2018
@griesemer griesemer added this to the Go1.12 milestone Nov 30, 2018
@griesemer
Copy link
Contributor

I can reproduce this. It does look like a regression.

@griesemer
Copy link
Contributor

Stand-alone reproducer (no need to use loader): https://play.golang.org/p/6rledUr3Mhx

@griesemer
Copy link
Contributor

The loader type-checks the test package by type-checking the _test file incrementally, via a 2nd go/types.Files call. That API is meant to be called like this, but in the process go/types starts with a fresh (internal) interface cache which causes incorrect recomputation of interface methods.

The following diff fixes the problem:

diff --git a/src/go/types/check.go b/src/go/types/check.go
index 91df94dcbc..10e8c500ac 100644
--- a/src/go/types/check.go
+++ b/src/go/types/check.go
@@ -192,7 +192,7 @@ func (check *Checker) initFiles(files []*ast.File) {
 
        check.firstErr = nil
        check.methods = nil
-       check.interfaces = nil
+       // check.interfaces = nil
        check.untyped = nil
        check.delayed = nil

We should definitively do this since adding (test) files to a package cannot change any of the already computed interfaces (even though it may add methods to concrete types). So this is a useful optimization in its own right. That said, it's unclear yet why it's also necessary.

@gopherbot
Copy link

Change https://golang.org/cl/152259 mentions this issue: go/types: fix interface receiver type for incremental type-checking

@griesemer
Copy link
Contributor

See comments in CL as to why the suggested diff is correct and also necessary.

@golang golang locked and limited conversation to collaborators Dec 3, 2019
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. release-blocker
Projects
None yet
Development

No branches or pull requests

4 participants