From 3ae2c6c52eb4b8714245b91d094e0ccdfdbe585c Mon Sep 17 00:00:00 2001 From: Than McIntosh Date: Wed, 12 Dec 2018 14:38:03 -0500 Subject: [PATCH] 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 TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- .../internal/gccgoimporter/importer_test.go | 1 + src/go/internal/gccgoimporter/parser.go | 9 +- .../gccgoimporter/testdata/issue29198.go | 37 ++++++++ .../gccgoimporter/testdata/issue29198.gox | 86 +++++++++++++++++++ 4 files changed, 127 insertions(+), 6 deletions(-) create mode 100644 src/go/internal/gccgoimporter/testdata/issue29198.go create mode 100644 src/go/internal/gccgoimporter/testdata/issue29198.gox diff --git a/src/go/internal/gccgoimporter/importer_test.go b/src/go/internal/gccgoimporter/importer_test.go index b659cfc1df..f678ddc3b5 100644 --- a/src/go/internal/gccgoimporter/importer_test.go +++ b/src/go/internal/gccgoimporter/importer_test.go @@ -90,6 +90,7 @@ var importerTests = [...]importerTest{ {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 5414046be4..d0081ad3b8 100644 --- a/src/go/internal/gccgoimporter/parser.go +++ b/src/go/internal/gccgoimporter/parser.go @@ -33,9 +33,9 @@ type parser struct { 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 @@ func (p *parser) parseNamedType(nlist []int) types.Type { 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 0000000000..75c2162d20 --- /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 0000000000..905c86637e --- /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 ; }> + func (a >) AMethod (y ) + func (f >) WriteEvents (ctx ; .time.ext ; .time.loc ; .time.zone ; .time.offset ; .time.isDST ; }>>>; .time.tx ; .time.index ; .time.isstd ; .time.isutc ; }>>>; .time.cacheStart ; .time.cacheEnd ; .time.cacheZone >; }> + func (l >) String () ; + func (l ) .time.lookupFirstZone () ; + func (l ) .time.get () ; + func (l ) .time.lookup (sec ) (name , offset , isDST , start , end ); + func (l ) .time.lookupName (name , unix ) (offset , ok ); + func (l ) .time.firstZoneUsed () ; +>>; }> + func (t ) In (loc ) ; + func (t ) .time.date (full ) (year , month + func (m ) String () ; +>, day , yday ); + func (t ) Sub (u ) + func (d ) Truncate (m ) ; + func (d ) String () ; + func (d ) Round (m ) ; + func (d ) Seconds () ; + func (d ) Nanoseconds () ; + func (d ) Minutes () ; + func (d ) Hours () ; +>; + func (t ) Add (d ) ; + func (t ) UTC () ; + func (t ) AddDate (years , months , days ) ; + func (t ) MarshalBinary () (? >, ? ); + func (t ) Nanosecond () ; + func (t ) Round (d ) ; + func (t ) Minute () ; + func (t ) Clock () (hour , min , sec ); + func (t ) ISOWeek () (year , week ); + func (t ) Day () ; + func (t >) .time.mono () ; + func (t ) UnixNano () ; + func (t ) .time.sec () ; + func (t ) Second () ; + func (t ) Before (u ) ; + func (t ) UnmarshalBinary (data >) ; + func (t ) Month () ; + func (t ) YearDay () ; + func (t ) Location () ; + func (t ) Zone () (name , offset ); + func (t ) Local () ; + func (t ) .time.setLoc (loc ); + func (t ) Truncate (d ) ; + func (t ) MarshalJSON () (? >, ? ); + func (t ) AppendFormat (b >, layout ) >; + func (t ) GobDecode (data >) ; + func (t ) UnmarshalJSON (data >) ; + func (t ) MarshalText () (? >, ? ); + func (t ) GobEncode () (? >, ? ); + func (t ) .time.stripMono (); + func (t ) After (u ) ; + func (t ) Hour () ; + func (t ) UnmarshalText (data >) ; + func (t ) Equal (u ) ; + func (t ) .time.setMono (m ); + func (t ) Year () ; + func (t ) IsZero () ; + func (t ) .time.addSec (d ); + func (t ) Weekday () + func (d ) String () ; +>; + func (t ) String () ; + func (t ) .time.nsec () ; + func (t ) Format (layout ) ; + func (t ) .time.unixSec () ; + func (t ) Unix () ; + func (t ) .time.abs () ; + func (t ) .time.locabs () (name , offset , abs ); + func (t ) Date () (year , month , day ); +>, ok ); Done () >; Err () ; Value (key ) ; }>>, x ) ; +>>; .issue29198.user ; .issue29198.ctx ; }>>>; +>; +type ; +func New (sctx , u ) (? >, ? ); +type ; +checksum 86C8D76B2582F55A8BD2CA9E00060358EC1CE214; -- 2.50.0