Commit bbd1dcdf authored by Robert Griesemer's avatar Robert Griesemer

cmd/compile: correctly export underlying type of predecl. error type

Fixes #15920.

Change-Id: I78cd79b91a58d0f7218b80f9445417f4ee071a6e
Reviewed-on: https://go-review.googlesource.com/23606Reviewed-by: 's avatarMatthew Dempsky <mdempsky@google.com>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 5db44c17
...@@ -622,6 +622,8 @@ func isInlineable(n *Node) bool { ...@@ -622,6 +622,8 @@ func isInlineable(n *Node) bool {
return false return false
} }
var errorInterface *Type // lazily initialized
func (p *exporter) typ(t *Type) { func (p *exporter) typ(t *Type) {
if t == nil { if t == nil {
Fatalf("exporter: nil type") Fatalf("exporter: nil type")
...@@ -673,7 +675,19 @@ func (p *exporter) typ(t *Type) { ...@@ -673,7 +675,19 @@ func (p *exporter) typ(t *Type) {
p.qualifiedName(tsym) p.qualifiedName(tsym)
// write underlying type // 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 // interfaces don't have associated methods
if t.Orig.IsInterface() { if t.Orig.IsInterface() {
......
...@@ -358,9 +358,7 @@ func typeinit() { ...@@ -358,9 +358,7 @@ func typeinit() {
itable = typPtr(Types[TUINT8]) itable = typPtr(Types[TUINT8])
} }
func lexinit1() { func makeErrorInterface() *Type {
// t = interface { Error() string }
rcvr := typ(TSTRUCT) rcvr := typ(TSTRUCT)
rcvr.StructType().Funarg = FunargRcvr rcvr.StructType().Funarg = FunargRcvr
field := newField() field := newField()
...@@ -387,10 +385,18 @@ func lexinit1() { ...@@ -387,10 +385,18 @@ func lexinit1() {
field.Type = f field.Type = f
t.SetFields([]*Field{field}) t.SetFields([]*Field{field})
return t
}
func lexinit1() {
// error type // error type
s := Pkglookup("error", builtinpkg) s := Pkglookup("error", builtinpkg)
errortype = t errortype = makeErrorInterface()
errortype.Sym = s 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) s.Def = typenod(errortype)
// byte alias // byte alias
......
...@@ -400,3 +400,28 @@ func TestIssue15517(t *testing.T) { ...@@ -400,3 +400,28 @@ func TestIssue15517(t *testing.T) {
} }
} }
} }
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)
}
}
// 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 }
// 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 }
// 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"
// 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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment