[release-branch.go1.20] all: merge master (245e95d) into release-branch.go1.20

Merge List:

+ 2023-01-11 245e95dfab go/types, types2: don't look up fields or methods when expecting a type
+ 2023-01-11 18625d9bec runtime: fix incorrect comment
+ 2023-01-11 6ad27161f8 cmd/compile: better error message for when a type is in a constraint but not the type set
+ 2023-01-10 76d39ae349 cmd/link, runtime: Apple libc atfork workaround take 3
+ 2023-01-10 0a0de0fc42 runtime: revert use of __fork to work around Apple atfork bugs
+ 2023-01-10 82f09b75ca os/exec: avoid leaking an exec.Cmd in TestWaitInterrupt
+ 2023-01-09 0202ad0b3a cmd/compile: prevent IsNewObject from taking quadratic time
+ 2023-01-09 64519baf38 cmd/compile/internal/pgo: add hint to missing start_line error
+ 2023-01-09 376076f3c6 runtime: skip TestCgoPprofCallback in short mode, don't run in parallel
+ 2023-01-09 0bbd67e52f runtime/pprof: document possibility of empty stacks
+ 2023-01-09 d9f23cfe78 runtime/pprof: improve output of TestLabelSystemstack
+ 2023-01-09 8232a09e3e sync/atomic: fix the note of atomic.Store
+ 2023-01-09 841c3eb166 all: fix typos in go file comments
+ 2023-01-06 f721fa3be9 syscall: skip TestUseCgroupFD if cgroupfs not mounted
+ 2023-01-06 76ec919237 net: fix typo in hosts.go
+ 2023-01-06 660d4815ea cmd/compile: describe how Go maps to wasm implementation
+ 2023-01-05 119f679a3b crypto/tls: fix typo in cacheEntry godoc
+ 2023-01-05 d50ea217f6 cmd/cover: fix problems with "go test -covermode=atomic sync/atomic"
+ 2023-01-04 bae7d772e8 doc/go1.20: fix links to new strings functions
+ 2023-01-04 4e7c838483 crypto/internal/boring: add dev.boringcrypto README.md text
+ 2023-01-04 46e3d9d12a cmd/compile: use "satisfies" (not "implements") for constraint errors
+ 2023-01-04 79cdecc852 cmd/gofmt: fix a typo in a comment
+ 2023-01-03 9955a7e9bb README.vendor: minor updates
+ 2023-01-03 d03231d9ce doc/go1.20: fix http.ResponseController example
+ 2023-01-03 cdc73f0679 .github: suggest using private browsing in pkgsite template

Change-Id: I73be496aa4163ad1d3a6cc8114f1a612968d4b10
diff --git a/.github/ISSUE_TEMPLATE/01-pkgsite.md b/.github/ISSUE_TEMPLATE/01-pkgsite.md
index fee00f5..31f0fd1 100644
--- a/.github/ISSUE_TEMPLATE/01-pkgsite.md
+++ b/.github/ISSUE_TEMPLATE/01-pkgsite.md
@@ -34,6 +34,8 @@
 
 <!--
 If possible, provide a recipe for reproducing the error.
+
+Starting with a Private/Incognito tab/window may help rule out problematic browser extensions.
 -->
 
 
diff --git a/doc/go1.20.html b/doc/go1.20.html
index aec3e25..23fa82c 100644
--- a/doc/go1.20.html
+++ b/doc/go1.20.html
@@ -458,7 +458,7 @@
 <pre>
 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)
 }
 </pre>
@@ -1121,10 +1121,10 @@
   <dd>
     <p><!-- CL 407176, https://go.dev/issue/42537 -->
       The new
-      <a href="/pkg/bytes/#CutPrefix"><code>CutPrefix</code></a> and
-      <a href="/pkg/bytes/#CutSuffix"><code>CutSuffix</code></a> functions
-      are like <a href="/pkg/bytes/#TrimPrefix"><code>TrimPrefix</code></a>
-      and <a href="/pkg/bytes/#TrimSuffix"><code>TrimSuffix</code></a>
+      <a href="/pkg/strings/#CutPrefix"><code>CutPrefix</code></a> and
+      <a href="/pkg/strings/#CutSuffix"><code>CutSuffix</code></a> functions
+      are like <a href="/pkg/strings/#TrimPrefix"><code>TrimPrefix</code></a>
+      and <a href="/pkg/strings/#TrimSuffix"><code>TrimSuffix</code></a>
       but also report whether the string was trimmed.
     </p>
 
