go/internal/gccgoimporter: permit fixups for V2 export data

The changes added in https://golang.org/cl/151997 to fix problems when
reading older export data introduced the ability to add "fixups" to
handle references to a type whose definition has not yet been
finalized. It turns out we need to allow for fixups even for more
recent export data (V2 and V3); this patch removes a version guard for
the fixup generation logic.

Fixes #29198.

Change-Id: I82136ac45b53e4a59c05ff0879ac6bb545d0ff31
Reviewed-on: https://go-review.googlesource.com/c/153821
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
diff --git a/src/go/internal/gccgoimporter/importer_test.go b/src/go/internal/gccgoimporter/importer_test.go
index b659cfc..f678ddc 100644
--- a/src/go/internal/gccgoimporter/importer_test.go
+++ b/src/go/internal/gccgoimporter/importer_test.go
@@ -90,6 +90,7 @@
 	{pkgpath: "issue27856", name: "M", want: "type M struct{E F}"},
 	{pkgpath: "v1reflect", name: "Type", want: "type Type interface{Align() int; AssignableTo(u Type) bool; Bits() int; ChanDir() ChanDir; Elem() Type; Field(i int) StructField; FieldAlign() int; FieldByIndex(index []int) StructField; FieldByName(name string) (StructField, bool); FieldByNameFunc(match func(string) bool) (StructField, bool); Implements(u Type) bool; In(i int) Type; IsVariadic() bool; Key() Type; Kind() Kind; Len() int; Method(int) Method; MethodByName(string) (Method, bool); Name() string; NumField() int; NumIn() int; NumMethod() int; NumOut() int; Out(i int) Type; PkgPath() string; Size() uintptr; String() string; common() *commonType; rawString() string; runtimeType() *runtimeType; uncommon() *uncommonType}"},
 	{pkgpath: "nointerface", name: "I", want: "type I int"},
+	{pkgpath: "issue29198", name: "FooServer", want: "type FooServer struct{FooServer *FooServer; user string; ctx context.Context}"},
 }
 
 func TestGoxImporter(t *testing.T) {
diff --git a/src/go/internal/gccgoimporter/parser.go b/src/go/internal/gccgoimporter/parser.go
index 5414046..d0081ad 100644
--- a/src/go/internal/gccgoimporter/parser.go
+++ b/src/go/internal/gccgoimporter/parser.go
@@ -33,9 +33,9 @@
 	initdata InitData                  // package init priority data
 }
 
-// When reading V1 export data it's possible to encounter a defined
-// type N1 with an underlying defined type N2 while we are still
-// reading in that defined type N2; see issue #29006 for an instance
+// When reading export data it's possible to encounter a defined type
+// N1 with an underlying defined type N2 while we are still reading in
+// that defined type N2; see issues #29006 and #29198 for instances
 // of this. Example:
 //
 //   type N1 N2
