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: incorrect type assertions on conflicting package names #21282
Comments
Append the following two lines at the end of var x interface { unexported() } = foo{}
_ = reflect.TypeOf(x) but append them at the end of package iface // import "github.com/dsnet/example/iface2/iface"
import "fmt"
import "reflect"
type Iface interface { unexported() }
func CheckInterface() {
var v interface{} = foo{}
t := reflect.TypeOf(v)
t1 := reflect.TypeOf((*Iface)(nil)).Elem()
t2 := reflect.TypeOf((*interface { unexported() })(nil)).Elem()
fmt.Println("reflect implements named interface: ", t.Implements(t1))
fmt.Println("reflect implements interface literal:", t.Implements(t2))
_, ok1 := v.(Iface)
_, ok2 := v.(interface { unexported() })
fmt.Println("type assertion on named interface: ", ok1)
fmt.Println("type assertion on interface literal: ", ok2)
fmt.Println()
//>> panic
var x interface { unexported() } = foo{}
_ = reflect.TypeOf(x)
//<<
}
type foo struct{}
func (foo) unexported() {} The panic is some weird, when it is triggered, the texts printed in
|
The issue is However, the runtime type descriptor we produce for both is given a linker symbol of The fix here is we need to qualify these method names by their package path, not just their package name. |
This is clearly undesirable, but I think the fix is too delicate for this late in the release cycle. We've evidently lived with it since 1.0, so I think it can wait another release. |
Change https://golang.org/cl/106175 mentions this issue: |
We'll always generate method expression wrappers for declared interface types in their own package, so no need to generate them in downstream packages. Noticed by gri@ while looking into #21282. Change-Id: I4fb7051b4e15297933da05fdd2b111d6b8f4178e Reviewed-on: https://go-review.googlesource.com/106175 Run-TryBot: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Robert Griesemer <gri@golang.org>
This has been around forever. Clearly we should fix it but it's also not a release blocker. |
This is a bug that has existed since Go1.0.
Consider the following packages:
In the setup, we have two packages both named
iface
where the source code of both packages is identical, but they have different absolute package paths.Running the following program:
Prints the following (on Go1.0 to Go1.8):
The output slightly differs on Go1.9, but is still wrong.
We expect that calling
iface1.CheckInterface()
andiface2.CheckInterface()
to produce the exact same results. However, that is not what we see. Iniface2
, type assertions via a interface literal on unexported fields no longer works properly, but it works as expected iniface1
.\cc @ianlancetaylor @josharian @mdempsky @neild
The text was updated successfully, but these errors were encountered: