all: add godoc links

Change-Id: Ic9532893740b9952ca429106b3c373cc14d0383e
Reviewed-on: https://go-review.googlesource.com/c/mod/+/500875
Run-TryBot: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Oleksandr Redko <oleksandr.red@gmail.com>
Auto-Submit: Bryan Mills <bcmills@google.com>
diff --git a/README.md b/README.md
index 07d44f0..94da72d 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,8 @@
 It is NOT about supporting general development tools that
 need to do things like load packages in module mode.
 That use case, where modules are incidental rather than the focus,
-should remain in x/tools, specifically x/tools/go/packages.
+should remain in [x/tools](https://pkg.go.dev/golang/org/x/tools),
+specifically [x/tools/go/packages](https://pkg.go.dev/golang.org/x/tools/go/packages).
 
 The specific case of loading packages should still be done by
 invoking the go command, which remains the single point of
diff --git a/internal/lazyregexp/lazyre.go b/internal/lazyregexp/lazyre.go
index 2681af3..150f887 100644
--- a/internal/lazyregexp/lazyre.go
+++ b/internal/lazyregexp/lazyre.go
@@ -13,7 +13,7 @@
 	"sync"
 )
 
-// Regexp is a wrapper around regexp.Regexp, where the underlying regexp will be
+// Regexp is a wrapper around [regexp.Regexp], where the underlying regexp will be
 // compiled the first time it is needed.
 type Regexp struct {
 	str  string
diff --git a/modfile/read.go b/modfile/read.go
index a503bc2..5b5bb5e 100644
--- a/modfile/read.go
+++ b/modfile/read.go
@@ -65,7 +65,7 @@
 }
 
 // Comment returns the receiver. This isn't useful by itself, but
-// a Comments struct is embedded into all the expression
+// a [Comments] struct is embedded into all the expression
 // implementation types, and this gives each of those a Comment
 // method to satisfy the Expr interface.
 func (c *Comments) Comment() *Comments {
diff --git a/modfile/rule.go b/modfile/rule.go
index b4dd799..930b6c5 100644
--- a/modfile/rule.go
+++ b/modfile/rule.go
@@ -5,17 +5,17 @@
 // Package modfile implements a parser and formatter for go.mod files.
 //
 // The go.mod syntax is described in
-// https://golang.org/cmd/go/#hdr-The_go_mod_file.
+// https://pkg.go.dev/cmd/go/#hdr-The_go_mod_file.
 //
-// The Parse and ParseLax functions both parse a go.mod file and return an
+// The [Parse] and [ParseLax] functions both parse a go.mod file and return an
 // abstract syntax tree. ParseLax ignores unknown statements and may be used to
 // parse go.mod files that may have been developed with newer versions of Go.
 //
-// The File struct returned by Parse and ParseLax represent an abstract
-// go.mod file. File has several methods like AddNewRequire and DropReplace
-// that can be used to programmatically edit a file.
+// The [File] struct returned by Parse and ParseLax represent an abstract
+// go.mod file. File has several methods like [File.AddNewRequire] and
+// [File.DropReplace] that can be used to programmatically edit a file.
 //
-// The Format function formats a File back to a byte slice which can be
+// The [Format] function formats a File back to a byte slice which can be
 // written to a file.
 package modfile
 
@@ -226,7 +226,7 @@
 // data is the content of the file.
 //
 // fix is an optional function that canonicalizes module versions.
-// If fix is nil, all module versions must be canonical (module.CanonicalVersion
+// If fix is nil, all module versions must be canonical ([module.CanonicalVersion]
 // must return the same string).
 func Parse(file string, data []byte, fix VersionFixer) (*File, error) {
 	return parseToFile(file, data, fix, true)
@@ -923,7 +923,7 @@
 }
 
 // Cleanup cleans up the file f after any edit operations.
-// To avoid quadratic behavior, modifications like DropRequire
+// To avoid quadratic behavior, modifications like [File.DropRequire]
 // clear the entry but do not remove it from the slice.
 // Cleanup cleans out all the cleared entries.
 func (f *File) Cleanup() {
@@ -1075,8 +1075,8 @@
 // The requirements in req must specify at most one distinct version for each
 // module path.
 //
-// If any existing requirements may be removed, the caller should call Cleanup
-// after all edits are complete.
+// If any existing requirements may be removed, the caller should call
+// [File.Cleanup] after all edits are complete.
 func (f *File) SetRequire(req []*Require) {
 	type elem struct {
 		version  string
diff --git a/modfile/work.go b/modfile/work.go
index 75dc1c5..d7b9937 100644
--- a/modfile/work.go
+++ b/modfile/work.go
@@ -34,7 +34,7 @@
 // data is the content of the file.
 //
 // fix is an optional function that canonicalizes module versions.
-// If fix is nil, all module versions must be canonical (module.CanonicalVersion
+// If fix is nil, all module versions must be canonical ([module.CanonicalVersion]
 // must return the same string).
 func ParseWork(file string, data []byte, fix VersionFixer) (*WorkFile, error) {
 	fs, err := parse(file, data)
@@ -83,7 +83,7 @@
 }
 
 // Cleanup cleans up the file f after any edit operations.
-// To avoid quadratic behavior, modifications like DropRequire
+// To avoid quadratic behavior, modifications like [WorkFile.DropRequire]
 // clear the entry but do not remove it from the slice.
 // Cleanup cleans out all the cleared entries.
 func (f *WorkFile) Cleanup() {
diff --git a/module/module.go b/module/module.go
index e9dec6e..2a364b2 100644
--- a/module/module.go
+++ b/module/module.go
@@ -4,7 +4,7 @@
 
 // Package module defines the module.Version type along with support code.
 //
-// The module.Version type is a simple Path, Version pair:
+// The [module.Version] type is a simple Path, Version pair:
 //
 //	type Version struct {
 //		Path string
@@ -12,7 +12,7 @@
 //	}
 //
 // There are no restrictions imposed directly by use of this structure,
-// but additional checking functions, most notably Check, verify that
+// but additional checking functions, most notably [Check], verify that
 // a particular path, version pair is valid.
 //
 // # Escaped Paths
@@ -140,7 +140,7 @@
 	Err     error
 }
 
-// VersionError returns a ModuleError derived from a Version and error,
+// VersionError returns a [ModuleError] derived from a [Version] and error,
 // or err itself if it is already such an error.
 func VersionError(v Version, err error) error {
 	var mErr *ModuleError
@@ -169,7 +169,7 @@
 // An InvalidVersionError indicates an error specific to a version, with the
 // module path unknown or specified externally.
 //
-// A ModuleError may wrap an InvalidVersionError, but an InvalidVersionError
+// A [ModuleError] may wrap an InvalidVersionError, but an InvalidVersionError
 // must not wrap a ModuleError.
 type InvalidVersionError struct {
 	Version string
@@ -193,8 +193,8 @@
 func (e *InvalidVersionError) Unwrap() error { return e.Err }
 
 // An InvalidPathError indicates a module, import, or file path doesn't
-// satisfy all naming constraints. See CheckPath, CheckImportPath,
-// and CheckFilePath for specific restrictions.
+// satisfy all naming constraints. See [CheckPath], [CheckImportPath],
+// and [CheckFilePath] for specific restrictions.
 type InvalidPathError struct {
 	Kind string // "module", "import", or "file"
 	Path string
@@ -294,7 +294,7 @@
 }
 
 // CheckPath checks that a module path is valid.
-// A valid module path is a valid import path, as checked by CheckImportPath,
+// A valid module path is a valid import path, as checked by [CheckImportPath],
 // with three additional constraints.
 // First, the leading path element (up to the first slash, if any),
 // by convention a domain name, must contain only lower-case ASCII letters,
@@ -380,7 +380,7 @@
 // checkPath returns an error describing why the path is not valid.
 // Because these checks apply to module, import, and file paths,
 // and because other checks may be applied, the caller is expected to wrap
-// this error with InvalidPathError.
+// this error with [InvalidPathError].
 func checkPath(path string, kind pathKind) error {
 	if !utf8.ValidString(path) {
 		return fmt.Errorf("invalid UTF-8")
@@ -532,7 +532,7 @@
 // they require ".vN" instead of "/vN", and for all N, not just N >= 2.
 // SplitPathVersion returns with ok = false when presented with
 // a path whose last path element does not satisfy the constraints
-// applied by CheckPath, such as "example.com/pkg/v1" or "example.com/pkg/v1.2".
+// applied by [CheckPath], such as "example.com/pkg/v1" or "example.com/pkg/v1.2".
 func SplitPathVersion(path string) (prefix, pathMajor string, ok bool) {
 	if strings.HasPrefix(path, "gopkg.in/") {
 		return splitGopkgIn(path)
@@ -582,7 +582,7 @@
 // MatchPathMajor reports whether the semantic version v
 // matches the path major version pathMajor.
 //
-// MatchPathMajor returns true if and only if CheckPathMajor returns nil.
+// MatchPathMajor returns true if and only if [CheckPathMajor] returns nil.
 func MatchPathMajor(v, pathMajor string) bool {
 	return CheckPathMajor(v, pathMajor) == nil
 }
@@ -622,7 +622,7 @@
 // PathMajorPrefix returns the major-version tag prefix implied by pathMajor.
 // An empty PathMajorPrefix allows either v0 or v1.
 //
-// Note that MatchPathMajor may accept some versions that do not actually begin
+// Note that [MatchPathMajor] may accept some versions that do not actually begin
 // with this prefix: namely, it accepts a 'v0.0.0-' prefix for a '.v1'
 // pathMajor, even though that pathMajor implies 'v1' tagging.
 func PathMajorPrefix(pathMajor string) string {
@@ -643,7 +643,7 @@
 }
 
 // CanonicalVersion returns the canonical form of the version string v.
-// It is the same as semver.Canonical(v) except that it preserves the special build suffix "+incompatible".
+// It is the same as [semver.Canonical] except that it preserves the special build suffix "+incompatible".
 func CanonicalVersion(v string) string {
 	cv := semver.Canonical(v)
 	if semver.Build(v) == "+incompatible" {
@@ -652,8 +652,8 @@
 	return cv
 }
 
-// Sort sorts the list by Path, breaking ties by comparing Version fields.
-// The Version fields are interpreted as semantic versions (using semver.Compare)
+// Sort sorts the list by Path, breaking ties by comparing [Version] fields.
+// The Version fields are interpreted as semantic versions (using [semver.Compare])
 // optionally followed by a tie-breaking suffix introduced by a slash character,
 // like in "v0.0.1/go.mod".
 func Sort(list []Version) {
@@ -793,7 +793,7 @@
 }
 
 // MatchPrefixPatterns reports whether any path prefix of target matches one of
-// the glob patterns (as defined by path.Match) in the comma-separated globs
+// the glob patterns (as defined by [path.Match]) in the comma-separated globs
 // list. This implements the algorithm used when matching a module path to the
 // GOPRIVATE environment variable, as described by 'go help module-private'.
 //
diff --git a/module/pseudo.go b/module/pseudo.go
index f04ad37..9cf19d3 100644
--- a/module/pseudo.go
+++ b/module/pseudo.go
@@ -125,7 +125,7 @@
 }
 
 // IsZeroPseudoVersion returns whether v is a pseudo-version with a zero base,
-// timestamp, and revision, as returned by ZeroPseudoVersion.
+// timestamp, and revision, as returned by [ZeroPseudoVersion].
 func IsZeroPseudoVersion(v string) bool {
 	return v == ZeroPseudoVersion(semver.Major(v))
 }
diff --git a/semver/semver.go b/semver/semver.go
index a30a22b..9a2dfd3 100644
--- a/semver/semver.go
+++ b/semver/semver.go
@@ -140,7 +140,7 @@
 // Max canonicalizes its arguments and then returns the version string
 // that compares greater.
 //
-// Deprecated: use Compare instead. In most cases, returning a canonicalized
+// Deprecated: use [Compare] instead. In most cases, returning a canonicalized
 // version is not expected or desired.
 func Max(v, w string) string {
 	v = Canonical(v)
@@ -151,7 +151,7 @@
 	return w
 }
 
-// ByVersion implements sort.Interface for sorting semantic version strings.
+// ByVersion implements [sort.Interface] for sorting semantic version strings.
 type ByVersion []string
 
 func (vs ByVersion) Len() int      { return len(vs) }
@@ -164,7 +164,7 @@
 	return vs[i] < vs[j]
 }
 
-// Sort sorts a list of semantic version strings using ByVersion.
+// Sort sorts a list of semantic version strings using [ByVersion].
 func Sort(list []string) {
 	sort.Sort(ByVersion(list))
 }
diff --git a/sumdb/client.go b/sumdb/client.go
index 1c1b029..aecdc68 100644
--- a/sumdb/client.go
+++ b/sumdb/client.go
@@ -19,7 +19,7 @@
 )
 
 // A ClientOps provides the external operations
-// (file caching, HTTP fetches, and so on) needed by the Client.
+// (file caching, HTTP fetches, and so on) needed by the [Client].
 // The methods must be safe for concurrent use by multiple goroutines.
 type ClientOps interface {
 	// ReadRemote reads and returns the content served at the given path
@@ -72,7 +72,7 @@
 // ErrWriteConflict signals a write conflict during Client.WriteConfig.
 var ErrWriteConflict = errors.New("write conflict")
 
-// ErrSecurity is returned by Client operations that invoke Client.SecurityError.
+// ErrSecurity is returned by [Client] operations that invoke Client.SecurityError.
 var ErrSecurity = errors.New("security error: misbehaving server")
 
 // A Client is a client connection to a checksum database.
@@ -102,7 +102,7 @@
 	tileSaved   map[tlog.Tile]bool // which tiles have been saved using c.ops.WriteCache already
 }
 
-// NewClient returns a new Client using the given Client.
+// NewClient returns a new [Client] using the given [ClientOps].
 func NewClient(ops ClientOps) *Client {
 	return &Client{
 		ops: ops,
@@ -155,7 +155,7 @@
 }
 
 // SetTileHeight sets the tile height for the Client.
-// Any call to SetTileHeight must happen before the first call to Lookup.
+// Any call to SetTileHeight must happen before the first call to [Client.Lookup].
 // If SetTileHeight is not called, the Client defaults to tile height 8.
 // SetTileHeight can be called at most once,
 // and if so it must be called before the first call to Lookup.
@@ -174,7 +174,7 @@
 
 // SetGONOSUMDB sets the list of comma-separated GONOSUMDB patterns for the Client.
 // For any module path matching one of the patterns,
-// Lookup will return ErrGONOSUMDB.
+// [Client.Lookup] will return ErrGONOSUMDB.
 // SetGONOSUMDB can be called at most once,
 // and if so it must be called before the first call to Lookup.
 func (c *Client) SetGONOSUMDB(list string) {
@@ -187,8 +187,8 @@
 	c.nosumdb = list
 }
 
-// ErrGONOSUMDB is returned by Lookup for paths that match
-// a pattern listed in the GONOSUMDB list (set by SetGONOSUMDB,
+// ErrGONOSUMDB is returned by [Client.Lookup] for paths that match
+// a pattern listed in the GONOSUMDB list (set by [Client.SetGONOSUMDB],
 // usually from the environment variable).
 var ErrGONOSUMDB = errors.New("skipped (listed in GONOSUMDB)")
 
diff --git a/sumdb/note/note.go b/sumdb/note/note.go
index 8c22b19..db9865c 100644
--- a/sumdb/note/note.go
+++ b/sumdb/note/note.go
@@ -20,45 +20,45 @@
 //
 // # Verifying Notes
 //
-// A Verifier allows verification of signatures by one server public key.
+// A [Verifier] allows verification of signatures by one server public key.
 // It can report the name of the server and the uint32 hash of the key,
 // and it can verify a purported signature by that key.
 //
 // The standard implementation of a Verifier is constructed
-// by NewVerifier starting from a verifier key, which is a
+// by [NewVerifier] starting from a verifier key, which is a
 // plain text string of the form "<name>+<hash>+<keydata>".
 //
-// A Verifiers allows looking up a Verifier by the combination
+// A [Verifiers] allows looking up a Verifier by the combination
 // of server name and key hash.
 //
 // The standard implementation of a Verifiers is constructed
 // by VerifierList from a list of known verifiers.
 //
-// A Note represents a text with one or more signatures.
+// A [Note] represents a text with one or more signatures.
 // An implementation can reject a note with too many signatures
 // (for example, more than 100 signatures).
 //
-// A Signature represents a signature on a note, verified or not.
+// A [Signature] represents a signature on a note, verified or not.
 //
-// The Open function takes as input a signed message
+// The [Open] function takes as input a signed message
 // and a set of known verifiers. It decodes and verifies
-// the message signatures and returns a Note structure
+// the message signatures and returns a [Note] structure
 // containing the message text and (verified or unverified) signatures.
 //
 // # Signing Notes
 //
-// A Signer allows signing a text with a given key.
+// A [Signer] allows signing a text with a given key.
 // It can report the name of the server and the hash of the key
 // and can sign a raw text using that key.
 //
 // The standard implementation of a Signer is constructed
-// by NewSigner starting from an encoded signer key, which is a
+// by [NewSigner] starting from an encoded signer key, which is a
 // plain text string of the form "PRIVATE+KEY+<name>+<hash>+<keydata>".
 // Anyone with an encoded signer key can sign messages using that key,
 // so it must be kept secret. The encoding begins with the literal text
 // "PRIVATE+KEY" to avoid confusion with the public server key.
 //
-// The Sign function takes as input a Note and a list of Signers
+// The [Sign] function takes as input a Note and a list of Signers
 // and returns an encoded, signed message.
 //
 // # Signed Note Format
@@ -88,7 +88,7 @@
 // although doing so will require deploying the new algorithms to all clients
 // before starting to depend on them for signatures.
 //
-// The GenerateKey function generates and returns a new signer
+// The [GenerateKey] function generates and returns a new signer
 // and corresponding verifier.
 //
 // # Example
@@ -123,9 +123,9 @@
 // base URLs, the only syntactic requirement is that they
 // not contain spaces or newlines).
 //
-// If Open is given access to a Verifiers including the
-// Verifier for this key, then it will succeed at verifying
-// the encoded message and returning the parsed Note:
+// If [Open] is given access to a [Verifiers] including the
+// [Verifier] for this key, then it will succeed at verifying
+// the encoded message and returning the parsed [Note]:
 //
 //	vkey := "PeterNeumann+c74f20a3+ARpc2QcUPDhMQegwxbzhKqiBfsVkmqq/LDE4izWy10TW"
 //	msg := []byte("If you think cryptography is the answer to your problem,\n" +
@@ -238,7 +238,7 @@
 	return name != "" && utf8.ValidString(name) && strings.IndexFunc(name, unicode.IsSpace) < 0 && !strings.Contains(name, "+")
 }
 
-// NewVerifier construct a new Verifier from an encoded verifier key.
+// NewVerifier construct a new [Verifier] from an encoded verifier key.
 func NewVerifier(vkey string) (Verifier, error) {
 	name, vkey := chop(vkey, "+")
 	hash16, key64 := chop(vkey, "+")
@@ -295,7 +295,7 @@
 func (v *verifier) KeyHash() uint32             { return v.hash }
 func (v *verifier) Verify(msg, sig []byte) bool { return v.verify(msg, sig) }
 
-// NewSigner constructs a new Signer from an encoded signer key.
+// NewSigner constructs a new [Signer] from an encoded signer key.
 func NewSigner(skey string) (Signer, error) {
 	priv1, skey := chop(skey, "+")
 	priv2, skey := chop(skey, "+")
@@ -409,7 +409,7 @@
 }
 
 // An ambiguousVerifierError indicates that the given name and hash
-// match multiple keys passed to VerifierList.
+// match multiple keys passed to [VerifierList].
 // (If this happens, some malicious actor has taken control of the
 // verifier list, at which point we may as well give up entirely,
 // but we diagnose the problem instead.)
@@ -422,7 +422,7 @@
 	return fmt.Sprintf("ambiguous key %s+%08x", e.name, e.hash)
 }
 
-// VerifierList returns a Verifiers implementation that uses the given list of verifiers.
+// VerifierList returns a [Verifiers] implementation that uses the given list of verifiers.
 func VerifierList(list ...Verifier) Verifiers {
 	m := make(verifierMap)
 	for _, v := range list {
@@ -510,7 +510,7 @@
 // If known.Verifier returns any other error, Open returns that error.
 //
 // If no known verifier has signed an otherwise valid note,
-// Open returns an UnverifiedNoteError.
+// Open returns an [UnverifiedNoteError].
 // In this case, the unverified note can be fetched from inside the error.
 func Open(msg []byte, known Verifiers) (*Note, error) {
 	if known == nil {
diff --git a/sumdb/server.go b/sumdb/server.go
index 899bd46..1e1779d 100644
--- a/sumdb/server.go
+++ b/sumdb/server.go
@@ -17,7 +17,7 @@
 )
 
 // A ServerOps provides the external operations
-// (underlying database access and so on) needed by the Server.
+// (underlying database access and so on) needed by the [Server].
 type ServerOps interface {
 	// Signed returns the signed hash of the latest tree.
 	Signed(ctx context.Context) ([]byte, error)
@@ -36,7 +36,7 @@
 
 // A Server is the checksum database HTTP server,
 // which implements http.Handler and should be invoked
-// to serve the paths listed in ServerPaths.
+// to serve the paths listed in [ServerPaths].
 type Server struct {
 	ops ServerOps
 }
diff --git a/sumdb/storage/mem.go b/sumdb/storage/mem.go
index 9b7823d..6cba011 100644
--- a/sumdb/storage/mem.go
+++ b/sumdb/storage/mem.go
@@ -11,7 +11,7 @@
 	"sync"
 )
 
-// Mem is an in-memory implementation of Storage.
+// Mem is an in-memory implementation of [Storage].
 // It is meant for tests and does not store any data to persistent storage.
 //
 // The zero value is an empty Mem ready for use.
diff --git a/sumdb/storage/storage.go b/sumdb/storage/storage.go
index 1806380..ed5df49 100644
--- a/sumdb/storage/storage.go
+++ b/sumdb/storage/storage.go
@@ -27,7 +27,7 @@
 }
 
 // A Transaction provides read and write operations within a transaction,
-// as executed by Storage's ReadOnly or ReadWrite methods.
+// as executed by [Storage]'s ReadOnly or ReadWrite methods.
 type Transaction interface {
 	// ReadValue reads the value associated with a single key.
 	// If there is no value associated with that key, ReadKey returns an empty value.
diff --git a/sumdb/test.go b/sumdb/test.go
index c2755b8..fb77245 100644
--- a/sumdb/test.go
+++ b/sumdb/test.go
@@ -14,15 +14,15 @@
 	"golang.org/x/mod/sumdb/tlog"
 )
 
-// NewTestServer constructs a new TestServer
+// NewTestServer constructs a new [TestServer]
 // that will sign its tree with the given signer key
-// (see golang.org/x/mod/sumdb/note)
+// (see [golang.org/x/mod/sumdb/note])
 // and fetch new records as needed by calling gosum.
 func NewTestServer(signer string, gosum func(path, vers string) ([]byte, error)) *TestServer {
 	return &TestServer{signer: signer, gosum: gosum}
 }
 
-// A TestServer is an in-memory implementation of Server for testing.
+// A TestServer is an in-memory implementation of [ServerOps] for testing.
 type TestServer struct {
 	signer string
 	gosum  func(path, vers string) ([]byte, error)
diff --git a/sumdb/tlog/tile.go b/sumdb/tlog/tile.go
index e4aeb14..857d487 100644
--- a/sumdb/tlog/tile.go
+++ b/sumdb/tlog/tile.go
@@ -28,7 +28,7 @@
 // is tile/3/4/x001/x234/067.p/1, and
 // Tile{H: 3, L: 4, N: 1234067, W: 8}'s path
 // is tile/3/4/x001/x234/067.
-// See Tile's Path method and the ParseTilePath function.
+// See the [Tile.Path] method and the [ParseTilePath] function.
 //
 // The special level L=-1 holds raw record data instead of hashes.
 // In this case, the level encodes into a tile path as the path element
@@ -46,7 +46,7 @@
 // TileForIndex returns the tile of fixed height h ≥ 1
 // and least width storing the given hash storage index.
 //
-// If h ≤ 0, TileForIndex panics.
+// If h ≤ 0, [TileForIndex] panics.
 func TileForIndex(h int, index int64) Tile {
 	if h <= 0 {
 		panic(fmt.Sprintf("TileForIndex: invalid height %d", h))
@@ -105,7 +105,7 @@
 // size newTreeSize to replace a tree of size oldTreeSize.
 // (No tiles need to be published for a tree of size zero.)
 //
-// If h ≤ 0, TileForIndex panics.
+// If h ≤ 0, NewTiles panics.
 func NewTiles(h int, oldTreeSize, newTreeSize int64) []Tile {
 	if h <= 0 {
 		panic(fmt.Sprintf("NewTiles: invalid height %d", h))
@@ -272,7 +272,7 @@
 // TileHashReader returns a HashReader that satisfies requests
 // by loading tiles of the given tree.
 //
-// The returned HashReader checks that loaded tiles are
+// The returned [HashReader] checks that loaded tiles are
 // valid for the given tree. Therefore, any hashes returned
 // by the HashReader are already proven to be in the tree.
 func TileHashReader(tree Tree, tr TileReader) HashReader {
diff --git a/sumdb/tlog/tlog.go b/sumdb/tlog/tlog.go
index ae065f8..6a11a75 100644
--- a/sumdb/tlog/tlog.go
+++ b/sumdb/tlog/tlog.go
@@ -131,7 +131,7 @@
 	return i + int64(level)
 }
 
-// SplitStoredHashIndex is the inverse of StoredHashIndex.
+// SplitStoredHashIndex is the inverse of [StoredHashIndex].
 // That is, SplitStoredHashIndex(StoredHashIndex(level, n)) == level, n.
 func SplitStoredHashIndex(index int64) (level int, n int64) {
 	// Determine level 0 record before index.
@@ -183,7 +183,7 @@
 	return StoredHashesForRecordHash(n, RecordHash(data), r)
 }
 
-// StoredHashesForRecordHash is like StoredHashes but takes
+// StoredHashesForRecordHash is like [StoredHashes] but takes
 // as its second argument RecordHash(data) instead of data itself.
 func StoredHashesForRecordHash(n int64, h Hash, r HashReader) ([]Hash, error) {
 	// Start with the record hash.
@@ -227,7 +227,7 @@
 	ReadHashes(indexes []int64) ([]Hash, error)
 }
 
-// A HashReaderFunc is a function implementing HashReader.
+// A HashReaderFunc is a function implementing [HashReader].
 type HashReaderFunc func([]int64) ([]Hash, error)
 
 func (f HashReaderFunc) ReadHashes(indexes []int64) ([]Hash, error) {
diff --git a/zip/zip.go b/zip/zip.go
index d890b99..574f83f 100644
--- a/zip/zip.go
+++ b/zip/zip.go
@@ -10,31 +10,31 @@
 //
 // • All file paths within a zip file must start with "<module>@<version>/",
 // where "<module>" is the module path and "<version>" is the version.
-// The module path must be valid (see golang.org/x/mod/module.CheckPath).
+// The module path must be valid (see [golang.org/x/mod/module.CheckPath]).
 // The version must be valid and canonical (see
-// golang.org/x/mod/module.CanonicalVersion). The path must have a major
+// [golang.org/x/mod/module.CanonicalVersion]). The path must have a major
 // version suffix consistent with the version (see
-// golang.org/x/mod/module.Check). The part of the file path after the
+// [golang.org/x/mod/module.Check]). The part of the file path after the
 // "<module>@<version>/" prefix must be valid (see
-// golang.org/x/mod/module.CheckFilePath).
+// [golang.org/x/mod/module.CheckFilePath]).
 //
 // • No two file paths may be equal under Unicode case-folding (see
-// strings.EqualFold).
+// [strings.EqualFold]).
 //
 // • A go.mod file may or may not appear in the top-level directory. If present,
 // it must be named "go.mod", not any other case. Files named "go.mod"
 // are not allowed in any other directory.
 //
-// • The total size in bytes of a module zip file may be at most MaxZipFile
+// • The total size in bytes of a module zip file may be at most [MaxZipFile]
 // bytes (500 MiB). The total uncompressed size of the files within the
-// zip may also be at most MaxZipFile bytes.
+// zip may also be at most [MaxZipFile] bytes.
 //
 // • Each file's uncompressed size must match its declared 64-bit uncompressed
 // size in the zip file header.
 //
 // • If the zip contains files named "<module>@<version>/go.mod" or
 // "<module>@<version>/LICENSE", their sizes in bytes may be at most
-// MaxGoMod or MaxLICENSE, respectively (both are 16 MiB).
+// [MaxGoMod] or [MaxLICENSE], respectively (both are 16 MiB).
 //
 // • Empty directories are ignored. File permissions and timestamps are also
 // ignored.
@@ -42,7 +42,7 @@
 // • Symbolic links and other irregular files are not allowed.
 //
 // Note that this package does not provide hashing functionality. See
-// golang.org/x/mod/sumdb/dirhash.
+// [golang.org/x/mod/sumdb/dirhash].
 package zip
 
 import (
@@ -118,8 +118,9 @@
 	SizeError error
 }
 
-// Err returns an error if CheckedFiles does not describe a valid module zip
-// file. SizeError is returned if that field is set. A FileErrorList is returned
+// Err returns an error if [CheckedFiles] does not describe a valid module zip
+// file. [CheckedFiles.SizeError] is returned if that field is set.
+// A [FileErrorList] is returned
 // if there are one or more invalid files. Other errors may be returned in the
 // future.
 func (cf CheckedFiles) Err() error {
@@ -322,17 +323,17 @@
 }
 
 // CheckDir reports whether the files in dir satisfy the name and size
-// constraints listed in the package documentation. The returned CheckedFiles
+// constraints listed in the package documentation. The returned [CheckedFiles]
 // record contains lists of valid, invalid, and omitted files. If a directory is
 // omitted (for example, a nested module or vendor directory), it will appear in
 // the omitted list, but its files won't be listed.
 //
 // CheckDir returns an error if it encounters an I/O error or if the returned
-// CheckedFiles does not describe a valid module zip file (according to
-// CheckedFiles.Err). The returned CheckedFiles is still populated when such
+// [CheckedFiles] does not describe a valid module zip file (according to
+// [CheckedFiles.Err]). The returned [CheckedFiles] is still populated when such
 // an error is returned.
 //
-// Note that CheckDir will not open any files, so CreateFromDir may still fail
+// Note that CheckDir will not open any files, so [CreateFromDir] may still fail
 // when CheckDir is successful due to I/O errors.
 func CheckDir(dir string) (CheckedFiles, error) {
 	// List files (as CreateFromDir would) and check which ones are omitted
@@ -363,13 +364,13 @@
 // CheckZip reports whether the files contained in a zip file satisfy the name
 // and size constraints listed in the package documentation.
 //
-// CheckZip returns an error if the returned CheckedFiles does not describe
-// a valid module zip file (according to CheckedFiles.Err). The returned
+// CheckZip returns an error if the returned [CheckedFiles] does not describe
+// a valid module zip file (according to [CheckedFiles.Err]). The returned
 // CheckedFiles is still populated when an error is returned. CheckZip will
 // also return an error if the module path or version is malformed or if it
 // encounters an error reading the zip file.
 //
-// Note that CheckZip does not read individual files, so Unzip may still fail
+// Note that CheckZip does not read individual files, so [Unzip] may still fail
 // when CheckZip is successful due to I/O errors.
 func CheckZip(m module.Version, zipFile string) (CheckedFiles, error) {
 	f, err := os.Open(zipFile)
@@ -477,7 +478,7 @@
 // and writes it to w.
 //
 // Create verifies the restrictions described in the package documentation
-// and should not produce an archive that Unzip cannot extract. Create does not
+// and should not produce an archive that [Unzip] cannot extract. Create does not
 // include files in the output archive if they don't belong in the module zip.
 // In particular, Create will not include files in modules found in
 // subdirectories, most files in vendor directories, or irregular files (such
@@ -544,12 +545,12 @@
 // a directory, dir. The zip content is written to w.
 //
 // CreateFromDir verifies the restrictions described in the package
-// documentation and should not produce an archive that Unzip cannot extract.
+// documentation and should not produce an archive that [Unzip] cannot extract.
 // CreateFromDir does not include files in the output archive if they don't
 // belong in the module zip. In particular, CreateFromDir will not include
 // files in modules found in subdirectories, most files in vendor directories,
 // or irregular files (such as symbolic links) in the output archive.
-// Additionally, unlike Create, CreateFromDir will not include directories
+// Additionally, unlike [Create], CreateFromDir will not include directories
 // named ".bzr", ".git", ".hg", or ".svn".
 func CreateFromDir(w io.Writer, m module.Version, dir string) (err error) {
 	defer func() {
@@ -581,8 +582,8 @@
 // "sub/dir". To create a zip from the base of the repository, pass an empty
 // string.
 //
-// If CreateFromVCS returns UnrecognizedVCSError, consider falling back to
-// CreateFromDir.
+// If CreateFromVCS returns [UnrecognizedVCSError], consider falling back to
+// [CreateFromDir].
 func CreateFromVCS(w io.Writer, m module.Version, repoRoot, revision, subdir string) (err error) {
 	defer func() {
 		if zerr, ok := err.(*zipError); ok {