Fixes #15920.
Change-Id: I78cd79b91a58d0f7218b80f9445417f4ee071a6e
Reviewed-on: https://go-review.googlesource.com/23606
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
return false
}
+var errorInterface *Type // lazily initialized
+
func (p *exporter) typ(t *Type) {
if t == nil {
Fatalf("exporter: nil type")
p.qualifiedName(tsym)
// write underlying type
- p.typ(t.Orig)
+ orig := t.Orig
+ if orig == errortype {
+ // The error type is the only predeclared type which has
+ // a composite underlying type. When we encode that type,
+ // make sure to encode the underlying interface rather than
+ // the named type again. See also the comment in universe.go
+ // regarding the errortype and issue #15920.
+ if errorInterface == nil {
+ errorInterface = makeErrorInterface()
+ }
+ orig = errorInterface
+ }
+ p.typ(orig)
// interfaces don't have associated methods
if t.Orig.IsInterface() {
itable = typPtr(Types[TUINT8])
}
-func lexinit1() {
- // t = interface { Error() string }
-
+func makeErrorInterface() *Type {
rcvr := typ(TSTRUCT)
rcvr.StructType().Funarg = FunargRcvr
field := newField()
field.Type = f
t.SetFields([]*Field{field})
+ return t
+}
+
+func lexinit1() {
// error type
s := Pkglookup("error", builtinpkg)
- errortype = t
+ errortype = makeErrorInterface()
errortype.Sym = s
+ // TODO: If we can prove that it's safe to set errortype.Orig here
+ // than we don't need the special errortype/errorInterface case in
+ // bexport.go. See also issue #15920.
+ // errortype.Orig = makeErrorInterface()
s.Def = typenod(errortype)
// byte alias
}
}
}
+
+func TestIssue15920(t *testing.T) {
+ skipSpecialPlatforms(t)
+
+ // This package only handles gc export data.
+ if runtime.Compiler != "gc" {
+ t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
+ return
+ }
+
+ // On windows, we have to set the -D option for the compiler to avoid having a drive
+ // letter and an illegal ':' in the import path - just skip it (see also issue #3483).
+ if runtime.GOOS == "windows" {
+ t.Skip("avoid dealing with relative paths/drive letters on windows")
+ }
+
+ if f := compile(t, "testdata", "issue15920.go"); f != "" {
+ defer os.Remove(f)
+ }
+
+ imports := make(map[string]*types.Package)
+ if _, err := Import(imports, "./testdata/issue15920", "."); err != nil {
+ t.Fatal(err)
+ }
+}
--- /dev/null
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+// The underlying type of Error is the underlying type of error.
+// Make sure we can import this again without problems.
+type Error error
+
+func F() Error { return nil }
--- /dev/null
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package a
+
+type Error error
+
+func F() Error { return nil }
--- /dev/null
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package b
+
+import _ "./a"
--- /dev/null
+// compiledir
+
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ignored