Skip to content

[go1.20] Merge master into go1.20 #1293

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 59 commits into from
Apr 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
59e4d76
Add typeparam test cases to the gorepo test suite.
nevkontakte Dec 2, 2023
82b84ff
Do not fail compilation when encountering generics.
nevkontakte Dec 2, 2023
9118679
Implement a new internal library for discovering generic instances.
nevkontakte Dec 17, 2023
af64433
Instantiate generic functions for each discovered set of type args.
nevkontakte Dec 24, 2023
f1a7c2a
Type parameter substitution when translating function instances.
nevkontakte Jan 4, 2024
ae5a9c2
Explicitly generate method instances for generic names types.
nevkontakte Jan 4, 2024
cdddbe2
Implement generic type instantiation.
nevkontakte Jan 5, 2024
b65288d
Re-triage failing test cases.
nevkontakte Jan 5, 2024
8f8d041
Correctly detect type conversions to generic types.
nevkontakte Jan 5, 2024
eff58dc
Correctly handle all integer types in funcContext.formatExpr().
nevkontakte Jan 5, 2024
2ca8aab
Discover generic type declarations inside generic functions.
nevkontakte Jan 5, 2024
aea4239
Perform type substitution for method selection expressions.
nevkontakte Jan 20, 2024
16af5b4
Fix variable name allocation for inline types.
nevkontakte Jan 20, 2024
b888728
Fix pointer-taking of an escaping variable.
nevkontakte Jan 21, 2024
77b5223
Re-triage remaining typeparam test failures.
nevkontakte Jan 21, 2024
ecc7d5f
Fix instance discovery for generic types embedded in structs.
nevkontakte Jan 21, 2024
7a384fd
Deduplicate collected typeNames within a package.
nevkontakte Jan 28, 2024
13fa377
Use types.Object as a key when grouping instances by object.
nevkontakte Feb 3, 2024
fe2849a
Assign unique numeric IDs to generic instances in the generated code.
nevkontakte Feb 18, 2024
49c773a
Include type arguments into generic type strings.
nevkontakte Feb 24, 2024
5a7c2d0
Fix variable name assignment for result variables.
nevkontakte Feb 24, 2024
61de589
Perform type substitution in the type switch expression.
nevkontakte Feb 24, 2024
0a51510
Implement builtins Sizeof(), Alignof() and Offsetof().
nevkontakte Feb 24, 2024
5aaeafb
Merge master with Go 1.19 support.
nevkontakte Feb 24, 2024
0343336
Borrow type substitution logic from x/tools/go/ssa package.
nevkontakte Feb 24, 2024
fb19fae
Update run.go to match the current set of passing tests.
nevkontakte Feb 24, 2024
deb26d0
Diagnose fixedbugs/issue50672.go issue.
nevkontakte Feb 25, 2024
8a80f06
Gofumpt the files to keep the linter happy.
nevkontakte Feb 25, 2024
b288e83
Address pull request comments.
nevkontakte Mar 2, 2024
2ce9bec
Merge remote-tracking branch 'upstream/generics-ng' into generics-ng
nevkontakte Mar 2, 2024
6de32f8
Merge pull request #1272 from nevkontakte/generics-ng
nevkontakte Mar 2, 2024
d06ba6e
Bump ip from 1.1.5 to 1.1.9 in /node-syscall
dependabot[bot] Mar 9, 2024
0134061
Refactor srctesting to support parsing and checking multiple packages.
nevkontakte Mar 9, 2024
9ecdb18
Support collecting instances across packages in typeparams.Collector.
nevkontakte Mar 9, 2024
201e081
Merge pull request #1268 from gopherjs/dependabot/npm_and_yarn/node-s…
nevkontakte Mar 9, 2024
a6219f0
chore: remove repetitive words
avoidalone Mar 11, 2024
95fdb0c
Merge pull request #1275 from avoidalone/master
nevkontakte Mar 14, 2024
4d56d3f
Merge pull request #1274 from nevkontakte/gng1
nevkontakte Mar 16, 2024
732a8f6
Merge pull request #1276 from nevkontakte/gng2
nevkontakte Mar 16, 2024
1a39bfe
Guard generics support behind an experiment flag.
nevkontakte Mar 23, 2024
7f11cd4
Merge pull request #1279 from nevkontakte/gng3
nevkontakte Mar 24, 2024
cd96796
Bump tar from 6.1.11 to 6.2.1 in /node-syscall
dependabot[bot] Apr 10, 2024
96fbf88
Bump tar from 6.1.11 to 6.2.1
dependabot[bot] Apr 10, 2024
70635ff
chore: fix some typos in comments
kindknow Apr 11, 2024
e3c702f
Merge pull request #1288 from kindknow/master
flimzy Apr 11, 2024
11fa655
Merge pull request #1286 from gopherjs/dependabot/npm_and_yarn/tar-6.2.1
nevkontakte Apr 11, 2024
ac2a8c1
Merge pull request #1285 from gopherjs/dependabot/npm_and_yarn/node-s…
nevkontakte Apr 11, 2024
0419127
Updated test/gorepo/run.go's build constraint checker
grantnelson-wf Apr 11, 2024
852c4d2
Address code review feedback from PR #1290.
nevkontakte Apr 15, 2024
42009d4
Merge pull request #1289 from Workiva/gorepoTestBuildConstraints
nevkontakte Apr 15, 2024
c0be063
Merge pull request #1290 from gopherjs/generics-ng
nevkontakte Apr 15, 2024
8d8794a
compiler: improve helpers for indentation management.
nevkontakte Oct 2, 2022
606129e
compiler: readability improvements to the functionContext type.
nevkontakte Apr 13, 2024
038d281
Rename and document functions responsible for identifier generation.
nevkontakte Apr 13, 2024
b0663d9
compiler: factor out utility types for processing Go sources and errors.
nevkontakte Jan 1, 2023
b5eb7ec
Merge pull request #1291 from nevkontakte/gng4
nevkontakte Apr 15, 2024
a5f0cfb
Fix function name in comment
deferdeter Apr 16, 2024
d25ca33
Merge pull request #1292 from deferdeter/master
flimzy Apr 16, 2024
2b0f3eb
Merge branch 'master' of github.com:gopherjs/gopherjs into mergeMaster
grantnelson-wf Apr 16, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 10 additions & 12 deletions build/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -418,18 +418,17 @@ func TestOverlayAugmentation(t *testing.T) {
test.want = test.src
}

