all: modernize with doc links and any

Change-Id: If3fc4542b92da802a31dcabc3405f7b1ab06a18d
Reviewed-on: https://go-review.googlesource.com/c/oauth2/+/666396
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Junyang Shao <shaojunyang@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
Auto-Submit: Sean Liao <sean@liao.dev>
Reviewed-by: Matt Hickford <matt.hickford@gmail.com>
diff --git a/authhandler/authhandler.go b/authhandler/authhandler.go
index 9bc6cd7..46d1396 100644
--- a/authhandler/authhandler.go
+++ b/authhandler/authhandler.go
@@ -34,7 +34,7 @@
 // and returns an auth code and state upon approval.
 type AuthorizationHandler func(authCodeURL string) (code string, state string, err error)
 
-// TokenSourceWithPKCE is an enhanced version of TokenSource with PKCE support.
+// TokenSourceWithPKCE is an enhanced version of [oauth2.TokenSource] with PKCE support.
 //
 // The pkce parameter supports PKCE flow, which uses code challenge and code verifier
 // to prevent CSRF attacks. A unique code challenge and code verifier should be generated
@@ -43,12 +43,12 @@
 	return oauth2.ReuseTokenSource(nil, authHandlerSource{config: config, ctx: ctx, authHandler: authHandler, state: state, pkce: pkce})
 }
 
-// TokenSource returns an oauth2.TokenSource that fetches access tokens
+// TokenSource returns an [oauth2.TokenSource] that fetches access tokens
 // using 3-legged-OAuth flow.
 //
-// The provided context.Context is used for oauth2 Exchange operation.
+// The provided [context.Context] is used for oauth2 Exchange operation.
 //
-// The provided oauth2.Config should be a full configuration containing AuthURL,
+// The provided [oauth2.Config] should be a full configuration containing AuthURL,
 // TokenURL, and Scope.
 //
 // An environment-specific AuthorizationHandler is used to obtain user consent.
diff --git a/clientcredentials/clientcredentials.go b/clientcredentials/clientcredentials.go
index 51121a3..e86346e 100644
--- a/clientcredentials/clientcredentials.go
+++ b/clientcredentials/clientcredentials.go
@@ -55,7 +55,7 @@
 
 // Token uses client credentials to retrieve a token.
 //
-// The provided context optionally controls which HTTP client is used. See the oauth2.HTTPClient variable.
+// The provided context optionally controls which HTTP client is used. See the [oauth2.HTTPClient] variable.
 func (c *Config) Token(ctx context.Context) (*oauth2.Token, error) {
 	return c.TokenSource(ctx).Token()
 }
@@ -64,18 +64,18 @@
 // The token will auto-refresh as necessary.
 //
 // The provided context optionally controls which HTTP client
-// is returned. See the oauth2.HTTPClient variable.
+// is returned. See the [oauth2.HTTPClient] variable.
 //
-// The returned Client and its Transport should not be modified.
+// The returned [http.Client] and its Transport should not be modified.
 func (c *Config) Client(ctx context.Context) *http.Client {
 	return oauth2.NewClient(ctx, c.TokenSource(ctx))
 }
 
-// TokenSource returns a TokenSource that returns t until t expires,
+// TokenSource returns a [oauth2.TokenSource] that returns t until t expires,
 // automatically refreshing it as necessary using the provided context and the
 // client ID and client secret.
 //
