.github/ISSUE_TEMPLATE/01-pkgsite.md | 2 ++
doc/go1.20.html | 10 +++++-----
src/README.vendor | 13 +++++--------
src/cmd/compile/internal/pgo/irgraph.go | 2 +-
src/cmd/compile/internal/ssa/writebarrier.go | 38 ++++++++++++++++++++++++--------------
src/cmd/compile/internal/types2/call.go | 21 ++++++++++++++++++++-
src/cmd/compile/internal/types2/expr.go | 2 +-
src/cmd/compile/internal/types2/instantiate.go | 58 ++++++++++++++++++++++++++++++++++++++++++-----------
src/cmd/compile/internal/types2/typexpr.go | 2 +-
src/cmd/compile/internal/wasm/ssa.go | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++
src/cmd/cover/cover.go | 52 ++++++++++++++++++++++++++++++++++++++++++++--------
src/cmd/go/internal/test/test.go | 7 +++++--
src/cmd/go/testdata/script/cover_sync_atomic_import.txt | 15 +++++++++++++++
src/cmd/gofmt/rewrite.go | 2 +-
src/cmd/internal/obj/arm64/asm7.go | 2 +-
src/cmd/link/internal/ld/macho.go | 7 +++++--
src/crypto/internal/boring/README.md | 22 +++++++++++++++++++++-
src/crypto/tls/cache.go | 2 +-
src/go/types/call.go | 21 ++++++++++++++++++++-
src/go/types/expr.go | 2 +-
src/go/types/instantiate.go | 58 ++++++++++++++++++++++++++++++++++++++++++-----------
src/go/types/typexpr.go | 2 +-
src/internal/types/testdata/check/cycles0.go | 2 +-
src/internal/types/testdata/check/decls0.go | 10 +++++-----
src/internal/types/testdata/check/issues0.go | 2 +-
src/internal/types/testdata/check/issues1.go | 8 ++++----
src/internal/types/testdata/check/typeinst1.go | 28 ++++++++++++++--------------
src/internal/types/testdata/examples/inference.go | 2 +-
src/internal/types/testdata/fixedbugs/issue39634.go | 2 +-
src/internal/types/testdata/fixedbugs/issue39754.go | 4 ++--
src/internal/types/testdata/fixedbugs/issue40350.go | 2 +-
src/internal/types/testdata/fixedbugs/issue45920.go | 4 ++--
src/internal/types/testdata/fixedbugs/issue47411.go | 10 +++++-----
src/internal/types/testdata/fixedbugs/issue49112.go | 4 ++--
src/internal/types/testdata/fixedbugs/issue49179.go | 8 ++++----
src/internal/types/testdata/fixedbugs/issue49739.go | 4 ++--
src/internal/types/testdata/fixedbugs/issue50417.go | 6 +++---
src/internal/types/testdata/fixedbugs/issue50646.go | 12 ++++++------
src/internal/types/testdata/fixedbugs/issue50782.go | 10 +++++-----
src/internal/types/testdata/fixedbugs/issue51257.go | 8 ++++----
src/internal/types/testdata/fixedbugs/issue51376.go | 4 ++--
src/internal/types/testdata/fixedbugs/issue51472.go | 4 ++--
src/internal/types/testdata/fixedbugs/issue57486.go | 6 +++---
src/internal/types/testdata/fixedbugs/issue57500.go | 16 ++++++++++++++++
src/internal/types/testdata/fixedbugs/issue57522.go | 24 ++++++++++++++++++++++++
src/internal/types/testdata/spec/comparable.go | 12 ++++++------
src/internal/types/testdata/spec/comparable1.19.go | 12 ++++++------
src/internal/types/testdata/spec/oldcomparable.go | 12 ++++++------
src/net/hosts.go | 2 +-
src/os/exec/exec_test.go | 1 +
src/runtime/crash_cgo_test.go | 4 +++-
src/runtime/mpagecache.go | 3 +--
src/runtime/os_darwin.go | 2 ++
src/runtime/pprof/pprof_test.go | 46 ++++++++++++++++++++++++++--------------------
src/runtime/pprof/proto.go | 4 ++++
src/runtime/sys_darwin.go | 42 ++++++++++++++++++++++++++++++++++++++++++
src/runtime/sys_darwin_amd64.s | 9 +++++++++
src/runtime/sys_darwin_arm64.s | 6 ++++++
src/sync/atomic/value.go | 2 +-
src/syscall/exec_libc2.go | 4 ++--
src/syscall/exec_linux_test.go | 5 +++--
src/syscall/syscall_darwin.go | 32 ++------------------------------
src/syscall/syscall_openbsd_libc.go | 6 +-----
src/syscall/zsyscall_darwin_amd64.go | 22 ++++------------------
src/syscall/zsyscall_darwin_amd64.s | 6 ++----
src/syscall/zsyscall_darwin_arm64.go | 22 ++++------------------
src/syscall/zsyscall_darwin_arm64.s | 6 ++----
src/testing/fuzz.go | 2 +-
test/fixedbugs/issue18392.go | 2 +-
test/fixedbugs/issue47068.dir/a.go | 2 +-
test/typeparam/graph.go | 2 +-
test/typeparam/mdempsky/8.dir/b.go | 2 +-
test/typeparam/mincheck.dir/main.go | 4 ++--
diff --git a/.github/ISSUE_TEMPLATE/01-pkgsite.md b/.github/ISSUE_TEMPLATE/01-pkgsite.md
index fee00f5b2752038b901bebaa5e0e7d9aa70b9b36..31f0fd16b17e9a7ddf3f4276e46c1849f65ee021 100644
--- a/.github/ISSUE_TEMPLATE/01-pkgsite.md
+++ b/.github/ISSUE_TEMPLATE/01-pkgsite.md
@@ -34,6 +34,8 @@ ### What did you do?
diff --git a/doc/go1.20.html b/doc/go1.20.html
index aec3e25285958993fa5af18540230f27c45c8388..23fa82c41b3b392c9cecacaa691757fe6a1a2dc6 100644
--- a/doc/go1.20.html
+++ b/doc/go1.20.html
@@ -458,7 +458,7 @@
func RequestHandler(w ResponseWriter, r *Request) {
rc := http.NewResponseController(w)
- rc.SetWriteDeadline(0) // disable Server.WriteTimeout when sending a large response
+ rc.SetWriteDeadline(time.Time{}) // disable Server.WriteTimeout when sending a large response
io.Copy(w, bigData)
}
@@ -1121,10 +1121,10 @@ - strings
-
The new
- CutPrefix and
- CutSuffix functions
- are like TrimPrefix
- and TrimSuffix
+ CutPrefix and
+ CutSuffix functions
+ are like TrimPrefix
+ and TrimSuffix
but also report whether the string was trimmed.
diff --git a/src/README.vendor b/src/README.vendor
index e74fc2f316daaab2d383f5956896f65db3412a10..4b6bdb8e748a7d746efb611d1255397c81cf047e 100644
--- a/src/README.vendor
+++ b/src/README.vendor
@@ -4,12 +4,8 @@
The Go command maintains copies of external packages needed by the
standard library in the src/vendor and src/cmd/vendor directories.
-In GOPATH mode, imports of vendored packages are resolved to these
-directories following normal vendor directory logic
-(see golang.org/s/go15vendor).
-
-In module mode, std and cmd are modules (defined in src/go.mod and
-src/cmd/go.mod). When a package outside std or cmd is imported
+There are two modules, std and cmd, defined in src/go.mod and
+src/cmd/go.mod. When a package outside std or cmd is imported
by a package inside std or cmd, the import path is interpreted
as if it had a "vendor/" prefix. For example, within "crypto/tls",
an import of "golang.org/x/crypto/cryptobyte" resolves to
@@ -34,14 +30,15 @@ Maintaining vendor directories
==============================
Before updating vendor directories, ensure that module mode is enabled.
-Make sure GO111MODULE=off is not set ('on' or 'auto' should work).
+Make sure that GO111MODULE is not set in the environment, or that it is
+set to 'on' or 'auto'.
Requirements may be added, updated, and removed with 'go get'.
The vendor directory may be updated with 'go mod vendor'.
A typical sequence might be:
cd src
- go get -d golang.org/x/net@latest
+ go get golang.org/x/net@latest
go mod tidy
go mod vendor
diff --git a/src/cmd/compile/internal/pgo/irgraph.go b/src/cmd/compile/internal/pgo/irgraph.go
index 311f20ed8175423b751b2bcd6ff1b180a0f4aafb..bf11e365f1042ac959199a12576771244df19557 100644
--- a/src/cmd/compile/internal/pgo/irgraph.go
+++ b/src/cmd/compile/internal/pgo/irgraph.go
@@ -217,7 +217,7 @@ if !seenStartLine {
// TODO(prattic): If Function.start_line is missing we could
// fall back to using absolute line numbers, which is better
// than nothing.
- log.Fatal("PGO profile missing Function.start_line data")
+ log.Fatal("PGO profile missing Function.start_line data (Go version of profiled application too old? Go 1.20+ automatically adds this to profiles)")
}
return true
diff --git a/src/cmd/compile/internal/ssa/writebarrier.go b/src/cmd/compile/internal/ssa/writebarrier.go
index 3b2f781cbe305565a6c616a00f190b860ad92dd6..1676a9347c4d5ec817c61bb15934f974a49a5330 100644
--- a/src/cmd/compile/internal/ssa/writebarrier.go
+++ b/src/cmd/compile/internal/ssa/writebarrier.go
@@ -27,7 +27,7 @@
// needwb reports whether we need write barrier for store op v.
// v must be Store/Move/Zero.
// zeroes provides known zero information (keyed by ID of memory-type values).
-func needwb(v *Value, zeroes map[ID]ZeroRegion) bool {
+func needwb(v *Value, zeroes map[ID]ZeroRegion, select1 []*Value) bool {
t, ok := v.Aux.(*types.Type)
if !ok {
v.Fatalf("store aux is not a type: %s", v.LongString())
@@ -39,7 +39,7 @@ if IsStackAddr(v.Args[0]) {
return false // write on stack doesn't need write barrier
}
if v.Op == OpMove && IsReadOnlyGlobalAddr(v.Args[1]) {
- if mem, ok := IsNewObject(v.Args[0]); ok && mem == v.MemoryArg() {
+ if mem, ok := IsNewObject(v.Args[0], select1); ok && mem == v.MemoryArg() {
// Copying data from readonly memory into a fresh object doesn't need a write barrier.
return false
}
@@ -99,7 +99,22 @@ var stores, after []*Value
var sset *sparseSet
var storeNumber []int32
- zeroes := f.computeZeroMap()
+ // Compute map from a value to the SelectN [1] value that uses it.
+ select1 := f.Cache.allocValueSlice(f.NumValues())
+ defer func() { f.Cache.freeValueSlice(select1) }()
+ for _, b := range f.Blocks {
+ for _, v := range b.Values {
+ if v.Op != OpSelectN {
+ continue
+ }
+ if v.AuxInt != 1 {
+ continue
+ }
+ select1[v.Args[0].ID] = v
+ }
+ }
+
+ zeroes := f.computeZeroMap(select1)
for _, b := range f.Blocks { // range loop is safe since the blocks we added contain no stores to expand
// first, identify all the stores that need to insert a write barrier.
// mark them with WB ops temporarily. record presence of WB ops.
@@ -107,7 +122,7 @@ nWBops := 0 // count of temporarily created WB ops remaining to be rewritten in the current block
for _, v := range b.Values {
switch v.Op {
case OpStore, OpMove, OpZero:
- if needwb(v, zeroes) {
+ if needwb(v, zeroes, select1) {
switch v.Op {
case OpStore:
v.Op = OpStoreWB
@@ -376,7 +391,8 @@ }
// computeZeroMap returns a map from an ID of a memory value to
// a set of locations that are known to be zeroed at that memory value.
-func (f *Func) computeZeroMap() map[ID]ZeroRegion {
+func (f *Func) computeZeroMap(select1 []*Value) map[ID]ZeroRegion {
+
ptrSize := f.Config.PtrSize
// Keep track of which parts of memory are known to be zero.
// This helps with removing write barriers for various initialization patterns.
@@ -386,7 +402,7 @@ zeroes := map[ID]ZeroRegion{}
// Find new objects.
for _, b := range f.Blocks {
for _, v := range b.Values {
- if mem, ok := IsNewObject(v); ok {
+ if mem, ok := IsNewObject(v, select1); ok {
// While compiling package runtime itself, we might see user
// calls to newobject, which will have result type
// unsafe.Pointer instead. We can't easily infer how large the
@@ -584,20 +600,14 @@ }
// IsNewObject reports whether v is a pointer to a freshly allocated & zeroed object,
// if so, also returns the memory state mem at which v is zero.
-func IsNewObject(v *Value) (mem *Value, ok bool) {
+func IsNewObject(v *Value, select1 []*Value) (mem *Value, ok bool) {
f := v.Block.Func
c := f.Config
if f.ABIDefault == f.ABI1 && len(c.intParamRegs) >= 1 {
if v.Op != OpSelectN || v.AuxInt != 0 {
return nil, false
}
- // Find the memory
- for _, w := range v.Block.Values {
- if w.Op == OpSelectN && w.AuxInt == 1 && w.Args[0] == v.Args[0] {
- mem = w
- break
- }
- }
+ mem = select1[v.Args[0].ID]
if mem == nil {
return nil, false
}
diff --git a/src/cmd/compile/internal/types2/call.go b/src/cmd/compile/internal/types2/call.go
index 50343bf77a6aecde608f31310409aaf949497031..7d660ca77244c7dcebf1be68948527784f766c51 100644
--- a/src/cmd/compile/internal/types2/call.go
+++ b/src/cmd/compile/internal/types2/call.go
@@ -447,7 +447,7 @@ "_Cfunc_",
"_Cmacro_", // function to evaluate the expanded expression
}
-func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, def *Named) {
+func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, def *Named, wantType bool) {
// these must be declared before the "goto Error" statements
var (
obj Object
@@ -556,6 +556,25 @@ case builtin:
check.errorf(e.Pos(), UncalledBuiltin, "cannot select on %s", x)
goto Error
case invalid:
+ goto Error
+ }
+
+ // Avoid crashing when checking an invalid selector in a method declaration
+ // (i.e., where def is not set):
+ //
+ // type S[T any] struct{}
+ // type V = S[any]
+ // func (fs *S[T]) M(x V.M) {}
+ //
+ // All codepaths below return a non-type expression. If we get here while
+ // expecting a type expression, it is an error.
+ //
+ // See issue #57522 for more details.
+ //
+ // TODO(rfindley): We should do better by refusing to check selectors in all cases where
+ // x.typ is incomplete.
+ if wantType {
+ check.errorf(e.Sel, NotAType, "%s is not a type", syntax.Expr(e))
goto Error
}
diff --git a/src/cmd/compile/internal/types2/expr.go b/src/cmd/compile/internal/types2/expr.go
index 9a0348e0250a4fbd9441d47c292bfc805083b132..a3abbb9532ec36c99924c5da0abbb4172bbc2b7d 100644
--- a/src/cmd/compile/internal/types2/expr.go
+++ b/src/cmd/compile/internal/types2/expr.go
@@ -1587,7 +1587,7 @@ x.expr = e
return kind
case *syntax.SelectorExpr:
- check.selector(x, e, nil)
+ check.selector(x, e, nil, false)
case *syntax.IndexExpr:
if check.indexExpr(x, e) {
diff --git a/src/cmd/compile/internal/types2/instantiate.go b/src/cmd/compile/internal/types2/instantiate.go
index 52f60d79a6c9792b18a469900a9c0fa9dffefc65..819368299386078856154283b68f5e210cc07ffd 100644
--- a/src/cmd/compile/internal/types2/instantiate.go
+++ b/src/cmd/compile/internal/types2/instantiate.go
@@ -188,7 +188,7 @@ // is called through an exported API call such as AssignableTo. If constraint
// is set, T is a type constraint.
//
// If the provided cause is non-nil, it may be set to an error string
-// explaining why V does not implement T.
+// explaining why V does not implement (or satisfy, for constraints) T.
func (check *Checker) implements(V, T Type, constraint bool, cause *string) bool {
Vu := under(V)
Tu := under(T)
@@ -199,6 +199,11 @@ if p, _ := Vu.(*Pointer); p != nil && under(p.base) == Typ[Invalid] {
return true // avoid follow-on errors (see issue #49541 for an example)
}
+ verb := "implement"
+ if constraint {
+ verb = "satisfy"
+ }
+
Ti, _ := Tu.(*Interface)
if Ti == nil {
if cause != nil {
@@ -208,7 +213,7 @@ detail = check.sprintf("type %s is pointer to interface, not interface", T)
} else {
detail = check.sprintf("%s is not an interface", T)
}
- *cause = check.sprintf("%s does not implement %s (%s)", V, T, detail)
+ *cause = check.sprintf("%s does not %s %s (%s)", V, verb, T, detail)
}
return false
}
@@ -230,7 +235,7 @@
// No type with non-empty type set satisfies the empty type set.
if Ti.typeSet().IsEmpty() {
if cause != nil {
- *cause = check.sprintf("cannot implement %s (empty type set)", T)
+ *cause = check.sprintf("cannot %s %s (empty type set)", verb, T)
}
return false
}
@@ -238,7 +243,7 @@
// V must implement T's methods, if any.
if m, wrong := check.missingMethod(V, Ti, true); m != nil /* !Implements(V, Ti) */ {
if cause != nil {
- *cause = check.sprintf("%s does not implement %s %s", V, T, check.missingMethodCause(V, T, m, wrong))
+ *cause = check.sprintf("%s does not %s %s %s", V, verb, T, check.missingMethodCause(V, T, m, wrong))
}
return false
}
@@ -258,7 +263,7 @@ // a test), we only consider strict comparability and we're done.
// TODO(gri) remove this check for Go 1.21
if check != nil && check.conf.OldComparableSemantics {
if cause != nil {
- *cause = check.sprintf("%s does not implement comparable", V)
+ *cause = check.sprintf("%s does not %s comparable", V, verb)
}
return false
}
@@ -270,12 +275,12 @@ if check == nil || check.allowVersion(check.pkg, 1, 20) {
return true
}
if cause != nil {
- *cause = check.sprintf("%s to implement comparable requires go1.20 or later", V)
+ *cause = check.sprintf("%s to %s comparable requires go1.20 or later", V, verb)
}
return false
}
if cause != nil {
- *cause = check.sprintf("%s does not implement comparable", V)
+ *cause = check.sprintf("%s does not %s comparable", V, verb)
}
return false
}
@@ -293,7 +298,7 @@ if Vi != nil {
if !Vi.typeSet().subsetOf(Ti.typeSet()) {
// TODO(gri) report which type is missing
if cause != nil {
- *cause = check.sprintf("%s does not implement %s", V, T)
+ *cause = check.sprintf("%s does not %s %s", V, verb, T)
}
return false
}
@@ -319,14 +324,43 @@ }
return false
}) {
if cause != nil {
- if alt != nil {
- *cause = check.sprintf("%s does not implement %s (possibly missing ~ for %s in constraint %s)", V, T, alt, T)
- } else {
- *cause = check.sprintf("%s does not implement %s (%s missing in %s)", V, T, V, Ti.typeSet().terms)
+ var detail string
+ switch {
+ case alt != nil:
+ detail = check.sprintf("possibly missing ~ for %s in %s", alt, T)
+ case mentions(Ti, V):
+ detail = check.sprintf("%s mentions %s, but %s is not in the type set of %s", T, V, V, T)
+ default:
+ detail = check.sprintf("%s missing in %s", V, Ti.typeSet().terms)
}
+ *cause = check.sprintf("%s does not %s %s (%s)", V, verb, T, detail)
}
return false
}
return checkComparability()
}
+
+// mentions reports whether type T "mentions" typ in an (embedded) element or term
+// of T (whether typ is in the type set of T or not). For better error messages.
+func mentions(T, typ Type) bool {
+ switch T := T.(type) {
+ case *Interface:
+ for _, e := range T.embeddeds {
+ if mentions(e, typ) {
+ return true
+ }
+ }
+ case *Union:
+ for _, t := range T.terms {
+ if mentions(t.typ, typ) {
+ return true
+ }
+ }
+ default:
+ if Identical(T, typ) {
+ return true
+ }
+ }
+ return false
+}
diff --git a/src/cmd/compile/internal/types2/typexpr.go b/src/cmd/compile/internal/types2/typexpr.go
index 4de658b0c4fe8bb42e6d2603e83052dcef930c0b..0f3106d70aa9c3f8f86bf769324fa5957ae71061 100644
--- a/src/cmd/compile/internal/types2/typexpr.go
+++ b/src/cmd/compile/internal/types2/typexpr.go
@@ -256,7 +256,7 @@ }
case *syntax.SelectorExpr:
var x operand
- check.selector(&x, e, def)
+ check.selector(&x, e, def, true)
switch x.mode {
case typexpr:
diff --git a/src/cmd/compile/internal/wasm/ssa.go b/src/cmd/compile/internal/wasm/ssa.go
index 27ba98c9cd0a6ffb50976384874507f5ba838ba8..0578c20d1642154642d22809a8b5e1178f786431 100644
--- a/src/cmd/compile/internal/wasm/ssa.go
+++ b/src/cmd/compile/internal/wasm/ssa.go
@@ -17,6 +17,119 @@ "cmd/internal/obj/wasm"
"internal/buildcfg"
)
+/*
+
+ Wasm implementation
+ -------------------
+
+ Wasm is a strange Go port because the machine isn't
+ a register-based machine, threads are different, code paths
+ are different, etc. We outline those differences here.
+
+ See the design doc for some additional info on this topic.
+ https://docs.google.com/document/d/131vjr4DH6JFnb-blm_uRdaC0_Nv3OUwjEY5qVCxCup4/edit#heading=h.mjo1bish3xni
+
+ PCs:
+
+ Wasm doesn't have PCs in the normal sense that you can jump
+ to or call to. Instead, we simulate these PCs using our own construct.
+
+ A PC in the Wasm implementation is the combination of a function
+ ID and a block ID within that function. The function ID is an index
+ into a function table which transfers control to the start of the
+ function in question, and the block ID is a sequential integer
+ indicating where in the function we are.
+
+ Every function starts with a branch table which transfers control
+ to the place in the function indicated by the block ID. The block
+ ID is provided to the function as the sole Wasm argument.
+
+ Block IDs do not encode every possible PC. They only encode places
+ in the function where it might be suspended. Typically these places
+ are call sites.
+
+ Sometimes we encode the function ID and block ID separately. When
+ recorded together as a single integer, we use the value F<<16+B.
+
+ Threads:
+
+ Wasm doesn't (yet) have threads. We have to simulate threads by
+ keeping goroutine stacks in linear memory and unwinding
+ the Wasm stack each time we want to switch goroutines.
+
+ To support unwinding a stack, each function call returns on the Wasm
+ stack a boolean that tells the function whether it should return
+ immediately or not. When returning immediately, a return address
+ is left on the top of the Go stack indicating where the goroutine
+ should be resumed.
+
+ Stack pointer:
+
+ There is a single global stack pointer which records the stack pointer
+ used by the currently active goroutine. This is just an address in
+ linear memory where the Go runtime is maintaining the stack for that
+ goroutine.
+
+ Functions cache the global stack pointer in a local variable for
+ faster access, but any changes must be spilled to the global variable
+ before any call and restored from the global variable after any call.
+
+ Calling convention:
+
+ All Go arguments and return values are passed on the Go stack, not
+ the wasm stack. In addition, return addresses are pushed on the
+ Go stack at every call point. Return addresses are not used during
+ normal execution, they are used only when resuming goroutines.
+ (So they are not really a "return address", they are a "resume address".)
+
+ All Go functions have the Wasm type (i32)->i32. The argument
+ is the block ID and the return value is the exit immediately flag.
+
+ Callsite:
+ - write arguments to the Go stack (starting at SP+0)
+ - push return address to Go stack (8 bytes)
+ - write local SP to global SP
+ - push 0 (type i32) to Wasm stack
+ - issue Call
+ - restore local SP from global SP
+ - pop int32 from top of Wasm stack. If nonzero, exit function immediately.
+ - use results from Go stack (starting at SP+sizeof(args))
+ - note that the callee will have popped the return address
+
+ Prologue:
+ - initialize local SP from global SP
+ - jump to the location indicated by the block ID argument
+ (which appears in local variable 0)
+ - at block 0
+ - check for Go stack overflow, call morestack if needed
+ - subtract frame size from SP
+ - note that arguments now start at SP+framesize+8
+
+ Normal epilogue:
+ - pop frame from Go stack
+ - pop return address from Go stack
+ - push 0 (type i32) on the Wasm stack
+ - return
+ Exit immediately epilogue:
+ - push 1 (type i32) on the Wasm stack
+ - return
+ - note that the return address and stack frame are left on the Go stack
+
+ The main loop that executes goroutines is wasm_pc_f_loop, in
+ runtime/rt0_js_wasm.s. It grabs the saved return address from
+ the top of the Go stack (actually SP-8?), splits it up into F
+ and B parts, then calls F with its Wasm argument set to B.
+
+ Note that when resuming a goroutine, only the most recent function
+ invocation of that goroutine appears on the Wasm stack. When that
+ Wasm function returns normally, the next most recent frame will
+ then be started up by wasm_pc_f_loop.
+
+ Global 0 is SP (stack pointer)
+ Global 1 is CTXT (closure pointer)
+ Global 2 is GP (goroutine pointer)
+*/
+
func Init(arch *ssagen.ArchInfo) {
arch.LinkArch = &wasm.Linkwasm
arch.REGSP = wasm.REG_SP
diff --git a/src/cmd/cover/cover.go b/src/cmd/cover/cover.go
index f4f225ef20859cfb02fa774f303d2d1dd54266f8..74bb500cb9d3296b99cfdfbdf1feaafc521e1062 100644
--- a/src/cmd/cover/cover.go
+++ b/src/cmd/cover/cover.go
@@ -382,8 +382,23 @@ // Similarly for bodyless funcs.
if n.Name.Name == "_" || n.Body == nil {
return nil
}
+ fname := n.Name.Name
+ // Skip AddUint32 and StoreUint32 if we're instrumenting
+ // sync/atomic itself in atomic mode (out of an abundance of
+ // caution), since as part of the instrumentation process we
+ // add calls to AddUint32/StoreUint32, and we don't want to
+ // somehow create an infinite loop.
+ //
+ // Note that in the current implementation (Go 1.20) both
+ // routines are assembly stubs that forward calls to the
+ // runtime/internal/atomic equivalents, hence the infinite
+ // loop scenario is purely theoretical (maybe if in some
+ // future implementation one of these functions might be
+ // written in Go). See #57445 for more details.
+ if atomicOnAtomic() && (fname == "AddUint32" || fname == "StoreUint32") {
+ return nil
+ }
// Determine proper function or method name.
- fname := n.Name.Name
if r := n.Recv; r != nil && len(r.List) == 1 {
t := r.List[0].Type
star := ""
@@ -508,8 +523,8 @@ return fmt.Sprintf("%s[%d] = %s", cv, which, val)
}
if *mode == "atomic" {
hookWrite = func(cv string, which int, val string) string {
- return fmt.Sprintf("%s.StoreUint32(&%s[%d], %s)", atomicPackageName,
- cv, which, val)
+ return fmt.Sprintf("%sStoreUint32(&%s[%d], %s)",
+ atomicPackagePrefix(), cv, which, val)
}
}
@@ -612,9 +627,13 @@ // Add import of sync/atomic immediately after package clause.
// We do this even if there is an existing import, because the
// existing import may be shadowed at any given place we want
// to refer to it, and our name (_cover_atomic_) is less likely to
- // be shadowed.
- file.edit.Insert(file.offset(file.astFile.Name.End()),
- fmt.Sprintf("; import %s %q", atomicPackageName, atomicPackagePath))
+ // be shadowed. The one exception is if we're visiting the
+ // sync/atomic package itself, in which case we can refer to
+ // functions directly without an import prefix. See also #57445.
+ if pkgconfig.PkgPath != "sync/atomic" {
+ file.edit.Insert(file.offset(file.astFile.Name.End()),
+ fmt.Sprintf("; import %s %q", atomicPackageName, atomicPackagePath))
+ }
}
if pkgconfig.PkgName == "main" {
file.edit.Insert(file.offset(file.astFile.Name.End()),
@@ -637,7 +656,7 @@
// Emit a reference to the atomic package to avoid
// import and not used error when there's no code in a file.
if *mode == "atomic" {
- fmt.Fprintf(fd, "var _ = %s.LoadUint32\n", atomicPackageName)
+ fmt.Fprintf(fd, "var _ = %sLoadUint32\n", atomicPackagePrefix())
}
// Last file? Emit meta-data and converage config.
@@ -658,7 +677,7 @@ }
// atomicCounterStmt returns the expression: atomic.AddUint32(&__count[23], 1)
func atomicCounterStmt(f *File, counter string) string {
- return fmt.Sprintf("%s.AddUint32(&%s, 1)", atomicPackageName, counter)
+ return fmt.Sprintf("%sAddUint32(&%s, 1)", atomicPackagePrefix(), counter)
}
// newCounter creates a new counter expression of the appropriate form.
@@ -1098,3 +1117,20 @@ if err := os.WriteFile(pkgconfig.OutConfig, fixdata, 0666); err != nil {
log.Fatalf("error writing %s: %v", pkgconfig.OutConfig, err)
}
}
+
+// atomicOnAtomic returns true if we're instrumenting
+// the sync/atomic package AND using atomic mode.
+func atomicOnAtomic() bool {
+ return *mode == "atomic" && pkgconfig.PkgPath == "sync/atomic"
+}
+
+// atomicPackagePrefix returns the import path prefix used to refer to
+// our special import of sync/atomic; this is either set to the
+// constant atomicPackageName plus a dot or the empty string if we're
+// instrumenting the sync/atomic package itself.
+func atomicPackagePrefix() string {
+ if atomicOnAtomic() {
+ return ""
+ }
+ return atomicPackageName + "."
+}
diff --git a/src/cmd/go/internal/test/test.go b/src/cmd/go/internal/test/test.go
index 0051970cfc65a3a2c7879e88a5bedaaedadde086..fe6e733538a3fa8a3b7d91a7f662736e9d2f5478 100644
--- a/src/cmd/go/internal/test/test.go
+++ b/src/cmd/go/internal/test/test.go
@@ -825,8 +825,11 @@ }
// Prepare build + run + print actions for all packages being tested.
for _, p := range pkgs {
- // sync/atomic import is inserted by the cover tool. See #18486
- if cfg.BuildCover && cfg.BuildCoverMode == "atomic" {
+ // sync/atomic import is inserted by the cover tool if we're
+ // using atomic mode (and not compiling sync/atomic package itself).
+ // See #18486 and #57445.
+ if cfg.BuildCover && cfg.BuildCoverMode == "atomic" &&
+ p.ImportPath != "sync/atomic" {
load.EnsureImport(p, "sync/atomic")
}
diff --git a/src/cmd/go/testdata/script/cover_sync_atomic_import.txt b/src/cmd/go/testdata/script/cover_sync_atomic_import.txt
index ee29bcbaba5fe3154b7657b71a3c8739e0e30048..b933cdb4c67fc27704e7fcdcc5d246d436892598 100644
--- a/src/cmd/go/testdata/script/cover_sync_atomic_import.txt
+++ b/src/cmd/go/testdata/script/cover_sync_atomic_import.txt
@@ -3,6 +3,21 @@ [compiler:gccgo] skip # gccgo has no cover tool
go test -short -cover -covermode=atomic -coverpkg=coverdep/p1 coverdep
+# In addition to the above, test to make sure there is no funny
+# business if we try "go test -cover" in atomic mode targeting
+# sync/atomic itself (see #57445). Just a short test run is needed
+# since we're mainly interested in making sure the test builds and can
+# execute at least one test.
+
+go test -short -covermode=atomic -run=TestStoreInt64 sync/atomic
+go test -short -covermode=atomic -run=TestAnd8 runtime/internal/atomic
+
+# Skip remainder if no race detector support.
+[!race] skip
+
+go test -short -cover -race -run=TestStoreInt64 sync/atomic
+go test -short -cover -race -run=TestAnd8 runtime/internal/atomic
+
-- go.mod --
module coverdep
diff --git a/src/cmd/gofmt/rewrite.go b/src/cmd/gofmt/rewrite.go
index a98c6a0cd9b4837d3cfbc23ba68255dfe4c989e2..0b7e21130905c0ca7197892d579f9b348ad2da11 100644
--- a/src/cmd/gofmt/rewrite.go
+++ b/src/cmd/gofmt/rewrite.go
@@ -199,7 +199,7 @@ case objectPtrType, positionType:
// object pointers and token positions always match
return true
case callExprType:
- // For calls, the Ellipsis fields (token.Position) must
+ // For calls, the Ellipsis fields (token.Pos) must
// match since that is how f(x) and f(x...) are different.
// Check them here but fall through for the remaining fields.
p := pattern.Interface().(*ast.CallExpr)
diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go
index d7a28388e51c57640491274f582d69ab79ebb432..db18bc8e0ae3aa2d71d168f986f5e2bdc6844c22 100644
--- a/src/cmd/internal/obj/arm64/asm7.go
+++ b/src/cmd/internal/obj/arm64/asm7.go
@@ -3215,7 +3215,7 @@ func SYSARG4(op1 int, Cn int, Cm int, op2 int) int {
return SYSARG5(0, op1, Cn, Cm, op2)
}
-// checkUnpredictable checks if the sourse and transfer registers are the same register.
+// checkUnpredictable checks if the source and transfer registers are the same register.
// ARM64 manual says it is "constrained unpredictable" if the src and dst registers of STP/LDP are same.
func (c *ctxt7) checkUnpredictable(p *obj.Prog, isload bool, wback bool, rn int16, rt1 int16, rt2 int16) {
if wback && rn != REGSP && (rn == rt1 || rn == rt2) {
diff --git a/src/cmd/link/internal/ld/macho.go b/src/cmd/link/internal/ld/macho.go
index 11cbf814861b5d093ce8517f184666a4447063b5..d6c28e4790ad7d5e2f6dedf61ce73335b98e980c 100644
--- a/src/cmd/link/internal/ld/macho.go
+++ b/src/cmd/link/internal/ld/macho.go
@@ -479,8 +479,11 @@ if ctxt.LinkMode == LinkInternal && machoPlatform == PLATFORM_MACOS {
var version uint32
switch ctxt.Arch.Family {
case sys.AMD64:
- // The version must be at least 10.9; see golang.org/issues/30488.
- version = 10<<16 | 9<<8 | 0<<0 // 10.9.0
+ // This must be fairly recent for Apple signing (go.dev/issue/30488).
+ // Having too old a version here was also implicated in some problems
+ // calling into macOS libraries (go.dev/issue/56784).
+ // In general this can be the most recent supported macOS version.
+ version = 10<<16 | 13<<8 | 0<<0 // 10.13.0
case sys.ARM64:
version = 11<<16 | 0<<8 | 0<<0 // 11.0.0
}
diff --git a/src/crypto/internal/boring/README.md b/src/crypto/internal/boring/README.md
index ffacd341c824b54294c4b1e80777dada0d3ac4ee..ec02786d96a8450bfae08dc100ecac3282e391dd 100644
--- a/src/crypto/internal/boring/README.md
+++ b/src/crypto/internal/boring/README.md
@@ -1,3 +1,21 @@
+We have been working inside Google on a fork of Go that uses
+BoringCrypto (the core of [BoringSSL](https://boringssl.googlesource.com/boringssl/))
+for various crypto primitives, in furtherance of some work related to FIPS 140.
+We have heard that some external users of Go would be
+interested in this code as well, so we have published this code
+here in the main Go repository behind the setting GOEXPERIMENT=boringcrypto.
+
+Use of GOEXPERIMENT=boringcrypto outside Google is _unsupported_.
+This mode is not part of the [Go 1 compatibility rules](https://go.dev/doc/go1compat),
+and it may change incompatibly or break in other ways at any time.
+
+To be clear, we are not making any statements or representations about
+the suitability of this code in relation to the FIPS 140 standard.
+Interested users will have to evaluate for themselves whether the code
+is useful for their own purposes.
+
+---
+
This directory holds the core of the BoringCrypto implementation
as well as the build scripts for the module itself: syso/*.syso.
@@ -16,4 +34,6 @@ apt-get install qemu-user-static qemu-binfmt-support
to allow the x86 kernel to run arm64 binaries via QEMU.
-See build.sh for more details.
+See build.sh for more details about the build.
+
+
diff --git a/src/crypto/tls/cache.go b/src/crypto/tls/cache.go
index 2bdf2d9a011df9a9ca2972e0909bd3b0557ec67e..fc8f2c08441086942c5455baedb3a1dbbe8e46d9 100644
--- a/src/crypto/tls/cache.go
+++ b/src/crypto/tls/cache.go
@@ -27,7 +27,7 @@ // the caller. When references to the activeCert are freed, the number of references
// to the certificate in the cache is decremented. Once the number of references
// reaches zero, the entry is evicted from the cache.
//
-// The main difference between this implmentation and CRYPTO_BUFFER_POOL is that
+// The main difference between this implementation and CRYPTO_BUFFER_POOL is that
// CRYPTO_BUFFER_POOL is a more generic structure which supports blobs of data,
// rather than specific structures. Since we only care about x509.Certificates,
// certCache is implemented as a specific cache, rather than a generic one.
diff --git a/src/go/types/call.go b/src/go/types/call.go
index 5558244f1beadf8b28a1d7aea418d0b850dbeb2b..db603b5260467cb5289230302e727a4e1f80255d 100644
--- a/src/go/types/call.go
+++ b/src/go/types/call.go
@@ -450,7 +450,7 @@ "_Cfunc_",
"_Cmacro_", // function to evaluate the expanded expression
}
-func (check *Checker) selector(x *operand, e *ast.SelectorExpr, def *Named) {
+func (check *Checker) selector(x *operand, e *ast.SelectorExpr, def *Named, wantType bool) {
// these must be declared before the "goto Error" statements
var (
obj Object
@@ -560,6 +560,25 @@ // types2 uses the position of '.' for the error
check.errorf(e.Sel, UncalledBuiltin, "cannot select on %s", x)
goto Error
case invalid:
+ goto Error
+ }
+
+ // Avoid crashing when checking an invalid selector in a method declaration
+ // (i.e., where def is not set):
+ //
+ // type S[T any] struct{}
+ // type V = S[any]
+ // func (fs *S[T]) M(x V.M) {}
+ //
+ // All codepaths below return a non-type expression. If we get here while
+ // expecting a type expression, it is an error.
+ //
+ // See issue #57522 for more details.
+ //
+ // TODO(rfindley): We should do better by refusing to check selectors in all cases where
+ // x.typ is incomplete.
+ if wantType {
+ check.errorf(e.Sel, NotAType, "%s is not a type", ast.Expr(e))
goto Error
}
diff --git a/src/go/types/expr.go b/src/go/types/expr.go
index e09b461d8c6b9c41abcf05bb9bf1fe84129223e7..aa90145b367e51dc4c69ddba409261b2de1d9696 100644
--- a/src/go/types/expr.go
+++ b/src/go/types/expr.go
@@ -1568,7 +1568,7 @@ x.expr = e
return kind
case *ast.SelectorExpr:
- check.selector(x, e, nil)
+ check.selector(x, e, nil, false)
case *ast.IndexExpr, *ast.IndexListExpr:
ix := typeparams.UnpackIndexExpr(e)
diff --git a/src/go/types/instantiate.go b/src/go/types/instantiate.go
index 59ac1009f51116f9935ce6ba0c9b8102efbb42ac..2cf48c17d298dcc1b39fb95ea634b6afb1e30e86 100644
--- a/src/go/types/instantiate.go
+++ b/src/go/types/instantiate.go
@@ -188,7 +188,7 @@ // is called through an exported API call such as AssignableTo. If constraint
// is set, T is a type constraint.
//
// If the provided cause is non-nil, it may be set to an error string
-// explaining why V does not implement T.
+// explaining why V does not implement (or satisfy, for constraints) T.
func (check *Checker) implements(V, T Type, constraint bool, cause *string) bool {
Vu := under(V)
Tu := under(T)
@@ -199,6 +199,11 @@ if p, _ := Vu.(*Pointer); p != nil && under(p.base) == Typ[Invalid] {
return true // avoid follow-on errors (see issue #49541 for an example)
}
+ verb := "implement"
+ if constraint {
+ verb = "satisfy"
+ }
+
Ti, _ := Tu.(*Interface)
if Ti == nil {
if cause != nil {
@@ -208,7 +213,7 @@ detail = check.sprintf("type %s is pointer to interface, not interface", T)
} else {
detail = check.sprintf("%s is not an interface", T)
}
- *cause = check.sprintf("%s does not implement %s (%s)", V, T, detail)
+ *cause = check.sprintf("%s does not %s %s (%s)", V, verb, T, detail)
}
return false
}
@@ -230,7 +235,7 @@
// No type with non-empty type set satisfies the empty type set.
if Ti.typeSet().IsEmpty() {
if cause != nil {
- *cause = check.sprintf("cannot implement %s (empty type set)", T)
+ *cause = check.sprintf("cannot %s %s (empty type set)", verb, T)
}
return false
}
@@ -238,7 +243,7 @@
// V must implement T's methods, if any.
if m, wrong := check.missingMethod(V, Ti, true); m != nil /* !Implements(V, Ti) */ {
if cause != nil {
- *cause = check.sprintf("%s does not implement %s %s", V, T, check.missingMethodCause(V, T, m, wrong))
+ *cause = check.sprintf("%s does not %s %s %s", V, verb, T, check.missingMethodCause(V, T, m, wrong))
}
return false
}
@@ -258,7 +263,7 @@ // a test), we only consider strict comparability and we're done.
// TODO(gri) remove this check for Go 1.21
if check != nil && check.conf.oldComparableSemantics {
if cause != nil {
- *cause = check.sprintf("%s does not implement comparable", V)
+ *cause = check.sprintf("%s does not %s comparable", V, verb)
}
return false
}
@@ -270,12 +275,12 @@ if check == nil || check.allowVersion(check.pkg, 1, 20) {
return true
}
if cause != nil {
- *cause = check.sprintf("%s to implement comparable requires go1.20 or later", V)
+ *cause = check.sprintf("%s to %s comparable requires go1.20 or later", V, verb)
}
return false
}
if cause != nil {
- *cause = check.sprintf("%s does not implement comparable", V)
+ *cause = check.sprintf("%s does not %s comparable", V, verb)
}
return false
}
@@ -293,7 +298,7 @@ if Vi != nil {
if !Vi.typeSet().subsetOf(Ti.typeSet()) {
// TODO(gri) report which type is missing
if cause != nil {
- *cause = check.sprintf("%s does not implement %s", V, T)
+ *cause = check.sprintf("%s does not %s %s", V, verb, T)
}
return false
}
@@ -319,14 +324,43 @@ }
return false
}) {
if cause != nil {
- if alt != nil {
- *cause = check.sprintf("%s does not implement %s (possibly missing ~ for %s in constraint %s)", V, T, alt, T)
- } else {
- *cause = check.sprintf("%s does not implement %s (%s missing in %s)", V, T, V, Ti.typeSet().terms)
+ var detail string
+ switch {
+ case alt != nil:
+ detail = check.sprintf("possibly missing ~ for %s in %s", alt, T)
+ case mentions(Ti, V):
+ detail = check.sprintf("%s mentions %s, but %s is not in the type set of %s", T, V, V, T)
+ default:
+ detail = check.sprintf("%s missing in %s", V, Ti.typeSet().terms)
}
+ *cause = check.sprintf("%s does not %s %s (%s)", V, verb, T, detail)
}
return false
}
return checkComparability()
}
+
+// mentions reports whether type T "mentions" typ in an (embedded) element or term
+// of T (whether typ is in the type set of T or not). For better error messages.
+func mentions(T, typ Type) bool {
+ switch T := T.(type) {
+ case *Interface:
+ for _, e := range T.embeddeds {
+ if mentions(e, typ) {
+ return true
+ }
+ }
+ case *Union:
+ for _, t := range T.terms {
+ if mentions(t.typ, typ) {
+ return true
+ }
+ }
+ default:
+ if Identical(T, typ) {
+ return true
+ }
+ }
+ return false
+}
diff --git a/src/go/types/typexpr.go b/src/go/types/typexpr.go
index 3d1f0b8bbb0ca2c5bf27504e53b36105e449368c..03817dded19ace430e04a3db12c659583f500c0f 100644
--- a/src/go/types/typexpr.go
+++ b/src/go/types/typexpr.go
@@ -256,7 +256,7 @@ }
case *ast.SelectorExpr:
var x operand
- check.selector(&x, e, def)
+ check.selector(&x, e, def, true)
switch x.mode {
case typexpr:
diff --git a/src/internal/types/testdata/check/cycles0.go b/src/internal/types/testdata/check/cycles0.go
index d4e7e60f832ac08e7971ffffe66e99922fdba8c7..7c00c7d625f81fa42d85c449fe8369929b7dc8b7 100644
--- a/src/internal/types/testdata/check/cycles0.go
+++ b/src/internal/types/testdata/check/cycles0.go
@@ -45,7 +45,7 @@ S6 S4
// pointers
P0 *P0
- PP *struct{ PP.f /* ERROR no field or method f */ }
+ PP *struct{ PP.f /* ERROR PP.f is not a type */ }
// functions
F0 func(F0)
diff --git a/src/internal/types/testdata/check/decls0.go b/src/internal/types/testdata/check/decls0.go
index 6002a9e8a74d8001a92e0870bebc4e5acb39d2ea..868b318a70f59964f9874a26936c322ec7131d1b 100644
--- a/src/internal/types/testdata/check/decls0.go
+++ b/src/internal/types/testdata/check/decls0.go
@@ -63,7 +63,7 @@ )
type (
- p1 pi.foo /* ERROR "no field or method foo" */
+ p1 pi.foo /* ERROR "pi.foo is not a type" */
p2 unsafe.Pointer
)
@@ -189,10 +189,10 @@ func f4() (x *f4 /* ERROR "not a type" */ ) { return }
// TODO(#43215) this should be detected as a cycle error
func f5([unsafe.Sizeof(f5)]int) {}
-func (S0) m1 (x S0 /* ERROR illegal cycle in method declaration */ .m1) {}
-func (S0) m2 (x *S0 /* ERROR illegal cycle in method declaration */ .m2) {}
-func (S0) m3 () (x S0 /* ERROR illegal cycle in method declaration */ .m3) { return }
-func (S0) m4 () (x *S0 /* ERROR illegal cycle in method declaration */ .m4) { return }
+func (S0) m1 (x S0.m1 /* ERROR S0.m1 is not a type */ ) {}
+func (S0) m2 (x *S0.m2 /* ERROR S0.m2 is not a type */ ) {}
+func (S0) m3 () (x S0.m3 /* ERROR S0.m3 is not a type */ ) { return }
+func (S0) m4 () (x *S0.m4 /* ERROR S0.m4 is not a type */ ) { return }
// interfaces may not have any blank methods
type BlankI interface {
diff --git a/src/internal/types/testdata/check/issues0.go b/src/internal/types/testdata/check/issues0.go
index 0cea36c01f126efd709103123eb42f28c646e83b..4a6664136969f9fce3bf79af12dfeced05d2a538 100644
--- a/src/internal/types/testdata/check/issues0.go
+++ b/src/internal/types/testdata/check/issues0.go
@@ -97,7 +97,7 @@ type _ interface {
nosuchpkg /* ERROR undefined: nosuchpkg */ .Nosuchtype
}
type I interface {
- I.m /* ERROR no field or method m */
+ I.m /* ERROR I.m is not a type */
m()
}
}
diff --git a/src/internal/types/testdata/check/issues1.go b/src/internal/types/testdata/check/issues1.go
index 02ad822e0f57eabdcf54bb4f9c70148ec1c208c6..2f3414de61abdb917aa84171ba905a7f346e2c5d 100644
--- a/src/internal/types/testdata/check/issues1.go
+++ b/src/internal/types/testdata/check/issues1.go
@@ -22,7 +22,7 @@ eql(x, y /* ERROR does not match */ ) // interfaces of different types
eql(x, x)
eql(y, y)
eql(y, nil /* ERROR cannot use nil as Y value in argument to eql */ )
- eql[io /* ERROR does not implement comparable */ .Reader](nil, nil)
+ eql[io /* ERROR does not satisfy comparable */ .Reader](nil, nil)
}
// If we have a receiver of pointer to type parameter type (below: *T)
@@ -58,7 +58,7 @@ // parameter's type set.
type T1[P interface{~uint}] struct{}
func _[P any]() {
- _ = T1[P /* ERROR P does not implement interface{~uint} */ ]{}
+ _ = T1[P /* ERROR P does not satisfy interface{~uint} */ ]{}
}
// This is the original (simplified) program causing the same issue.
@@ -74,8 +74,8 @@ func (u T2[U]) Add1() U {
return u.s + 1
}
-func NewT2[U any]() T2[U /* ERROR U does not implement Unsigned */ ] {
- return T2[U /* ERROR U does not implement Unsigned */ ]{}
+func NewT2[U any]() T2[U /* ERROR U does not satisfy Unsigned */ ] {
+ return T2[U /* ERROR U does not satisfy Unsigned */ ]{}
}
func _() {
diff --git a/src/internal/types/testdata/check/typeinst1.go b/src/internal/types/testdata/check/typeinst1.go
index e7b4539ff33ceda951392330f06042524b859f14..e7bb2479411a9c1fa772618a4a3877bd7e2f0134 100644
--- a/src/internal/types/testdata/check/typeinst1.go
+++ b/src/internal/types/testdata/check/typeinst1.go
@@ -210,7 +210,7 @@ func f0[T I0]() {}
var _ = f0[int]
var _ = f0[bool]
var _ = f0[string]
-var _ = f0[float64 /* ERROR does not implement I0 */ ]
+var _ = f0[float64 /* ERROR does not satisfy I0 */ ]
type I01 interface {
E0
@@ -219,9 +219,9 @@ }
func f01[T I01]() {}
var _ = f01[int]
-var _ = f01[bool /* ERROR does not implement I0 */ ]
+var _ = f01[bool /* ERROR does not satisfy I0 */ ]
var _ = f01[string]
-var _ = f01[float64 /* ERROR does not implement I0 */ ]
+var _ = f01[float64 /* ERROR does not satisfy I0 */ ]
type I012 interface {
E0
@@ -230,10 +230,10 @@ E2
}
func f012[T I012]() {}
-var _ = f012[int /* ERROR cannot implement I012.*empty type set */ ]
-var _ = f012[bool /* ERROR cannot implement I012.*empty type set */ ]
-var _ = f012[string /* ERROR cannot implement I012.*empty type set */ ]
-var _ = f012[float64 /* ERROR cannot implement I012.*empty type set */ ]
+var _ = f012[int /* ERROR cannot satisfy I012.*empty type set */ ]
+var _ = f012[bool /* ERROR cannot satisfy I012.*empty type set */ ]
+var _ = f012[string /* ERROR cannot satisfy I012.*empty type set */ ]
+var _ = f012[float64 /* ERROR cannot satisfy I012.*empty type set */ ]
type I12 interface {
E1
@@ -241,9 +241,9 @@ E2
}
func f12[T I12]() {}
-var _ = f12[int /* ERROR does not implement I12 */ ]
-var _ = f12[bool /* ERROR does not implement I12 */ ]
-var _ = f12[string /* ERROR does not implement I12 */ ]
+var _ = f12[int /* ERROR does not satisfy I12 */ ]
+var _ = f12[bool /* ERROR does not satisfy I12 */ ]
+var _ = f12[string /* ERROR does not satisfy I12 */ ]
var _ = f12[float64]
type I0_ interface {
@@ -253,9 +253,9 @@ }
func f0_[T I0_]() {}
var _ = f0_[int]
-var _ = f0_[bool /* ERROR does not implement I0_ */ ]
-var _ = f0_[string /* ERROR does not implement I0_ */ ]
-var _ = f0_[float64 /* ERROR does not implement I0_ */ ]
+var _ = f0_[bool /* ERROR does not satisfy I0_ */ ]
+var _ = f0_[string /* ERROR does not satisfy I0_ */ ]
+var _ = f0_[float64 /* ERROR does not satisfy I0_ */ ]
// Using a function instance as a type is an error.
var _ f0 // ERROR not a type
@@ -273,7 +273,7 @@ func gg[T any]() {}
func hh[T ~int]() {}
func _[T none]() {
- _ = ff[int /* ERROR cannot implement none \(empty type set\) */ ]
+ _ = ff[int /* ERROR cannot satisfy none \(empty type set\) */ ]
_ = ff[T] // pathological but ok because T's type set is empty, too
_ = gg[int]
_ = gg[T]
diff --git a/src/internal/types/testdata/examples/inference.go b/src/internal/types/testdata/examples/inference.go
index 23a3d81f3deb207bae719659014e0e8e00f0c7d3..073df9ce3bbaf5ec25105a4c2447621861bec9a1 100644
--- a/src/internal/types/testdata/examples/inference.go
+++ b/src/internal/types/testdata/examples/inference.go
@@ -97,7 +97,7 @@ // type inference. Untyped arguments are always considered
// last.
related2(1.2, []float64{})
related2(1.0, []int{})
- related2 /* ERROR does not implement */ (float64(1.0), []int{}) // TODO(gri) fix error position
+ related2 /* ERROR does not satisfy */ (float64(1.0), []int{}) // TODO(gri) fix error position
}
type List[P any] []P
diff --git a/src/internal/types/testdata/fixedbugs/issue39634.go b/src/internal/types/testdata/fixedbugs/issue39634.go
index 7b458f22f28720ee50f199033e1ce512e657a593..6ee15489c5d23566b47ea470fb89d16647952a16 100644
--- a/src/internal/types/testdata/fixedbugs/issue39634.go
+++ b/src/internal/types/testdata/fixedbugs/issue39634.go
@@ -19,7 +19,7 @@ // type Numeric2 interface{t2 /* ERROR not a type */ }
// func t2[T Numeric2](s[]T){0 /* ERROR not a type */ []{s /* ERROR cannot index */ [0][0]}}
// crash 3
-type t3 *interface{ t3.p /* ERROR no field or method p */ }
+type t3 *interface{ t3.p /* ERROR t3.p is not a type */ }
// crash 4
type Numeric4 interface{t4 /* ERROR not a type */ }
diff --git a/src/internal/types/testdata/fixedbugs/issue39754.go b/src/internal/types/testdata/fixedbugs/issue39754.go
index 9edd239d7d97c2e3e00bd6031327f180939494b0..97365e2ddde66f6a36a066a34db9f6ec0e1a7b4c 100644
--- a/src/internal/types/testdata/fixedbugs/issue39754.go
+++ b/src/internal/types/testdata/fixedbugs/issue39754.go
@@ -16,6 +16,6 @@ func f[V interface{}, A, B Box[V]]() {}
func _() {
f[int, Optional[int], Optional[int]]()
- _ = f[int, Optional[int], Optional /* ERROR does not implement Box */ [string]]
- _ = f[int, Optional[int], Optional /* ERROR Optional.* does not implement Box.* */ [string]]
+ _ = f[int, Optional[int], Optional /* ERROR does not satisfy Box */ [string]]
+ _ = f[int, Optional[int], Optional /* ERROR Optional.* does not satisfy Box.* */ [string]]
}
diff --git a/src/internal/types/testdata/fixedbugs/issue40350.go b/src/internal/types/testdata/fixedbugs/issue40350.go
index 7ffd551c2e178f56161a33226924e0279d9064d8..08eb42641085197d483d081d31ce638214713fc6 100644
--- a/src/internal/types/testdata/fixedbugs/issue40350.go
+++ b/src/internal/types/testdata/fixedbugs/issue40350.go
@@ -12,5 +12,5 @@
func f[T number]() {}
func _() {
- _ = f[int /* ERROR int does not implement number \(int missing in float64 | ~int32\)*/]
+ _ = f[int /* ERROR int does not satisfy number \(number mentions int, but int is not in the type set of number\)*/]
}
diff --git a/src/internal/types/testdata/fixedbugs/issue45920.go b/src/internal/types/testdata/fixedbugs/issue45920.go
index d67dfc0f9d17868875f52c59441b5ac6492881e3..0a281c5484b246dbb9bd47497a256bf3eb529e88 100644
--- a/src/internal/types/testdata/fixedbugs/issue45920.go
+++ b/src/internal/types/testdata/fixedbugs/issue45920.go
@@ -8,10 +8,10 @@ func f1[T any, C chan T | <-chan T](ch C) {}
func _(ch chan int) { f1(ch) }
func _(ch <-chan int) { f1(ch) }
-func _(ch chan<- int) { f1 /* ERROR chan<- int does not implement chan int \| <-chan int */ (ch) }
+func _(ch chan<- int) { f1 /* ERROR chan<- int does not satisfy chan int \| <-chan int */ (ch) }
func f2[T any, C chan T | chan<- T](ch C) {}
func _(ch chan int) { f2(ch) }
-func _(ch <-chan int) { f2 /* ERROR <-chan int does not implement chan int \| chan<- int */ (ch) }
+func _(ch <-chan int) { f2 /* ERROR <-chan int does not satisfy chan int \| chan<- int */ (ch) }
func _(ch chan<- int) { f2(ch) }
diff --git a/src/internal/types/testdata/fixedbugs/issue47411.go b/src/internal/types/testdata/fixedbugs/issue47411.go
index 12303072edf97deaa90f0d754504e178c2e01b6d..33b169a39ebbfb5cd68e40da947a41d365ea9456 100644
--- a/src/internal/types/testdata/fixedbugs/issue47411.go
+++ b/src/internal/types/testdata/fixedbugs/issue47411.go
@@ -15,12 +15,12 @@ ]() {
_ = f[int]
_ = f[P]
_ = f[Q]
- _ = f[func /* ERROR does not implement comparable */ ()]
- _ = f[R /* ERROR R does not implement comparable */ ]
+ _ = f[func /* ERROR does not satisfy comparable */ ()]
+ _ = f[R /* ERROR R does not satisfy comparable */ ]
_ = g[int]
- _ = g[P /* ERROR P does not implement interface{interface{comparable; ~int \| ~string} */ ]
+ _ = g[P /* ERROR P does not satisfy interface{interface{comparable; ~int \| ~string} */ ]
_ = g[Q]
- _ = g[func /* ERROR func\(\) does not implement interface{interface{comparable; ~int \| ~string}} */ ()]
- _ = g[R /* ERROR R does not implement interface{interface{comparable; ~int \| ~string} */ ]
+ _ = g[func /* ERROR func\(\) does not satisfy interface{interface{comparable; ~int \| ~string}} */ ()]
+ _ = g[R /* ERROR R does not satisfy interface{interface{comparable; ~int \| ~string} */ ]
}
diff --git a/src/internal/types/testdata/fixedbugs/issue49112.go b/src/internal/types/testdata/fixedbugs/issue49112.go
index 61b757ccb2f631bbbb15cbe3bbff050904e2b156..dea26082194ad3f592224b6bff39c0f2b7d891f9 100644
--- a/src/internal/types/testdata/fixedbugs/issue49112.go
+++ b/src/internal/types/testdata/fixedbugs/issue49112.go
@@ -8,8 +8,8 @@ func f[P int](P) {}
func _() {
_ = f[int]
- _ = f[[ /* ERROR \[\]int does not implement int */ ]int]
+ _ = f[[ /* ERROR \[\]int does not satisfy int */ ]int]
f(0)
- f/* ERROR \[\]int does not implement int */ ([]int{})
+ f/* ERROR \[\]int does not satisfy int */ ([]int{})
}
diff --git a/src/internal/types/testdata/fixedbugs/issue49179.go b/src/internal/types/testdata/fixedbugs/issue49179.go
index 8890e92f510f5361e905702e0f125acaf9e2b70c..2ddfa3312d27733b8924cb567bbc08ceed96a74f 100644
--- a/src/internal/types/testdata/fixedbugs/issue49179.go
+++ b/src/internal/types/testdata/fixedbugs/issue49179.go
@@ -13,11 +13,11 @@ type myFloat float64
func _() {
_ = f1[int]
- _ = f1[myInt /* ERROR possibly missing ~ for int in constraint int \| string */]
+ _ = f1[myInt /* ERROR possibly missing ~ for int in int \| string */]
_ = f2[myInt]
- _ = f2[myFloat /* ERROR possibly missing ~ for float64 in constraint ~int \| string \| float64 */]
+ _ = f2[myFloat /* ERROR possibly missing ~ for float64 in ~int \| string \| float64 */]
var x myInt
- f3 /* ERROR myInt does not implement int \(possibly missing ~ for int in constraint int\) */ (x)
+ f3 /* ERROR myInt does not satisfy int \(possibly missing ~ for int in int\) */ (x)
}
// test case from the issue
@@ -33,5 +33,5 @@
type MySlice []int
func f(s MySlice) {
- Map[MySlice /* ERROR MySlice does not implement SliceConstraint\[int\] \(possibly missing ~ for \[\]int in constraint SliceConstraint\[int\]\) */, int](s, nil)
+ Map[MySlice /* ERROR MySlice does not satisfy SliceConstraint\[int\] \(possibly missing ~ for \[\]int in SliceConstraint\[int\]\) */, int](s, nil)
}
diff --git a/src/internal/types/testdata/fixedbugs/issue49739.go b/src/internal/types/testdata/fixedbugs/issue49739.go
index 46b1e71a3b95cfb43cfd760524c89d4054738b9c..7feb5637dcaf624653d67446471a500e9188a01b 100644
--- a/src/internal/types/testdata/fixedbugs/issue49739.go
+++ b/src/internal/types/testdata/fixedbugs/issue49739.go
@@ -17,7 +17,7 @@ func g[_ interface{ C }]() {}
func h[_ C | int]() {}
func _() {
- _ = f[int /* ERROR cannot implement C \(empty type set\) */]
- _ = g[int /* ERROR cannot implement interface{C} \(empty type set\) */]
+ _ = f[int /* ERROR cannot satisfy C \(empty type set\) */]
+ _ = g[int /* ERROR cannot satisfy interface{C} \(empty type set\) */]
_ = h[int]
}
diff --git a/src/internal/types/testdata/fixedbugs/issue50417.go b/src/internal/types/testdata/fixedbugs/issue50417.go
index 2caef1b9863e65fabccec6eeb9b8d6108599710e..69ebf31b16feeba58469b1baea824a5c5b09356d 100644
--- a/src/internal/types/testdata/fixedbugs/issue50417.go
+++ b/src/internal/types/testdata/fixedbugs/issue50417.go
@@ -25,8 +25,8 @@
var _ = f0[Sf]
var _ = f0t[Sf]
-var _ = f0[Sm /* ERROR does not implement */ ]
-var _ = f0t[Sm /* ERROR does not implement */ ]
+var _ = f0[Sm /* ERROR does not satisfy */ ]
+var _ = f0t[Sm /* ERROR does not satisfy */ ]
func f1[P interface{ Sf; m() }](p P) {
_ = p.f // ERROR p\.f undefined
@@ -35,7 +35,7 @@ p.m()
}
var _ = f1[Sf /* ERROR missing method m */ ]
-var _ = f1[Sm /* ERROR does not implement */ ]
+var _ = f1[Sm /* ERROR does not satisfy */ ]
type Sm struct {}
diff --git a/src/internal/types/testdata/fixedbugs/issue50646.go b/src/internal/types/testdata/fixedbugs/issue50646.go
index bc53700704b98278077cca7cd8d1884dcf6ac516..ed7261c6b84004091c64e52b17b97c86486654b0 100644
--- a/src/internal/types/testdata/fixedbugs/issue50646.go
+++ b/src/internal/types/testdata/fixedbugs/issue50646.go
@@ -13,16 +13,16 @@ type T interface{ m() }
func _[P comparable, Q ~int, R any]() {
_ = f1[int]
- _ = f1[T /* ERROR T does not implement comparable */ ]
- _ = f1[any /* ERROR any does not implement comparable */ ]
+ _ = f1[T /* ERROR T does not satisfy comparable */ ]
+ _ = f1[any /* ERROR any does not satisfy comparable */ ]
_ = f1[P]
_ = f1[Q]
- _ = f1[R /* ERROR R does not implement comparable */]
+ _ = f1[R /* ERROR R does not satisfy comparable */]
_ = f2[int]
- _ = f2[T /* ERROR T does not implement comparable */ ]
- _ = f2[any /* ERROR any does not implement comparable */ ]
+ _ = f2[T /* ERROR T does not satisfy comparable */ ]
+ _ = f2[any /* ERROR any does not satisfy comparable */ ]
_ = f2[P]
_ = f2[Q]
- _ = f2[R /* ERROR R does not implement comparable */]
+ _ = f2[R /* ERROR R does not satisfy comparable */]
}
diff --git a/src/internal/types/testdata/fixedbugs/issue50782.go b/src/internal/types/testdata/fixedbugs/issue50782.go
index fd1ab11b8cf120ba3870b7add36b317a13064b69..0e7b712a097150fe0596ccf11b8c25c6b4e073ad 100644
--- a/src/internal/types/testdata/fixedbugs/issue50782.go
+++ b/src/internal/types/testdata/fixedbugs/issue50782.go
@@ -21,7 +21,7 @@ }
// AbsDifference computes the absolute value of the difference of
// a and b, where the absolute value is determined by the Abs method.
-func absDifference[T numericAbs[T /* ERROR T does not implement Numeric */]](a, b T) T {
+func absDifference[T numericAbs[T /* ERROR T does not satisfy Numeric */]](a, b T) T {
// Field accesses are not permitted for now. Keep an error so
// we can find and fix this code once the situation changes.
return a.Value // ERROR a\.Value undefined
@@ -33,15 +33,15 @@
// The second example from the issue.
type T[P int] struct{ f P }
-func _[P T[P /* ERROR "P does not implement int" */ ]]() {}
+func _[P T[P /* ERROR "P does not satisfy int" */ ]]() {}
// Additional tests
-func _[P T[T /* ERROR "T\[P\] does not implement int" */ [P /* ERROR "P does not implement int" */ ]]]() {}
-func _[P T[Q /* ERROR "Q does not implement int" */ ], Q T[P /* ERROR "P does not implement int" */ ]]() {}
+func _[P T[T /* ERROR "T\[P\] does not satisfy int" */ [P /* ERROR "P does not satisfy int" */ ]]]() {}
+func _[P T[Q /* ERROR "Q does not satisfy int" */ ], Q T[P /* ERROR "P does not satisfy int" */ ]]() {}
func _[P T[Q], Q int]() {}
type C[P comparable] struct{ f P }
func _[P C[C[P]]]() {}
-func _[P C[C /* ERROR "C\[Q\] does not implement comparable" */ [Q /* ERROR "Q does not implement comparable" */]], Q func()]() {}
+func _[P C[C /* ERROR "C\[Q\] does not satisfy comparable" */ [Q /* ERROR "Q does not satisfy comparable" */]], Q func()]() {}
func _[P [10]C[P]]() {}
func _[P struct{ f C[C[P]]}]() {}
diff --git a/src/internal/types/testdata/fixedbugs/issue51257.go b/src/internal/types/testdata/fixedbugs/issue51257.go
index 4730c98e2f0c509eddd10e77482136d540130119..be4b81fee7968c5b727aa79b7e40ab75a2d340c7 100644
--- a/src/internal/types/testdata/fixedbugs/issue51257.go
+++ b/src/internal/types/testdata/fixedbugs/issue51257.go
@@ -14,13 +14,13 @@ type S3 struct{ x [10]interface{ m() } }
func _[P1 comparable, P2 S2]() {
_ = f[S1]
- _ = f[S2 /* ERROR S2 does not implement comparable */ ]
- _ = f[S3 /* ERROR S3 does not implement comparable */ ]
+ _ = f[S2 /* ERROR S2 does not satisfy comparable */ ]
+ _ = f[S3 /* ERROR S3 does not satisfy comparable */ ]
type L1 struct { x P1 }
type L2 struct { x P2 }
_ = f[L1]
- _ = f[L2 /* ERROR L2 does not implement comparable */ ]
+ _ = f[L2 /* ERROR L2 does not satisfy comparable */ ]
}
@@ -41,7 +41,7 @@
type T struct{ x any }
func main() {
- NewSetFromSlice /* ERROR T does not implement comparable */ ([]T{
+ NewSetFromSlice /* ERROR T does not satisfy comparable */ ([]T{
{"foo"},
{5},
})
diff --git a/src/internal/types/testdata/fixedbugs/issue51376.go b/src/internal/types/testdata/fixedbugs/issue51376.go
index d51607b7abb5fc2f67045e5618a42020bc250293..3801d6883ccbb2234e448f1e8adc83f0ef441c89 100644
--- a/src/internal/types/testdata/fixedbugs/issue51376.go
+++ b/src/internal/types/testdata/fixedbugs/issue51376.go
@@ -12,7 +12,7 @@
func _[M1 ~map[K]V, M2 map[K]V, K comparable, V any]() {
var m1 M1
f(m1)
- g /* ERROR M1 does not implement map\[K\]V */ (m1) // M1 has tilde
+ g /* ERROR M1 does not satisfy map\[K\]V */ (m1) // M1 has tilde
var m2 M2
f(m2)
@@ -20,5 +20,5 @@ g(m2) // M1 does not have tilde
var m3 Map
f(m3)
- g /* ERROR Map does not implement map\[string\]int */ (m3) // M in g does not have tilde
+ g /* ERROR Map does not satisfy map\[string\]int */ (m3) // M in g does not have tilde
}
diff --git a/src/internal/types/testdata/fixedbugs/issue51472.go b/src/internal/types/testdata/fixedbugs/issue51472.go
index 52ae09dad789c49be32d38343fc23faf81ac272b..a0f9e9c025a88d6d7551eb3aa64b9af3937f4cc9 100644
--- a/src/internal/types/testdata/fixedbugs/issue51472.go
+++ b/src/internal/types/testdata/fixedbugs/issue51472.go
@@ -49,6 +49,6 @@ _ = x == x
}
func _(s []byte) {
- f /* ERROR \[\]byte does not implement interface{comparable; \[\]byte \| string} */ (s)
- _ = f[[ /* ERROR does not implement */ ]byte]
+ f /* ERROR \[\]byte does not satisfy interface{comparable; \[\]byte \| string} */ (s)
+ _ = f[[ /* ERROR does not satisfy */ ]byte]
}
diff --git a/src/internal/types/testdata/fixedbugs/issue57486.go b/src/internal/types/testdata/fixedbugs/issue57486.go
index ff9e3d1db5611699afdb468c7a6deaf85720e89a..43ba1b044009968f344f8e93d1782cd31276b2f5 100644
--- a/src/internal/types/testdata/fixedbugs/issue57486.go
+++ b/src/internal/types/testdata/fixedbugs/issue57486.go
@@ -17,13 +17,13 @@ func G1[T C1](t T) { _ = t == t }
func G2[T C2](t T) { _ = t == t }
func F1[V [2]any](v V) {
- _ = G1[V /* ERROR "V does not implement comparable" */]
+ _ = G1[V /* ERROR "V does not satisfy comparable" */]
_ = G1[[2]any]
_ = G1[int]
}
func F2[V [2]any](v V) {
- _ = G2[V /* ERROR "V does not implement C2" */]
- _ = G2[[ /* ERROR "\[2\]any does not implement C2 \(\[2\]any missing in int\)" */ 2]any]
+ _ = G2[V /* ERROR "V does not satisfy C2" */]
+ _ = G2[[ /* ERROR "\[2\]any does not satisfy C2 \(C2 mentions \[2\]any, but \[2\]any is not in the type set of C2\)" */ 2]any]
_ = G2[int]
}
diff --git a/src/internal/types/testdata/fixedbugs/issue57500.go b/src/internal/types/testdata/fixedbugs/issue57500.go
new file mode 100644
index 0000000000000000000000000000000000000000..abdcb5ea35cb816c60f4e9045b8b8ad1a04e25eb
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue57500.go
@@ -0,0 +1,16 @@
+// Copyright 2023 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 p
+
+type C interface {
+ comparable
+ [2]any | int
+}
+
+func f[T C]() {}
+
+func _() {
+ _ = f[[ /* ERROR \[2\]any does not satisfy C \(C mentions \[2\]any, but \[2\]any is not in the type set of C\) */ 2]any]
+}
diff --git a/src/internal/types/testdata/fixedbugs/issue57522.go b/src/internal/types/testdata/fixedbugs/issue57522.go
new file mode 100644
index 0000000000000000000000000000000000000000..d83e5b2443e1aa14fa99911606f4836d179f3ce5
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue57522.go
@@ -0,0 +1,24 @@
+// Copyright 2023 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 p
+
+// A simplified version of the code in the original report.
+type S[T any] struct{}
+var V = S[any]{}
+func (fs *S[T]) M(V.M /* ERROR "V.M is not a type" */) {}
+
+// Other minimal reproducers.
+type S1[T any] V1.M /* ERROR "V1.M is not a type" */
+type V1 = S1[any]
+
+type S2[T any] struct{}
+type V2 = S2[any]
+func (fs *S2[T]) M(x V2.M /* ERROR "V2.M is not a type" */ ) {}
+
+// The following still panics, as the selector is reached from check.expr
+// rather than check.typexpr. TODO(rfindley): fix this.
+// type X[T any] int
+// func (X[T]) M(x [X[int].M]int) {}
+
diff --git a/src/internal/types/testdata/spec/comparable.go b/src/internal/types/testdata/spec/comparable.go
index 03c8471393b014af22cbd58fc7ca6aa193b7bc3a..f407c356d39dc14206365a4f10e26d503f1338cb 100644
--- a/src/internal/types/testdata/spec/comparable.go
+++ b/src/internal/types/testdata/spec/comparable.go
@@ -11,16 +11,16 @@ type T interface{ m() }
func _[P comparable, Q ~int, R any]() {
_ = f1[int]
- _ = f1[T /* T does implement comparable */]
- _ = f1[any /* any does implement comparable */]
+ _ = f1[T /* T does satisfy comparable */]
+ _ = f1[any /* any does satisfy comparable */]
_ = f1[P]
_ = f1[Q]
- _ = f1[R /* ERROR R does not implement comparable */]
+ _ = f1[R /* ERROR R does not satisfy comparable */]
_ = f2[int]
- _ = f2[T /* T does implement comparable */]
- _ = f2[any /* any does implement comparable */]
+ _ = f2[T /* T does satisfy comparable */]
+ _ = f2[any /* any does satisfy comparable */]
_ = f2[P]
_ = f2[Q]
- _ = f2[R /* ERROR R does not implement comparable */]
+ _ = f2[R /* ERROR R does not satisfy comparable */]
}
diff --git a/src/internal/types/testdata/spec/comparable1.19.go b/src/internal/types/testdata/spec/comparable1.19.go
index c9c87e4f77ba8b907cd6ea173a301c7236b1f9ab..dc1c5fa0299de500a0aaf3479d25c1bcca22a86d 100644
--- a/src/internal/types/testdata/spec/comparable1.19.go
+++ b/src/internal/types/testdata/spec/comparable1.19.go
@@ -13,16 +13,16 @@ type T interface{ m() }
func _[P comparable, Q ~int, R any]() {
_ = f1[int]
- _ = f1[T /* ERROR T to implement comparable requires go1\.20 or later */]
- _ = f1[any /* ERROR any to implement comparable requires go1\.20 or later */]
+ _ = f1[T /* ERROR T to satisfy comparable requires go1\.20 or later */]
+ _ = f1[any /* ERROR any to satisfy comparable requires go1\.20 or later */]
_ = f1[P]
_ = f1[Q]
- _ = f1[R /* ERROR R does not implement comparable */]
+ _ = f1[R /* ERROR R does not satisfy comparable */]
_ = f2[int]
- _ = f2[T /* ERROR T to implement comparable requires go1\.20 or later */]
- _ = f2[any /* ERROR any to implement comparable requires go1\.20 or later */]
+ _ = f2[T /* ERROR T to satisfy comparable requires go1\.20 or later */]
+ _ = f2[any /* ERROR any to satisfy comparable requires go1\.20 or later */]
_ = f2[P]
_ = f2[Q]
- _ = f2[R /* ERROR R does not implement comparable */]
+ _ = f2[R /* ERROR R does not satisfy comparable */]
}
diff --git a/src/internal/types/testdata/spec/oldcomparable.go b/src/internal/types/testdata/spec/oldcomparable.go
index 9f6cf749f02ae803fc8df0ae51446fe835aabe0b..081d972ab054ecaf4b821c8b0eb2af9b69fe0c49 100644
--- a/src/internal/types/testdata/spec/oldcomparable.go
+++ b/src/internal/types/testdata/spec/oldcomparable.go
@@ -13,16 +13,16 @@ type T interface{ m() }
func _[P comparable, Q ~int, R any]() {
_ = f1[int]
- _ = f1[T /* ERROR T does not implement comparable */]
- _ = f1[any /* ERROR any does not implement comparable */]
+ _ = f1[T /* ERROR T does not satisfy comparable */]
+ _ = f1[any /* ERROR any does not satisfy comparable */]
_ = f1[P]
_ = f1[Q]
- _ = f1[R /* ERROR R does not implement comparable */]
+ _ = f1[R /* ERROR R does not satisfy comparable */]
_ = f2[int]
- _ = f2[T /* ERROR T does not implement comparable */]
- _ = f2[any /* ERROR any does not implement comparable */]
+ _ = f2[T /* ERROR T does not satisfy comparable */]
+ _ = f2[any /* ERROR any does not satisfy comparable */]
_ = f2[P]
_ = f2[Q]
- _ = f2[R /* ERROR R does not implement comparable */]
+ _ = f2[R /* ERROR R does not satisfy comparable */]
}
diff --git a/src/net/hosts.go b/src/net/hosts.go
index 7c8642c6ac58bacf94be476d10272a33d7d5a32e..dbf8fea136d7731c7daaff0fa5c7130ce346bdee 100644
--- a/src/net/hosts.go
+++ b/src/net/hosts.go
@@ -125,7 +125,7 @@ hosts.size = size
file.close()
}
-// lookupStaticHost looks up the addresses and the cannonical name for the given host from /etc/hosts.
+// lookupStaticHost looks up the addresses and the canonical name for the given host from /etc/hosts.
func lookupStaticHost(host string) ([]string, string) {
hosts.Lock()
defer hosts.Unlock()
diff --git a/src/os/exec/exec_test.go b/src/os/exec/exec_test.go
index edff9a201ef2e085a13db4826b78170e242ea8e3..67e2d256b450276317d0dd82bf1c89e20620ed4c 100644
--- a/src/os/exec/exec_test.go
+++ b/src/os/exec/exec_test.go
@@ -1182,6 +1182,7 @@ cmd.Wait()
os.Exit(1)
}
fmt.Fprintf(os.Stderr, "%d: started %d: %v\n", pid, cmd.Process.Pid, cmd)
+ go cmd.Wait() // Release resources if cmd happens not to outlive this process.
}
if *exitOnInterrupt {
diff --git a/src/runtime/crash_cgo_test.go b/src/runtime/crash_cgo_test.go
index ba0e9f4ceda7c4b8a00860cf06c40ad7cace53cf..51d7bb50915d8e257496e33e1838c5830927ff33 100644
--- a/src/runtime/crash_cgo_test.go
+++ b/src/runtime/crash_cgo_test.go
@@ -218,7 +218,9 @@ }
}
func TestCgoPprofCallback(t *testing.T) {
- t.Parallel()
+ if testing.Short() {
+ t.Skip("skipping in short mode") // takes a full second
+ }
switch runtime.GOOS {
case "windows", "plan9":
t.Skipf("skipping cgo pprof callback test on %s", runtime.GOOS)
diff --git a/src/runtime/mpagecache.go b/src/runtime/mpagecache.go
index 5bad4f789a11982659da1d894509f312859f8faa..5bc9c84408db525e107d274864362635f4e2f162 100644
--- a/src/runtime/mpagecache.go
+++ b/src/runtime/mpagecache.go
@@ -21,8 +21,7 @@ cache uint64 // 64-bit bitmap representing free pages (1 means free)
scav uint64 // 64-bit bitmap representing scavenged pages (1 means scavenged)
}
-// empty returns true if the pageCache has any free pages, and false
-// otherwise.
+// empty reports whether the page cache has no free pages.
func (c *pageCache) empty() bool {
return c.cache == 0
}
diff --git a/src/runtime/os_darwin.go b/src/runtime/os_darwin.go
index af5c18c30195c1b70c4aa173c79972b709d34789..c4f3bb6a818585ca78284c39cc4011fbeaabe141 100644
--- a/src/runtime/os_darwin.go
+++ b/src/runtime/os_darwin.go
@@ -136,6 +136,8 @@ // can look at the environment first.
ncpu = getncpu()
physPageSize = getPageSize()
+
+ osinit_hack()
}
func sysctlbynameInt32(name []byte) (int32, int32) {
diff --git a/src/runtime/pprof/pprof_test.go b/src/runtime/pprof/pprof_test.go
index 39bc9d11f1e4e90cfd8dff0e5626df78fe6bfacf..53688ad825b514d7aac1a4a659dc0b4f573ca502 100644
--- a/src/runtime/pprof/pprof_test.go
+++ b/src/runtime/pprof/pprof_test.go
@@ -607,7 +607,7 @@
var total uintptr
for i, name := range need {
total += have[i]
- t.Logf("%s: %d\n", name, have[i])
+ t.Logf("found %d samples in expected function %s\n", have[i], name)
}
if total == 0 {
t.Logf("no samples in expected functions")
@@ -727,6 +727,9 @@ }
}
func fprintStack(w io.Writer, stk []*profile.Location) {
+ if len(stk) == 0 {
+ fmt.Fprintf(w, " (stack empty)")
+ }
for _, loc := range stk {
fmt.Fprintf(w, " %#x", loc.Address)
fmt.Fprintf(w, " (")
@@ -1867,14 +1870,14 @@ for _, s := range p.Sample {
isLabeled := s.Label != nil && contains(s.Label["key"], "value")
var (
mayBeLabeled bool
- mustBeLabeled bool
- mustNotBeLabeled bool
+ mustBeLabeled string
+ mustNotBeLabeled string
)
for _, loc := range s.Location {
for _, l := range loc.Line {
switch l.Function.Name {
case "runtime/pprof.labelHog", "runtime/pprof.parallelLabelHog", "runtime/pprof.parallelLabelHog.func1":
- mustBeLabeled = true
+ mustBeLabeled = l.Function.Name
case "runtime/pprof.Do":
// Do sets the labels, so samples may
// or may not be labeled depending on
@@ -1886,7 +1889,7 @@ // Runtime system goroutines or threads
// (such as those identified by
// runtime.isSystemGoroutine). These
// should never be labeled.
- mustNotBeLabeled = true
+ mustNotBeLabeled = l.Function.Name
case "gogo", "gosave_systemstack_switch", "racecall":
// These are context switch/race
// critical that we can't do a full
@@ -1908,25 +1911,28 @@ mayBeLabeled = true
}
}
}
- if mustNotBeLabeled {
- // If this must not be labeled, then mayBeLabeled hints
- // are not relevant.
+ errorStack := func(f string, args ...any) {
+ var buf strings.Builder
+ fprintStack(&buf, s.Location)
+ t.Errorf("%s: %s", fmt.Sprintf(f, args...), buf.String())
+ }
+ if mustBeLabeled != "" && mustNotBeLabeled != "" {
+ errorStack("sample contains both %s, which must be labeled, and %s, which must not be labeled", mustBeLabeled, mustNotBeLabeled)
+ continue
+ }
+ if mustBeLabeled != "" || mustNotBeLabeled != "" {
+ // We found a definitive frame, so mayBeLabeled hints are not relevant.
mayBeLabeled = false
}
- if mustBeLabeled && !isLabeled {
- var buf strings.Builder
- fprintStack(&buf, s.Location)
- t.Errorf("Sample labeled got false want true: %s", buf.String())
+ if mayBeLabeled {
+ // This sample may or may not be labeled, so there's nothing we can check.
+ continue
}
- if mustNotBeLabeled && isLabeled {
- var buf strings.Builder
- fprintStack(&buf, s.Location)
- t.Errorf("Sample labeled got true want false: %s", buf.String())
+ if mustBeLabeled != "" && !isLabeled {
+ errorStack("sample must be labeled because of %s, but is not", mustBeLabeled)
}
- if isLabeled && !(mayBeLabeled || mustBeLabeled) {
- var buf strings.Builder
- fprintStack(&buf, s.Location)
- t.Errorf("Sample labeled got true want false: %s", buf.String())
+ if mustNotBeLabeled != "" && isLabeled {
+ errorStack("sample must not be labeled because of %s, but is", mustNotBeLabeled)
}
}
}
diff --git a/src/runtime/pprof/proto.go b/src/runtime/pprof/proto.go
index 8a49e144b995bdd0c40ab5051088a094a8d63d56..b68f30d923162c64fdb2d425c6a2ca7ddac55383 100644
--- a/src/runtime/pprof/proto.go
+++ b/src/runtime/pprof/proto.go
@@ -395,6 +395,10 @@ // appendLocsForStack appends the location IDs for the given stack trace to the given
// location ID slice, locs. The addresses in the stack are return PCs or 1 + the PC of
// an inline marker as the runtime traceback function returns.
//
+// It may return an empty slice even if locs is non-empty, for example if locs consists
+// solely of runtime.goexit. We still count these empty stacks in profiles in order to
+// get the right cumulative sample count.
+//
// It may emit to b.pb, so there must be no message encoding in progress.
func (b *profileBuilder) appendLocsForStack(locs []uint64, stk []uintptr) (newLocs []uint64) {
b.deck.reset()
diff --git a/src/runtime/sys_darwin.go b/src/runtime/sys_darwin.go
index 61b7f8c728ffab4197c9c60ed09a2303d654e7e2..8bff695f5729d8d29459bf4772615f8768967260 100644
--- a/src/runtime/sys_darwin.go
+++ b/src/runtime/sys_darwin.go
@@ -179,6 +179,45 @@ return
}
func pthread_kill_trampoline()
+// osinit_hack is a clumsy hack to work around Apple libc bugs
+// causing fork+exec to hang in the child process intermittently.
+// See go.dev/issue/33565 and go.dev/issue/56784 for a few reports.
+//
+// The stacks obtained from the hung child processes are in
+// libSystem_atfork_child, which is supposed to reinitialize various
+// parts of the C library in the new process.
+//
+// One common stack dies in _notify_fork_child calling _notify_globals
+// (inlined) calling _os_alloc_once, because _os_alloc_once detects that
+// the once lock is held by the parent process and then calls
+// _os_once_gate_corruption_abort. The allocation is setting up the
+// globals for the notification subsystem. See the source code at [1].
+// To work around this, we can allocate the globals earlier in the Go
+// program's lifetime, before any execs are involved, by calling any
+// notify routine that is exported, calls _notify_globals, and doesn't do
+// anything too expensive otherwise. notify_is_valid_token(0) fits the bill.
+//
+// The other common stack dies in xpc_atfork_child calling
+// _objc_msgSend_uncached which ends up in
+// WAITING_FOR_ANOTHER_THREAD_TO_FINISH_CALLING_+initialize. Of course,
+// whatever thread the child is waiting for is in the parent process and
+// is not going to finish anything in the child process. There is no
+// public source code for these routines, so it is unclear exactly what
+// the problem is. An Apple engineer suggests using xpc_date_create_from_current,
+// which empirically does fix the problem.
+//
+// So osinit_hack_trampoline (in sys_darwin_$GOARCH.s) calls
+// notify_is_valid_token(0) and xpc_date_create_from_current(), which makes the
+// fork+exec hangs stop happening. If Apple fixes the libc bug in
+// some future version of macOS, then we can remove this awful code.
+//
+//go:nosplit
+func osinit_hack() {
+ libcCall(unsafe.Pointer(abi.FuncPCABI0(osinit_hack_trampoline)), nil)
+ return
+}
+func osinit_hack_trampoline()
+
// mmap is used to do low-level memory allocation via mmap. Don't allow stack
// splits, since this function (used by sysAlloc) is called in a lot of low-level
// parts of the runtime and callers often assume it won't acquire any locks.
@@ -548,3 +587,6 @@ //go:cgo_import_dynamic libc_pthread_cond_init pthread_cond_init "/usr/lib/libSystem.B.dylib"
//go:cgo_import_dynamic libc_pthread_cond_wait pthread_cond_wait "/usr/lib/libSystem.B.dylib"
//go:cgo_import_dynamic libc_pthread_cond_timedwait_relative_np pthread_cond_timedwait_relative_np "/usr/lib/libSystem.B.dylib"
//go:cgo_import_dynamic libc_pthread_cond_signal pthread_cond_signal "/usr/lib/libSystem.B.dylib"
+
+//go:cgo_import_dynamic libc_notify_is_valid_token notify_is_valid_token "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_xpc_date_create_from_current xpc_date_create_from_current "/usr/lib/libSystem.B.dylib"
diff --git a/src/runtime/sys_darwin_amd64.s b/src/runtime/sys_darwin_amd64.s
index 369b12e8f9f86d86b3b9f63d432c5abaa01f9a11..6eaeeb915f7e242037c7274c6a08e093c05f3c21 100644
--- a/src/runtime/sys_darwin_amd64.s
+++ b/src/runtime/sys_darwin_amd64.s
@@ -597,6 +597,15 @@ CALL libc_pthread_kill(SB)
POPQ BP
RET
+TEXT runtime·osinit_hack_trampoline(SB),NOSPLIT,$0
+ PUSHQ BP
+ MOVQ SP, BP
+ MOVQ $0, DI // arg 1 val
+ CALL libc_notify_is_valid_token(SB)
+ CALL libc_xpc_date_create_from_current(SB)
+ POPQ BP
+ RET
+
// syscall calls a function in libc on behalf of the syscall package.
// syscall takes a pointer to a struct like:
// struct {
diff --git a/src/runtime/sys_darwin_arm64.s b/src/runtime/sys_darwin_arm64.s
index 4fa99cc0f98cff8d8f02b9a8eb446239aeb67e47..4a51fb3a86349a85a976d4bce8c439f0c510366c 100644
--- a/src/runtime/sys_darwin_arm64.s
+++ b/src/runtime/sys_darwin_arm64.s
@@ -458,6 +458,12 @@ MOVD 0(R0), R0 // arg 1 key
BL libc_pthread_setspecific(SB)
RET
+TEXT runtime·osinit_hack_trampoline(SB),NOSPLIT,$0
+ MOVD $0, R0 // arg 1 val
+ BL libc_notify_is_valid_token(SB)
+ BL libc_xpc_date_create_from_current(SB)
+ RET
+
// syscall calls a function in libc on behalf of the syscall package.
// syscall takes a pointer to a struct like:
// struct {
diff --git a/src/sync/atomic/value.go b/src/sync/atomic/value.go
index 2bef76c9285d12b27161b2d36204e0c6c4df7f81..8c491b4616267f6b8785a663bfc1f205ced2691a 100644
--- a/src/sync/atomic/value.go
+++ b/src/sync/atomic/value.go
@@ -41,7 +41,7 @@ }
var firstStoreInProgress byte
-// Store sets the value of the Value to x.
+// Store sets the value of the Value v to val.
// All calls to Store for a given Value must use values of the same concrete type.
// Store of an inconsistent type panics, as does Store(nil).
func (v *Value) Store(val any) {
diff --git a/src/syscall/exec_libc2.go b/src/syscall/exec_libc2.go
index 6e3c2bf9d7608f6671e33731248470d7a18a1577..41bc79a721e7d4fa186d1896888f5f0b88e90732 100644
--- a/src/syscall/exec_libc2.go
+++ b/src/syscall/exec_libc2.go
@@ -78,7 +78,7 @@
// About to call fork.
// No more allocation or calls of non-assembly functions.
runtime_BeforeFork()
- r1, _, err1 = rawSyscall(forkTrampoline, 0, 0, 0)
+ r1, _, err1 = rawSyscall(abi.FuncPCABI0(libc_fork_trampoline), 0, 0, 0)
if err1 != 0 {
runtime_AfterFork()
return 0, err1
@@ -276,6 +276,6 @@ childerror:
// send error code on pipe
rawSyscall(abi.FuncPCABI0(libc_write_trampoline), uintptr(pipe), uintptr(unsafe.Pointer(&err1)), unsafe.Sizeof(err1))
for {
- rawSyscall(exitTrampoline, 253, 0, 0)
+ rawSyscall(abi.FuncPCABI0(libc_exit_trampoline), 253, 0, 0)
}
}
diff --git a/src/syscall/exec_linux_test.go b/src/syscall/exec_linux_test.go
index 1e21fffaef9f1c8ae56eee2959caa373d451f534..a6900f9033829e1df62bebabf0fda82a8a4ab118 100644
--- a/src/syscall/exec_linux_test.go
+++ b/src/syscall/exec_linux_test.go
@@ -505,8 +505,9 @@
// Need an ability to create a sub-cgroup.
subCgroup, err := os.MkdirTemp(prefix+string(bytes.TrimSpace(cg)), "subcg-")
if err != nil {
- // Running in an unprivileged container, this may also return EROFS #57262.
- if os.IsPermission(err) || errors.Is(err, syscall.EROFS) {
+ // ErrPermission or EROFS (#57262) when running in an unprivileged container.
+ // ErrNotExist when cgroupfs is not mounted in chroot/schroot.
+ if os.IsNotExist(err) || os.IsPermission(err) || errors.Is(err, syscall.EROFS) {
t.Skip(err)
}
t.Fatal(err)
diff --git a/src/syscall/syscall_darwin.go b/src/syscall/syscall_darwin.go
index 5ec311962a5a42d7b5018e5bb6992ced9963b3ee..a39e99dc633a86df864a1d1e820bcc138b2db4c2 100644
--- a/src/syscall/syscall_darwin.go
+++ b/src/syscall/syscall_darwin.go
@@ -22,34 +22,7 @@ func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
-// These are called from exec_libc2.go in the child of fork.
-// The names differ between macOS and OpenBSD, so we need
-// to declare the specific ones used here to keep the exec_libc2.go
-// code portable.
-//
-// We use __fork and __exit, not fork and exit, to avoid the libc atfork
-// and atexit handlers. The atfork handlers have caused fork child
-// hangs in the past (see #33565, #56784). The atexit handlers have
-// not, but the non-libc ports all invoke the system call, so doing
-// the same here makes sense. In general we wouldn't expect
-// atexit handlers to work terribly well in a fork child anyway.
-// (Also, perhaps the atfork handlers clear the atexit handlers,
-// in which case we definitely need to avoid calling the libc exit
-// if we bypass the libc fork.)
-//
-// Other calls that are made in the child after the fork are
-// ptrace, setsid, setpgid, getpid, ioctl, chroot, setgroups,
-// setgid, setuid, chdir, dup2, fcntl, close, execve, and write.
-// Those are all simple kernel wrappers that should be safe
-// to be called directly. The fcntl and ioctl functions do run
-// some code around the kernel call, but they don't call any
-// other functions, so for now we keep using them instead of
-// calling the lower-level __fcntl and __ioctl functions.
-var (
- dupTrampoline = abi.FuncPCABI0(libc_dup2_trampoline)
- exitTrampoline = abi.FuncPCABI0(libc___exit_trampoline)
- forkTrampoline = abi.FuncPCABI0(libc___fork_trampoline)
-)
+var dupTrampoline = abi.FuncPCABI0(libc_dup2_trampoline)
type SockaddrDatalink struct {
Len uint8
@@ -237,12 +210,11 @@ //sys write(fd int, p []byte) (n int, err error)
//sys writev(fd int, iovecs []Iovec) (cnt uintptr, err error)
//sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
//sys munmap(addr uintptr, length uintptr) (err error)
-//sysnb __fork() (pid int, err error)
+//sysnb fork() (pid int, err error)
//sysnb ioctl(fd int, req int, arg int) (err error)
//sysnb ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) = SYS_ioctl
//sysnb execve(path *byte, argv **byte, envp **byte) (err error)
//sysnb exit(res int) (err error)
-//sysnb __exit(res int) (err error)
//sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error)
//sys fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (val int, err error) = SYS_fcntl
//sys unlinkat(fd int, path string, flags int) (err error)
diff --git a/src/syscall/syscall_openbsd_libc.go b/src/syscall/syscall_openbsd_libc.go
index 6358a9a390a0c3298946e6e6bc139adc5a21317c..516d02975c530a3ea1aea3b826039f7891797c80 100644
--- a/src/syscall/syscall_openbsd_libc.go
+++ b/src/syscall/syscall_openbsd_libc.go
@@ -10,11 +10,7 @@ import (
"internal/abi"
)
-var (
- dupTrampoline = abi.FuncPCABI0(libc_dup3_trampoline)
- exitTrampoline = abi.FuncPCABI0(libc_exit_trampoline)
- forkTrampoline = abi.FuncPCABI0(libc_fork_trampoline)
-)
+var dupTrampoline = abi.FuncPCABI0(libc_dup3_trampoline)
func init() {
execveOpenBSD = execve
diff --git a/src/syscall/zsyscall_darwin_amd64.go b/src/syscall/zsyscall_darwin_amd64.go
index 5e3f6cccf0053b24db7c6b3bc5bc3df228f6f5f0..6b3fff3f3726a224ad1c6bbdc856eec18e73fdfe 100644
--- a/src/syscall/zsyscall_darwin_amd64.go
+++ b/src/syscall/zsyscall_darwin_amd64.go
@@ -1734,8 +1734,8 @@ //go:cgo_import_dynamic libc_munmap munmap "/usr/lib/libSystem.B.dylib"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func __fork() (pid int, err error) {
- r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc___fork_trampoline), 0, 0, 0)
+func fork() (pid int, err error) {
+ r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_fork_trampoline), 0, 0, 0)
pid = int(r0)
if e1 != 0 {
err = errnoErr(e1)
@@ -1743,9 +1743,9 @@ }
return
}
-func libc___fork_trampoline()
+func libc_fork_trampoline()
-//go:cgo_import_dynamic libc___fork __fork "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_fork fork "/usr/lib/libSystem.B.dylib"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1798,20 +1798,6 @@
func libc_exit_trampoline()
//go:cgo_import_dynamic libc_exit exit "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func __exit(res int) (err error) {
- _, _, e1 := rawSyscall(abi.FuncPCABI0(libc___exit_trampoline), uintptr(res), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc___exit_trampoline()
-
-//go:cgo_import_dynamic libc___exit __exit "/usr/lib/libSystem.B.dylib"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
diff --git a/src/syscall/zsyscall_darwin_amd64.s b/src/syscall/zsyscall_darwin_amd64.s
index cbb4496a50ed16b6347b9aeaba30bf6552d552b4..90e51fb9a4f43a63b4fff6150a47626b4d6c1135 100644
--- a/src/syscall/zsyscall_darwin_amd64.s
+++ b/src/syscall/zsyscall_darwin_amd64.s
@@ -221,16 +221,14 @@ TEXT ·libc_mmap_trampoline(SB),NOSPLIT,$0-0
JMP libc_mmap(SB)
TEXT ·libc_munmap_trampoline(SB),NOSPLIT,$0-0
JMP libc_munmap(SB)
-TEXT ·libc___fork_trampoline(SB),NOSPLIT,$0-0
- JMP libc___fork(SB)
+TEXT ·libc_fork_trampoline(SB),NOSPLIT,$0-0
+ JMP libc_fork(SB)
TEXT ·libc_ioctl_trampoline(SB),NOSPLIT,$0-0
JMP libc_ioctl(SB)
TEXT ·libc_execve_trampoline(SB),NOSPLIT,$0-0
JMP libc_execve(SB)
TEXT ·libc_exit_trampoline(SB),NOSPLIT,$0-0
JMP libc_exit(SB)
-TEXT ·libc___exit_trampoline(SB),NOSPLIT,$0-0
- JMP libc___exit(SB)
TEXT ·libc_sysctl_trampoline(SB),NOSPLIT,$0-0
JMP libc_sysctl(SB)
TEXT ·libc_unlinkat_trampoline(SB),NOSPLIT,$0-0
diff --git a/src/syscall/zsyscall_darwin_arm64.go b/src/syscall/zsyscall_darwin_arm64.go
index d4c56be8188518e6702f10d59ee74ea7f4d54c68..61601449a04043f185cd640cd3599af492d565cd 100644
--- a/src/syscall/zsyscall_darwin_arm64.go
+++ b/src/syscall/zsyscall_darwin_arm64.go
@@ -1734,8 +1734,8 @@ //go:cgo_import_dynamic libc_munmap munmap "/usr/lib/libSystem.B.dylib"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func __fork() (pid int, err error) {
- r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc___fork_trampoline), 0, 0, 0)
+func fork() (pid int, err error) {
+ r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_fork_trampoline), 0, 0, 0)
pid = int(r0)
if e1 != 0 {
err = errnoErr(e1)
@@ -1743,9 +1743,9 @@ }
return
}
-func libc___fork_trampoline()
+func libc_fork_trampoline()
-//go:cgo_import_dynamic libc___fork __fork "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_fork fork "/usr/lib/libSystem.B.dylib"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -1798,20 +1798,6 @@
func libc_exit_trampoline()
//go:cgo_import_dynamic libc_exit exit "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func __exit(res int) (err error) {
- _, _, e1 := rawSyscall(abi.FuncPCABI0(libc___exit_trampoline), uintptr(res), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc___exit_trampoline()
-
-//go:cgo_import_dynamic libc___exit __exit "/usr/lib/libSystem.B.dylib"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
diff --git a/src/syscall/zsyscall_darwin_arm64.s b/src/syscall/zsyscall_darwin_arm64.s
index ce1850e0aef5a81d1694d2eb59f24c8dc3adb3bb..f00747939efa36d38d2f920b79169fe31eab8e64 100644
--- a/src/syscall/zsyscall_darwin_arm64.s
+++ b/src/syscall/zsyscall_darwin_arm64.s
@@ -221,16 +221,14 @@ TEXT ·libc_mmap_trampoline(SB),NOSPLIT,$0-0
JMP libc_mmap(SB)
TEXT ·libc_munmap_trampoline(SB),NOSPLIT,$0-0
JMP libc_munmap(SB)
-TEXT ·libc___fork_trampoline(SB),NOSPLIT,$0-0
- JMP libc___fork(SB)
+TEXT ·libc_fork_trampoline(SB),NOSPLIT,$0-0
+ JMP libc_fork(SB)
TEXT ·libc_ioctl_trampoline(SB),NOSPLIT,$0-0
JMP libc_ioctl(SB)
TEXT ·libc_execve_trampoline(SB),NOSPLIT,$0-0
JMP libc_execve(SB)
TEXT ·libc_exit_trampoline(SB),NOSPLIT,$0-0
JMP libc_exit(SB)
-TEXT ·libc___exit_trampoline(SB),NOSPLIT,$0-0
- JMP libc___exit(SB)
TEXT ·libc_sysctl_trampoline(SB),NOSPLIT,$0-0
JMP libc_sysctl(SB)
TEXT ·libc_unlinkat_trampoline(SB),NOSPLIT,$0-0
diff --git a/src/testing/fuzz.go b/src/testing/fuzz.go
index 6e43ae7710faba41b84fc4ccd2f602f3e39f15a1..d31a3f81f528bc2c8b715a66fc06dff6a7cae994 100644
--- a/src/testing/fuzz.go
+++ b/src/testing/fuzz.go
@@ -40,7 +40,7 @@ )
// fuzzWorkerExitCode is used as an exit code by fuzz worker processes after an
// internal error. This distinguishes internal errors from uncontrolled panics
-// and other failiures. Keep in sync with internal/fuzz.workerExitCode.
+// and other failures. Keep in sync with internal/fuzz.workerExitCode.
const fuzzWorkerExitCode = 70
// InternalFuzzTarget is an internal type but exported because it is
diff --git a/test/fixedbugs/issue18392.go b/test/fixedbugs/issue18392.go
index e0640ed2ee48b408b4a5e6f72c0c1195425e126f..32c39c3a7fea3a924e474138ca4436c9f8179d2e 100644
--- a/test/fixedbugs/issue18392.go
+++ b/test/fixedbugs/issue18392.go
@@ -10,5 +10,5 @@ type A interface {
// TODO(mdempsky): This should be an error, but this error is
// nonsense. The error should actually mention that there's a
// type loop.
- Fn(A.Fn) // ERROR "type A has no method Fn|A.Fn undefined"
+ Fn(A.Fn) // ERROR "type A has no method Fn|A.Fn undefined|A.Fn is not a type"
}
diff --git a/test/fixedbugs/issue47068.dir/a.go b/test/fixedbugs/issue47068.dir/a.go
index f7b780d459d274140e13bffda0ec26a8a3a057b1..30a51c1edb24d10f163675426862f67060d6eb31 100644
--- a/test/fixedbugs/issue47068.dir/a.go
+++ b/test/fixedbugs/issue47068.dir/a.go
@@ -10,6 +10,6 @@ 0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0,
10: 0, 11: 0, 12: 0, 13: 0, 14: 0, 15: 0, 16: 0, 17: 0, 18: 0, 19: 0,
20: 0, 21: 0, 22: 0, 23: 0, 24: 0, 25: 0, 26: 0, 27: 0, 28: 0, 29: 0}
if len(m) != 30 {
- panic("unepexted map length")
+ panic("unexpected map length")
}
}
diff --git a/test/typeparam/graph.go b/test/typeparam/graph.go
index 38a97bcfb1e8ca9fe49efeea3bc08b7bf7334e19..5cd1faa76f523d7708df04c34f32093308281d4b 100644
--- a/test/typeparam/graph.go
+++ b/test/typeparam/graph.go
@@ -36,7 +36,7 @@ type _Graph[_Node _NodeC[_Edge], _Edge _EdgeC[_Node]] struct {
nodes []_Node
}
-// _NodeC is the contraints on a node in a graph, given the _Edge type.
+// _NodeC is the constraints on a node in a graph, given the _Edge type.
type _NodeC[_Edge any] interface {
comparable
Edges() []_Edge
diff --git a/test/typeparam/mdempsky/8.dir/b.go b/test/typeparam/mdempsky/8.dir/b.go
index 84037bf763ecb625fad1de7c081c146ea7beef9b..ef2637b894fb69c563689081f44dc3f431a9ee5d 100644
--- a/test/typeparam/mdempsky/8.dir/b.go
+++ b/test/typeparam/mdempsky/8.dir/b.go
@@ -7,5 +7,5 @@
import "./a"
func init() {
- a.F[func()]() // ERROR "does not implement comparable"
+ a.F[func()]() // ERROR "does not satisfy comparable"
}
diff --git a/test/typeparam/mincheck.dir/main.go b/test/typeparam/mincheck.dir/main.go
index c9ca50a23be50be11bbf0d219b73c9dbdcd7bb7a..6f85f9e5e12bf0514a10633ed34c07b06d193e42 100644
--- a/test/typeparam/mincheck.dir/main.go
+++ b/test/typeparam/mincheck.dir/main.go
@@ -28,11 +28,11 @@ panic(fmt.Sprintf("got %d, want %d", got, want))
}
const want2 = "ay"
- if got := a.Min[string]("bb", "ay"); got != want2 { // ERROR "string does not implement"
+ if got := a.Min[string]("bb", "ay"); got != want2 { // ERROR "string does not satisfy"
panic(fmt.Sprintf("got %d, want %d", got, want2))
}
- if got := a.Min("bb", "ay"); got != want2 { // ERROR "string does not implement"
+ if got := a.Min("bb", "ay"); got != want2 { // ERROR "string does not satisfy"
panic(fmt.Sprintf("got %d, want %d", got, want2))
}
}