fsetSrc := token.NewFileSet()
fileSrc := srctesting.Parse(t, fsetSrc, pkgName+test.src)
f := srctesting.New(t)
fileSrc := f.Parse("test.go", pkgName+test.src)

overrides := map[string]overrideInfo{}
augmentOverlayFile(fileSrc, overrides)
pruneImports(fileSrc)

got := srctesting.Format(t, fsetSrc, fileSrc)
got := srctesting.Format(t, f.FileSet, fileSrc)

fsetWant := token.NewFileSet()
fileWant := srctesting.Parse(t, fsetWant, pkgName+test.want)
want := srctesting.Format(t, fsetWant, fileWant)
fileWant := f.Parse("test.go", pkgName+test.want)
want := srctesting.Format(t, f.FileSet, fileWant)

if got != want {
t.Errorf("augmentOverlayFile and pruneImports got unexpected code:\n"+
Expand Down Expand Up @@ -720,18 +719,17 @@ func TestOriginalAugmentation(t *testing.T) {
t.Run(test.desc, func(t *testing.T) {
pkgName := "package testpackage\n\n"
importPath := `math/rand`
fsetSrc := token.NewFileSet()
fileSrc := srctesting.Parse(t, fsetSrc, pkgName+test.src)
f := srctesting.New(t)
fileSrc := f.Parse("test.go", pkgName+test.src)

augmentOriginalImports(importPath, fileSrc)
augmentOriginalFile(fileSrc, test.info)
pruneImports(fileSrc)

got := srctesting.Format(t, fsetSrc, fileSrc)
got := srctesting.Format(t, f.FileSet, fileSrc)

fsetWant := token.NewFileSet()
fileWant := srctesting.Parse(t, fsetWant, pkgName+test.want)
want := srctesting.Format(t, fsetWant, fileWant)
fileWant := f.Parse("test.go", pkgName+test.want)
want := srctesting.Format(t, f.FileSet, fileWant)

if got != want {
t.Errorf("augmentOriginalImports, augmentOriginalFile, and pruneImports got unexpected code:\n"+
Expand Down
2 changes: 1 addition & 1 deletion build/cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func Clear() error {
// the cache. For example, any artifacts that were cached for a minified build
// must not be reused for a non-minified build. GopherJS version change also
// invalidates the cache. It is callers responsibility to ensure that artifacts
// passed the the StoreArchive function were generated with the same build
// passed the StoreArchive function were generated with the same build
// parameters as the cache is configured.
//
// There is no upper limit for the total cache size. It can be cleared
Expand Down
10 changes: 10 additions & 0 deletions circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ orbs:
jobs:
build:
executor: gopherjs
environment:
GOPHERJS_EXPERIMENT: generics
steps:
- setup_and_install_gopherjs
- run:
Expand Down Expand Up @@ -129,6 +131,8 @@ jobs:
gopherjs_tests:
executor: gopherjs
parallelism: 4
environment:
GOPHERJS_EXPERIMENT: generics
steps:
- setup_and_install_gopherjs
- run:
Expand All @@ -155,6 +159,8 @@ jobs:

gorepo_tests:
executor: gopherjs
environment:
GOPHERJS_EXPERIMENT: generics
parallelism: 4
steps:
- setup_environment
Expand All @@ -170,6 +176,8 @@ jobs:
executor:
name: win/default
shell: powershell.exe
environment:
GOPHERJS_EXPERIMENT: generics
steps:
- checkout
- run:
Expand Down Expand Up @@ -204,6 +212,8 @@ jobs:
darwin_smoke:
macos:
xcode: 13.4.1 # Mac OS 12.6.1, see https://circleci.com/docs/using-macos/
environment:
GOPHERJS_EXPERIMENT: generics
steps:
- checkout
- setup_environment
Expand Down
5 changes: 3 additions & 2 deletions compiler/analysis/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -342,8 +342,8 @@ func (fi *FuncInfo) visitCallExpr(n *ast.CallExpr) ast.Visitor {
return nil // No need to walk under this CallExpr, we already did it manually.
default:
if astutil.IsTypeExpr(f, fi.pkgInfo.Info) {
// This is a type assertion, not a call. Type assertion itself is not
// blocking, but we will visit the expression itself.
// This is a type conversion, not a call. Type assertion itself is not
// blocking, but we will visit the input expression.
} else {
// The function is returned by a non-trivial expression. We have to be
// conservative and assume that function might be blocking.
Expand All @@ -357,6 +357,7 @@ func (fi *FuncInfo) visitCallExpr(n *ast.CallExpr) ast.Visitor {
func (fi *FuncInfo) callToNamedFunc(callee types.Object) {
switch o := callee.(type) {
case *types.Func:
o = o.Origin()
if recv := o.Type().(*types.Signature).Recv(); recv != nil {
if _, ok := recv.Type().Underlying().(*types.Interface); ok {
// Conservatively assume that an interface implementation may be blocking.
Expand Down
9 changes: 4 additions & 5 deletions compiler/analysis/info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package analysis

import (
"go/ast"
"go/token"
"go/types"
"testing"

Expand Down Expand Up @@ -34,11 +33,11 @@ func notBlocking() {
func() { println() } ()
}
`
fset := token.NewFileSet()
file := srctesting.Parse(t, fset, src)
typesInfo, typesPkg := srctesting.Check(t, fset, file)
f := srctesting.New(t)
file := f.Parse("test.go", src)
typesInfo, typesPkg := f.Check("pkg/test", file)

pkgInfo := AnalyzePkg([]*ast.File{file}, fset, typesInfo, typesPkg, func(f *types.Func) bool {
pkgInfo := AnalyzePkg([]*ast.File{file}, f.FileSet, typesInfo, typesPkg, func(f *types.Func) bool {
panic("isBlocking() should be never called for imported functions in this test.")
})

Expand Down
22 changes: 22 additions & 0 deletions compiler/astutil/astutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,15 @@ func NewIdent(name string, t types.Type, info *types.Info, pkg *types.Package) *
return ident
}

// IsTypeExpr returns true if expr denotes a type. This can be used to
// distinguish between calls and type conversions.
func IsTypeExpr(expr ast.Expr, info *types.Info) bool {
// Note that we could've used info.Types[expr].IsType() instead of doing our
// own analysis. However, that creates a problem because we synthesize some
// *ast.CallExpr nodes and, more importantly, *ast.Ident nodes that denote a
// type. Unfortunately, because the flag that controls
// types.TypeAndValue.IsType() return value is unexported we wouldn't be able
// to set it correctly. Thus, we can't rely on IsType().
switch e := expr.(type) {
case *ast.ArrayType, *ast.ChanType, *ast.FuncType, *ast.InterfaceType, *ast.MapType, *ast.StructType:
return true
Expand All @@ -47,6 +55,20 @@ func IsTypeExpr(expr ast.Expr, info *types.Info) bool {
case *ast.SelectorExpr:
_, ok := info.Uses[e.Sel].(*types.TypeName)
return ok
case *ast.IndexExpr:
ident, ok := e.X.(*ast.Ident)
if !ok {
return false
}
_, ok = info.Uses[ident].(*types.TypeName)
return ok
case *ast.IndexListExpr:
ident, ok := e.X.(*ast.Ident)
if !ok {
return false
}
_, ok = info.Uses[ident].(*types.TypeName)
return ok
case *ast.ParenExpr:
return IsTypeExpr(e.X, info)
default:
Expand Down
10 changes: 3 additions & 7 deletions compiler/astutil/astutil_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package astutil

import (
"go/ast"
"go/token"
"strconv"
"testing"

Expand Down Expand Up @@ -44,8 +43,7 @@ func TestImportsUnsafe(t *testing.T) {
for _, test := range tests {
t.Run(test.desc, func(t *testing.T) {
src := "package testpackage\n\n" + test.imports
fset := token.NewFileSet()
file := srctesting.Parse(t, fset, src)
file := srctesting.New(t).Parse("test.go", src)
got := ImportsUnsafe(file)
if got != test.want {
t.Fatalf("ImportsUnsafe() returned %t, want %t", got, test.want)
Expand Down Expand Up @@ -81,8 +79,7 @@ func TestImportName(t *testing.T) {
for _, test := range tests {
t.Run(test.desc, func(t *testing.T) {
src := "package testpackage\n\n" + test.src
fset := token.NewFileSet()
file := srctesting.Parse(t, fset, src)
file := srctesting.New(t).Parse("test.go", src)
if len(file.Imports) != 1 {
t.Fatal(`expected one and only one import`)
}
Expand Down Expand Up @@ -399,8 +396,7 @@ func TestHasDirectiveOnFile(t *testing.T) {
for _, test := range tests {
t.Run(test.desc, func(t *testing.T) {
const action = `do-stuff`
fset := token.NewFileSet()
file := srctesting.Parse(t, fset, test.src)
file := srctesting.New(t).Parse("test.go", test.src)
if got := hasDirective(file, action); got != test.want {
t.Errorf(`hasDirective(%T, %q) returned %t, want %t`, file, action, got, test.want)
}
Expand Down
27 changes: 8 additions & 19 deletions compiler/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"strings"
"time"

"github.com/gopherjs/gopherjs/compiler/internal/symbol"
"github.com/gopherjs/gopherjs/compiler/prelude"
"golang.org/x/tools/go/gcexportdata"
)
Expand All @@ -32,22 +33,6 @@ func init() {
}
}

type ErrorList []error

func (err ErrorList) Error() string {
if len(err) == 0 {
return "<no errors>"
}
return fmt.Sprintf("%s (and %d more errors)", err[0].Error(), len(err[1:]))
}

func (err ErrorList) Normalize() error {
if len(err) == 0 {
return nil
}
return err
}

// Archive contains intermediate build outputs of a single package.
//
// This is a logical equivalent of an object file in traditional compilers.
Expand Down Expand Up @@ -112,9 +97,13 @@ type Decl struct {
// Go compiler/linker toolchain. Used by GopherJS to support go:linkname
// directives. Must be set for decls that are supported by go:linkname
// implementation.
LinkingName SymName
LinkingName symbol.Name
// A list of package-level JavaScript variable names this symbol needs to declare.
Vars []string
// A JS expression by which the object represented by this decl may be
// referenced within the package context. Empty if the decl represents no such
// object.
RefExpr string
// NamedRecvType is method named recv declare.
NamedRecvType string
// JavaScript code that declares basic information about a symbol. For a type
Expand Down Expand Up @@ -326,7 +315,7 @@ func WritePkgCode(pkg *Archive, dceSelection map[*Decl]struct{}, gls goLinknameS
if recv, method, ok := d.LinkingName.IsMethod(); ok {
code = fmt.Sprintf("\t$linknames[%q] = $unsafeMethodToFunction(%v,%q,%t);\n", d.LinkingName.String(), d.NamedRecvType, method, strings.HasPrefix(recv, "*"))
} else {
code = fmt.Sprintf("\t$linknames[%q] = %s;\n", d.LinkingName.String(), d.Vars[0])
code = fmt.Sprintf("\t$linknames[%q] = %s;\n", d.LinkingName.String(), d.RefExpr)
}
if _, err := w.Write(removeWhitespace([]byte(code), minify)); err != nil {
return err
Expand Down Expand Up @@ -357,7 +346,7 @@ func WritePkgCode(pkg *Archive, dceSelection map[*Decl]struct{}, gls goLinknameS
if !found {
continue // The symbol is not affected by a go:linkname directive.
}
lines = append(lines, fmt.Sprintf("\t\t%s = $linknames[%q];\n", d.Vars[0], impl.String()))
lines = append(lines, fmt.Sprintf("\t\t%s = $linknames[%q];\n", d.RefExpr, impl.String()))
}
if len(lines) > 0 {
code := fmt.Sprintf("\t$pkg.$initLinknames = function() {\n%s};\n", strings.Join(lines, ""))
Expand Down
68 changes: 68 additions & 0 deletions compiler/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package compiler

import (
"errors"
"fmt"
)

// ErrTooManyErrors is added to the ErrorList by the Trim method.
var ErrTooManyErrors = errors.New("too many errors")

// ErrorList wraps multiple errors as a single error.
type ErrorList []error

func (errs ErrorList) Error() string {
if len(errs) == 0 {
return "<no errors>"
}
return fmt.Sprintf("%s (and %d more errors)", errs[0].Error(), len(errs[1:]))
}

// ErrOrNil returns nil if ErrorList is empty, or the error otherwise.
func (errs ErrorList) ErrOrNil() error {
if len(errs) == 0 {
return nil
}
return errs
}

// Append an error to the list.
//
// If err is an instance of ErrorList, the lists are concatenated together,
// otherwise err is appended at the end of the list. If err is nil, the list is
// returned unmodified.
//
// err := DoStuff()
// errList := errList.Append(err)
func (errs ErrorList) Append(err error) ErrorList {
if err == nil {
return errs
}
if err, ok := err.(ErrorList); ok {
return append(errs, err...)
}
return append(errs, err)
}

// AppendDistinct is similar to Append, but doesn't append the error if it has
// the same message as the last error on the list.
func (errs ErrorList) AppendDistinct(err error) ErrorList {
if l := len(errs); l > 0 {
if prev := errs[l-1]; prev != nil && err.Error() == prev.Error() {
return errs // The new error is the same as the last one, skip it.
}
}

return errs.Append(err)
}

// Trim the error list if it has more than limit errors. If the list is trimmed,
// all extraneous errors are replaced with a single ErrTooManyErrors, making the
// returned ErrorList length of limit+1.
func (errs ErrorList) Trim(limit int) ErrorList {
if len(errs) <= limit {
return errs
}

return append(errs[:limit], ErrTooManyErrors)
}
Loading
Loading