diff --git a/src/README.vendor b/src/README.vendor
index e74fc2f..4b6bdb8 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 @@
 ==============================
 
 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 311f20e..bf11e36 100644
--- a/src/cmd/compile/internal/pgo/irgraph.go
+++ b/src/cmd/compile/internal/pgo/irgraph.go
@@ -217,7 +217,7 @@
 		// 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 3b2f781..1676a93 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 @@
 		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 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 @@
 		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 @@
 	// 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 50343bf..7d660ca 100644
--- a/src/cmd/compile/internal/types2/call.go
+++ b/src/cmd/compile/internal/types2/call.go
@@ -447,7 +447,7 @@
 	"_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
@@ -559,6 +559,25 @@
 		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
+	}
+
 	obj, index, indirect = LookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, sel)
 	if obj == nil {
 		// Don't report another error if the underlying type was invalid (issue #49541).
diff --git a/src/cmd/compile/internal/types2/expr.go b/src/cmd/compile/internal/types2/expr.go
index 9a0348e..a3abbb9 100644
--- a/src/cmd/compile/internal/types2/expr.go
+++ b/src/cmd/compile/internal/types2/expr.go
@@ -1587,7 +1587,7 @@
 		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 52f60d7..8193682 100644
--- a/src/cmd/compile/internal/types2/instantiate.go
+++ b/src/cmd/compile/internal/types2/instantiate.go
@@ -188,7 +188,7 @@
 // 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 @@
 		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 @@
 			} 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 @@
 		// 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 @@
 				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.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 4de658b..0f3106d 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 27ba98c..0578c20 100644
--- a/src/cmd/compile/internal/wasm/ssa.go
+++ b/src/cmd/compile/internal/wasm/ssa.go
@@ -17,6 +17,119 @@
 	"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 f4f225e..74bb500 100644
--- a/src/cmd/cover/cover.go
+++ b/src/cmd/cover/cover.go
@@ -382,8 +382,23 @@
 		if n.Name.Name == "_" || n.Body == nil {
 			return nil
 		}
-		// Determine proper function or method name.
 		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.
 		if r := n.Recv; r != nil && len(r.List) == 1 {
 			t := r.List[0].Type
 			star := ""
@@ -508,8 +523,8 @@
 	}
 	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 @@
 		// 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 @@
 		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 0051970..fe6e733 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 ee29bcb..b933cdb 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 @@
 
 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 a98c6a0..0b7e211 100644
--- a/src/cmd/gofmt/rewrite.go
+++ b/src/cmd/gofmt/rewrite.go
@@ -199,7 +199,7 @@
 		// 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 d7a2838..db18bc8 100644
--- a/src/cmd/internal/obj/arm64/asm7.go
+++ b/src/cmd/internal/obj/arm64/asm7.go
@@ -3215,7 +3215,7 @@
 	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 11cbf81..d6c28e4 100644
--- a/src/cmd/link/internal/ld/macho.go
+++ b/src/cmd/link/internal/ld/macho.go
@@ -479,8 +479,11 @@
 			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 ffacd34..ec02786 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 @@
 
 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 2bdf2d9..fc8f2c0 100644
--- a/src/crypto/tls/cache.go
+++ b/src/crypto/tls/cache.go
@@ -27,7 +27,7 @@
 // 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 5558244..db603b5 100644
--- a/src/go/types/call.go
+++ b/src/go/types/call.go
@@ -450,7 +450,7 @@
 	"_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
@@ -563,6 +563,25 @@
 		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
+	}
+
 	obj, index, indirect = LookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, sel)
 	if obj == nil {
 		// Don't report another error if the underlying type was invalid (issue #49541).
diff --git a/src/go/types/expr.go b/src/go/types/expr.go
index e09b461..aa90145 100644
--- a/src/go/types/expr.go
+++ b/src/go/types/expr.go
@@ -1568,7 +1568,7 @@
 		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 59ac100..2cf48c1 100644
--- a/src/go/types/instantiate.go
+++ b/src/go/types/instantiate.go
@@ -188,7 +188,7 @@
 // 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 @@
 		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 @@
 			} 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 @@
 		// 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 @@
 				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.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 3d1f0b8..03817dd 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 d4e7e60..7c00c7d 100644
--- a/src/internal/types/testdata/check/cycles0.go
+++ b/src/internal/types/testdata/check/cycles0.go
@@ -45,7 +45,7 @@
 
 	// 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 6002a9e..868b318 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 @@
 // 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 0cea36c..4a66641 100644
