go/internal/gccgoimporter: port recent changes from stdlib version
This CL brings over the following changes from the std lib: https://golang.org/cl/137857 https://golang.org/cl/137935 https://golang.org/cl/137975 There are no further code changes except that the importer test cases are split between importer_test.go and importer19_test.go to support multiple Go versions. Updates golang/go#27856. Change-Id: I625def738c22c24c6659af37c3871038fdd8b981 Reviewed-on: https://go-review.googlesource.com/137995 Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
ef4a2a23bb
commit
b14f328a62
|
@ -7,7 +7,8 @@
|
|||
package gccgoimporter
|
||||
|
||||
var aliasTests = []importerTest{
|
||||
{pkgpath: "alias", name: "IntAlias2", want: "type IntAlias2 = Int"},
|
||||
{pkgpath: "aliases", name: "A14", want: "type A14 = func(int, T0) chan T2"},
|
||||
{pkgpath: "aliases", name: "C0", want: "type C0 struct{f1 C1; f2 C1}"},
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
|
@ -104,7 +104,11 @@ var importerTests = []importerTest{
|
|||
{pkgpath: "unicode", name: "IsUpper", want: "func IsUpper(r rune) bool"},
|
||||
{pkgpath: "unicode", name: "MaxRune", want: "const MaxRune untyped rune", wantval: "1114111"},
|
||||
{pkgpath: "imports", wantinits: []string{"imports..import", "fmt..import", "math..import"}},
|
||||
// moved to importer19_test.go (they import interface types)
|
||||
// {pkgpath: "aliases", name: "A14", want: "type A14 = func(int, T0) chan T2"},
|
||||
// {pkgpath: "aliases", name: "C0", want: "type C0 struct{f1 C1; f2 C1}"},
|
||||
{pkgpath: "escapeinfo", name: "NewT", want: "func NewT(data []byte) *T"},
|
||||
{pkgpath: "issue27856", name: "M", want: "type M struct{E F}"},
|
||||
}
|
||||
|
||||
func TestGoxImporter(t *testing.T) {
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package gccgoimporter
|
||||
// This is a verbatim copy of $GOROOT/src/go/internal/gccgoimporter/parser.go
|
||||
// with a small modification in parseInterface to support older Go versions.
|
||||
|
||||
// This is a verbatim copy of $GOROOT/src/go/internal/gccgoimporter/parser.go.
|
||||
package gccgoimporter
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
@ -28,7 +29,7 @@ type parser struct {
|
|||
pkgname string // name of imported package
|
||||
pkg *types.Package // reference to imported package
|
||||
imports map[string]*types.Package // package path -> package object
|
||||
typeMap map[int]types.Type // type number -> type
|
||||
typeList []types.Type // type number -> type
|
||||
initdata InitData // package init priority data
|
||||
}
|
||||
|
||||
|
@ -40,7 +41,7 @@ func (p *parser) init(filename string, src io.Reader, imports map[string]*types.
|
|||
p.scanner.Filename = filename // for good error messages
|
||||
p.next()
|
||||
p.imports = imports
|
||||
p.typeMap = make(map[int]types.Type)
|
||||
p.typeList = make([]types.Type, 1 /* type numbers start at 1 */, 16)
|
||||
}
|
||||
|
||||
type importError struct {
|
||||
|
@ -380,52 +381,80 @@ func (p *parser) parseConst(pkg *types.Package) *types.Const {
|
|||
return types.NewConst(token.NoPos, pkg, name, typ, val)
|
||||
}
|
||||
|
||||
// reserved is a singleton type used to fill type map slots that have
|
||||
// been reserved (i.e., for which a type number has been parsed) but
|
||||
// which don't have their actual type yet. When the type map is updated,
|
||||
// the actual type must replace a reserved entry (or we have an internal
|
||||
// error). Used for self-verification only - not required for correctness.
|
||||
var reserved = new(struct{ types.Type })
|
||||
|
||||
// reserve reserves the type map entry n for future use.
|
||||
func (p *parser) reserve(n int) {
|
||||
if n != len(p.typeList) {
|
||||
p.errorf("invalid type number %d (out of sync)", n)
|
||||
}
|
||||
p.typeList = append(p.typeList, reserved)
|
||||
}
|
||||
|
||||
// update sets the type map entries for the given type numbers nlist to t.
|
||||
func (p *parser) update(t types.Type, nlist []int) {
|
||||
for _, n := range nlist {
|
||||
if p.typeList[n] != reserved {
|
||||
p.errorf("typeMap[%d] not reserved", n)
|
||||
}
|
||||
p.typeList[n] = t
|
||||
}
|
||||
}
|
||||
|
||||
// NamedType = TypeName [ "=" ] Type { Method } .
|
||||
// TypeName = ExportedName .
|
||||
// Method = "func" "(" Param ")" Name ParamList ResultList ";" .
|
||||
func (p *parser) parseNamedType(n int) types.Type {
|
||||
func (p *parser) parseNamedType(nlist []int) types.Type {
|
||||
pkg, name := p.parseExportedName()
|
||||
scope := pkg.Scope()
|
||||
|
||||
if p.tok == '=' {
|
||||
// type alias
|
||||
p.next()
|
||||
typ := p.parseType(pkg)
|
||||
if obj := scope.Lookup(name); obj != nil {
|
||||
typ = obj.Type() // use previously imported type
|
||||
if typ == nil {
|
||||
p.errorf("%v (type alias) used in cycle", obj)
|
||||
}
|
||||
} else {
|
||||
obj = types.NewTypeName(token.NoPos, pkg, name, typ)
|
||||
scope.Insert(obj)
|
||||
}
|
||||
p.typeMap[n] = typ
|
||||
return typ
|
||||
}
|
||||
|
||||
// named type
|
||||
obj := scope.Lookup(name)
|
||||
if obj != nil && obj.Type() == nil {
|
||||
p.errorf("%v has nil type", obj)
|
||||
}
|
||||
|
||||
// type alias
|
||||
if p.tok == '=' {
|
||||
p.next()
|
||||
if obj != nil {
|
||||
// use the previously imported (canonical) type
|
||||
t := obj.Type()
|
||||
p.update(t, nlist)
|
||||
p.parseType(pkg) // discard
|
||||
return t
|
||||
}
|
||||
t := p.parseType(pkg, nlist...)
|
||||
obj = types.NewTypeName(token.NoPos, pkg, name, t)
|
||||
scope.Insert(obj)
|
||||
return t
|
||||
}
|
||||
|
||||
// defined type
|
||||
if obj == nil {
|
||||
// a named type may be referred to before the underlying type
|
||||
// is known - set it up
|
||||
// A named type may be referred to before the underlying type
|
||||
// is known - set it up.
|
||||
tname := types.NewTypeName(token.NoPos, pkg, name, nil)
|
||||
types.NewNamed(tname, nil, nil)
|
||||
scope.Insert(tname)
|
||||
obj = tname
|
||||
}
|
||||
|
||||
typ := obj.Type()
|
||||
p.typeMap[n] = typ
|
||||
// use the previously imported (canonical), or newly created type
|
||||
t := obj.Type()
|
||||
p.update(t, nlist)
|
||||
|
||||
nt, ok := typ.(*types.Named)
|
||||
nt, ok := t.(*types.Named)
|
||||
if !ok {
|
||||
// This can happen for unsafe.Pointer, which is a TypeName holding a Basic type.
|
||||
pt := p.parseType(pkg)
|
||||
if pt != typ {
|
||||
if pt != t {
|
||||
p.error("unexpected underlying type for non-named TypeName")
|
||||
}
|
||||
return typ
|
||||
return t
|
||||
}
|
||||
|
||||
underlying := p.parseType(pkg)
|
||||
|
@ -451,41 +480,70 @@ func (p *parser) parseNamedType(n int) types.Type {
|
|||
return nt
|
||||
}
|
||||
|
||||
func (p *parser) parseInt() int64 {
|
||||
func (p *parser) parseInt64() int64 {
|
||||
lit := p.expect(scanner.Int)
|
||||
n, err := strconv.ParseInt(lit, 10, 0)
|
||||
n, err := strconv.ParseInt(lit, 10, 64)
|
||||
if err != nil {
|
||||
p.error(err)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (p *parser) parseInt() int {
|
||||
lit := p.expect(scanner.Int)
|
||||
n, err := strconv.ParseInt(lit, 10, 0 /* int */)
|
||||
if err != nil {
|
||||
p.error(err)
|
||||
}
|
||||
return int(n)
|
||||
}
|
||||
|
||||
// ArrayOrSliceType = "[" [ int ] "]" Type .
|
||||
func (p *parser) parseArrayOrSliceType(pkg *types.Package) types.Type {
|
||||
func (p *parser) parseArrayOrSliceType(pkg *types.Package, nlist []int) types.Type {
|
||||
p.expect('[')
|
||||
if p.tok == ']' {
|
||||
p.next()
|
||||
return types.NewSlice(p.parseType(pkg))
|
||||
|
||||
t := new(types.Slice)
|
||||
p.update(t, nlist)
|
||||
|
||||
*t = *types.NewSlice(p.parseType(pkg))
|
||||
return t
|
||||
}
|
||||
|
||||
n := p.parseInt()
|
||||
t := new(types.Array)
|
||||
p.update(t, nlist)
|
||||
|
||||
len := p.parseInt64()
|
||||
p.expect(']')
|
||||
return types.NewArray(p.parseType(pkg), n)
|
||||
|
||||
*t = *types.NewArray(p.parseType(pkg), len)
|
||||
return t
|
||||
}
|
||||
|
||||
// MapType = "map" "[" Type "]" Type .
|
||||
func (p *parser) parseMapType(pkg *types.Package) types.Type {
|
||||
func (p *parser) parseMapType(pkg *types.Package, nlist []int) types.Type {
|
||||
p.expectKeyword("map")
|
||||
|
||||
t := new(types.Map)
|
||||
p.update(t, nlist)
|
||||
|
||||
p.expect('[')
|
||||
key := p.parseType(pkg)
|
||||
p.expect(']')
|
||||
elem := p.parseType(pkg)
|
||||
return types.NewMap(key, elem)
|
||||
|
||||
*t = *types.NewMap(key, elem)
|
||||
return t
|
||||
}
|
||||
|
||||
// ChanType = "chan" ["<-" | "-<"] Type .
|
||||
func (p *parser) parseChanType(pkg *types.Package) types.Type {
|
||||
func (p *parser) parseChanType(pkg *types.Package, nlist []int) types.Type {
|
||||
p.expectKeyword("chan")
|
||||
|
||||
t := new(types.Chan)
|
||||
p.update(t, nlist)
|
||||
|
||||
dir := types.SendRecv
|
||||
switch p.tok {
|
||||
case '-':
|
||||
|
@ -502,13 +560,17 @@ func (p *parser) parseChanType(pkg *types.Package) types.Type {
|
|||
}
|
||||
}
|
||||
|
||||
return types.NewChan(dir, p.parseType(pkg))
|
||||
*t = *types.NewChan(dir, p.parseType(pkg))
|
||||
return t
|
||||
}
|
||||
|
||||
// StructType = "struct" "{" { Field } "}" .
|
||||
func (p *parser) parseStructType(pkg *types.Package) types.Type {
|
||||
func (p *parser) parseStructType(pkg *types.Package, nlist []int) types.Type {
|
||||
p.expectKeyword("struct")
|
||||
|
||||
t := new(types.Struct)
|
||||
p.update(t, nlist)
|
||||
|
||||
var fields []*types.Var
|
||||
var tags []string
|
||||
|
||||
|
@ -521,7 +583,8 @@ func (p *parser) parseStructType(pkg *types.Package) types.Type {
|
|||
}
|
||||
p.expect('}')
|
||||
|
||||
return types.NewStruct(fields, tags)
|
||||
*t = *types.NewStruct(fields, tags)
|
||||
return t
|
||||
}
|
||||
|
||||
// ParamList = "(" [ { Parameter "," } Parameter ] ")" .
|
||||
|
@ -564,10 +627,15 @@ func (p *parser) parseResultList(pkg *types.Package) *types.Tuple {
|
|||
}
|
||||
|
||||
// FunctionType = ParamList ResultList .
|
||||
func (p *parser) parseFunctionType(pkg *types.Package) *types.Signature {
|
||||
func (p *parser) parseFunctionType(pkg *types.Package, nlist []int) *types.Signature {
|
||||
t := new(types.Signature)
|
||||
p.update(t, nlist)
|
||||
|
||||
params, isVariadic := p.parseParamList(pkg)
|
||||
results := p.parseResultList(pkg)
|
||||
return types.NewSignature(nil, params, results, isVariadic)
|
||||
|
||||
*t = *types.NewSignature(nil, params, results, isVariadic)
|
||||
return t
|
||||
}
|
||||
|
||||
// Func = Name FunctionType .
|
||||
|
@ -579,13 +647,16 @@ func (p *parser) parseFunc(pkg *types.Package) *types.Func {
|
|||
p.discardDirectiveWhileParsingTypes(pkg)
|
||||
return nil
|
||||
}
|
||||
return types.NewFunc(token.NoPos, pkg, name, p.parseFunctionType(pkg))
|
||||
return types.NewFunc(token.NoPos, pkg, name, p.parseFunctionType(pkg, nil))
|
||||
}
|
||||
|
||||
// InterfaceType = "interface" "{" { ("?" Type | Func) ";" } "}" .
|
||||
func (p *parser) parseInterfaceType(pkg *types.Package) types.Type {
|
||||
func (p *parser) parseInterfaceType(pkg *types.Package, nlist []int) types.Type {
|
||||
p.expectKeyword("interface")
|
||||
|
||||
t := new(types.Interface)
|
||||
p.update(t, nlist)
|
||||
|
||||
var methods []*types.Func
|
||||
var embeddeds []types.Type
|
||||
|
||||
|
@ -602,53 +673,61 @@ func (p *parser) parseInterfaceType(pkg *types.Package) types.Type {
|
|||
}
|
||||
p.expect('}')
|
||||
|
||||
return newInterface(methods, embeddeds)
|
||||
*t = *newInterface(methods, embeddeds)
|
||||
return t
|
||||
}
|
||||
|
||||
// PointerType = "*" ("any" | Type) .
|
||||
func (p *parser) parsePointerType(pkg *types.Package) types.Type {
|
||||
func (p *parser) parsePointerType(pkg *types.Package, nlist []int) types.Type {
|
||||
p.expect('*')
|
||||
if p.tok == scanner.Ident {
|
||||
p.expectKeyword("any")
|
||||
return types.Typ[types.UnsafePointer]
|
||||
t := types.Typ[types.UnsafePointer]
|
||||
p.update(t, nlist)
|
||||
return t
|
||||
}
|
||||
return types.NewPointer(p.parseType(pkg))
|
||||
|
||||
t := new(types.Pointer)
|
||||
p.update(t, nlist)
|
||||
|
||||
*t = *types.NewPointer(p.parseType(pkg))
|
||||
|
||||
return t
|
||||
}
|
||||
|
||||
// TypeDefinition = NamedType | MapType | ChanType | StructType | InterfaceType | PointerType | ArrayOrSliceType | FunctionType .
|
||||
func (p *parser) parseTypeDefinition(pkg *types.Package, n int) types.Type {
|
||||
var t types.Type
|
||||
// TypeSpec = NamedType | MapType | ChanType | StructType | InterfaceType | PointerType | ArrayOrSliceType | FunctionType .
|
||||
func (p *parser) parseTypeSpec(pkg *types.Package, nlist []int) types.Type {
|
||||
switch p.tok {
|
||||
case scanner.String:
|
||||
t = p.parseNamedType(n)
|
||||
return p.parseNamedType(nlist)
|
||||
|
||||
case scanner.Ident:
|
||||
switch p.lit {
|
||||
case "map":
|
||||
t = p.parseMapType(pkg)
|
||||
return p.parseMapType(pkg, nlist)
|
||||
|
||||
case "chan":
|
||||
t = p.parseChanType(pkg)
|
||||
return p.parseChanType(pkg, nlist)
|
||||
|
||||
case "struct":
|
||||
t = p.parseStructType(pkg)
|
||||
return p.parseStructType(pkg, nlist)
|
||||
|
||||
case "interface":
|
||||
t = p.parseInterfaceType(pkg)
|
||||
return p.parseInterfaceType(pkg, nlist)
|
||||
}
|
||||
|
||||
case '*':
|
||||
t = p.parsePointerType(pkg)
|
||||
return p.parsePointerType(pkg, nlist)
|
||||
|
||||
case '[':
|
||||
t = p.parseArrayOrSliceType(pkg)
|
||||
return p.parseArrayOrSliceType(pkg, nlist)
|
||||
|
||||
case '(':
|
||||
t = p.parseFunctionType(pkg)
|
||||
return p.parseFunctionType(pkg, nlist)
|
||||
}
|
||||
|
||||
p.typeMap[n] = t
|
||||
return t
|
||||
p.errorf("expected type name or literal, got %s", scanner.TokenString(p.tok))
|
||||
return nil
|
||||
}
|
||||
|
||||
const (
|
||||
|
@ -702,29 +781,36 @@ func lookupBuiltinType(typ int) types.Type {
|
|||
}[typ]
|
||||
}
|
||||
|
||||
// Type = "<" "type" ( "-" int | int [ TypeDefinition ] ) ">" .
|
||||
func (p *parser) parseType(pkg *types.Package) (t types.Type) {
|
||||
// Type = "<" "type" ( "-" int | int [ TypeSpec ] ) ">" .
|
||||
//
|
||||
// parseType updates the type map to t for all type numbers n.
|
||||
//
|
||||
func (p *parser) parseType(pkg *types.Package, n ...int) (t types.Type) {
|
||||
p.expect('<')
|
||||
p.expectKeyword("type")
|
||||
|
||||
switch p.tok {
|
||||
case scanner.Int:
|
||||
n := p.parseInt()
|
||||
|
||||
n1 := p.parseInt()
|
||||
if p.tok == '>' {
|
||||
t = p.typeMap[int(n)]
|
||||
t = p.typeList[n1]
|
||||
if t == reserved {
|
||||
p.errorf("invalid type cycle, type %d not yet defined", n1)
|
||||
}
|
||||
p.update(t, n)
|
||||
} else {
|
||||
t = p.parseTypeDefinition(pkg, int(n))
|
||||
p.reserve(n1)
|
||||
t = p.parseTypeSpec(pkg, append(n, n1))
|
||||
}
|
||||
|
||||
case '-':
|
||||
p.next()
|
||||
n := p.parseInt()
|
||||
t = lookupBuiltinType(int(n))
|
||||
n1 := p.parseInt()
|
||||
t = lookupBuiltinType(n1)
|
||||
p.update(t, n)
|
||||
|
||||
default:
|
||||
p.errorf("expected type number, got %s (%q)", scanner.TokenString(p.tok), p.lit)
|
||||
return nil
|
||||
}
|
||||
|
||||
p.expect('>')
|
||||
|
@ -737,7 +823,7 @@ func (p *parser) parsePackageInit() PackageInit {
|
|||
initfunc := p.parseUnquotedString()
|
||||
priority := -1
|
||||
if p.version == "v1" {
|
||||
priority = int(p.parseInt())
|
||||
priority = p.parseInt()
|
||||
}
|
||||
return PackageInit{Name: name, InitFunc: initfunc, Priority: priority}
|
||||
}
|
||||
|
@ -783,7 +869,7 @@ func (p *parser) parseInitDataDirective() {
|
|||
|
||||
case "priority":
|
||||
p.next()
|
||||
p.initdata.Priority = int(p.parseInt())
|
||||
p.initdata.Priority = p.parseInt()
|
||||
p.expect(';')
|
||||
|
||||
case "init":
|
||||
|
@ -797,8 +883,8 @@ func (p *parser) parseInitDataDirective() {
|
|||
p.next()
|
||||
// The graph data is thrown away for now.
|
||||
for p.tok != ';' && p.tok != scanner.EOF {
|
||||
p.parseInt()
|
||||
p.parseInt()
|
||||
p.parseInt64()
|
||||
p.parseInt64()
|
||||
}
|
||||
p.expect(';')
|
||||
|
||||
|
@ -900,7 +986,7 @@ func (p *parser) parsePackage() *types.Package {
|
|||
for p.tok != scanner.EOF {
|
||||
p.parseDirective()
|
||||
}
|
||||
for _, typ := range p.typeMap {
|
||||
for _, typ := range p.typeList {
|
||||
if it, ok := typ.(*types.Interface); ok {
|
||||
it.Complete()
|
||||
}
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
v1;
|
||||
package alias;
|
||||
pkgpath alias;
|
||||
type <type 115 "I1" <type 116 interface { M1 (? <type 117 "IntAlias2" = <type 118 "IntAlias" = <type 119 "Int" <type -11>>>>) < type 114>; M2 () <type 1>; }>>;
|
|
@ -0,0 +1,65 @@
|
|||
package aliases
|
||||
|
||||
type (
|
||||
T0 [10]int
|
||||
T1 []byte
|
||||
T2 struct {
|
||||
x int
|
||||
}
|
||||
T3 interface {
|
||||
m() T2
|
||||
}
|
||||
T4 func(int, T0) chan T2
|
||||
)
|
||||
|
||||
// basic aliases
|
||||
type (
|
||||
Ai = int
|
||||
A0 = T0
|
||||
A1 = T1
|
||||
A2 = T2
|
||||
A3 = T3
|
||||
A4 = T4
|
||||
|
||||
A10 = [10]int
|
||||
A11 = []byte
|
||||
A12 = struct {
|
||||
x int
|
||||
}
|
||||
A13 = interface {
|
||||
m() A2
|
||||
}
|
||||
A14 = func(int, A0) chan A2
|
||||
)
|
||||
|
||||
// alias receiver types
|
||||
func (T0) m1() {}
|
||||
func (A0) m2() {}
|
||||
|
||||
// alias receiver types (long type declaration chains)
|
||||
type (
|
||||
V0 = V1
|
||||
V1 = (V2)
|
||||
V2 = (V3)
|
||||
V3 = T0
|
||||
)
|
||||
|
||||
func (V1) n() {}
|
||||
|
||||
// cycles
|
||||
type C0 struct {
|
||||
f1 C1
|
||||
f2 C2
|
||||
}
|
||||
|
||||
type (
|
||||
C1 *C0
|
||||
C2 = C1
|
||||
)
|
||||
|
||||
type (
|
||||
C5 struct {
|
||||
f *C6
|
||||
}
|
||||
C6 = C5
|
||||
)
|
|
@ -0,0 +1,33 @@
|
|||
v2;
|
||||
package aliases;
|
||||
prefix go;
|
||||
package aliases go.aliases go.aliases;
|
||||
type <type 1 "A0" = <type 2 "T0" <type 3 [10 ] <type -11>>
|
||||
func (? <esc:0x1> <type 2>) .go.aliases.m1 ();
|
||||
func (? <esc:0x1> <type 1>) .go.aliases.m2 ();
|
||||
func (? <esc:0x1> <type 4 "V1" = <type 5 "V2" = <type 6 "V3" = <type 2>>>>) .go.aliases.n ();
|
||||
>>;
|
||||
type <type 7 "A1" = <type 8 "T1" <type 9 [] <type -20>>>>;
|
||||
type <type 10 "A10" = <type 11 [10 ] <type -11>>>;
|
||||
type <type 12 "A11" = <type 13 [] <type -20>>>;
|
||||
type <type 14 "A12" = <type 15 struct { .go.aliases.x <type -11>; }>>;
|
||||
type <type 16 "A13" = <type 17 interface { .go.aliases.m () <type 18 "A2" = <type 19 "T2" <type 20 struct { .go.aliases.x <type -11>; }>>>; }>>;
|
||||
type <type 21 "A14" = <type 22 (? <type -11>, ? <type 1>) <type 23 chan <type 18>>>>;
|
||||
type <type 18>;
|
||||
type <type 24 "A3" = <type 25 "T3" <type 26 interface { .go.aliases.m () <type 19>; }>>>;
|
||||
type <type 27 "A4" = <type 28 "T4" <type 29 (? <type -11>, ? <type 2>) <type 30 chan <type 19>>>>>;
|
||||
type <type 31 "Ai" = <type -11>>;
|
||||
type <type 32 "C0" <type 33 struct { .go.aliases.f1 <type 34 "C1" <type 35 *<type 32>>>; .go.aliases.f2 <type 36 "C2" = <type 34>>; }>>;
|
||||
type <type 34>;
|
||||
type <type 36>;
|
||||
type <type 37 "C5" <type 38 struct { .go.aliases.f <type 39 *<type 40 "C6" = <type 37>>>; }>>;
|
||||
type <type 40>;
|
||||
type <type 2>;
|
||||
type <type 8>;
|
||||
type <type 19>;
|
||||
type <type 25>;
|
||||
type <type 28>;
|
||||
type <type 41 "V0" = <type 4>>;
|
||||
type <type 4>;
|
||||
type <type 5>;
|
||||
type <type 6>;
|
|
@ -0,0 +1,9 @@
|
|||
package lib
|
||||
|
||||
type M struct {
|
||||
E E
|
||||
}
|
||||
type F struct {
|
||||
_ *M
|
||||
}
|
||||
type E = F
|
|
@ -0,0 +1,9 @@
|
|||
v2;
|
||||
package main;
|
||||
pkgpath main;
|
||||
import runtime runtime "runtime";
|
||||
init runtime runtime..import sys runtime_internal_sys..import;
|
||||
init_graph 0 1;
|
||||
type <type 1 "E" = <type 2 "F" <type 3 struct { .main._ <type 4 *<type 5 "M" <type 6 struct { E <type 1>; }>>>; }>>>;
|
||||
type <type 2>;
|
||||
type <type 5>;
|
Loading…
Reference in New Issue