-// Most users will use Config.Client instead.
+// Most users will use [Config.Client] instead.
 func (c *Config) TokenSource(ctx context.Context) oauth2.TokenSource {
 	source := &tokenSource{
 		ctx:  ctx,
diff --git a/google/externalaccount/basecredentials.go b/google/externalaccount/basecredentials.go
index aa0bba2..6f76621 100644
--- a/google/externalaccount/basecredentials.go
+++ b/google/externalaccount/basecredentials.go
@@ -486,11 +486,11 @@
 		ClientID:     conf.ClientID,
 		ClientSecret: conf.ClientSecret,
 	}
-	var options map[string]interface{}
+	var options map[string]any
 	// Do not pass workforce_pool_user_project when client authentication is used.
 	// The client ID is sufficient for determining the user project.
 	if conf.WorkforcePoolUserProject != "" && conf.ClientID == "" {
-		options = map[string]interface{}{
+		options = map[string]any{
 			"userProject": conf.WorkforcePoolUserProject,
 		}
 	}
diff --git a/google/externalaccount/filecredsource.go b/google/externalaccount/filecredsource.go
index d1a3d70..46ebc18 100644
--- a/google/externalaccount/filecredsource.go
+++ b/google/externalaccount/filecredsource.go
@@ -35,7 +35,7 @@
 	tokenBytes = bytes.TrimSpace(tokenBytes)
 	switch cs.Format.Type {
 	case "json":
-		jsonData := make(map[string]interface{})
+		jsonData := make(map[string]any)
 		err = json.Unmarshal(tokenBytes, &jsonData)
 		if err != nil {
 			return "", fmt.Errorf("oauth2/google/externalaccount: failed to unmarshal subject token file: %v", err)
diff --git a/google/externalaccount/urlcredsource.go b/google/externalaccount/urlcredsource.go
index 1e595fa..65bfd20 100644
--- a/google/externalaccount/urlcredsource.go
+++ b/google/externalaccount/urlcredsource.go
@@ -53,7 +53,7 @@
 
 	switch cs.Format.Type {
 	case "json":
-		jsonData := make(map[string]interface{})
+		jsonData := make(map[string]any)
 		err = json.Unmarshal(respBody, &jsonData)
 		if err != nil {
 			return "", fmt.Errorf("oauth2/google/externalaccount: failed to unmarshal subject token file: %v", err)
diff --git a/google/google.go b/google/google.go
index 61b98d1..e2eb9c9 100644
--- a/google/google.go
+++ b/google/google.go
@@ -301,7 +301,7 @@
 	// NOTE(cbro): add hidden metadata about where the token is from.
 	// This is needed for detection by client libraries to know that credentials come from the metadata server.
 	// This may be removed in a future version of this library.
-	return tok.WithExtra(map[string]interface{}{
+	return tok.WithExtra(map[string]any{
 		"oauth2.google.tokenSource":    "compute-metadata",
 		"oauth2.google.serviceAccount": acct,
 	}), nil
diff --git a/google/internal/stsexchange/sts_exchange.go b/google/internal/stsexchange/sts_exchange.go
index 9557f7c..edf700e 100644
--- a/google/internal/stsexchange/sts_exchange.go
+++ b/google/internal/stsexchange/sts_exchange.go
@@ -27,7 +27,7 @@
 // The first 4 fields are all mandatory.  headers can be used to pass additional
 // headers beyond the bare minimum required by the token exchange.  options can
 // be used to pass additional JSON-structured options to the remote server.
-func ExchangeToken(ctx context.Context, endpoint string, request *TokenExchangeRequest, authentication ClientAuthentication, headers http.Header, options map[string]interface{}) (*Response, error) {
+func ExchangeToken(ctx context.Context, endpoint string, request *TokenExchangeRequest, authentication ClientAuthentication, headers http.Header, options map[string]any) (*Response, error) {
 	data := url.Values{}
 	data.Set("audience", request.Audience)
 	data.Set("grant_type", "urn:ietf:params:oauth:grant-type:token-exchange")
diff --git a/google/internal/stsexchange/sts_exchange_test.go b/google/internal/stsexchange/sts_exchange_test.go
index 05b8dc3..1cac582 100644
--- a/google/internal/stsexchange/sts_exchange_test.go
+++ b/google/internal/stsexchange/sts_exchange_test.go
@@ -146,7 +146,7 @@
 		} else if len(strOpts) < 1 {
 			t.Errorf("\"options\" field has length 0.")
 		}
-		var opts map[string]interface{}
+		var opts map[string]any
 		err = json.Unmarshal([]byte(strOpts[0]), &opts)
 		if err != nil {
 			t.Fatalf("Couldn't parse received \"options\" field.")
@@ -159,7 +159,7 @@
 		if !ok {
 			t.Errorf("Couldn't find first option parameter.")
 		} else {
-			tOpts1, ok := val.(map[string]interface{})
+			tOpts1, ok := val.(map[string]any)
 			if !ok {
 				t.Errorf("Failed to assert the first option parameter as type testOpts.")
 			} else {
@@ -176,7 +176,7 @@
 		if !ok {
 			t.Errorf("Couldn't find second option parameter.")
 		} else {
-			tOpts2, ok := val2.(map[string]interface{})
+			tOpts2, ok := val2.(map[string]any)
 			if !ok {
 				t.Errorf("Failed to assert the second option parameter as type testOpts.")
 			} else {
@@ -200,7 +200,7 @@
 
 	firstOption := testOpts{optsValues[0][0], optsValues[0][1]}
 	secondOption := testOpts{optsValues[1][0], optsValues[1][1]}
-	inputOpts := make(map[string]interface{})
+	inputOpts := make(map[string]any)
 	inputOpts["one"] = firstOption
 	inputOpts["two"] = secondOption
 	ExchangeToken(context.Background(), ts.URL, &exchangeTokenRequest, auth, headers, inputOpts)
diff --git a/internal/doc.go b/internal/doc.go
index 03265e8..8c7c475 100644
--- a/internal/doc.go
+++ b/internal/doc.go
@@ -2,5 +2,5 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Package internal contains support packages for oauth2 package.
+// Package internal contains support packages for [golang.org/x/oauth2].
 package internal
diff --git a/internal/oauth2.go b/internal/oauth2.go
index 14989be..71ea6ad 100644
--- a/internal/oauth2.go
+++ b/internal/oauth2.go
@@ -13,7 +13,7 @@
 )
 
 // ParseKey converts the binary contents of a private key file
-// to an *rsa.PrivateKey. It detects whether the private key is in a
+// to an [*rsa.PrivateKey]. It detects whether the private key is in a
 // PEM container or not. If so, it extracts the private key
 // from PEM container before conversion. It only supports PEM
 // containers with no passphrase.
diff --git a/internal/token.go b/internal/token.go
index 17746d6..f1bd44b 100644
--- a/internal/token.go
+++ b/internal/token.go
@@ -25,9 +25,9 @@
 // the requests to access protected resources on the OAuth 2.0
 // provider's backend.
 //
-// This type is a mirror of oauth2.Token and exists to break
+// This type is a mirror of [golang.org/x/oauth2.Token] and exists to break
 // an otherwise-circular dependency. Other internal packages
-// should convert this Token into an oauth2.Token before use.
+// should convert this Token into an [golang.org/x/oauth2.Token] before use.
 type Token struct {
 	// AccessToken is the token that authorizes and authenticates
 	// the requests.
@@ -58,7 +58,7 @@
 
 	// Raw optionally contains extra metadata from the server
 	// when updating a token.
-	Raw interface{}
+	Raw any
 }
 
 // tokenJSON is the struct representing the HTTP response from OAuth2
@@ -319,7 +319,7 @@
 			RefreshToken: tj.RefreshToken,
 			Expiry:       tj.expiry(),
 			ExpiresIn:    int64(tj.ExpiresIn),
-			Raw:          make(map[string]interface{}),
+			Raw:          make(map[string]any),
 		}
 		json.Unmarshal(body, &token.Raw) // no error checks for optional fields
 	}
diff --git a/internal/transport.go b/internal/transport.go
index cb9656f..afc0aeb 100644
--- a/internal/transport.go
+++ b/internal/transport.go
@@ -9,8 +9,8 @@
 	"net/http"
 )
 
-// HTTPClient is the context key to use with [context.WithValue]'s
-// function to associate an *http.Client value with a context.
+// HTTPClient is the context key to use with [context.WithValue]
+// to associate an [*http.Client] value with a context.
 var HTTPClient ContextKey
 
 // ContextKey is just an empty struct. It exists so HTTPClient can be
diff --git a/jws/jws.go b/jws/jws.go
index 27ab061..9bc4844 100644
--- a/jws/jws.go
+++ b/jws/jws.go
@@ -4,7 +4,7 @@
 
 // Package jws provides a partial implementation
 // of JSON Web Signature encoding and decoding.
-// It exists to support the golang.org/x/oauth2 package.
+// It exists to support the [golang.org/x/oauth2] package.
 //
 // See RFC 7515.
 //
@@ -48,7 +48,7 @@
 
 	// See http://tools.ietf.org/html/draft-jones-json-web-token-10#section-4.3
 	// This array is marshalled using custom code (see (c *ClaimSet) encode()).
-	PrivateClaims map[string]interface{} `json:"-"`
+	PrivateClaims map[string]any `json:"-"`
 }
 
 func (c *ClaimSet) encode() (string, error) {
@@ -152,7 +152,7 @@
 }
 
 // Encode encodes a signed JWS with provided header and claim set.
-// This invokes EncodeWithSigner using crypto/rsa.SignPKCS1v15 with the given RSA private key.
+// This invokes [EncodeWithSigner] using [crypto/rsa.SignPKCS1v15] with the given RSA private key.
 func Encode(header *Header, c *ClaimSet, key *rsa.PrivateKey) (string, error) {
 	sg := func(data []byte) (sig []byte, err error) {
 		h := sha256.New()
diff --git a/jwt/jwt.go b/jwt/jwt.go
index cbe7f8c..38a92da 100644
--- a/jwt/jwt.go
+++ b/jwt/jwt.go
@@ -68,7 +68,7 @@
 
 	// PrivateClaims optionally specifies custom private claims in the JWT.
 	// See http://tools.ietf.org/html/draft-jones-json-web-token-10#section-4.3
-	PrivateClaims map[string]interface{}
+	PrivateClaims map[string]any
 
 	// UseIDToken optionally specifies whether ID token should be used instead
 	// of access token when the server returns both.
@@ -157,7 +157,7 @@
 		AccessToken: tokenRes.AccessToken,
 		TokenType:   tokenRes.TokenType,
 	}
-	raw := make(map[string]interface{})
+	raw := make(map[string]any)
 	json.Unmarshal(body, &raw) // no error checks for optional fields
 	token = token.WithExtra(raw)
 
diff --git a/jwt/jwt_test.go b/jwt/jwt_test.go
index 9772dc5..c7619a1 100644
--- a/jwt/jwt_test.go
+++ b/jwt/jwt_test.go
@@ -227,7 +227,7 @@
 			PrivateKey:   dummyPrivateKey,
 			PrivateKeyID: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
 			TokenURL:     ts.URL,
-			PrivateClaims: map[string]interface{}{
+			PrivateClaims: map[string]any{
 				"private0": "claim0",
 				"private1": "claim1",
 			},
@@ -273,11 +273,11 @@
 				t.Errorf("payload prn = %q; want %q", got, want)
 			}
 			if len(conf.PrivateClaims) > 0 {
-				var got interface{}
+				var got any
 				if err := json.Unmarshal(gotjson, &got); err != nil {
 					t.Errorf("failed to parse payload; err = %q", err)
 				}
-				m := got.(map[string]interface{})
+				m := got.(map[string]any)
 				for v, k := range conf.PrivateClaims {
 					if !reflect.DeepEqual(m[v], k) {
 						t.Errorf("payload private claims key = %q: got %#v; want %#v", v, m[v], k)
diff --git a/oauth2.go b/oauth2.go
index 52a085a..de34feb 100644
--- a/oauth2.go
+++ b/oauth2.go
@@ -24,7 +24,7 @@
 // NoContext is the default context you should supply if not using
 // your own [context.Context].
 //
-// Deprecated: Use context.Background() or context.TODO() instead.
+// Deprecated: Use [context.Background] or [context.TODO] instead.
 var NoContext = context.TODO()
 
 // RegisterBrokenAuthHeaderProvider previously did something. It is now a no-op.
@@ -37,8 +37,8 @@
 
 // Config describes a typical 3-legged OAuth2 flow, with both the
 // client application information and the server's endpoint URLs.
-// For the client credentials 2-legged OAuth2 flow, see the clientcredentials
-// package (https://golang.org/x/oauth2/clientcredentials).
+// For the client credentials 2-legged OAuth2 flow, see the
+// [golang.org/x/oauth2/clientcredentials] package.
 type Config struct {
 	// ClientID is the application's ID.
 	ClientID string
@@ -46,7 +46,7 @@
 	// ClientSecret is the application's secret.
 	ClientSecret string
 
-	// Endpoint contains the resource server's token endpoint
+	// Endpoint contains the authorization server's token endpoint
 	// URLs. These are constants specific to each server and are
 	// often available via site-specific packages, such as
 	// google.Endpoint or github.Endpoint.
@@ -135,7 +135,7 @@
 
 func (p setParam) setValue(m url.Values) { m.Set(p.k, p.v) }
 
-// SetAuthURLParam builds an AuthCodeOption which passes key/value parameters
+// SetAuthURLParam builds an [AuthCodeOption] which passes key/value parameters
 // to a provider's authorization endpoint.
 func SetAuthURLParam(key, value string) AuthCodeOption {
 	return setParam{key, value}
@@ -148,8 +148,8 @@
 // request and callback. The authorization server includes this value when
 // redirecting the user agent back to the client.
 //
-// Opts may include AccessTypeOnline or AccessTypeOffline, as well
-// as ApprovalForce.
+// Opts may include [AccessTypeOnline] or [AccessTypeOffline], as well
+// as [ApprovalForce].
 //
 // To protect against CSRF attacks, opts should include a PKCE challenge
 // (S256ChallengeOption). Not all servers support PKCE. An alternative is to
@@ -194,7 +194,7 @@
 // and when other authorization grant types are not available."
 // See https://tools.ietf.org/html/rfc6749#section-4.3 for more info.
 //
-// The provided context optionally controls which HTTP client is used. See the HTTPClient variable.
+// The provided context optionally controls which HTTP client is used. See the [HTTPClient] variable.
 func (c *Config) PasswordCredentialsToken(ctx context.Context, username, password string) (*Token, error) {
 	v := url.Values{
 		"grant_type": {"password"},
@@ -212,10 +212,10 @@
 // It is used after a resource provider redirects the user back
 // to the Redirect URI (the URL obtained from AuthCodeURL).
 //
-// The provided context optionally controls which HTTP client is used. See the HTTPClient variable.
+// The provided context optionally controls which HTTP client is used. See the [HTTPClient] variable.
 //
-// The code will be in the *http.Request.FormValue("code"). Before
-// calling Exchange, be sure to validate FormValue("state") if you are
+// The code will be in the [http.Request.FormValue]("code"). Before
+// calling Exchange, be sure to validate [http.Request.FormValue]("state") if you are
 // using it to protect against CSRF attacks.
 //
 // If using PKCE to protect against CSRF attacks, opts should include a
@@ -242,10 +242,10 @@
 	return NewClient(ctx, c.TokenSource(ctx, t))
 }
 
-// TokenSource returns a TokenSource that returns t until t expires,
+// TokenSource returns a [TokenSource] that returns t until t expires,
 // automatically refreshing it as necessary using the provided context.
 //
-// Most users will use Config.Client instead.
+// Most users will use [Config.Client] instead.
 func (c *Config) TokenSource(ctx context.Context, t *Token) TokenSource {
 	tkr := &tokenRefresher{
 		ctx:  ctx,
@@ -260,7 +260,7 @@
 	}
 }
 
-// tokenRefresher is a TokenSource that makes "grant_type"=="refresh_token"
+// tokenRefresher is a TokenSource that makes "grant_type=refresh_token"
 // HTTP requests to renew a token using a RefreshToken.
 type tokenRefresher struct {
 	ctx          context.Context // used to get HTTP requests
@@ -305,8 +305,7 @@
 }
 
 // Token returns the current token if it's still valid, else will
-// refresh the current token (using r.Context for HTTP client
-// information) and return the new one.
+// refresh the current token and return the new one.
 func (s *reuseTokenSource) Token() (*Token, error) {
 	s.mu.Lock()
 	defer s.mu.Unlock()
@@ -322,7 +321,7 @@
 	return t, nil
 }
 
-// StaticTokenSource returns a TokenSource that always returns the same token.
+// StaticTokenSource returns a [TokenSource] that always returns the same token.
 // Because the provided token t is never refreshed, StaticTokenSource is only
 // useful for tokens that never expire.
 func StaticTokenSource(t *Token) TokenSource {
@@ -338,16 +337,16 @@
 	return s.t, nil
 }
 
-// HTTPClient is the context key to use with [context.WithValue]'s
-// function to associate an *http.Client value with a context.
+// HTTPClient is the context key to use with [context.WithValue]
+// to associate a [*http.Client] value with a context.
 var HTTPClient internal.ContextKey
 
-// NewClient creates an *http.Client from a Context and TokenSource.
+// NewClient creates an [*http.Client] from a [context.Context] and [TokenSource].
 // The returned client is not valid beyond the lifetime of the context.
 //
-// Note that if a custom *http.Client is provided via the Context it
+// Note that if a custom [*http.Client] is provided via the [context.Context] it
 // is used only for token acquisition and is not used to configure the
-// *http.Client returned from NewClient.
+// [*http.Client] returned from NewClient.
 //
 // As a special case, if src is nil, a non-OAuth2 client is returned
 // using the provided context. This exists to support related OAuth2
@@ -368,7 +367,7 @@
 	}
 }
 
-// ReuseTokenSource returns a TokenSource which repeatedly returns the
+// ReuseTokenSource returns a [TokenSource] which repeatedly returns the
 // same token as long as it's valid, starting with t.
 // When its cached token is invalid, a new token is obtained from src.
 //
@@ -376,10 +375,10 @@
 // (such as a file on disk) between runs of a program, rather than
 // obtaining new tokens unnecessarily.
 //
-// The initial token t may be nil, in which case the TokenSource is
+// The initial token t may be nil, in which case the [TokenSource] is
 // wrapped in a caching version if it isn't one already. This also
 // means it's always safe to wrap ReuseTokenSource around any other
-// TokenSource without adverse effects.
+// [TokenSource] without adverse effects.
 func ReuseTokenSource(t *Token, src TokenSource) TokenSource {
 	// Don't wrap a reuseTokenSource in itself. That would work,
 	// but cause an unnecessary number of mutex operations.
@@ -397,8 +396,8 @@
 	}
 }
 
-// ReuseTokenSourceWithExpiry returns a TokenSource that acts in the same manner as the
-// TokenSource returned by ReuseTokenSource, except the expiry buffer is
+// ReuseTokenSourceWithExpiry returns a [TokenSource] that acts in the same manner as the
+// [TokenSource] returned by [ReuseTokenSource], except the expiry buffer is
 // configurable. The expiration time of a token is calculated as
 // t.Expiry.Add(-earlyExpiry).
 func ReuseTokenSourceWithExpiry(t *Token, src TokenSource, earlyExpiry time.Duration) TokenSource {
diff --git a/pkce.go b/pkce.go
index 6a95da9..cea8374 100644
--- a/pkce.go
+++ b/pkce.go
@@ -1,6 +1,7 @@
 // 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 oauth2
 
 import (
@@ -20,9 +21,9 @@
 // This follows recommendations in RFC 7636.
 //
 // A fresh verifier should be generated for each authorization.
-// S256ChallengeOption(verifier) should then be passed to Config.AuthCodeURL
-// (or Config.DeviceAuth) and VerifierOption(verifier) to Config.Exchange
-// (or Config.DeviceAccessToken).
+// The resulting verifier should be passed to [Config.AuthCodeURL] or [Config.DeviceAuth]
+// with [S256ChallengeOption], and to [Config.Exchange] or [Config.DeviceAccessToken]
+// with [VerifierOption].
 func GenerateVerifier() string {
 	// "RECOMMENDED that the output of a suitable random number generator be
 	// used to create a 32-octet sequence.  The octet sequence is then
@@ -36,22 +37,22 @@
 	return base64.RawURLEncoding.EncodeToString(data)
 }
 
-// VerifierOption returns a PKCE code verifier AuthCodeOption. It should be
-// passed to Config.Exchange or Config.DeviceAccessToken only.
+// VerifierOption returns a PKCE code verifier [AuthCodeOption]. It should only be
+// passed to [Config.Exchange] or [Config.DeviceAccessToken].
 func VerifierOption(verifier string) AuthCodeOption {
 	return setParam{k: codeVerifierKey, v: verifier}
 }
 
 // S256ChallengeFromVerifier returns a PKCE code challenge derived from verifier with method S256.
 //
-// Prefer to use S256ChallengeOption where possible.
+// Prefer to use [S256ChallengeOption] where possible.
 func S256ChallengeFromVerifier(verifier string) string {
 	sha := sha256.Sum256([]byte(verifier))
 	return base64.RawURLEncoding.EncodeToString(sha[:])
 }
 
 // S256ChallengeOption derives a PKCE code challenge derived from verifier with
-// method S256. It should be passed to Config.AuthCodeURL or Config.DeviceAuth
+// method S256. It should be passed to [Config.AuthCodeURL] or [Config.DeviceAuth]
 // only.
 func S256ChallengeOption(verifier string) AuthCodeOption {
 	return challengeOption{
diff --git a/token.go b/token.go
index bb7545e..239ec32 100644
--- a/token.go
+++ b/token.go
@@ -44,7 +44,7 @@
 
 	// Expiry is the optional expiration time of the access token.
 	//
-	// If zero, TokenSource implementations will reuse the same
+	// If zero, [TokenSource] implementations will reuse the same
 	// token forever and RefreshToken or equivalent
 	// mechanisms for that TokenSource will not be used.
 	Expiry time.Time `json:"expiry,omitempty"`
@@ -58,7 +58,7 @@
 
 	// raw optionally contains extra metadata from the server
 	// when updating a token.
-	raw interface{}
+	raw any
 
 	// expiryDelta is used to calculate when a token is considered
 	// expired, by subtracting from Expiry. If zero, defaultExpiryDelta
@@ -86,16 +86,16 @@
 // SetAuthHeader sets the Authorization header to r using the access
 // token in t.
 //
-// This method is unnecessary when using Transport or an HTTP Client
+// This method is unnecessary when using [Transport] or an HTTP Client
 // returned by this package.
 func (t *Token) SetAuthHeader(r *http.Request) {
 	r.Header.Set("Authorization", t.Type()+" "+t.AccessToken)
 }
 
-// WithExtra returns a new Token that's a clone of t, but using the
+// WithExtra returns a new [Token] that's a clone of t, but using the
 // provided raw extra map. This is only intended for use by packages
 // implementing derivative OAuth2 flows.
-func (t *Token) WithExtra(extra interface{}) *Token {
+func (t *Token) WithExtra(extra any) *Token {
 	t2 := new(Token)
 	*t2 = *t
 	t2.raw = extra
@@ -105,8 +105,8 @@
 // Extra returns an extra field.
 // Extra fields are key-value pairs returned by the server as a
 // part of the token retrieval response.
-func (t *Token) Extra(key string) interface{} {
-	if raw, ok := t.raw.(map[string]interface{}); ok {
+func (t *Token) Extra(key string) any {
+	if raw, ok := t.raw.(map[string]any); ok {
 		return raw[key]
 	}
 
diff --git a/token_test.go b/token_test.go
index 0d8c7df..5fa14fa 100644
--- a/token_test.go
+++ b/token_test.go
@@ -12,8 +12,8 @@
 func TestTokenExtra(t *testing.T) {
 	type testCase struct {
 		key  string
-		val  interface{}
-		want interface{}
+		val  any
+		want any
 	}
 	const key = "extra-key"
 	cases := []testCase{
@@ -23,7 +23,7 @@
 		{key: "other-key", val: "def", want: nil},
 	}
 	for _, tc := range cases {
-		extra := make(map[string]interface{})
+		extra := make(map[string]any)
 		extra[tc.key] = tc.val
 		tok := &Token{raw: extra}
 		if got, want := tok.Extra(key), tc.want; got != want {
diff --git a/transport.go b/transport.go
index 9065791..8bbebba 100644
--- a/transport.go
+++ b/transport.go
@@ -11,12 +11,12 @@
 	"sync"
 )
 
-// Transport is an http.RoundTripper that makes OAuth 2.0 HTTP requests,
-// wrapping a base RoundTripper and adding an Authorization header
-// with a token from the supplied Sources.
+// Transport is an [http.RoundTripper] that makes OAuth 2.0 HTTP requests,
+// wrapping a base [http.RoundTripper] and adding an Authorization header
+// with a token from the supplied [TokenSource].
 //
 // Transport is a low-level mechanism. Most code will use the
-// higher-level Config.Client method instead.
+// higher-level [Config.Client] method instead.
 type Transport struct {
 	// Source supplies the token to add to outgoing requests'
 	// Authorization headers.
@@ -47,7 +47,7 @@
 		return nil, err
 	}
 
-	req2 := cloneRequest(req) // per RoundTripper contract
+	req2 := req.Clone(req.Context())
 	token.SetAuthHeader(req2)
 
 	// req.Body is assumed to be closed by the base RoundTripper.
@@ -73,17 +73,3 @@
 	}
 	return http.DefaultTransport
 }
-
-// cloneRequest returns a clone of the provided *http.Request.
-// The clone is a shallow copy of the struct and its Header map.
-func cloneRequest(r *http.Request) *http.Request {
-	// shallow copy of the struct
-	r2 := new(http.Request)
-	*r2 = *r
-	// deep copy of the Header
-	r2.Header = make(http.Header, len(r.Header))
-	for k, s := range r.Header {
-		r2.Header[k] = append([]string(nil), s...)
-	}
-	return r2
-}