Skip to content

Commit 1990b96

Browse files
ldezmvertes
andauthored
update to go1.21 (#1598)
* feat: generate go1.21 files * chore: update CI * feat: add support for generic symbols in standard library packages This is necessary to fully support go1.21 and beyond, which now provide some generic packages such as `cmp`, `maps` or `slices` in the standard library. The principle is to embed the generic symbols in source form (as strings) so they can be instantiated as required during interpretation. Extract() has been modified to skip the generic types, functions and constraint interfaces which can't be represented as reflect.Values. A new stdlib/generic package has been added to provide the corresponding source files as embedded strings. The `Use()` function has been changed to pre-parse generic symbols as doing lazy parsing was causing cyclic dependencies issues at compiling. This is something we may improve in the future. A unit test using `cmp` has been added. For now, there are still some issues with generic stdlib packages inter-dependencies, for example `slices` importing `cmp`, or when generic types or function signatures depends on pre-compiled types in the same package, which we will support shortly. * fixup * fixup * fixup * fixup * fixup * fixup * fixes for go1.20 * fix previous * update unsafe2 for go1.21, skip faky tests In go1.21, the reflect rtype definition has been move to internal/abi. We follow this change for maintainability, even if there is no layout change (the go1.20 unsafe2 is compatible with go1.21). We have isolated a few problematic tests which are failing sometimes in go1.21, but work in go1.20, and also in go1.22. Those tests are skipped if in go1.21. A preliminary investigation can not confirm that something is wrong in yaegi, and the problem disappears with go1.22. * add new wrapper for go1.21 package testing/slogtest * add missing wrapper for go/doc/comment * add support for slices generic package --------- Co-authored-by: Marc Vertes <[email protected]>
1 parent da27c4f commit 1990b96

File tree

540 files changed

+7711
-4114
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

540 files changed

+7711
-4114
lines changed

.github/workflows/go-cross.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717

1818
strategy:
1919
matrix:
20-
go-version: [ 1.19, '1.20' ]
20+
go-version: [ '1.20', '1.21' ]
2121
os: [ubuntu-latest, macos-latest, windows-latest]
2222

2323
include:

.github/workflows/main.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ on:
77
pull_request:
88

99
env:
10-
GO_VERSION: '1.20'
11-
GOLANGCI_LINT_VERSION: v1.53.3
10+
GO_VERSION: '1.21'
11+
GOLANGCI_LINT_VERSION: v1.55.2
1212

1313
jobs:
1414

@@ -45,7 +45,7 @@ jobs:
4545
needs: linting
4646
strategy:
4747
matrix:
48-
go-version: [ 1.19, '1.20' ]
48+
go-version: [ '1.20', '1.21' ]
4949
steps:
5050
- name: Set up Go ${{ matrix.go-version }}
5151
uses: actions/setup-go@v2
@@ -76,7 +76,7 @@ jobs:
7676
working-directory: ${{ github.workspace }}/go/src/github.com/traefik/yaegi
7777
strategy:
7878
matrix:
79-
go-version: [ 1.19, '1.20' ]
79+
go-version: [ '1.20', '1.21' ]
8080

8181
steps:
8282
- name: Set up Go ${{ matrix.go-version }}

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ on:
66
- v[0-9]+.[0-9]+*
77

88
env:
9-
GO_VERSION: '1.20'
9+
GO_VERSION: '1.21'
1010

1111
jobs:
1212

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ It powers executable Go scripts and plugins, in embedded interpreters or interac
1717
* Works everywhere Go works
1818
* All Go & runtime resources accessible from script (with control)
1919
* Security: `unsafe` and `syscall` packages neither used nor exported by default
20-
* Support the latest 2 major releases of Go (Go 1.19 and Go 1.20)
20+
* Support the latest 2 major releases of Go (Go 1.20 and Go 1.21)
2121

2222
## Install
2323

extract/extract.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ import (
3939
"{{$key}}"
4040
{{- end}}
4141
{{- end}}
42+
{{- if or .Val .Typ }}
4243
"{{.ImportPath}}"
44+
{{- end}}
4345
"reflect"
4446
)
4547
@@ -199,6 +201,10 @@ func (e *Extractor) genContent(importPath string, p *types.Package) ([]byte, err
199201
val[name] = Val{pname, false}
200202
}
201203
case *types.Func:
204+
// Skip generic functions and methods.
205+
if s := o.Type().(*types.Signature); s.TypeParams().Len() > 0 || s.RecvTypeParams().Len() > 0 {
206+
continue
207+
}
202208
val[name] = Val{pname, false}
203209
case *types.Var:
204210
val[name] = Val{pname, true}
@@ -207,9 +213,13 @@ func (e *Extractor) genContent(importPath string, p *types.Package) ([]byte, err
207213
if t, ok := o.Type().(*types.Named); ok && t.TypeParams().Len() > 0 {
208214
continue
209215
}
210-
211216
typ[name] = pname
212217
if t, ok := o.Type().Underlying().(*types.Interface); ok {
218+
if t.NumMethods() == 0 && t.NumEmbeddeds() != 0 {
219+
// Skip interfaces used to implement constraints for generics.
220+
delete(typ, name)
221+
continue
222+
}
213223
var methods []Method
214224
for i := 0; i < t.NumMethods(); i++ {
215225
f := t.Method(i)
@@ -468,7 +478,7 @@ func GetMinor(part string) string {
468478
return minor
469479
}
470480

471-
const defaultMinorVersion = 20
481+
const defaultMinorVersion = 21
472482

473483
func genBuildTags() (string, error) {
474484
version := runtime.Version()

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
module github.com/traefik/yaegi
22

3-
go 1.19
3+
go 1.20

internal/unsafe2/unsafe.go renamed to internal/unsafe2/go1_20_unsafe.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
//go:build !go1.21
2+
// +build !go1.21
3+
14
// Package unsafe2 provides helpers to generate recursive struct types.
25
package unsafe2
36

internal/unsafe2/go1_21_unsafe.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
//go:build go1.21
2+
// +build go1.21
3+
4+
// Package unsafe2 provides helpers to generate recursive struct types.
5+
package unsafe2
6+
7+
import (
8+
"reflect"
9+
"unsafe"
10+
)
11+
12+
type dummy struct{}
13+
14+
// DummyType represents a stand-in for a recursive type.
15+
var DummyType = reflect.TypeOf(dummy{})
16+
17+
// The following type sizes must match their original definition in Go src/internal/abi/type.go.
18+
type abiType struct {
19+
_ uintptr
20+
_ uintptr
21+
_ uint32
22+
_ uint8
23+
_ uint8
24+
_ uint8
25+
_ uint8
26+
_ uintptr
27+
_ uintptr
28+
_ int32
29+
_ int32
30+
}
31+
32+
type abiName struct {
33+
Bytes *byte
34+
}
35+
36+
type abiStructField struct {
37+
Name abiName
38+
Typ *abiType
39+
Offset uintptr
40+
}
41+
42+
type abiStructType struct {
43+
abiType
44+
PkgPath abiName
45+
Fields []abiStructField
46+
}
47+
48+
type emptyInterface struct {
49+
typ *abiType
50+
_ unsafe.Pointer
51+
}
52+
53+
// SetFieldType sets the type of the struct field at the given index, to the given type.
54+
//
55+
// The struct type must have been created at runtime. This is very unsafe.
56+
func SetFieldType(s reflect.Type, idx int, t reflect.Type) {
57+
if s.Kind() != reflect.Struct || idx >= s.NumField() {
58+
return
59+
}
60+
61+
rtyp := unpackType(s)
62+
styp := (*abiStructType)(unsafe.Pointer(rtyp))
63+
f := styp.Fields[idx]
64+
f.Typ = unpackType(t)
65+
styp.Fields[idx] = f
66+
}
67+
68+
func unpackType(t reflect.Type) *abiType {
69+
v := reflect.New(t).Elem().Interface()
70+
eface := *(*emptyInterface)(unsafe.Pointer(&v))
71+
return eface.typ
72+
}

interp/generic.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,12 +306,12 @@ func checkConstraint(it, ct *itype) error {
306306
return nil
307307
}
308308
for _, c := range ct.constraint {
309-
if it.equals(c) {
309+
if it.equals(c) || it.matchDefault(c) {
310310
return nil
311311
}
312312
}
313313
for _, c := range ct.ulconstraint {
314-
if it.underlying().equals(c) {
314+
if it.underlying().equals(c) || it.matchDefault(c) {
315315
return nil
316316
}
317317
}

interp/interp_consistent_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ func TestInterpConsistencyBuild(t *testing.T) {
121121
file.Name() == "type33.go" { // expect error
122122
continue
123123
}
124+
// Skip some tests which are problematic in go1.21 only.
125+
if go121 && testsToSkipGo121[file.Name()] {
126+
continue
127+
}
124128

125129
file := file
126130
t.Run(file.Name(), func(t *testing.T) {

0 commit comments

Comments
 (0)