_content: add https://go.dev/doc/toolchain

This documents the new toolchain selection and switching
for the forward compatibility work.

For golang/go#57001.

Change-Id: I0efdac6771018063446dd0db22013c5fd756bea4
Reviewed-on: https://go-review.googlesource.com/c/website/+/500775
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Michael Matloob <matloob@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Russ Cox <rsc@golang.org>
diff --git a/_content/doc/modules/gomod-ref.md b/_content/doc/modules/gomod-ref.md
index d78e6c0..6b64efd 100644
--- a/_content/doc/modules/gomod-ref.md
+++ b/_content/doc/modules/gomod-ref.md
@@ -158,11 +158,14 @@
 
 ### Notes {#go-notes}
 
-The `go` directive was originally intended to support backward incompatible
-changes to the Go language (see [Go 2
-transition](/design/28221-go2-transitions)). There have been no incompatible
-language changes since modules were introduced, but the `go` directive still
-affects use of new language features:
+The `go` directive sets the minimum version of Go required to use this module.
+Before Go 1.21, the directive was advisory only; now it is a mandatory requirement:
+Go toolchains refuse to use modules declaring newer Go versions.
+
+The `go` directive is an input into selecting which Go toolchain to run.
+See “[/doc/toolchain](Go toolchains)” for details.
+
+The `go` directive affects use of new language features:
 
 * For packages within the module, the compiler rejects use of language features
   introduced after the version specified by the `go` directive. For example, if
@@ -174,8 +177,7 @@
   numeric literal `1_000_000`. If that package is built with Go 1.12, the
   compiler notes that the code is written for Go 1.13.
 
-Additionally, the `go` command changes its behavior based on the version
-specified by the `go` directive. This has the following effects:
+The `go` directive also affects the behavior of the `go` command:
 
 * At `go 1.14` or higher, automatic [vendoring](/ref/mod#vendoring) may be
   enabled.  If the file `vendor/modules.txt` is present and consistent with
@@ -203,11 +205,50 @@
      subdirectories of `vendor` to identify the correct main module.)
    * `go mod vendor` records the `go` version from each dependency's `go.mod`
      file in `vendor/modules.txt`.
+* At `go 1.21` or higher:
+   * The `go` line declares a required minimum version of Go to use with this module.
+   * The `go` line must be greater than or equal to the `go` line of all dependencies.
+   * The `go` command no longer attempts to maintain compatibility with the previous older version of Go.
+   * The `go` command is more careful about keeping checksums of `go.mod` files in the `go.sum` file.
 <!-- If you update this list, also update /ref/mod#go-mod-file-go. -->
 
 A `go.mod` file may contain at most one `go` directive. Most commands will add a
 `go` directive with the current Go version if one is not present.
 