@@ -526,9 +526,6 @@
 	underlying := p.parseType(pkg)
 	if nt.Underlying() == nil {
 		if underlying.Underlying() == nil {
-			if p.version != "v1" {
-				p.errorf("internal error: unexpected fixup required for %v", nt)
-			}
 			fix := fixupRecord{toUpdate: nt, target: underlying}
 			p.fixups = append(p.fixups, fix)
 		} else {
diff --git a/src/go/internal/gccgoimporter/testdata/issue29198.go b/src/go/internal/gccgoimporter/testdata/issue29198.go
new file mode 100644
index 0000000..75c2162
--- /dev/null
+++ b/src/go/internal/gccgoimporter/testdata/issue29198.go
@@ -0,0 +1,37 @@
+// Copyright 2018 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 server
+
+import (
+	"context"
+	"errors"
+)
+
+type A struct {
+	x int
+}
+
+func (a *A) AMethod(y int) *Server {
+	return nil
+}
+
+// FooServer is a server that provides Foo services
+type FooServer Server
+
+func (f *FooServer) WriteEvents(ctx context.Context, x int) error {
+	return errors.New("hey!")
+}
+
+type Server struct {
+	FooServer *FooServer
+	user      string
+	ctx       context.Context
+}
+
+func New(sctx context.Context, u string) (*Server, error) {
+	s := &Server{user: u, ctx: sctx}
+	s.FooServer = (*FooServer)(s)
+	return s, nil
+}
diff --git a/src/go/internal/gccgoimporter/testdata/issue29198.gox b/src/go/internal/gccgoimporter/testdata/issue29198.gox
new file mode 100644
index 0000000..905c866
--- /dev/null
+++ b/src/go/internal/gccgoimporter/testdata/issue29198.gox
@@ -0,0 +1,86 @@
+v2;
+package server;
+pkgpath issue29198;
+import context context "context";
+import errors errors "errors";
+init context context..import fmt fmt..import poll internal_poll..import testlog internal_testlog..import io io..import os os..import reflect reflect..import runtime runtime..import sys runtime_internal_sys..import strconv strconv..import sync sync..import syscall syscall..import time time..import unicode unicode..import;
+init_graph 0 1 0 2 0 3 0 4 0 5 0 6 0 7 0 8 0 9 0 10 0 11 0 12 0 13 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1 11 1 12 1 13 2 4 2 7 2 8 2 10 2 11 2 12 4 7 4 8 4 10 5 2 5 3 5 4 5 7 5 8 5 10 5 11 5 12 6 7 6 8 6 9 6 10 6 13 7 8 9 7 9 8 10 7 10 8 11 7 11 8 11 10 12 7 12 8 12 10 12 11;
+type <type 1 "A" <type 2 struct { .issue29198.x <type -11>; }>
+ func (a <esc:0x1> <type 3 *<type 1>>) AMethod (y <type -11>) <type 4 *<type 5 "Server" <type 6 struct { FooServer <type 7 *<type 8 "FooServer" <type 5>
+ func (f <esc:0x1> <type 9 *<type 8>>) WriteEvents (ctx <esc:0x1> <type 10 "context.Context" <type 11 interface { Deadline () (deadline <type 12 "time.Time" "time" <type 13 struct { .time.wall <type -8>; .time.ext <type -4>; .time.loc <type 14 *<type 15 "time.Location" <type 16 struct { .time.name <type -16>; .time.zone <type 17 [] <type 18 ".time.zone" <type 19 struct { .time.name <type -16>; .time.offset <type -11>; .time.isDST <type -15>; }>>>; .time.tx <type 20 [] <type 21 ".time.zoneTrans" <type 22 struct { .time.when <type -4>; .time.index <type -5>; .time.isstd <type -15>; .time.isutc <type -15>; }>>>; .time.cacheStart <type -4>; .time.cacheEnd <type -4>; .time.cacheZone <type 23 *<type 18>>; }>
+ func (l <esc:0x22> <type 24 *<type 15>>) String () <type -16>;
+ func (l <esc:0x1> <type 24>) .time.lookupFirstZone () <type -11>;
+ func (l <esc:0x12> <type 24>) .time.get () <type 24>;
+ func (l <esc:0x32> <type 24>) .time.lookup (sec <type -4>) (name <type -16>, offset <type -11>, isDST <type -15>, start <type -4>, end <type -4>);
+ func (l <esc:0x1> <type 24>) .time.lookupName (name <esc:0x1> <type -16>, unix <type -4>) (offset <type -11>, ok <type -15>);
+ func (l <esc:0x1> <type 24>) .time.firstZoneUsed () <type -15>;
+>>; }>
+ func (t <esc:0x12> <type 12>) In (loc <type 14>) <type 12>;
+ func (t <esc:0x1> <type 12>) .time.date (full <type -15>) (year <type -11>, month <type 25 "time.Month" <type -11>
+ func (m <type 25>) String () <type -16>;
+>, day <type -11>, yday <type -11>);
+ func (t <esc:0x1> <type 12>) Sub (u <esc:0x1> <type 12>) <type 26 "time.Duration" <type -4>
+ func (d <type 26>) Truncate (m <type 26>) <type 26>;
+ func (d <type 26>) String () <type -16>;
+ func (d <type 26>) Round (m <type 26>) <type 26>;
+ func (d <type 26>) Seconds () <type -10>;
+ func (d <type 26>) Nanoseconds () <type -4>;
+ func (d <type 26>) Minutes () <type -10>;
+ func (d <type 26>) Hours () <type -10>;
+>;
+ func (t <esc:0x12> <type 12>) Add (d <type 26>) <type 12>;
+ func (t <esc:0x12> <type 12>) UTC () <type 12>;
+ func (t <type 12>) AddDate (years <type -11>, months <type -11>, days <type -11>) <type 12>;
+ func (t <esc:0x1> <type 12>) MarshalBinary () (? <type 27 [] <type -20>>, ? <type -19>);
+ func (t <esc:0x1> <type 12>) Nanosecond () <type -11>;
+ func (t <esc:0x12> <type 12>) Round (d <type 26>) <type 12>;
+ func (t <esc:0x1> <type 12>) Minute () <type -11>;
+ func (t <esc:0x1> <type 12>) Clock () (hour <type -11>, min <type -11>, sec <type -11>);
+ func (t <esc:0x1> <type 12>) ISOWeek () (year <type -11>, week <type -11>);
+ func (t <esc:0x1> <type 12>) Day () <type -11>;
+ func (t <esc:0x1> <type 28 *<type 12>>) .time.mono () <type -4>;
+ func (t <esc:0x1> <type 12>) UnixNano () <type -4>;
+ func (t <esc:0x1> <type 28>) .time.sec () <type -4>;
+ func (t <esc:0x1> <type 12>) Second () <type -11>;
+ func (t <esc:0x1> <type 12>) Before (u <esc:0x1> <type 12>) <type -15>;
+ func (t <esc:0x1> <type 28>) UnmarshalBinary (data <esc:0x1> <type 29 [] <type -20>>) <type -19>;
+ func (t <esc:0x1> <type 12>) Month () <type 25>;
+ func (t <esc:0x1> <type 12>) YearDay () <type -11>;
+ func (t <esc:0x12> <type 12>) Location () <type 14>;
+ func (t <esc:0x32> <type 12>) Zone () (name <type -16>, offset <type -11>);
+ func (t <esc:0x12> <type 12>) Local () <type 12>;
+ func (t <esc:0x1> <type 28>) .time.setLoc (loc <type 14>);
+ func (t <esc:0x12> <type 12>) Truncate (d <type 26>) <type 12>;
+ func (t <esc:0x1> <type 12>) MarshalJSON () (? <type 30 [] <type -20>>, ? <type -19>);
+ func (t <esc:0x1> <type 12>) AppendFormat (b <esc:0x12> <type 31 [] <type -20>>, layout <esc:0x1> <type -16>) <type 32 [] <type -20>>;
+ func (t <esc:0x1> <type 28>) GobDecode (data <esc:0x1> <type 33 [] <type -20>>) <type -19>;
+ func (t <esc:0x1> <type 28>) UnmarshalJSON (data <esc:0x1> <type 34 [] <type -20>>) <type -19>;
+ func (t <esc:0x1> <type 12>) MarshalText () (? <type 35 [] <type -20>>, ? <type -19>);
+ func (t <esc:0x1> <type 12>) GobEncode () (? <type 36 [] <type -20>>, ? <type -19>);
+ func (t <esc:0x1> <type 28>) .time.stripMono ();
+ func (t <esc:0x1> <type 12>) After (u <esc:0x1> <type 12>) <type -15>;
+ func (t <esc:0x1> <type 12>) Hour () <type -11>;
+ func (t <esc:0x1> <type 28>) UnmarshalText (data <esc:0x1> <type 37 [] <type -20>>) <type -19>;
+ func (t <esc:0x1> <type 12>) Equal (u <esc:0x1> <type 12>) <type -15>;
+ func (t <esc:0x1> <type 28>) .time.setMono (m <type -4>);
+ func (t <esc:0x1> <type 12>) Year () <type -11>;
+ func (t <esc:0x1> <type 12>) IsZero () <type -15>;
+ func (t <esc:0x1> <type 28>) .time.addSec (d <type -4>);
+ func (t <esc:0x1> <type 12>) Weekday () <type 38 "time.Weekday" <type -11>
+ func (d <type 38>) String () <type -16>;
+>;
+ func (t <esc:0x1> <type 12>) String () <type -16>;
+ func (t <esc:0x1> <type 28>) .time.nsec () <type -3>;
+ func (t <esc:0x1> <type 12>) Format (layout <esc:0x1> <type -16>) <type -16>;
+ func (t <esc:0x1> <type 28>) .time.unixSec () <type -4>;
+ func (t <esc:0x1> <type 12>) Unix () <type -4>;
+ func (t <esc:0x1> <type 12>) .time.abs () <type -8>;
+ func (t <esc:0x32> <type 12>) .time.locabs () (name <type -16>, offset <type -11>, abs <type -8>);
+ func (t <esc:0x1> <type 12>) Date () (year <type -11>, month <type 25>, day <type -11>);
+>, ok <type -15>); Done () <type 39 chan <- <type 40 struct { }>>; Err () <type -19>; Value (key <type 41 interface { }>) <type 42 interface { }>; }>>, x <type -11>) <type -19>;
+>>; .issue29198.user <type -16>; .issue29198.ctx <type 10>; }>>>;
+>;
+type <type 8>;
+func New (sctx <type 10>, u <type -16>) (? <type 43 *<type 5>>, ? <type -19>);
+type <type 5>;
+checksum 86C8D76B2582F55A8BD2CA9E00060358EC1CE214;