--- a/src/internal/types/testdata/check/issues0.go
+++ b/src/internal/types/testdata/check/issues0.go
@@ -97,7 +97,7 @@
 		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 02ad822..2f3414d 100644
--- a/src/internal/types/testdata/check/issues1.go
+++ b/src/internal/types/testdata/check/issues1.go
@@ -22,7 +22,7 @@
 	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 @@
 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 @@
     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 e7b4539..e7bb247 100644
--- a/src/internal/types/testdata/check/typeinst1.go
+++ b/src/internal/types/testdata/check/typeinst1.go
@@ -210,7 +210,7 @@
 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 @@
 }
 
 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 @@
 }
 
 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 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 23a3d81..073df9c 100644
--- a/src/internal/types/testdata/examples/inference.go
+++ b/src/internal/types/testdata/examples/inference.go
@@ -97,7 +97,7 @@
 	// 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 7b458f2..6ee1548 100644
--- a/src/internal/types/testdata/fixedbugs/issue39634.go
+++ b/src/internal/types/testdata/fixedbugs/issue39634.go
@@ -19,7 +19,7 @@
 // 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 9edd239..97365e2 100644
--- a/src/internal/types/testdata/fixedbugs/issue39754.go
+++ b/src/internal/types/testdata/fixedbugs/issue39754.go
@@ -16,6 +16,6 @@
 

 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 7ffd551..08eb426 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 d67dfc0..0a281c5 100644
--- a/src/internal/types/testdata/fixedbugs/issue45920.go
+++ b/src/internal/types/testdata/fixedbugs/issue45920.go
@@ -8,10 +8,10 @@
 
 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 1230307..33b169a 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 61b757c..dea2608 100644
--- a/src/internal/types/testdata/fixedbugs/issue49112.go
+++ b/src/internal/types/testdata/fixedbugs/issue49112.go
@@ -8,8 +8,8 @@
 
 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 8890e92..2ddfa33 100644
--- a/src/internal/types/testdata/fixedbugs/issue49179.go
+++ b/src/internal/types/testdata/fixedbugs/issue49179.go
@@ -13,11 +13,11 @@
 
 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 46b1e71..7feb563 100644
--- a/src/internal/types/testdata/fixedbugs/issue49739.go
+++ b/src/internal/types/testdata/fixedbugs/issue49739.go
@@ -17,7 +17,7 @@
 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 2caef1b..69ebf31 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 @@
 }
 
 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 bc53700..ed7261c 100644
--- a/src/internal/types/testdata/fixedbugs/issue50646.go
+++ b/src/internal/types/testdata/fixedbugs/issue50646.go
@@ -13,16 +13,16 @@
 
 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 fd1ab11..0e7b712 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 4730c98..be4b81fe 100644
--- a/src/internal/types/testdata/fixedbugs/issue51257.go
+++ b/src/internal/types/testdata/fixedbugs/issue51257.go
@@ -14,13 +14,13 @@
 
 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 d51607b..3801d68 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 @@
 
         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 52ae09d..a0f9e9c 100644
--- a/src/internal/types/testdata/fixedbugs/issue51472.go
+++ b/src/internal/types/testdata/fixedbugs/issue51472.go
@@ -49,6 +49,6 @@
 }
 
 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 ff9e3d1..43ba1b0 100644
--- a/src/internal/types/testdata/fixedbugs/issue57486.go
+++ b/src/internal/types/testdata/fixedbugs/issue57486.go
@@ -17,13 +17,13 @@
 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 0000000..abdcb5e
--- /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 0000000..d83e5b2
--- /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 03c8471..f407c35 100644
--- a/src/internal/types/testdata/spec/comparable.go
+++ b/src/internal/types/testdata/spec/comparable.go
@@ -11,16 +11,16 @@
 
 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 c9c87e4..dc1c5fa 100644
--- a/src/internal/types/testdata/spec/comparable1.19.go
+++ b/src/internal/types/testdata/spec/comparable1.19.go
@@ -13,16 +13,16 @@
 
 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 9f6cf74..081d972 100644
--- a/src/internal/types/testdata/spec/oldcomparable.go
+++ b/src/internal/types/testdata/spec/oldcomparable.go
@@ -13,16 +13,16 @@
 
 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 7c8642c..dbf8fea 100644
--- a/src/net/hosts.go
+++ b/src/net/hosts.go
@@ -125,7 +125,7 @@
 	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 edff9a2..67e2d25 100644
