-// UNREVIEWED
// 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.
return i
}
+// Keep this in sync with constants in iexport.go.
+const (
+ iexportVersionGo1_11 = 0
+ iexportVersionPosCol = 1
+ iexportVersionGenerics = 2
+
+ // Start of the unstable series of versions, remove "+ n" before release.
+ iexportVersionCurrent = iexportVersionGenerics + 1
+)
+
const predeclReserved = 32
type itag uint64
// If the export data version is not recognized or the format is otherwise
// compromised, an error is returned.
func iImportData(imports map[string]*types2.Package, data []byte, path string) (_ int, pkg *types2.Package, err error) {
- const currentVersion = 1
+ const currentVersion = iexportVersionCurrent
version := int64(-1)
defer func() {
if e := recover(); e != nil {
version = int64(r.uint64())
switch version {
- case currentVersion, 0:
+ case currentVersion, iexportVersionPosCol, iexportVersionGo1_11:
default:
- errorf("unknown iexport format version %d", version)
+ if version > iexportVersionGenerics {
+ errorf("unstable iexport format version %d, just rebuild compiler and std library", version)
+ } else {
+ errorf("unknown iexport format version %d", version)
+ }
}
sLen := int64(r.uint64())
r.Seek(sLen+dLen, io_SeekCurrent)
p := iimporter{
- ipath: path,
- version: int(version),
+ exportVersion: version,
+ ipath: path,
+ version: int(version),
stringData: stringData,
stringCache: make(map[uint64]string),
}
type iimporter struct {
- ipath string
- version int
+ exportVersion int64
+ ipath string
+ version int
stringData []byte
stringCache map[uint64]string
r.declare(types2.NewConst(pos, r.currPkg, name, typ, val))
case 'F':
- tparams := r.tparamList()
+ var tparams []*types2.TypeName
+ if r.p.exportVersion >= iexportVersionGenerics {
+ tparams = r.tparamList()
+ }
sig := r.signature(nil)
sig.SetTParams(tparams)
r.declare(types2.NewFunc(pos, r.currPkg, name, sig))
case 'T':
- tparams := r.tparamList()
+ var tparams []*types2.TypeName
+ if r.p.exportVersion >= iexportVersionGenerics {
+ tparams = r.tparamList()
+ }
// Types can be recursive. We need to setup a stub
// declaration before recursing.
return typ
case typeParamType:
+ if r.p.exportVersion < iexportVersionGenerics {
+ errorf("unexpected type param type")
+ }
r.currPkg = r.pkg()
pos := r.pos()
name := r.string()
return t
case instType:
+ if r.p.exportVersion < iexportVersionGenerics {
+ errorf("unexpected instantiation type")
+ }
pos := r.pos()
len := r.uint64()
targs := make([]types2.Type, len)
)
// Current indexed export format version. Increase with each format change.
-// 1: added column details to Pos
// 0: Go1.11 encoding
-const iexportVersion = 1
+// 1: added column details to Pos
+// 2: added information for generic function/types (currently unstable)
+const (
+ iexportVersionGo1_11 = 0
+ iexportVersionPosCol = 1
+ iexportVersionGenerics = 2
+
+ // Start of the unstable series of versions, remove "+ n" before release.
+ iexportVersionCurrent = iexportVersionGenerics + 1
+)
// predeclReserved is the number of type offsets reserved for types
// implicitly declared in the universe block.
// Assemble header.
var hdr intWriter
hdr.WriteByte('i')
- hdr.uint64(iexportVersion)
+ hdr.uint64(iexportVersionCurrent)
hdr.uint64(uint64(p.strings.Len()))
hdr.uint64(dataLen)
ird := &intReader{in, pkg}
version := ird.uint64()
- if version != iexportVersion {
- base.Errorf("import %q: unknown export format version %d", pkg.Path, version)
+ switch version {
+ case iexportVersionCurrent, iexportVersionPosCol, iexportVersionGo1_11:
+ default:
+ if version > iexportVersionGenerics {
+ base.Errorf("import %q: unstable export format version %d, just recompile", pkg.Path, version)
+ } else {
+ base.Errorf("import %q: unknown export format version %d", pkg.Path, version)
+ }
base.ErrorExit()
}
in.MustSeek(int64(sLen+dLen), os.SEEK_CUR)
p := &iimporter{
- ipkg: pkg,
+ exportVersion: version,
+ ipkg: pkg,
pkgCache: map[uint64]*types.Pkg{},
posBaseCache: map[uint64]*src.PosBase{},
}
type iimporter struct {
- ipkg *types.Pkg
+ exportVersion uint64
+ ipkg *types.Pkg
pkgCache map[uint64]*types.Pkg
posBaseCache map[uint64]*src.PosBase
return n
case 'F':
- tparams := r.tparamList()
+ var tparams []*types.Field
+ if r.p.exportVersion >= iexportVersionGenerics {
+ tparams = r.tparamList()
+ }
typ := r.signature(nil, tparams)
n := importfunc(r.p.ipkg, pos, sym, typ)
return n
case 'T':
- rparams := r.typeList()
+ var rparams []*types.Type
+ if r.p.exportVersion >= iexportVersionGenerics {
+ rparams = r.typeList()
+ }
// Types can be recursive. We need to setup a stub
// declaration before recursing.
return t
case typeParamType:
+ if r.p.exportVersion < iexportVersionGenerics {
+ base.Fatalf("unexpected type param type")
+ }
r.setPkg()
pos := r.pos()
name := r.string()
return t
case instType:
+ if r.p.exportVersion < iexportVersionGenerics {
+ base.Fatalf("unexpected instantiation type")
+ }
pos := r.pos()
len := r.uint64()
targs := make([]*types.Type, len)
// This package only handles gc export data.
// Disable test until we put in the new export version.
- if true || runtime.Compiler != "gc" {
+ if runtime.Compiler != "gc" {
t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
}
return i
}
+// Keep this in sync with constants in iexport.go.
+const (
+ iexportVersionGo1_11 = 0
+ iexportVersionPosCol = 1
+ iexportVersionGenerics = 2
+
+ // Start of the unstable series of versions, remove "+ n" before release.
+ iexportVersionCurrent = iexportVersionGenerics + 1
+)
+
const predeclReserved = 32
type itag uint64
// If the export data version is not recognized or the format is otherwise
// compromised, an error is returned.
func iImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) {
- const currentVersion = 1
+ const currentVersion = iexportVersionCurrent
version := int64(-1)
defer func() {
if e := recover(); e != nil {
version = int64(r.uint64())
switch version {
- case currentVersion, 0:
+ case currentVersion, iexportVersionPosCol, iexportVersionGo1_11:
default:
- errorf("unknown iexport format version %d", version)
+ if version > iexportVersionGenerics {
+ errorf("unstable iexport format version %d, just rebuild compiler and std library", version)
+ } else {
+ errorf("unknown iexport format version %d", version)
+ }
}
sLen := int64(r.uint64())
r.Seek(sLen+dLen, io.SeekCurrent)
p := iimporter{
- ipath: path,
- version: int(version),
+ exportVersion: version,
+ ipath: path,
+ version: int(version),
stringData: stringData,
stringCache: make(map[uint64]string),
}
type iimporter struct {
- ipath string
- version int
+ exportVersion int64
+ ipath string
+ version int
stringData []byte
stringCache map[uint64]string
r.declare(types.NewConst(pos, r.currPkg, name, typ, val))
case 'F':
- numTparams := r.uint64()
- if numTparams > 0 {
- errorf("unexpected tparam")
- return
+ if r.p.exportVersion >= iexportVersionGenerics {
+ numTparams := r.uint64()
+ if numTparams > 0 {
+ errorf("unexpected tparam")
+ }
}
sig := r.signature(nil)
r.declare(types.NewFunc(pos, r.currPkg, name, sig))
case 'T':
- numTparams := r.uint64()
- if numTparams > 0 {
- errorf("unexpected tparam")
+ if r.p.exportVersion >= iexportVersionGenerics {
+ numTparams := r.uint64()
+ if numTparams > 0 {
+ errorf("unexpected tparam")
+ }
}
// Types can be recursive. We need to setup a stub
return typ
case typeParamType:
- errorf("do not handle tparams yet")
+ errorf("do not handle type param types yet")
return nil
case instType:
--- /dev/null
+package a
+
+type Ordered interface {
+ type int, int8, int16, int32, int64,
+ uint, uint8, uint16, uint32, uint64, uintptr,
+ float32, float64,
+ string
+}
+
+// List is a linked list of ordered values of type T.
+type List[T Ordered] struct {
+ Next *List[T]
+ Val T
+}
+
+func (l *List[T]) Largest() T {
+ var max T
+ for p := l; p != nil; p = p.Next {
+ if p.Val > max {
+ max = p.Val
+ }
+ }
+ return max
+}
+
+type OrderedNum interface {
+ type int, int8, int16, int32, int64,
+ uint, uint8, uint16, uint32, uint64, uintptr,
+ float32, float64
+}
+
+// ListNum is a linked _List of ordered numeric values of type T.
+type ListNum[T OrderedNum] struct {
+ Next *ListNum[T]
+ Val T
+}
+
+const Clip = 5
+
+// clippedLargest returns the largest in the list of OrderNums, but a max of 5.
+// TODO(danscales): fix export/import of an untype constant with typeparam type
+func (l *ListNum[T]) ClippedLargest() T {
+ var max T
+ for p := l; p != nil; p = p.Next {
+ if p.Val > max && p.Val < T(Clip) {
+ max = p.Val
+ }
+ }
+ return max
+}
--- /dev/null
+package main
+
+import (
+ "a"
+ "fmt"
+)
+
+func main() {
+ i3 := &a.List[int]{nil, 1}
+ i2 := &a.List[int]{i3, 3}
+ i1 := &a.List[int]{i2, 2}
+ if got, want := i1.Largest(), 3; got != want {
+ panic(fmt.Sprintf("got %d, want %d", got, want))
+ }
+
+ b3 := &a.List[byte]{nil, byte(1)}
+ b2 := &a.List[byte]{b3, byte(3)}
+ b1 := &a.List[byte]{b2, byte(2)}
+ if got, want := b1.Largest(), byte(3); got != want {
+ panic(fmt.Sprintf("got %d, want %d", got, want))
+ }
+
+ f3 := &a.List[float64]{nil, 13.5}
+ f2 := &a.List[float64]{f3, 1.2}
+ f1 := &a.List[float64]{f2, 4.5}
+ if got, want := f1.Largest(), 13.5; got != want {
+ panic(fmt.Sprintf("got %f, want %f", got, want))
+ }
+
+ s3 := &a.List[string]{nil, "dd"}
+ s2 := &a.List[string]{s3, "aa"}
+ s1 := &a.List[string]{s2, "bb"}
+ if got, want := s1.Largest(), "dd"; got != want {
+ panic(fmt.Sprintf("got %s, want %s", got, want))
+ }
+ j3 := &a.ListNum[int]{nil, 1}
+ j2 := &a.ListNum[int]{j3, 32}
+ j1 := &a.ListNum[int]{j2, 2}
+ if got, want := j1.ClippedLargest(), 2; got != want {
+ panic(fmt.Sprintf("got %d, want %d", got, want))
+ }
+ g3 := &a.ListNum[float64]{nil, 13.5}
+ g2 := &a.ListNum[float64]{g3, 1.2}
+ g1 := &a.ListNum[float64]{g2, 4.5}
+ if got, want := g1.ClippedLargest(), 4.5; got != want {
+ panic(fmt.Sprintf("got %f, want %f", got, want))
+ }
+}
--- /dev/null
+// rundir -G=3
+
+// Copyright 2021 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