github.com/4ad/go@v0.0.0-20161219182952-69a12818b605/src/go/internal/gcimporter/bimport.go (about)

     1  // Copyright 2015 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package gcimporter
     6  
     7  import (
     8  	"encoding/binary"
     9  	"fmt"
    10  	"go/constant"
    11  	"go/token"
    12  	"go/types"
    13  	"sort"
    14  	"strings"
    15  	"unicode"
    16  	"unicode/utf8"
    17  )
    18  
    19  type importer struct {
    20  	imports map[string]*types.Package
    21  	data    []byte
    22  	path    string
    23  	buf     []byte // for reading strings
    24  	version string
    25  
    26  	// object lists
    27  	strList       []string         // in order of appearance
    28  	pkgList       []*types.Package // in order of appearance
    29  	typList       []types.Type     // in order of appearance
    30  	trackAllTypes bool
    31  
    32  	// position encoding
    33  	posInfoFormat bool
    34  	prevFile      string
    35  	prevLine      int
    36  
    37  	// debugging support
    38  	debugFormat bool
    39  	read        int // bytes read
    40  }
    41  
    42  // BImportData imports a package from the serialized package data
    43  // and returns the number of bytes consumed and a reference to the package.
    44  // If data is obviously malformed, an error is returned but in
    45  // general it is not recommended to call BImportData on untrusted data.
    46  func BImportData(imports map[string]*types.Package, data []byte, path string) (int, *types.Package, error) {
    47  	p := importer{
    48  		imports: imports,
    49  		data:    data,
    50  		path:    path,
    51  		strList: []string{""}, // empty string is mapped to 0
    52  	}
    53  
    54  	// read low-level encoding format
    55  	switch format := p.rawByte(); format {
    56  	case 'c':
    57  		// compact format - nothing to do
    58  	case 'd':
    59  		p.debugFormat = true
    60  	default:
    61  		return p.read, nil, fmt.Errorf("invalid encoding format in export data: got %q; want 'c' or 'd'", format)
    62  	}
    63  
    64  	p.trackAllTypes = p.rawByte() == 'a'
    65  
    66  	p.posInfoFormat = p.int() != 0
    67  
    68  	// --- generic export data ---
    69  
    70  	p.version = p.string()
    71  	if p.version != "v0" && p.version != "v1" {
    72  		return p.read, nil, fmt.Errorf("unknown export data version: %s", p.version)
    73  	}
    74  
    75  	// populate typList with predeclared "known" types
    76  	p.typList = append(p.typList, predeclared...)
    77  
    78  	// read package data
    79  	pkg := p.pkg()
    80  
    81  	// read objects of phase 1 only (see cmd/compiler/internal/gc/bexport.go)
    82  	objcount := 0
    83  	for {
    84  		tag := p.tagOrIndex()
    85  		if tag == endTag {
    86  			break
    87  		}
    88  		p.obj(tag)
    89  		objcount++
    90  	}
    91  
    92  	// self-verification
    93  	if count := p.int(); count != objcount {
    94  		panic(fmt.Sprintf("got %d objects; want %d", objcount, count))
    95  	}
    96  
    97  	// ignore compiler-specific import data
    98  
    99  	// complete interfaces
   100  	for _, typ := range p.typList {
   101  		// If we only record named types (!p.trackAllTypes),
   102  		// we must check the underlying types here. If we
   103  		// track all types, the Underlying() method call is
   104  		// not needed.
   105  		// TODO(gri) Remove if p.trackAllTypes is gone.
   106  		if it, ok := typ.Underlying().(*types.Interface); ok {
   107  			it.Complete()
   108  		}
   109  	}
   110  
   111  	// record all referenced packages as imports
   112  	list := append(([]*types.Package)(nil), p.pkgList[1:]...)
   113  	sort.Sort(byPath(list))
   114  	pkg.SetImports(list)
   115  
   116  	// package was imported completely and without errors
   117  	pkg.MarkComplete()
   118  
   119  	return p.read, pkg, nil
   120  }
   121  
   122  func (p *importer) pkg() *types.Package {
   123  	// if the package was seen before, i is its index (>= 0)
   124  	i := p.tagOrIndex()
   125  	if i >= 0 {
   126  		return p.pkgList[i]
   127  	}
   128  
   129  	// otherwise, i is the package tag (< 0)
   130  	if i != packageTag {
   131  		panic(fmt.Sprintf("unexpected package tag %d", i))
   132  	}
   133  
   134  	// read package data
   135  	name := p.string()
   136  	path := p.string()
   137  
   138  	// we should never see an empty package name
   139  	if name == "" {
   140  		panic("empty package name in import")
   141  	}
   142  
   143  	// an empty path denotes the package we are currently importing;
   144  	// it must be the first package we see
   145  	if (path == "") != (len(p.pkgList) == 0) {
   146  		panic(fmt.Sprintf("package path %q for pkg index %d", path, len(p.pkgList)))
   147  	}
   148  
   149  	// if the package was imported before, use that one; otherwise create a new one
   150  	if path == "" {
   151  		path = p.path
   152  	}
   153  	pkg := p.imports[path]
   154  	if pkg == nil {
   155  		pkg = types.NewPackage(path, name)
   156  		p.imports[path] = pkg
   157  	} else if pkg.Name() != name {
   158  		panic(fmt.Sprintf("conflicting names %s and %s for package %q", pkg.Name(), name, path))
   159  	}
   160  	p.pkgList = append(p.pkgList, pkg)
   161  
   162  	return pkg
   163  }
   164  
   165  func (p *importer) declare(obj types.Object) {
   166  	pkg := obj.Pkg()
   167  	if alt := pkg.Scope().Insert(obj); alt != nil {
   168  		// This could only trigger if we import a (non-type) object a second time.
   169  		// This should never happen because 1) we only import a package once; and
   170  		// b) we ignore compiler-specific export data which may contain functions
   171  		// whose inlined function bodies refer to other functions that were already
   172  		// imported.
   173  		// (See also the comment in cmd/compile/internal/gc/bimport.go importer.obj,
   174  		// switch case importing functions).
   175  		panic(fmt.Sprintf("inconsistent import:\n\t%v\npreviously imported as:\n\t%v\n", alt, obj))
   176  	}
   177  }
   178  
   179  func (p *importer) obj(tag int) {
   180  	switch tag {
   181  	case constTag:
   182  		p.pos()
   183  		pkg, name := p.qualifiedName()
   184  		typ := p.typ(nil)
   185  		val := p.value()
   186  		p.declare(types.NewConst(token.NoPos, pkg, name, typ, val))
   187  
   188  	case typeTag:
   189  		_ = p.typ(nil)
   190  
   191  	case varTag:
   192  		p.pos()
   193  		pkg, name := p.qualifiedName()
   194  		typ := p.typ(nil)
   195  		p.declare(types.NewVar(token.NoPos, pkg, name, typ))
   196  
   197  	case funcTag:
   198  		p.pos()
   199  		pkg, name := p.qualifiedName()
   200  		params, isddd := p.paramList()
   201  		result, _ := p.paramList()
   202  		sig := types.NewSignature(nil, params, result, isddd)
   203  		p.declare(types.NewFunc(token.NoPos, pkg, name, sig))
   204  
   205  	default:
   206  		panic(fmt.Sprintf("unexpected object tag %d", tag))
   207  	}
   208  }
   209  
   210  func (p *importer) pos() {
   211  	if !p.posInfoFormat {
   212  		return
   213  	}
   214  
   215  	file := p.prevFile
   216  	line := p.prevLine
   217  	if delta := p.int(); delta != 0 {
   218  		// line changed
   219  		line += delta
   220  	} else if n := p.int(); n >= 0 {
   221  		// file changed
   222  		file = p.prevFile[:n] + p.string()
   223  		p.prevFile = file
   224  		line = p.int()
   225  	}
   226  	p.prevLine = line
   227  
   228  	// TODO(gri) register new position
   229  }
   230  
   231  func (p *importer) qualifiedName() (pkg *types.Package, name string) {
   232  	name = p.string()
   233  	pkg = p.pkg()
   234  	return
   235  }
   236  
   237  func (p *importer) record(t types.Type) {
   238  	p.typList = append(p.typList, t)
   239  }
   240  
   241  // A dddSlice is a types.Type representing ...T parameters.
   242  // It only appears for parameter types and does not escape
   243  // the importer.
   244  type dddSlice struct {
   245  	elem types.Type
   246  }
   247  
   248  func (t *dddSlice) Underlying() types.Type { return t }
   249  func (t *dddSlice) String() string         { return "..." + t.elem.String() }
   250  
   251  // parent is the package which declared the type; parent == nil means
   252  // the package currently imported. The parent package is needed for
   253  // exported struct fields and interface methods which don't contain
   254  // explicit package information in the export data.
   255  func (p *importer) typ(parent *types.Package) types.Type {
   256  	// if the type was seen before, i is its index (>= 0)
   257  	i := p.tagOrIndex()
   258  	if i >= 0 {
   259  		return p.typList[i]
   260  	}
   261  
   262  	// otherwise, i is the type tag (< 0)
   263  	switch i {
   264  	case namedTag:
   265  		// read type object
   266  		p.pos()
   267  		parent, name := p.qualifiedName()
   268  		scope := parent.Scope()
   269  		obj := scope.Lookup(name)
   270  
   271  		// if the object doesn't exist yet, create and insert it
   272  		if obj == nil {
   273  			obj = types.NewTypeName(token.NoPos, parent, name, nil)
   274  			scope.Insert(obj)
   275  		}
   276  
   277  		if _, ok := obj.(*types.TypeName); !ok {
   278  			panic(fmt.Sprintf("pkg = %s, name = %s => %s", parent, name, obj))
   279  		}
   280  
   281  		// associate new named type with obj if it doesn't exist yet
   282  		t0 := types.NewNamed(obj.(*types.TypeName), nil, nil)
   283  
   284  		// but record the existing type, if any
   285  		t := obj.Type().(*types.Named)
   286  		p.record(t)
   287  
   288  		// read underlying type
   289  		t0.SetUnderlying(p.typ(parent))
   290  
   291  		// interfaces don't have associated methods
   292  		if types.IsInterface(t0) {
   293  			return t
   294  		}
   295  
   296  		// read associated methods
   297  		for i := p.int(); i > 0; i-- {
   298  			// TODO(gri) replace this with something closer to fieldName
   299  			p.pos()
   300  			name := p.string()
   301  			if !exported(name) {
   302  				p.pkg()
   303  			}
   304  
   305  			recv, _ := p.paramList() // TODO(gri) do we need a full param list for the receiver?
   306  			params, isddd := p.paramList()
   307  			result, _ := p.paramList()
   308  
   309  			if p.version == "v1" {
   310  				p.int() // nointerface flag - discarded
   311  			}
   312  
   313  			sig := types.NewSignature(recv.At(0), params, result, isddd)
   314  			t0.AddMethod(types.NewFunc(token.NoPos, parent, name, sig))
   315  		}
   316  
   317  		return t
   318  
   319  	case arrayTag:
   320  		t := new(types.Array)
   321  		if p.trackAllTypes {
   322  			p.record(t)
   323  		}
   324  
   325  		n := p.int64()
   326  		*t = *types.NewArray(p.typ(parent), n)
   327  		return t
   328  
   329  	case sliceTag:
   330  		t := new(types.Slice)
   331  		if p.trackAllTypes {
   332  			p.record(t)
   333  		}
   334  
   335  		*t = *types.NewSlice(p.typ(parent))
   336  		return t
   337  
   338  	case dddTag:
   339  		t := new(dddSlice)
   340  		if p.trackAllTypes {
   341  			p.record(t)
   342  		}
   343  
   344  		t.elem = p.typ(parent)
   345  		return t
   346  
   347  	case structTag:
   348  		t := new(types.Struct)
   349  		if p.trackAllTypes {
   350  			p.record(t)
   351  		}
   352  
   353  		*t = *types.NewStruct(p.fieldList(parent))
   354  		return t
   355  
   356  	case pointerTag:
   357  		t := new(types.Pointer)
   358  		if p.trackAllTypes {
   359  			p.record(t)
   360  		}
   361  
   362  		*t = *types.NewPointer(p.typ(parent))
   363  		return t
   364  
   365  	case signatureTag:
   366  		t := new(types.Signature)
   367  		if p.trackAllTypes {
   368  			p.record(t)
   369  		}
   370  
   371  		params, isddd := p.paramList()
   372  		result, _ := p.paramList()
   373  		*t = *types.NewSignature(nil, params, result, isddd)
   374  		return t
   375  
   376  	case interfaceTag:
   377  		// Create a dummy entry in the type list. This is safe because we
   378  		// cannot expect the interface type to appear in a cycle, as any
   379  		// such cycle must contain a named type which would have been
   380  		// first defined earlier.
   381  		n := len(p.typList)
   382  		if p.trackAllTypes {
   383  			p.record(nil)
   384  		}
   385  
   386  		// no embedded interfaces with gc compiler
   387  		if p.int() != 0 {
   388  			panic("unexpected embedded interface")
   389  		}
   390  
   391  		t := types.NewInterface(p.methodList(parent), nil)
   392  		if p.trackAllTypes {
   393  			p.typList[n] = t
   394  		}
   395  		return t
   396  
   397  	case mapTag:
   398  		t := new(types.Map)
   399  		if p.trackAllTypes {
   400  			p.record(t)
   401  		}
   402  
   403  		key := p.typ(parent)
   404  		val := p.typ(parent)
   405  		*t = *types.NewMap(key, val)
   406  		return t
   407  
   408  	case chanTag:
   409  		t := new(types.Chan)
   410  		if p.trackAllTypes {
   411  			p.record(t)
   412  		}
   413  
   414  		var dir types.ChanDir
   415  		// tag values must match the constants in cmd/compile/internal/gc/go.go
   416  		switch d := p.int(); d {
   417  		case 1 /* Crecv */ :
   418  			dir = types.RecvOnly
   419  		case 2 /* Csend */ :
   420  			dir = types.SendOnly
   421  		case 3 /* Cboth */ :
   422  			dir = types.SendRecv
   423  		default:
   424  			panic(fmt.Sprintf("unexpected channel dir %d", d))
   425  		}
   426  		val := p.typ(parent)
   427  		*t = *types.NewChan(dir, val)
   428  		return t
   429  
   430  	default:
   431  		panic(fmt.Sprintf("unexpected type tag %d", i))
   432  	}
   433  }
   434  
   435  func (p *importer) fieldList(parent *types.Package) (fields []*types.Var, tags []string) {
   436  	if n := p.int(); n > 0 {
   437  		fields = make([]*types.Var, n)
   438  		tags = make([]string, n)
   439  		for i := range fields {
   440  			fields[i] = p.field(parent)
   441  			tags[i] = p.string()
   442  		}
   443  	}
   444  	return
   445  }
   446  
   447  func (p *importer) field(parent *types.Package) *types.Var {
   448  	p.pos()
   449  	pkg, name := p.fieldName(parent)
   450  	typ := p.typ(parent)
   451  
   452  	anonymous := false
   453  	if name == "" {
   454  		// anonymous field - typ must be T or *T and T must be a type name
   455  		switch typ := deref(typ).(type) {
   456  		case *types.Basic: // basic types are named types
   457  			pkg = nil // // objects defined in Universe scope have no package
   458  			name = typ.Name()
   459  		case *types.Named:
   460  			name = typ.Obj().Name()
   461  		default:
   462  			panic("anonymous field expected")
   463  		}
   464  		anonymous = true
   465  	}
   466  
   467  	return types.NewField(token.NoPos, pkg, name, typ, anonymous)
   468  }
   469  
   470  func (p *importer) methodList(parent *types.Package) (methods []*types.Func) {
   471  	if n := p.int(); n > 0 {
   472  		methods = make([]*types.Func, n)
   473  		for i := range methods {
   474  			methods[i] = p.method(parent)
   475  		}
   476  	}
   477  	return
   478  }
   479  
   480  func (p *importer) method(parent *types.Package) *types.Func {
   481  	p.pos()
   482  	pkg, name := p.fieldName(parent)
   483  	params, isddd := p.paramList()
   484  	result, _ := p.paramList()
   485  	sig := types.NewSignature(nil, params, result, isddd)
   486  	return types.NewFunc(token.NoPos, pkg, name, sig)
   487  }
   488  
   489  func (p *importer) fieldName(parent *types.Package) (*types.Package, string) {
   490  	pkg := parent
   491  	if pkg == nil {
   492  		// use the imported package instead
   493  		pkg = p.pkgList[0]
   494  	}
   495  	name := p.string()
   496  	if name == "" {
   497  		return pkg, "" // anonymous
   498  	}
   499  	if name == "?" || name != "_" && !exported(name) {
   500  		// explicitly qualified field
   501  		if name == "?" {
   502  			name = "" // anonymous
   503  		}
   504  		pkg = p.pkg()
   505  	}
   506  	return pkg, name
   507  }
   508  
   509  func (p *importer) paramList() (*types.Tuple, bool) {
   510  	n := p.int()
   511  	if n == 0 {
   512  		return nil, false
   513  	}
   514  	// negative length indicates unnamed parameters
   515  	named := true
   516  	if n < 0 {
   517  		n = -n
   518  		named = false
   519  	}
   520  	// n > 0
   521  	params := make([]*types.Var, n)
   522  	isddd := false
   523  	for i := range params {
   524  		params[i], isddd = p.param(named)
   525  	}
   526  	return types.NewTuple(params...), isddd
   527  }
   528  
   529  func (p *importer) param(named bool) (*types.Var, bool) {
   530  	t := p.typ(nil)
   531  	td, isddd := t.(*dddSlice)
   532  	if isddd {
   533  		t = types.NewSlice(td.elem)
   534  	}
   535  
   536  	var pkg *types.Package
   537  	var name string
   538  	if named {
   539  		name = p.string()
   540  		if name == "" {
   541  			panic("expected named parameter")
   542  		}
   543  		if name != "_" {
   544  			pkg = p.pkg()
   545  		}
   546  		if i := strings.Index(name, "ยท"); i > 0 {
   547  			name = name[:i] // cut off gc-specific parameter numbering
   548  		}
   549  	}
   550  
   551  	// read and discard compiler-specific info
   552  	p.string()
   553  
   554  	return types.NewVar(token.NoPos, pkg, name, t), isddd
   555  }
   556  
   557  func exported(name string) bool {
   558  	ch, _ := utf8.DecodeRuneInString(name)
   559  	return unicode.IsUpper(ch)
   560  }
   561  
   562  func (p *importer) value() constant.Value {
   563  	switch tag := p.tagOrIndex(); tag {
   564  	case falseTag:
   565  		return constant.MakeBool(false)
   566  	case trueTag:
   567  		return constant.MakeBool(true)
   568  	case int64Tag:
   569  		return constant.MakeInt64(p.int64())
   570  	case floatTag:
   571  		return p.float()
   572  	case complexTag:
   573  		re := p.float()
   574  		im := p.float()
   575  		return constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
   576  	case stringTag:
   577  		return constant.MakeString(p.string())
   578  	default:
   579  		panic(fmt.Sprintf("unexpected value tag %d", tag))
   580  	}
   581  }
   582  
   583  func (p *importer) float() constant.Value {
   584  	sign := p.int()
   585  	if sign == 0 {
   586  		return constant.MakeInt64(0)
   587  	}
   588  
   589  	exp := p.int()
   590  	mant := []byte(p.string()) // big endian
   591  
   592  	// remove leading 0's if any
   593  	for len(mant) > 0 && mant[0] == 0 {
   594  		mant = mant[1:]
   595  	}
   596  
   597  	// convert to little endian
   598  	// TODO(gri) go/constant should have a more direct conversion function
   599  	//           (e.g., once it supports a big.Float based implementation)
   600  	for i, j := 0, len(mant)-1; i < j; i, j = i+1, j-1 {
   601  		mant[i], mant[j] = mant[j], mant[i]
   602  	}
   603  
   604  	// adjust exponent (constant.MakeFromBytes creates an integer value,
   605  	// but mant represents the mantissa bits such that 0.5 <= mant < 1.0)
   606  	exp -= len(mant) << 3
   607  	if len(mant) > 0 {
   608  		for msd := mant[len(mant)-1]; msd&0x80 == 0; msd <<= 1 {
   609  			exp++
   610  		}
   611  	}
   612  
   613  	x := constant.MakeFromBytes(mant)
   614  	switch {
   615  	case exp < 0:
   616  		d := constant.Shift(constant.MakeInt64(1), token.SHL, uint(-exp))
   617  		x = constant.BinaryOp(x, token.QUO, d)
   618  	case exp > 0:
   619  		x = constant.Shift(x, token.SHL, uint(exp))
   620  	}
   621  
   622  	if sign < 0 {
   623  		x = constant.UnaryOp(token.SUB, x, 0)
   624  	}
   625  	return x
   626  }
   627  
   628  // ----------------------------------------------------------------------------
   629  // Low-level decoders
   630  
   631  func (p *importer) tagOrIndex() int {
   632  	if p.debugFormat {
   633  		p.marker('t')
   634  	}
   635  
   636  	return int(p.rawInt64())
   637  }
   638  
   639  func (p *importer) int() int {
   640  	x := p.int64()
   641  	if int64(int(x)) != x {
   642  		panic("exported integer too large")
   643  	}
   644  	return int(x)
   645  }
   646  
   647  func (p *importer) int64() int64 {
   648  	if p.debugFormat {
   649  		p.marker('i')
   650  	}
   651  
   652  	return p.rawInt64()
   653  }
   654  
   655  func (p *importer) string() string {
   656  	if p.debugFormat {
   657  		p.marker('s')
   658  	}
   659  	// if the string was seen before, i is its index (>= 0)
   660  	// (the empty string is at index 0)
   661  	i := p.rawInt64()
   662  	if i >= 0 {
   663  		return p.strList[i]
   664  	}
   665  	// otherwise, i is the negative string length (< 0)
   666  	if n := int(-i); n <= cap(p.buf) {
   667  		p.buf = p.buf[:n]
   668  	} else {
   669  		p.buf = make([]byte, n)
   670  	}
   671  	for i := range p.buf {
   672  		p.buf[i] = p.rawByte()
   673  	}
   674  	s := string(p.buf)
   675  	p.strList = append(p.strList, s)
   676  	return s
   677  }
   678  
   679  func (p *importer) marker(want byte) {
   680  	if got := p.rawByte(); got != want {
   681  		panic(fmt.Sprintf("incorrect marker: got %c; want %c (pos = %d)", got, want, p.read))
   682  	}
   683  
   684  	pos := p.read
   685  	if n := int(p.rawInt64()); n != pos {
   686  		panic(fmt.Sprintf("incorrect position: got %d; want %d", n, pos))
   687  	}
   688  }
   689  
   690  // rawInt64 should only be used by low-level decoders
   691  func (p *importer) rawInt64() int64 {
   692  	i, err := binary.ReadVarint(p)
   693  	if err != nil {
   694  		panic(fmt.Sprintf("read error: %v", err))
   695  	}
   696  	return i
   697  }
   698  
   699  // needed for binary.ReadVarint in rawInt64
   700  func (p *importer) ReadByte() (byte, error) {
   701  	return p.rawByte(), nil
   702  }
   703  
   704  // byte is the bottleneck interface for reading p.data.
   705  // It unescapes '|' 'S' to '$' and '|' '|' to '|'.
   706  // rawByte should only be used by low-level decoders.
   707  func (p *importer) rawByte() byte {
   708  	b := p.data[0]
   709  	r := 1
   710  	if b == '|' {
   711  		b = p.data[1]
   712  		r = 2
   713  		switch b {
   714  		case 'S':
   715  			b = '$'
   716  		case '|':
   717  			// nothing to do
   718  		default:
   719  			panic("unexpected escape sequence in export data")
   720  		}
   721  	}
   722  	p.data = p.data[r:]
   723  	p.read += r
   724  	return b
   725  
   726  }
   727  
   728  // ----------------------------------------------------------------------------
   729  // Export format
   730  
   731  // Tags. Must be < 0.
   732  const (
   733  	// Objects
   734  	packageTag = -(iota + 1)
   735  	constTag
   736  	typeTag
   737  	varTag
   738  	funcTag
   739  	endTag
   740  
   741  	// Types
   742  	namedTag
   743  	arrayTag
   744  	sliceTag
   745  	dddTag
   746  	structTag
   747  	pointerTag
   748  	signatureTag
   749  	interfaceTag
   750  	mapTag
   751  	chanTag
   752  
   753  	// Values
   754  	falseTag
   755  	trueTag
   756  	int64Tag
   757  	floatTag
   758  	fractionTag // not used by gc
   759  	complexTag
   760  	stringTag
   761  	unknownTag // not used by gc (only appears in packages with errors)
   762  )
   763  
   764  var predeclared = []types.Type{
   765  	// basic types
   766  	types.Typ[types.Bool],
   767  	types.Typ[types.Int],
   768  	types.Typ[types.Int8],
   769  	types.Typ[types.Int16],
   770  	types.Typ[types.Int32],
   771  	types.Typ[types.Int64],
   772  	types.Typ[types.Uint],
   773  	types.Typ[types.Uint8],
   774  	types.Typ[types.Uint16],
   775  	types.Typ[types.Uint32],
   776  	types.Typ[types.Uint64],
   777  	types.Typ[types.Uintptr],
   778  	types.Typ[types.Float32],
   779  	types.Typ[types.Float64],
   780  	types.Typ[types.Complex64],
   781  	types.Typ[types.Complex128],
   782  	types.Typ[types.String],
   783  
   784  	// aliases
   785  	types.Universe.Lookup("byte").Type(),
   786  	types.Universe.Lookup("rune").Type(),
   787  
   788  	// error
   789  	types.Universe.Lookup("error").Type(),
   790  
   791  	// untyped types
   792  	types.Typ[types.UntypedBool],
   793  	types.Typ[types.UntypedInt],
   794  	types.Typ[types.UntypedRune],
   795  	types.Typ[types.UntypedFloat],
   796  	types.Typ[types.UntypedComplex],
   797  	types.Typ[types.UntypedString],
   798  	types.Typ[types.UntypedNil],
   799  
   800  	// package unsafe
   801  	types.Typ[types.UnsafePointer],
   802  
   803  	// invalid type
   804  	types.Typ[types.Invalid], // only appears in packages with errors
   805  
   806  	// used internally by gc; never used by this package or in .a files
   807  	anyType{},
   808  }
   809  
   810  type anyType struct{}
   811  
   812  func (t anyType) Underlying() types.Type { return t }
   813  func (t anyType) String() string         { return "any" }