--- a/src/os/exec/exec_test.go
+++ b/src/os/exec/exec_test.go
@@ -1182,6 +1182,7 @@
 			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 ba0e9f4..51d7bb5 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 5bad4f7..5bc9c84 100644
--- a/src/runtime/mpagecache.go
+++ b/src/runtime/mpagecache.go
@@ -21,8 +21,7 @@
 	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 af5c18c..c4f3bb6 100644
--- a/src/runtime/os_darwin.go
+++ b/src/runtime/os_darwin.go
@@ -136,6 +136,8 @@
 
 	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 39bc9d1..53688ad 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 @@
 		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 @@
 					// (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 @@
 				}
 			}
 		}
-		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 8a49e14..b68f30d 100644
--- a/src/runtime/pprof/proto.go
+++ b/src/runtime/pprof/proto.go
@@ -395,6 +395,10 @@
 // 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 61b7f8c..8bff695 100644
--- a/src/runtime/sys_darwin.go
+++ b/src/runtime/sys_darwin.go
@@ -179,6 +179,45 @@
 }
 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_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 369b12e..6eaeeb9 100644
--- a/src/runtime/sys_darwin_amd64.s
+++ b/src/runtime/sys_darwin_amd64.s
@@ -597,6 +597,15 @@
 	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 4fa99cc..4a51fb3 100644
--- a/src/runtime/sys_darwin_arm64.s
+++ b/src/runtime/sys_darwin_arm64.s
@@ -458,6 +458,12 @@
 	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 2bef76c..8c491b4 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 6e3c2bf..41bc79a 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 @@
 	// 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 1e21fff..a6900f9 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 5ec3119..a39e99d 100644
--- a/src/syscall/syscall_darwin.go
+++ b/src/syscall/syscall_darwin.go
@@ -22,34 +22,7 @@
 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	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 6358a9a..516d029 100644
--- a/src/syscall/syscall_openbsd_libc.go
+++ b/src/syscall/syscall_openbsd_libc.go
@@ -10,11 +10,7 @@
 	"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 5e3f6cc..6b3fff3 100644
--- a/src/syscall/zsyscall_darwin_amd64.go
+++ b/src/syscall/zsyscall_darwin_amd64.go
@@ -1734,8 +1734,8 @@
 
 // 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
 
@@ -1801,20 +1801,6 @@
 
 // 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
-
 func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
 	var _p0 unsafe.Pointer
 	if len(mib) > 0 {
diff --git a/src/syscall/zsyscall_darwin_amd64.s b/src/syscall/zsyscall_darwin_amd64.s
index cbb4496..90e51fb 100644
--- a/src/syscall/zsyscall_darwin_amd64.s
+++ b/src/syscall/zsyscall_darwin_amd64.s
@@ -221,16 +221,14 @@
 	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 d4c56be..6160144 100644
--- a/src/syscall/zsyscall_darwin_arm64.go
+++ b/src/syscall/zsyscall_darwin_arm64.go
@@ -1734,8 +1734,8 @@
 
 // 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
 
@@ -1801,20 +1801,6 @@
 
 // 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
-
 func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
 	var _p0 unsafe.Pointer
 	if len(mib) > 0 {
diff --git a/src/syscall/zsyscall_darwin_arm64.s b/src/syscall/zsyscall_darwin_arm64.s
index ce1850e..f007479 100644
--- a/src/syscall/zsyscall_darwin_arm64.s
+++ b/src/syscall/zsyscall_darwin_arm64.s
@@ -221,16 +221,14 @@
 	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 6e43ae7..d31a3f8 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 e0640ed..32c39c3 100644
--- a/test/fixedbugs/issue18392.go
+++ b/test/fixedbugs/issue18392.go
@@ -10,5 +10,5 @@
 	// 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 f7b780d..30a51c1 100644
--- a/test/fixedbugs/issue47068.dir/a.go
+++ b/test/fixedbugs/issue47068.dir/a.go
@@ -10,6 +10,6 @@
 		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 38a97bc..5cd1faa 100644
--- a/test/typeparam/graph.go
+++ b/test/typeparam/graph.go
@@ -36,7 +36,7 @@
 	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 84037bf..ef2637b 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 c9ca50a..6f85f9e 100644
--- a/test/typeparam/mincheck.dir/main.go
+++ b/test/typeparam/mincheck.dir/main.go
@@ -28,11 +28,11 @@
 	}
 
 	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))
 	}
 }