+## toolchain {#toolchain}
+
+Declares a suggested Go toolchain to use with this module.
+Only takes effect when the module is the main module
+and the default toolchain is older than the suggested toolchain.
+
+For more see “[/doc/toolchain](Go toolchains)” and
+[`toolchain` directive](/ref/mod/#go-mod-file-toolchain) in the
+Go Modules Reference.
+
+### Syntax {#toolchain-syntax}
+
+<pre>toolchain <var>toolchain-name</var></pre>
+
+<dl>
+    <dt>toolchain-name</dt>
+    <dd>The suggested Go toolchain's name. Standard toolchain names take the form
+      <code>go<i>V</i></code> for a Go version <i>V</i>, as in
+      <code>go1.21.0</code> and <code>go1.18rc1</code>.
+      The special value <code>default</code> disables automatic toolchain switching.</dd>
+</dl>
+
+### Examples {#toolchain-examples}
+
+* Suggest using Go 1.21.0 or newer:
+    ```
+    toolchain go1.21.0
+    ```
+
+### Notes {#toolchain-notes}
+
+See “[/doc/toolchain](Go toolchains)” for details about how the `toolchain` line
+affects Go toolchain selection.
+
 ## require {#require}
 
 Declares a module as a dependency of the current module, specifying the
diff --git a/_content/doc/toolchain.md b/_content/doc/toolchain.md
new file mode 100644
index 0000000..6e83643
--- /dev/null
+++ b/_content/doc/toolchain.md
@@ -0,0 +1,446 @@
+---
+title: "Go Toolchains"
+layout: article
+---
+
+## Introduction {#intro}
+
+Starting in Go 1.21, the Go distribution consists of a `go` command and a bundled Go toolchain,
+which is the standard library as well as the compiler, assembler, and other tools.
+The `go` command can use its bundled Go toolchain as well as other versions
+that it finds in the local `PATH` or downloads as needed.
+
+The choice of Go toolchain being used depends on the `GOTOOLCHAIN` environment setting
+and the `go` and `toolchain` lines in the main module's `go.mod` file or the current workspace's `go.work` file.
+As you move between different main modules and workspaces,
+the toolchain version being used can vary, just as module dependency versions do.
+
+In the standard configuration, the `go` command uses its own bundled toolchain
+when that toolchain is at least as new as the `go` or `toolchain` lines in the main module or workspace.
+For example, when using the `go` command bundled with Go 1.21.3 in a main module that says `go 1.21.0`,
+the `go` command uses Go 1.21.3.
+When the `go` or `toolchain` line is newer than the bundled toolchain,
+the `go` command runs the newer toolchain instead.
+For example, when using the `go` command bundled with Go 1.21.3 in a main module that says `go 1.21.9`,
+the `go` command finds and runs Go 1.21.9 instead.
+It first looks in the PATH for a program named `go1.21.9` and otherwise downloads and caches
+a copy of the Go 1.21.9 toolchain.
+This automatic toolchain switching can be disabled, but in that case,
+for more precise forwards compatibility,
+the `go` command will refuse to run in a main module or workspace in which the `go` line
+requires a newer version of Go.
+That is, the `go` line sets the minimum required Go version necessary to use a module or workspace.
+
+Modules that are dependencies of other modules may need to set a minimum Go version requirement
+lower than the preferred toolchain to use when working in that module directly.
+In this case, the `toolchain` line in `go.mod` or `go.work` sets a preferred toolchain
+that takes precedence over the `go` line when the `go` command is deciding
+which toolchain to use.
+
+The `go` and `toolchain` lines can be thought of as specifying the version requirements
+for the module's dependency on the Go toolchain itself, just as the `require` lines in `go.mod`
+specify the version requirements for dependencies on other modules.
+The `go get` command manages the Go toolchain dependency just as it
+manages dependencies on other modules.
+For example, `go get go@latest` updates the module to require the latest released Go toolchain.
+
+The `GOTOOLCHAIN` environment setting can force a specific Go version, overriding
+the `go` and `toolchain` lines. For example, to test a package with Go 1.21rc3:
+
+	GOTOOLCHAIN=go1.21rc3 go test
+
+The default `GOTOOLCHAIN` setting is `auto`, which enables the toolchain switching described earlier.
+The alternate form `<name>+auto` sets the default toolchain to use before deciding whether to
+switch further. For example `GOTOOLCHAIN=go1.21.3+auto` directs the `go` command to
+begin its decision with a default of using Go 1.21.3 but still use a newer toolchain if
+directed by `go` and `toolchain` lines.
+Because the default `GOTOOLCHAIN` setting can be changed with `go env -w`,
+if you have Go 1.21.0 or later installed, then
+
+	go env -w GOTOOLCHAIN=go1.21.3+auto
+
+is equivalent to replacing your Go 1.21.0 installation with Go 1.21.3.
+
+The rest of this document explains how Go toolchains are versioned, chosen, and managed in more detail.
+
+## Go versions {#version}
+
+Released versions of Go use the version syntax ‘1.*N*.*P*’, denoting the *P*th release of Go 1.*N*.
+The initial release is 1.*N*.0, like in ‘1.21.0’. Later releases like 1.*N*.9 are often referred to as patch releases.
+
+Go 1.*N* release candidates, which are issued before 1.*N*.0, use the version syntax ‘1.*N*rc*R*’.
+The first release candidate for Go 1.*N* has version 1.*N*rc1, like in `1.23rc1`.
+
+The syntax ‘1.*N*’ is called a “language version”. It denotes the overall family of Go releases
+implementing that version of the Go language and standard library.
+
+The language version for a Go version is the result of truncating everything after the *N*:
+1.21, 1.21rc2, and 1.21.3 all implement language version 1.21.
+
+Released Go toolchains such as Go 1.21.0 and Go 1.21rc1 report that specific version
+(for example, `go1.21.0` or `go1.21rc1`)
+from `go version` and [`runtime.Version](/pkg/runtime/#Version).
+Unreleased (still in development) Go toolchains built from the Go development repository
+instead report only the language version (for example, `go1.21`).
+
+Any two Go versions can be compared to decide whether one is less than, greater than,
+or equal to the other. If the language versions are different, that decides the comparison:
+1.21.9 < 1.22. Within a language version, the ordering from least to greatest is:
+the language version itself, then release candidates ordered by *R*, then releases ordered by *P*.
+
+For example, 1.21 < 1.21rc1 < 1.21rc2 < 1.21.0 < 1.21.1 < 1.21.2.
+
+Before Go 1.21, the initial release of a Go toolchain was version 1.*N*, not 1.*N*.0,
+so for *N* < 21, the ordering is adjusted to place 1.*N* after the release candidates.
+
+For example, 1.20rc1 < 1.20rc2 < 1.20rc3 < 1.20 < 1.20.1.
+
+Earlier versions of Go had beta releases, with versions like 1.18beta2.
+Beta releases are placed immediately before release candidates in the version ordering.
+
+For example, 1.18beta1 < 1.18beta2 < 1.18rc1 < 1.18 < 1.18.1.
+
+<!-- Unpublished note: the download page also lists Go 1.9.2rc2, which does not respect
+this version syntax. That was created as a test of some potential release automation
+before Go 1.9.2 but is not considered a “real” toolchain. -->
+
+## Go toolchain names {#name}
+
+The standard Go toolchains are named <code>go<i>V</i></code> where *V* is a Go version
+denoting a beta release, release candidate, or release.
+For example, `go1.21rc1` and `go1.21.0` are toolchain names;
+`go1.21` and `go1.22` are not (the initial releases are `go1.21.0` and `go1.22.0`),
+but `go1.20` and `go1.19` are.
+
+Non-standard toolchains use names of the form <code>go<i>V</i>-<i>suffix</i></code>
+for any suffix.
+
+Toolchains are compared by comparing the version <code><i>V</i></code> embedded in the name
+(dropping the initial `go` and discarding off any suffix beginning with `-`).
+For example, `go1.21.0` and `go1.21.0-custom` compare equal for ordering purposes.
+
+## Module and workspace configuration {#config}
+
+Go modules and workspaces specify version-related configuration
+in their `go.mod` or `go.work` files.
+
+The `go` line declares the minimum required Go version for using
+the module or workspace.
+For compatibility reasons, if the `go` line is omitted from a `go.mod` file,
+the module is considered to have an implicit `go 1.16` line,
+and if the `go` line is omitted from a `go.work` file,
+the workspace is considered to have an implicit `go 1.18` line.
+
+The `toolchain` line declares a suggested toolchain to use with
+the module or workspace.
+As described in “[Go toolchain selection](#select)” below,
+the `go` command may run this specific toolchain when operating
+in that module or workspace
+if the default toolchain's version is less than the suggested toolchain's version.
+If the `toolchain` line is omitted,
+the module or workspace is considered to have an implicit
+<code>toolchain go<i>V</i></code> line,
+where *V* is the Go version from the `go` line.
+
+For example, a `go.mod` that says `go 1.21.0` with no `toolchain` line
+is interpreted as if it had a `toolchain go1.21.0` line.
+
+The Go toolchain refuses to load a module or workspace that declares
+a minimum required Go version greater than the toolchain's own version.
+
+For example, Go 1.21.2 will refuse to load a module or workspace
+with a `go 1.21.3` or `go 1.22` line.
+
+A module's `go` line must declare a version greater than or equal to
+the `go` version declared by each of the modules listed in `require` statements.
+A workspace's `go` line must declare a version greater than or equal to
+the `go` version declared by each of the modules listed in `use` statements.
+
+For example, if module *M* requires a dependency *D* with a `go.mod`
+that declares `go 1.22.0`, then *M*'s `go.mod` cannot say `go 1.21.3`.
+
+The `go` line for each module sets the language version the compiler
+enforces when compiling packages in that module.
+The language version can be changed on a per-file basis by using a
+[build constraint](/cmd/go#hdr-Build_constraints).
+
+For example, a module containing code that uses the Go 1.21 language version
+should have a `go.mod` file with a `go` line such as `go 1.21` or `go 1.21.3`.
+If a specific source file should be compiled only when using a newer Go toolchain,
+adding `//go:build go1.22` to that source file both ensures that only Go 1.22 and
+newer toolchains will compile the file and also changes the language version in that
+file to Go 1.22.
+
+The `go` and `toolchain` lines are most conveniently and safely modified
+by using `go get`; see the [section dedicated to `go get` below](#get).
+
+Before Go 1.21, Go toolchains treated the `go` line as an advisory requirement:
+if builds succeeded the toolchain assumed everything worked,
+and if not it printed a note about the potential version mismatch.
+Go 1.21 changed the `go` line to be a mandatory requirement instead.
+This behavior is partly backported to earlier language versions:
+Go 1.19 releases starting at Go 1.19.11 and Go 1.20 releases starting at Go 1.20.6,
+refuse to load workspaces or modules declaring version Go 1.21 or later.
+
+Before Go 1.21, toolchains did not require a module
+or workspace to have a `go` line greater than or equal to the
+`go` version required by each of its dependency modules.
+
+## The `GOTOOLCHAIN` setting {#GOTOOLCHAIN}
+
+The `go` command selects the Go toolchain to use based on the `GOTOOLCHAIN` setting.
+To find the `GOTOOLCHAIN` setting, the `go` command uses the standard rules for any
+Go environment setting:
+
+ - If `GOTOOLCHAIN` is set to a non-empty value in the process environment
+   (as queried by [`os.Getenv`](/pkg/os/#Getenv)), the `go` command uses that value.
+
+ - Otherwise, if `GOTOOLCHAIN` is set in the user's environment default file
+   (managed with
+   [`go env -w` and `go env -u`](/cmd/go/#hdr-Print_Go_environment_information)),
+   the `go` command uses that value.
+
+ - Otherwise, if `GOTOOLCHAIN` is set in the bundled Go toolchain's environment
+   default file (`$GOROOT/go.env`), the `go` command uses that value.
+
+In standard Go toolchains, the `$GOROOT/go.env` file sets the default `GOTOOLCHAIN=auto`,
+but repackaged Go toolchains may change this value.
+
+If the `$GOROOT/go.env` file is missing or does not set a default, the `go` command
+assumes `GOTOOLCHAIN=local`.
+
+Running `go env GOTOOLCHAIN` prints the `GOTOOLCHAIN` setting.
+
+## Go toolchain selection {#select}
+
+At startup, the `go` command selects which Go toolchain to use.
+It consults the `GOTOOLCHAIN` setting,
+which takes the form `<name>`, `<name>+auto`, or `<name>+path`.
+`GOTOOLCHAIN=auto` is shorthand for `GOTOOLCHAIN=local+auto`;
+similarly, `GOTOOLCHAIN=path` is shorthand for `GOTOOLCHAIN=local+path`.
+The `<name>` sets the default Go toolchain:
+`local` indicates the bundled Go toolchain
+(the one that shipped with the `go` command being run), and otherwise `<name>` must
+be a specific Go toolchain name, such as `go1.21.0`.
+The `go` command prefers to run the default Go toolchain.
+As noted above, starting in Go 1.21, Go toolchains refuse to run in
+workspaces or modules that require newer Go versions.
+Instead, they report an error and exit.
+
+When `GOTOOLCHAIN` is set to `local`, the `go` command always runs the bundled Go toolchain.
+
+When `GOTOOLCHAIN` is set to `<name>` (for example, `GOTOOLCHAIN=go1.21.0`),
+the `go` command always runs that specific Go toolchain.
+If a binary with that name is found in the system PATH, the `go` command uses it.
+Otherwise the `go` command uses a Go toolchain it downloads and verifies.
+
+When `GOTOOLCHAIN` is set to `<name>+auto` or `<name>+path` (or the shorthands `auto` or `path`),
+the `go` command selects and runs a newer Go version as needed.
+Specifically, it consults the `toolchain` and `go` lines in the current workspace's
+`go.work` file or, when there is no workspace,
+the main module's `go.mod` file.
+If the `go.work` or `go.mod` file has a `toolchain <tname>` line
+and `<tname>` is newer than the default Go toolchain,
+then the `go` command runs `<tname>` instead.
+If the file has a `toolchain default` line,
+then the `go` command runs the default Go toolchain,
+disabling any attempt at updating beyond `<name>`.
+Otherwise, if the file has a `go <version>` line
+and `<version>` is newer than the default Go toolchain,
+then the `go` command runs `go<version>` instead.
+
+To run a toolchain other than the bundled Go toolchain,
+the `go` command searches the process's executable path
+(`$PATH` on Unix and Plan 9, `%PATH%` on Windows)
+for a program with the given name (for example, `go1.21.3`) and runs that program.
+If no such program is found, the `go` command
+[downloads and runs the specified Go toolchain](#download).
+Using the `GOTOOLCHAIN` form `<name>+path` disables the download fallback,
+causing the `go` command to stop after searching the executable path.
+
+Running `go version` prints the selected Go toolchain's version
+(by running the selected toolchain's implementation of `go version`).
+
+Running `GOTOOLCHAIN=local go version` prints the bundled Go toolchain's version.
+
+## Go toolchain switches {#switch}
+
+For most commands, the workspace's `go.work` or the main module's `go.mod`
+will have a `go` line that is at least as new as the `go` line in any module dependency,
+due to the version ordering [configuration requirements](#config).
+In this case, the startup toolchain selection runs a new enough Go toolchain
+to complete the command.
+
+Some commands incorporate new module versions as part of their operation:
+`go get` adds new module dependencies to the main module;
+`go work use` adds new local modules to the workspace;
+`go work sync` resynchronizes a workspace with local modules that may have been updated
+since the workspace was created;
+`go install package@version` and `go run package@version`
+effectively run in an empty main module and add `package@version` as a new dependency.
+All these commands may encounter a module with a `go.mod` `go` line
+requiring a newer Go version than the currently executed Go version.
+
+When a command encounters a module requiring a newer Go version
+and `GOTOOLCHAIN` permits running different toolchains
+(it is one of the `auto` or `path` forms),
+the `go` command chooses and switches to an appropriate newer toolchain
+to continue executing the current command.
+
+Any time the `go` command switches toolchains after startup toolchain selection,
+it prints a message explaining why. For example:
+
+	go: module example.com/widget@v1.2.3 requires go >= 1.24rc1; switching to go 1.27.9
+
+As shown in the example, the `go` command may switch to a toolchain
+newer than the discovered requirement.
+In general the `go` command aims to switch to a supported Go toolchain.
+
+To choose the toolchain, the `go` command first obtains a list of available toolchains.
+For the `auto` form, the `go` command downloads a list of available toolchains.
+For the `path` form, the `go` command scans the PATH for any executables
+named for valid toolchains and uses a list of all the toolchains it finds.
+Using that list of toolchains, the `go` command identifies up to three candidates:
+
+ - the latest release candidate of an unreleased Go language version (1.*N*₃rc*R*₃),
+ - the latest patch release of the most recently released Go language version (1.*N*₂.*P*₂), and
+ - the latest patch release of the previous Go language version (1.*N*₁.*P*₁).
+
+These are the supported Go releases according to Go's [release policy](/doc/devel/release#policy).
+Consistent with [minimal version selection](https://research.swtch.com/vgo-mvs),
+the `go` command then conservatively uses the candidate with the _minimum_ (oldest)
+version that satisfies the new requirement.
+
+For example, suppose `example.com/widget@v1.2.3` requires Go 1.24rc1 or later.
+The `go` command obtains the list of available toolchains
+and finds that the latest patch releases of the two most recent Go toolchains are
+Go 1.28.3 and Go 1.27.9,
+and the release candidate Go 1.29rc2 is also available.
+In this situation, the `go` command will choose Go 1.27.9.
+If `widget` had required Go 1.28 or later, the `go` command would choose Go 1.28.3,
+because Go 1.27.9 is too old.
+If `widget` had required Go 1.29 or later, the `go` command would choose Go 1.29rc2,
+because both Go 1.27.9 and Go 1.28.3 are too old.
+
+Commands that incorporate new module versions that require new Go versions
+write the new minimum `go` version requirement to the current workspace's `go.work` file
+or the main module's `go.mod` file, updating the `go` line.
+For [repeatability](https://research.swtch.com/vgo-principles#repeatability),
+any command that updates the `go` line also updates the `toolchain` line
+to record its own toolchain name.
+The next time the `go` command runs in that workspace or module,
+it will use that updated `toolchain` line during [toolchain selection](#select).
+
+For example, `go get example.com/widget@v1.2.3` may print a switching notice
+like above and switch to Go 1.27.9.
+Go 1.27.9 will complete the `go get` and update the `toolchain` line
+to say `toolchain go1.27.9`.
+The next `go` command run in that module or workspace will select `go1.27.9`
+during startup and will not print any switching message.
+
+In general, if any `go` command is run twice, if the first prints a switching
+message, the second will not, because the first also updated `go.work` or `go.mod`
+to select the right toolchain at startup.
+The exception is the `go install package@version` and `go run package@version` forms,
+which run in no workspace or main module and cannot write a `toolchain` line.
+They print a switching message every time they need to switch
+to a newer toolchain.
+
+## Downloading toolchains (#download)
+
+When using `GOTOOLCHAIN=auto` or `GOTOOLCHAIN=<name>+auto`, the Go command
+downloads newer toolchains as needed.
+These toolchains are packaged as special modules
+with module path `golang.org/toolchain`
+and version <code>v0.0.1-go<i>VERSION</i>.<i>GOOS</i>-<i>GOARCH</i></code>.
+Toolchains are downloaded like any other module,
+meaning that toolchain downloads can be proxied by setting `GOPROXY`
+and have their checksums checked by the Go checksum database.
+Because the specific toolchain used depends on the system's own
+default toolchain as well as the local operating system and architecture (GOOS and GOARCH),
+it is not practical to write toolchain module checksums to `go.sum`.
+Instead, toolchain downloads fail for lack of verification if `GOSUMDB=off`.
+`GOPRIVATE` and `GONOSUMDB` patterns do not apply to the toolchain downloads.
+
+## Managing Go version module requirements with `go get` {#get}
+
+In general the `go` command treats the `go` and `toolchain` lines
+as declaring versioned toolchain dependencies of the main module.
+The `go get` command can manage these lines just as it manages
+the `require` lines that specify versioned module dependencies.
+
+For example, `go get go@1.22.1 toolchain@1.24rc1` changes the main module's
+`go.mod` file to read `go 1.22.1` and `toolchain go1.24rc1`.
+
+The `go` command understands that the `go` dependency requires a `toolchain` dependency
+with a greater or equal Go version.
+
+Continuing the example, a later `go get go@1.25.0` will update
+the toolchain to `go1.25.0` as well.
+When the toolchain matches the `go` line exactly, it can be
+omitted and implied, so this `go get` will delete the `toolchain` line.
+
+The same requirement applies in reverse when downgrading:
+if the `go.mod` starts at `go 1.22.1` and `toolchain go1.24rc1`,
+then `go get toolchain@go1.22.9` will update only the `toolchain` line,
+but `go get toolchain@go1.21.3` will downgrade the `go` line to
+`go 1.21.3` as well.
+The effect will be to leave just `go 1.21.3` with no `toolchain` line.
+
+The special form `toolchain@none` means to remove any `toolchain` line,
+as in `go get toolchain@none` or `go get go@1.25.0 toolchain@none`.
+
+The `go` command understands the version syntax for
+`go` and `toolchain` dependencies as well as queries.
+
+For example, just as `go get example.com/widget@v1.2` uses
+the latest `v1.2` version of `example.com/widget` (perhaps `v1.2.3`),
+`go get go@1.22` uses the latest available release of the Go 1.22 language version
+(perhaps `1.22rc3`, or perhaps `1.22.3`).
+The same applies to `go get toolchain@go1.22`.
+
+The `go get` and `go mod tidy` commands maintain the `go` line to
+be greater than or equal to the `go` line of any required dependency module.
+
+For example, if the main module has `go 1.22.1` and we run
+`go get example.com/widget@v1.2.3` which declares `go 1.24rc1`,
+then `go get` will update the main module's `go` line to `go 1.24rc1`.
+
+Continuing the example, a later `go get go@1.22.1` will
+downgrade `example.com/widget` to a version compatible with Go 1.22.1
+or else remove the requirement entirely,
+just as it would when downgrading any other dependency of `example.com/widget`.
+
+Before Go 1.21, the suggested way to update a module to a new Go version (say, Go 1.22)
+was `go mod tidy -go=1.22`, to make sure that any adjustments
+specific to Go 1.22 were made to the `go.mod` at the same time that the
+`go` line is updated.
+That form is still valid, but the simpler `go get go@1.22` is now preferred.
+
+When `go get` is run in a module in a directory contained in a workspace root,
+`go get` mostly ignores the workspace,
+but it does update the `go.work` file to upgrade the `go` line
+when the workspace would otherwise be left with too old a `go` line.
+
+## Managing Go version workspace requirements with `go work` (#work)
+
+As noted in the previous section, `go get` run in a directory
+inside a workspace root will take care to update the `go.work` file's `go` line
+as needed to be greater than or equal to any module inside that root.
+However, workspaces can also refer to modules outside the root directory;
+running `go get` in those directories may result in an invalid workspace
+configuration, one in which the `go` version declared in `go.work` is less
+than one or more of the modules in the `use` directives.
+
+The command `go work use`, which adds new `use` directives, also checks
+that the `go` version in the `go.work` file is new enough for all the
+existing `use` directives.
+To update a workspace that has gotten its `go` version out of sync
+with its modules, run `go work use` with no arguments.
+
+The commands `go work init` and `go work sync` also update the `go`
+version as needed.
+
+To remove the `toolchain` line from a `go.work` file, use
+`go work edit -toolchain=none`.
+
diff --git a/_content/ref/mod.md b/_content/ref/mod.md
index 849bcfa..b32ffe1 100644
--- a/_content/ref/mod.md
+++ b/_content/ref/mod.md
@@ -534,15 +534,17 @@
 ### `go` directive {#go-mod-file-go}
 
 A `go` directive indicates that a module was written assuming the semantics of a
-given version of Go. The version must be a valid Go release version: a positive
-integer followed by a dot and a non-negative integer (for example, `1.9`,
-`1.14`).
+given version of Go. The version must be a valid [Go release version](/doc/toolchain#version),
+such as `1.9`, `1.14`, or `1.21rc1`.
 
-The `go` directive was originally intended to support backward incompatible
-changes to the Go language (see [Go 2
-transition](https://go.googlesource.com/proposal/+/master/design/28221-go2-transitions.md)). There have been no incompatible
-language changes since modules were introduced, but the `go` directive still
-affects use of new language features:
+The `go` directive sets the minimum version of Go required to use this module.
+Before Go 1.21, the directive was advisory only; now it is a mandatory requirement:
+Go toolchains refuse to use modules declaring newer Go versions.
+
+The `go` directive is an input into selecting which Go toolchain to run.
+See “[/doc/toolchain](Go toolchains)” for details.
+
+The `go` directive affects use of new language features:
 
 * For packages within the module, the compiler rejects use of language features
   introduced after the version specified by the `go` directive. For example, if
@@ -554,8 +556,7 @@
   numeric literal `1_000_000`. If that package is built with Go 1.12, the
   compiler notes that the code is written for Go 1.13.
 
-Additionally, the `go` command changes its behavior based on the version
-specified by the `go` directive. This has the following effects:
+The `go` directive also affects the behavior of the `go` command:
 
 * At `go 1.14` or higher, automatic [vendoring](#vendoring) may be enabled.
   If the file `vendor/modules.txt` is present and consistent with `go.mod`,
@@ -583,13 +584,17 @@
      subdirectories of `vendor` to identify the correct main module.)
    * `go mod vendor` records the `go` version from each dependency's `go.mod`
      file in `vendor/modules.txt`.
+* At `go 1.21` or higher:
+   * The `go` line declares a required minimum version of Go to use with this module.
+   * The `go` line must be greater than or equal to the `go` line of all dependencies.
+   * The `go` command no longer attempts to maintain compatibility with the previous older version of Go.
+   * The `go` command is more careful about keeping checksums of `go.mod` files in the `go.sum` file.
 <!-- If you update this list, also update /doc/modules/gomod-ref#go-notes. -->
 
 A `go.mod` file may contain at most one `go` directive. Most commands will add a
 `go` directive with the current Go version if one is not present.
 
-As of the Go 1.17 release, if the `go` directive is missing, `go 1.16`
-is assumed.
+If the `go` directive is missing, `go 1.16` is assumed.
 
 ```
 GoDirective = "go" GoVersion newline .
@@ -602,6 +607,31 @@
 go 1.14
 ```
 
+### `toolchain` directive {#go-mod-file-toolchain}
+
+A `toolchain` directive declares a suggested Go toolchain to use with a module.
+The suggested Go toolchain's version cannot be less than the required Go version
+declared in the `go` directive.
+The `toolchain` directive
+only has an effect when the module is the main module and the default toolchain's
+version is less than the suggested toolchain's version.
+
+For reproducibility, the `go` command writes its own toolchain name in a `toolchain` line any time
+it is updating the `go` version in the `go.mod` file (usually during `go get`).
+
+For details, see “[/doc/toolchain](Go toolchains)”.
+
+```
+ToolchainDirective = "toolchain" ToolchainName newline .
+ToolchainName = string | ident .  /* valid toolchain name; see “Go toolchains” */
+```
+
+Example:
+
+```
+toolchain go1.21.0
+```
+
 ### `require` directive {#go-mod-file-require}
 
 A `require` directive declares a minimum required version of a given module
@@ -1160,6 +1190,7 @@
 ```
 GoWork = { Directive } .
 Directive = GoDirective |
+            ToolchainDirective |
             UseDirective |
             ReplaceDirective .
 ```
@@ -1176,7 +1207,7 @@
 Version = ident | string .    /* see restrictions above */
 ```
 
-### `go` directive {#go-mod-file-go}
+### `go` directive {#go-work-file-go}
 
 A `go` directive is required in a valid `go.work` file. The version must
 be a valid Go release version: a positive
@@ -1201,6 +1232,25 @@
 go 1.18
 ```
 
+### `toolchain` directive {#go-work-file-toolchain}
+
+A `toolchain` directive declares a suggested Go toolchain to use in a workspace.
+It only has an effect when the default toolchain
+is older than the suggested toolchain.
+
+For details, see “[/doc/toolchain](Go toolchains)”.
+
+```
+ToolchainDirective = "toolchain" ToolchainName newline .
+ToolchainName = string | ident .  /* valid toolchain name; see “Go toolchains” */
+```
+
+Example:
+
+```
+toolchain go1.21.0
+```
+
 ### `use` directive {#go-work-file-use}
 
 A `use` adds a module on disk to the set of main modules in a workspace.
@@ -1540,6 +1590,15 @@
 # Remove a dependency on a module and downgrade modules that require it
 # to versions that don't require it.
 $ go get golang.org/x/text@none
+
+# Upgrade the minimum required Go version for the main module.
+$ go get go
+
+# Upgrade the suggested Go toolchain, leaving the minimum Go version alone.
+$ go get toolchain
+
+# Upgrade to the latest patch release of the suggested Go toolchain.
+$ go get toolchain@patch
 ```
 
 The `go get` command updates module dependencies in the [`go.mod`