{ return {{$a := .}}{{range $i, $v := .FuncResults}} {{- if $i}}, {{end -}} {{- if eq ($a.TypeName $v.Type) "error" -}} {{$a.Placeholder $errName}} {{- else -}} {{$a.Zero $v.Type}} {{- end -}} {{end}} } {{end}}
The selected code contains references to these free* symbols:
The type assertion \'x.(SomeInterface)\', when \'x\' already has type \'SomeInterface\', can only fail if \'x\' is nil. Usually, this is left-over code from when \'x\' had a different type and you can safely delete the type assertion. If you want to check that \'x\' is not nil, consider being explicit and using an actual \'if x == nil\' comparison instead of relying on the type assertion panicking. (CallExpr (Symbol name@(Or "fmt.Errorf" "fmt.Printf" "fmt.Sprintf" "log.Fatalf" "log.Panicf" "log.Printf" "(*log.Logger).Printf" "(*testing.common).Logf" "(*testing.common).Errorf" "(*testing.common).Fatalf" "(*testing.common).Skipf" "(testing.TB).Logf" "(testing.TB).Errorf" "(testing.TB).Fatalf" "(testing.TB).Skipf")) format:[]) gopls is a Go language server. It is typically used with an editor to provide language features. When no command is specified, gopls will default to the 'serve' command. The language features can also be accessed via the gopls command-line interface. For documentation of all its features, see: https://github.com/golang/tools/blob/master/gopls/doc/features Usage: gopls help [A Quick Guide to Go's Assembler
Experimental. Contributions welcome!
Click on a source line marker L1234 to navigate your editor there.
(VS Code users: please upvote #208093)
Compiling...
A TOML datetime must be in one of the following formats:
2006-01-02T15:04:05Z07:00 Date and time, with timezone.
2006-01-02T15:04:05 Date and time, but without timezone.
2006-01-02 Date without a time or timezone.
15:04:05 Just a time, without any timezone.
Seconds may optionally have a fraction, up to nanosecond precision:
15:04:05.123
15:04:05.856018510
In IEEE 754 floating point math, zero has a sign and can be positive
or negative. This can be useful in certain numerical code.
Go constants, however, cannot express negative zero. This means that
the literals \'-0.0\' and \'0.0\' have the same ideal value (zero) and
will both represent positive zero at runtime.
To explicitly and reliably create a negative zero, you can use the
\'math.Copysign\' function: \'math.Copysign(0, -1)\'.// 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 nilfunc defines an Analyzer that checks for useless
// comparisons against nil.
//
// # Analyzer nilfunc
//
// nilfunc: check for useless comparisons between functions and nil
//
// A useless comparison is one like f == nil as opposed to f() == nil.
package nilfunc
This number is outside of the "safe" range for floating point numbers; whole
(non-fractional) numbers outside the below range can not always be represented
accurately in a float, leading to some loss of accuracy.
Explicitly mark a number as a fractional unit by adding ".0", which will incur
some loss of accuracy; for example:
f = 2_000_000_000.0
Accuracy ranges:
float32 = 16,777,215
float64 = 9,007,199,254,740,991
(Or
(RangeStmt
key@(Ident _) value@(Ident _) ":=" src
[(AssignStmt (IndexExpr dst key) "=" value)])
(RangeStmt
key@(Ident _) nil ":=" src
[(AssignStmt (IndexExpr dst key) "=" (IndexExpr src key))])
(ForStmt
(AssignStmt key@(Ident _) ":=" (IntegerLiteral "0"))
(BinaryExpr key "<" (CallExpr (Symbol "len") [src]))
(IncDecStmt key "++")
[(AssignStmt (IndexExpr dst key) "=" (IndexExpr src key))]))
(Or
(CallExpr
(Symbol (Or
"fmt.Print"
"fmt.Println"
"fmt.Sprint"
"fmt.Sprintln"
"log.Fatal"
"log.Fatalln"
"log.Panic"
"log.Panicln"
"log.Print"
"log.Println"
"(*log.Logger).Fatal"
"(*log.Logger).Fatalln"
"(*log.Logger).Panic"
"(*log.Logger).Panicln"
"(*log.Logger).Print"
"(*log.Logger).Println")) args)
(CallExpr (Symbol (Or
"fmt.Fprint"
"fmt.Fprintln")) _:args))A function that calls itself recursively needs to have an exit
condition. Otherwise it will recurse forever, until the system runs
out of memory.
This issue can be caused by simple bugs such as forgetting to add an
exit condition. It can also happen "on purpose". Some languages have
tail call optimization which makes certain infinite recursive calls
safe to use. Go, however, does not implement TCO, and as such a loop
should be used instead.check for mistakes using HTTP responses
A common mistake when using the net/http package is to defer a function
call to close the http.Response Body before checking the error that
determines whether the response is valid:
resp, err := http.Head(url)
defer resp.Body.Close()
if err != nil {
log.Fatal(err)
}
// (defer statement belongs here)
This checker helps uncover latent nil dereference bugs by reporting a
diagnostic for such mistakes.Doc comments work best as complete sentences, which
allow a wide variety of automated presentations. The first sentence
should be a one-sentence summary that starts with the name being
declared.
If every doc comment begins with the name of the item it describes,
you can use the \'doc\' subcommand of the \'go\' tool and run the output
through grep.
See https://go.dev/doc/effective_go#commentary for more
information on how to write good documentation.{{if and .StmtOK (eq (.TypeName .Type) "error") -}}
{{- $a := . -}}
{{- $errName := .VarName nil "err" -}}
{{$errName | $a.SpecifiedPlaceholder 1}} := {{.X}}
if {{$errName | $a.SpecifiedPlaceholder 1}} != nil {
return {{range $i, $v := .FuncResults}}
{{- if $i}}, {{end -}}
{{- if eq ($a.TypeName $v.Type) "error" -}}
{{$errName | $a.SpecifiedPlaceholder 1 | $a.SpecifiedPlaceholder 2}}
{{- else -}}
{{$a.Zero $v.Type}}
{{- end -}}
{{end}}
}
{{end}}EOFBoolInt64Uint64StringValueValRelocsRelocUseRelocPublicPosPosBaseObjectObject1PkgPkgDefMethodTypeTypeIdxTypeParamNamesSignatureParamsParamCodeObjSymLocalIdentSelectorPrivateFuncExtVarExtTypeExtPragmaExprListExprsExprExprTypeAssignOpFuncLitCompLitDeclFuncBodyOpenScopeCloseScopeCloseAnotherScopeDeclNamesDeclNameStmtsBlockStmtIfStmtForStmtSwitchStmtRangeStmtCaseClauseCommClauseSelectStmtDeclsLabeledStmtUseObjLocalAddLocalLinknameStmt1StmtsEndLabelOptLabelMultiExprRTypeConvRTTI// 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 assign defines an Analyzer that detects useless assignments.
//
// # Analyzer assign
//
// assign: check for useless assignments
//
// This checker reports assignments of the form x = x or a[i] = a[i].
// These are almost always useless, and even when they aren't they are
// usually a mistake.
package assign
Error strings follow a set of guidelines to ensure uniformity and good
composability.
Quoting Go Code Review Comments:
> Error strings should not be capitalized (unless beginning with
> proper nouns or acronyms) or end with punctuation, since they are
> usually printed following other context. That is, use
> \'fmt.Errorf("something bad")\' not \'fmt.Errorf("Something bad")\', so
> that \'log.Printf("Reading %s: %v", filename, err)\' formats without a
> spurious capital letter mid-message.{{if and .StmtOK (eq .Kind "tuple") (len .Tuple) (eq (.TypeName .TupleLast.Type) "error") -}}
{{- $a := . -}}
if {{range $i, $v := .Tuple}}{{if $i}}, {{end}}{{if and (eq ($a.TypeName $v.Type) "error") (eq (inc $i) (len $a.Tuple))}}err{{else}}_{{end}}{{end}} := {{.X -}}
; err != nil {
return {{range $i, $v := .FuncResults}}
{{- if $i}}, {{end -}}
{{- if eq ($a.TypeName $v.Type) "error" -}}
{{$a.Placeholder "err"}}
{{- else -}}
{{$a.Zero $v.Type}}
{{- end -}}
{{end}}
}
{{end}}// 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 atomic defines an Analyzer that checks for common mistakes
// using the sync/atomic package.
//
// # Analyzer atomic
//
// atomic: check for common mistakes using the sync/atomic package
//
// The atomic checker looks for assignment statements of the form:
//
// x = atomic.AddUint64(&x, 1)
//
// which are not atomic.
package atomic
Bit shifting a value past its size will always clear the value.
For instance:
v := int8(42)
v >>= 8
will always result in 0.
This check flags bit shifting operations on fixed size integer values only.
That is, int, uint and uintptr are never flagged to avoid potential false
positives in somewhat exotic but valid bit twiddling tricks:
// Clear any value above 32 bits if integers are more than 32 bits.
func f(i int) int {
v := i >> 32
v = v << 32
return i-v
}When dividing two integer constants, the result will
also be an integer. Thus, a division such as \'2 / 3\' results in \'0\'.
This is true for all of the following examples:
_ = 2 / 3
const _ = 2 / 3
const _ float64 = 2 / 3
_ = float64(2 / 3)
Staticcheck will flag such divisions if both sides of the division are
integer literals, as it is highly unlikely that the division was
intended to truncate to zero. Staticcheck will not flag integer
division involving named constants, to avoid noisy positives.
When accessing a map key that doesn't exist yet, one receives a zero
value. Often, the zero value is a suitable value, for example when
using append or doing integer math.
The following
if _, ok := m["foo"]; ok {
m["foo"] = append(m["foo"], "bar")
} else {
m["foo"] = []string{"bar"}
}
can be simplified to
m["foo"] = append(m["foo"], "bar")
and
if _, ok := m2["k"]; ok {
m2["k"] += 4
} else {
m2["k"] = 4
}
can be simplified to
m["k"] += 4
A '\' inside a "-delimited string is interpreted as an escape character.
The following escape sequences are supported:
\b, \t, \n, \f, \r, \", \\, \uXXXX, and \UXXXXXXXX
To prevent a '\' from being recognized as an escape character, use either:
- a ' or '''-delimited string; escape characters aren't processed in them; or
- write two backslashes to get a single backslash: '\\'.
If you're trying to add a Windows path (e.g. "C:\Users\martin") then using '/'
instead of '\' will usually also work: "C:/Users/martin".
// 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 unreachable defines an Analyzer that checks for unreachable code.
//
// # Analyzer unreachable
//
// unreachable: check for unreachable code
//
// The unreachable analyzer finds statements that execution can never reach
// because they are preceded by a return statement, a call to panic, an
// infinite loop, or similar constructs.
package unreachable
In many instances, there are easier and more efficient ways of getting
a value's string representation. Whenever a value's underlying type is
a string already, or the type has a String method, they should be used
directly.
Given the following shared definitions
type T1 string
type T2 int
func (T2) String() string { return "Hello, world" }
var x string
var y T1
var z T2
we can simplify
fmt.Sprintf("%s", x)
fmt.Sprintf("%s", y)
fmt.Sprintf("%s", z)
to
x
string(y)
z.String()
Empty critical sections of the kind
mu.Lock()
mu.Unlock()
are very often a typo, and the following was intended instead:
mu.Lock()
defer mu.Unlock()
Do note that sometimes empty critical sections can be useful, as a
form of signaling to wait on another goroutine. Many times, there are
simpler ways of achieving the same effect. When that isn't the case,
the code should be amply commented to avoid confusion. Combining such
comments with a \'//lint:ignore\' directive can be used to suppress this
rare false positive.
(Or
(IfStmt
(AssignStmt [(Ident "_") ok@(Ident _)] ":=" indexexpr@(IndexExpr _ _))
ok
set@(AssignStmt indexexpr "=" (CallExpr (Builtin "append") indexexpr:values))
(AssignStmt indexexpr "=" (CompositeLit _ values)))
(IfStmt
(AssignStmt [(Ident "_") ok] ":=" indexexpr@(IndexExpr _ _))
ok
set@(AssignStmt indexexpr "+=" value)
(AssignStmt indexexpr "=" value))
(IfStmt
(AssignStmt [(Ident "_") ok] ":=" indexexpr@(IndexExpr _ _))
ok
set@(IncDecStmt indexexpr "++")
(AssignStmt indexexpr "=" (IntegerLiteral "1"))))check format of addresses passed to net.Dial
This analyzer flags code that produce network address strings using
fmt.Sprintf, as in this example:
addr := fmt.Sprintf("%s:%d", host, 12345) // "will not work with IPv6"
...
conn, err := net.Dial("tcp", addr) // "when passed to dial here"
The analyzer suggests a fix to use the correct approach, a call to
net.JoinHostPort:
addr := net.JoinHostPort(host, "12345")
...
conn, err := net.Dial("tcp", addr)
A similar diagnostic and fix are produced for a format string of "%s:%s".
/* Copyright 2025 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.
*/
li {
list-style: none;
}
span.component {
display: inline-block;
min-width: 8em;
}
span.delete {
color: grey;
opacity: 0.3;
}
span.delete:hover {
opacity: 1;
}
hr {
border-top: thin solid #EEE;
}
p.help {
width: 6in;
line-height: 120%; /* tighter than default */
font-size: 80%;
text-align: justify;
text-justify: inter-word;
color: #AAA;
}
// 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 deprecated defines an Analyzer that marks deprecated symbols and package imports.
//
// # Analyzer deprecated
//
// deprecated: check for use of deprecated identifiers
//
// The deprecated analyzer looks for deprecated symbols and package
// imports.
//
// See https://go.dev/wiki/Deprecated to learn about Go's convention
// for documenting and signaling deprecated identifiers.
package deprecated
// 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.
// The unmarshal package defines an Analyzer that checks for passing
// non-pointer or non-interface types to unmarshal and decode functions.
//
// # Analyzer unmarshal
//
// unmarshal: report passing non-pointer or non-interface values to unmarshal
//
// The unmarshal analysis reports calls to functions such as json.Unmarshal
// in which the argument type is not a pointer or an interface.
package unmarshal
It is virtually never correct to delete system directories such as
/tmp or the user's home directory. However, it can be fairly easy to
do by mistake, for example by mistakenly using \'os.TempDir\' instead
of \'ioutil.TempDir\', or by forgetting to add a suffix to the result
of \'os.UserHomeDir\'.
Writing
d := os.TempDir()
defer os.RemoveAll(d)
in your unit tests will have a devastating effect on the stability of your system.
This check flags attempts at deleting the following directories:
- os.TempDir
- os.UserCacheDir
- os.UserConfigDir
- os.UserHomeDir
// 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 appends defines an Analyzer that detects
// if there is only one variable in append.
//
// # Analyzer appends
//
// appends: check for missing values after append
//
// This checker reports calls to append that pass
// no values to be appended to the slice.
//
// s := []string{"a", "b", "c"}
// _ = append(s)
//
// Such calls are always no-ops and often indicate an
// underlying mistake.
package appends
You may want to loop over the runes in a string. Instead of converting
the string to a slice of runes and looping over that, you can loop
over the string itself. That is,
for _, r := range s {}
and
for _, r := range []rune(s) {}
will yield the same values. The first version, however, will be faster
and avoid unnecessary memory allocations.
Do note that if you are interested in the indices, ranging over a
string and over a slice of runes will yield different indices. The
first one yields byte offsets, while the second one yields indices in
the slice of runes.// 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 sigchanyzer defines an Analyzer that detects
// misuse of unbuffered signal as argument to signal.Notify.
//
// # Analyzer sigchanyzer
//
// sigchanyzer: check for unbuffered channel of os.Signal
//
// This checker reports call expression of the form
//
// signal.Notify(c <-chan os.Signal, sig ...os.Signal),
//
// where c is an unbuffered channel, which can be at risk of missing the signal.
package sigchanyzer
// Copyright 2020 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 nonewvars defines an Analyzer that applies suggested fixes
// to errors of the type "no new variables on left side of :=".
//
// # Analyzer nonewvars
//
// nonewvars: suggested fixes for "no new vars on left side of :="
//
// This checker provides suggested fixes for type errors of the
// type "no new vars on left side of :=". For example:
//
// z := 1
// z := 2
//
// will turn into
//
// z := 1
// z = 2
package nonewvars
check Go toolchain directives such as //go:debug
This analyzer checks for problems with known Go toolchain directives
in all Go source files in a package directory, even those excluded by
//go:build constraints, and all non-Go source files too.
For //go:debug (see https://go.dev/doc/godebug), the analyzer checks
that the directives are placed only in Go source files, only above the
package comment, and only in package main or *_test.go files.
Support for other known directives may be added in the future.
This analyzer does not check //go:build, which is handled by the
buildtag analyzer.
A \'sync.Pool\' is used to avoid unnecessary allocations and reduce the
amount of work the garbage collector has to do.
When passing a value that is not a pointer to a function that accepts
an interface, the value needs to be placed on the heap, which means an
additional allocation. Slices are a common thing to put in sync.Pools,
and they're structs with 3 fields (length, capacity, and a pointer to
an array). In order to avoid the extra allocation, one should store a
pointer to the slice instead.
See the comments on https://go-review.googlesource.com/c/go/+/24371
that discuss this problem.
(CallExpr
(Symbol
name@(Or
"math/rand.Int31n"
"math/rand.Int63n"
"math/rand.Intn"
"(*math/rand.Rand).Int31n"
"(*math/rand.Rand).Int63n"
"(*math/rand.Rand).Intn"
"math/rand/v2.Int32N"
"math/rand/v2.Int64N"
"math/rand/v2.IntN"
"math/rand/v2.N"
"math/rand/v2.Uint32N"
"math/rand/v2.Uint64N"
"math/rand/v2.UintN"
"(*math/rand/v2.Rand).Int32N"
"(*math/rand/v2.Rand).Int64N"
"(*math/rand/v2.Rand).IntN"
"(*math/rand/v2.Rand).Uint32N"
"(*math/rand/v2.Rand).Uint64N"
"(*math/rand/v2.Rand).UintN"))
[(IntegerLiteral "1")])InvalidIterVarInvalidRangeExprMisplacedBreakMisplacedContinueMisplacedFallthroughDuplicateCaseDuplicateDefaultBadTypeKeywordInvalidTypeSwitchInvalidExprSwitchInvalidSelectCaseUndeclaredLabelDuplicateLabelMisplacedLabelUnusedLabelJumpOverDeclJumpIntoBlockInvalidMethodExprWrongArgCountInvalidCallUnusedResultsInvalidDeferInvalidGoBadDeclRepeatedDeclInvalidUnsafeAddInvalidUnsafeSliceUnsupportedFeatureNotAGenericTypeWrongTypeArgCountCannotInferTypeArgsInvalidTypeArgInvalidInstanceCycleInvalidUnionMisplacedConstraintIfaceInvalidMethodTypeParamsMisplacedTypeParamInvalidUnsafeSliceDataInvalidUnsafeString
{{define "title"}}Gopls server information{{end}}
{{define "body"}}
Caches
{{range .State.Caches}}- {{template "cachelink" .ID}}
{{end}}
Sessions
{{range .State.Sessions}}- {{template "sessionlink" .ID}} from {{template "cachelink" .Cache.ID}}
{{end}}
Clients
{{range .State.Clients}}- {{template "clientlink" .Session.ID}}
{{end}}
Servers
{{range .State.Servers}}- {{template "serverlink" .ID}}
{{end}}
Bug reports
{{range .State.Bugs}}- {{.Key}}
- {{.Description}}
{{end}}
{{end}}
When declaring variables as part of an \'if\' statement (like in \"if
foo := ...; foo {\"), the same variables will also be in the scope of
the \'else\' branch. This means that in the following example
if x, ok := x.(int); ok {
// ...
} else {
fmt.Printf("unexpected type %T", x)
}
\'x\' in the \'else\' branch will refer to the \'x\' from \'x, ok
:=\'; it will not refer to the \'x\' that is being type-asserted. The
result of a failed type assertion is the zero value of the type that
is being asserted to, so \'x\' in the else branch will always have the
value \'0\' and the type \'int\'.
Using \'fmt.Printf\' with a dynamic first argument can lead to unexpected
output. The first argument is a format string, where certain character
combinations have special meaning. If, for example, a user were to
enter a string such as
Interest rate: 5%
and you printed it with
fmt.Printf(s)
it would lead to the following output:
Interest rate: 5%!(NOVERB).
Similarly, forming the first parameter via string concatenation with
user input should be avoided for the same reason. When printing user
input, either use a variant of \'fmt.Print\', or use the \'%s\' Printf verb
and pass the string as an argument.// 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 noresultvalues defines an Analyzer that applies suggested fixes
// to errors of the type "no result values expected".
//
// # Analyzer noresultvalues
//
// noresultvalues: suggested fixes for unexpected return values
//
// This checker provides suggested fixes for type errors of the
// type "no result values expected" or "too many return values".
// For example:
//
// func z() { return nil }
//
// will turn into
//
// func z() { return }
package noresultvalues
report uses of too-new standard library symbols
The stdversion analyzer reports references to symbols in the standard
library that were introduced by a Go release higher than the one in
force in the referring file. (Recall that the file's Go version is
defined by the 'go' directive its module's go.mod file, or by a
"//go:build go1.X" build tag at the top of the file.)
The analyzer does not report a diagnostic for a reference to a "too
new" field or method of a type that is itself "too new", as this may
have false positives, for example if fields or methods are accessed
through a type alias that is guarded by a Go version constraint.
The execute command sends an LSP ExecuteCommand request to gopls,
with a set of optional JSON argument values.
Some commands return a result, also JSON.
Gopls' command set is defined by the command.Interface type; see
https://pkg.go.dev/golang.org/x/tools/gopls/internal/protocol/command#Interface.
It is not a stable interface: commands may change or disappear without notice.
Examples:
$ gopls execute gopls.add_import '{"ImportPath": "fmt", "URI": "file:///hello.go"}'
$ gopls execute gopls.run_tests '{"URI": "file:///a_test.go", "Tests": ["Test"]}'
$ gopls execute gopls.list_known_packages '{"URI": "file:///hello.go"}'
execute-flags:
SubroutineTypeTypedefUnionTypeUnspecifiedParametersVariantCommonDwarfBlockCommonInclusionInheritanceInlinedSubroutineModulePtrToMemberTypeSetTypeSubrangeTypeWithStmtAccessDeclarationBaseTypeCatchDwarfBlockConstTypeConstantEnumeratorFileTypeFriendNamelistNamelistItemPackedTypeSubprogramTemplateTypeParameterTemplateValueParameterThrownTypeTryDwarfBlockVariantPartVariableVolatileTypeDwarfProcedureRestrictTypeInterfaceTypeNamespaceImportedModuleUnspecifiedTypePartialUnitImportedUnitMutableTypeConditionSharedTypeTypeUnitRvalueReferenceTypeTemplateAliasCoarrayTypeGenericSubrangeDynamicTypeAtomicTypeCallSiteCallSiteParameterSkeletonUnitImmutableTypeA finalizer is a function associated with an object that runs when the
garbage collector is ready to collect said object, that is when the
object is no longer referenced by anything.
If the finalizer references the object, however, it will always remain
as the final reference to that object, preventing the garbage
collector from collecting the object. The finalizer will never run,
and the object will never be collected, leading to a memory leak. That
is why the finalizer should instead use its first argument to operate
on the object. That way, the number of references can temporarily go
to zero before the object is being passed to the finalizer.// 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 timeformat defines an Analyzer that checks for the use
// of time.Format or time.Parse calls with a bad format.
//
// # Analyzer timeformat
//
// timeformat: check for calls of (time.Time).Format or time.Parse with 2006-02-01
//
// The timeformat checker looks for time formats with the 2006-02-01 (yyyy-dd-mm)
// format. Internationally, "yyyy-dd-mm" does not occur in common calendar date
// standards, and so it is more likely that 2006-01-02 (yyyy-mm-dd) was intended.
package timeformat
The \'time\'.Sleep function takes a \'time.Duration\' as its only argument.
Durations are expressed in nanoseconds. Thus, calling \'time.Sleep(1)\'
will sleep for 1 nanosecond. This is a common source of bugs, as sleep
functions in other languages often accept seconds or milliseconds.
The \'time\' package provides constants such as \'time.Second\' to express
large durations. These can be combined with arithmetic to express
arbitrary durations, for example \'5 * time.Second\' for 5 seconds.
If you truly meant to sleep for a tiny amount of time, use
\'n * time.Nanosecond\' to signal to Staticcheck that you did mean to sleep
for some amount of nanoseconds.Provides the locations of references to a (possibly qualified)
package-level Go symbol referenced from the current file.
For example, given arguments {"file": "/path/to/foo.go", "name": "Foo"},
go_symbol_references returns references to the symbol "Foo" declared
in the current package.
Similarly, given arguments {"file": "/path/to/foo.go", "name": "lib.Bar"},
go_symbol_references returns references to the symbol "Bar" in the imported lib
package.
Finally, symbol references supporting querying fields and methods: symbol
"T.M" selects the "M" field or method of the "T" type (or value), and "lib.T.M"
does the same for a symbol in the imported package "lib".
// 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 lostcancel defines an Analyzer that checks for failure to
// call a context cancellation function.
//
// # Analyzer lostcancel
//
// lostcancel: check cancel func returned by context.WithCancel is called
//
// The cancellation function returned by context.WithCancel, WithTimeout,
// WithDeadline and variants such as WithCancelCause must be called,
// or the new context will remain live until its parent context is cancelled.
// (The background context is never cancelled.)
package lostcancel
// 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 embeddirective defines an Analyzer that validates //go:embed directives.
// The analyzer defers fixes to its parent golang.Analyzer.
//
// # Analyzer embed
//
// embed: check //go:embed directive usage
//
// This analyzer checks that the embed package is imported if //go:embed
// directives are present, providing a suggested fix to add the import if
// it is missing.
//
// This analyzer also checks that //go:embed directives precede the
// declaration of a single variable.
package embeddirective
help
Click on a value or block to toggle highlighting of that value/block
and its uses. (Values and blocks are highlighted by ID, and IDs of
dead items may be reused, so not all highlights necessarily correspond
to the clicked item.)
Faded out values and blocks are dead code that has not been eliminated.
Values printed in italics have a dependency cycle.
CFG: Dashed edge is for unlikely branches. Blue color is for backward edges.
Edge with a dot means that this edge follows the order in which blocks were laid out.
// 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 simplifyslice defines an Analyzer that simplifies slice statements.
// https://github.com/golang/go/blob/master/src/cmd/gofmt/simplify.go
// https://golang.org/cmd/gofmt/#hdr-The_simplify_command
//
// # Analyzer simplifyslice
//
// simplifyslice: check for slice simplifications
//
// A slice expression of the form:
//
// s[a:len(s)]
//
// will be simplified to:
//
// s[a:]
//
// This is one of the simplifications that "gofmt -s" applies.
//
// This analyzer ignores generated code.
package simplifyslice
\'os/exec\' runs programs directly (using variants of the fork and exec
system calls on Unix systems). This shouldn't be confused with running
a command in a shell. The shell will allow for features such as input
redirection, pipes, and general scripting. The shell is also
responsible for splitting the user's input into a program name and its
arguments. For example, the equivalent to
ls / /tmp
would be
exec.Command("ls", "/", "/tmp")
If you want to run a command in a shell, consider using something like
the following – but be aware that not all systems, particularly
Windows, will have a \'/bin/sh\' program:
exec.Command("/bin/sh", "-c", "ls | grep Awesome")Some type assertions can be statically proven to be
impossible. This is the case when the method sets of both
arguments of the type assertion conflict with each other, for
example by containing the same method with different
signatures.
The Go compiler already applies this check when asserting from an
interface value to a concrete type. If the concrete type misses
methods from the interface, or if function signatures don't match,
then the type assertion can never succeed.
This check applies the same logic when asserting from one interface to
another. If both interface types contain the same method but with
different signatures, then the type assertion can never succeed,
either.// 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 tests defines an Analyzer that checks for common mistaken
// usages of tests and examples.
//
// # Analyzer tests
//
// tests: check for common mistaken usages of tests and examples
//
// The tests checker walks Test, Benchmark, Fuzzing and Example functions checking
// malformed names, wrong signatures and examples documenting non-existent
// identifiers.
//
// Please see the documentation for package testing in golang.org/pkg/testing
// for the conventions that are enforced for Tests, Benchmarks, and Examples.
package tests
Go allows importing the same package multiple times, as long as
different import aliases are being used. That is, the following
bit of code is valid:
import (
"fmt"
fumpt "fmt"
format "fmt"
_ "fmt"
)
However, this is very rarely done on purpose. Usually, it is a
sign of code that got refactored, accidentally adding duplicate
import statements. It is also a rarely known feature, which may
contribute to confusion.
Do note that sometimes, this feature may be used
intentionally (see for example
https://github.com/golang/go/commit/3409ce39bfd7584523b7a8c150a310cea92d879d)
– if you want to allow this pattern in your code base, you're
advised to disable this check.
{{define "title"}}RPC Information{{end}}
{{define "body"}}
Inbound
{{template "rpcSection" .Inbound}}
Outbound
{{template "rpcSection" .Outbound}}
{{end}}
{{define "rpcSection"}}
{{range .}}
{{.Method}} {{.Started}} traces ({{.InProgress}} in progress)
Latency {{with .Latency}}{{.Mean}} ({{.Min}}<{{.Max}}){{end}}
By bucket 0s {{range .Latency.Values}}{{if gt .Count 0}}{{.Count}} {{.Limit}} {{end}}{{end}}
Received {{.Received}} (avg. {{.ReceivedMean}})
Sent {{.Sent}} (avg. {{.SentMean}})
Result codes {{range .Codes}}{{.Key}}={{.Count}} {{end}}
{{end}}
{{end}}
Quoting Go Code Review Comments:
> The name of a method's receiver should be a reflection of its
> identity; often a one or two letter abbreviation of its type
> suffices (such as "c" or "cl" for "Client"). Don't use generic
> names such as "me", "this" or "self", identifiers typical of
> object-oriented languages that place more emphasis on methods as
> opposed to functions. The name need not be as descriptive as that
> of a method argument, as its role is obvious and serves no
> documentary purpose. It can be very short as it will appear on
> almost every line of every method of the type; familiarity admits
> brevity. Be consistent, too: if you call the receiver "c" in one
> method, don't call it "cl" in another.// 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 unsafeptr defines an Analyzer that checks for invalid
// conversions of uintptr to unsafe.Pointer.
//
// # Analyzer unsafeptr
//
// unsafeptr: check for invalid conversions of uintptr to unsafe.Pointer
//
// The unsafeptr analyzer reports likely incorrect uses of unsafe.Pointer
// to convert integers to pointers. A conversion from uintptr to
// unsafe.Pointer is invalid if it implies that there is a uintptr-typed
// word in memory that holds a pointer value, because that word will be
// invisible to stack copying and to the garbage collector.
package unsafeptr
InvalidPtrEmbedBadRecvInvalidRecvDuplicateFieldAndMethodDuplicateMethodInvalidBlankInvalidIotaMissingInitBodyInvalidInitSigInvalidInitDeclInvalidMainDeclTooManyValuesNotAnExprTruncatedFloatNumericOverflowUndefinedOpMismatchedTypesDivByZeroNonNumericIncDecUnaddressableOperandInvalidIndirectionNonIndexableOperandInvalidIndexSwappedSliceIndicesNonSliceableOperandInvalidSliceExprInvalidShiftCountInvalidShiftOperandInvalidReceiveInvalidSendDuplicateLitKeyMissingLitKeyInvalidLitIndexOversizeArrayLitMixedStructLitInvalidStructLitMissingLitFieldDuplicateLitFieldUnexportedLitFieldInvalidLitFieldUntypedLitInvalidLitAmbiguousSelectorUndeclaredImportedNameUnexportedNameUndeclaredNameMissingFieldOrMethodBadDotDotDotSyntaxNonVariadicDotDotDotKeys in \'http.Header\' maps are canonical, meaning they follow a specific
combination of uppercase and lowercase letters. Methods such as
\'http.Header.Add\' and \'http.Header.Del\' convert inputs into this canonical
form before manipulating the map.
When manipulating \'http.Header\' maps directly, as opposed to using the
provided methods, care should be taken to stick to canonical form in
order to avoid inconsistencies. The following piece of code
demonstrates one such inconsistency:
h := http.Header{}
h["etag"] = []string{"1234"}
h.Add("etag", "5678")
fmt.Println(h)
// Output:
// map[Etag:[5678] etag:[1234]]
The easiest way of obtaining the canonical form of a key is to use
\'http.CanonicalHeaderKey\'.// 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 simplifycompositelit defines an Analyzer that simplifies composite literals.
// https://github.com/golang/go/blob/master/src/cmd/gofmt/simplify.go
// https://golang.org/cmd/gofmt/#hdr-The_simplify_command
//
// # Analyzer simplifycompositelit
//
// simplifycompositelit: check for composite literal simplifications
//
// An array, slice, or map composite literal of the form:
//
// []T{T{}, T{}}
//
// will be simplified to:
//
// []T{{}, {}}
//
// This is one of the simplifications that "gofmt -s" applies.
//
// This analyzer ignores generated code.
package simplifycompositelit
This number is too large; this may be an error in the TOML, but it can also be a
bug in the program that uses too small of an integer.
The maximum and minimum values are:
size │ lowest │ highest
───────┼────────────────┼──────────────
int8 │ -128 │ 127
int16 │ -32,768 │ 32,767
int32 │ -2,147,483,648 │ 2,147,483,647
int64 │ -9.2 × 10¹⁷ │ 9.2 × 10¹⁷
uint8 │ 0 │ 255
uint16 │ 0 │ 65,535
uint32 │ 0 │ 4,294,967,295
uint64 │ 0 │ 1.8 × 10¹⁸
int refers to int32 on 32-bit systems and int64 on 64-bit systems.
// 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 defers defines an Analyzer that checks for common mistakes in defer
// statements.
//
// # Analyzer defers
//
// defers: report common mistakes in defer statements
//
// The defers analyzer reports a diagnostic when a defer statement would
// result in a non-deferred call to time.Since, as experience has shown
// that this is nearly always a mistake.
//
// For example:
//
// start := time.Now()
// ...
// defer recordLatency(time.Since(start)) // error: call to time.Since is not deferred
//
// The correct code is:
//
// defer func() { recordLatency(time.Since(start)) }()
package defers
{{define "title"}}Session {{.ID}}{{end}}
{{define "body"}}
From: {{template "cachelink" .Cache.ID}}
{{- $session := . -}}
Views
{{range .Views}}
{{- $envOverlay := .EnvOverlay -}}
- ID: {{.ID}}
Type: {{.Type}}
Root: {{.Root}}
{{- if $envOverlay}}
Env overlay: {{$envOverlay}})
{{end -}}
Folder.Name: {{.Folder.Name}}
Folder.Dir: {{.Folder.Dir}}
Latest metadata
Settings:
{{range .Folder.Options.Debug}}- {{.}}
{{end}}
{{end}}
Overlays
{{$session := .}}
{{range .Overlays}}
-
{{.Identity.URI}}
{{end}}
{{end}}
Converting two strings to the same case and comparing them like so
if strings.ToLower(s1) == strings.ToLower(s2) {
...
}
is significantly more expensive than comparing them with
\'strings.EqualFold(s1, s2)\'. This is due to memory usage as well as
computational complexity.
\'strings.ToLower\' will have to allocate memory for the new strings, as
well as convert both strings fully, even if they differ on the very
first byte. strings.EqualFold, on the other hand, compares the strings
one character at a time. It doesn't need to create two intermediate
strings and can return as soon as the first non-matching character has
been found.
For a more in-depth explanation of this issue, see
https://blog.digitalocean.com/how-to-efficiently-compare-strings-in-go/{{if and .StmtOK (eq .Kind "tuple") (len .Tuple) (eq (.TypeName .TupleLast.Type) "error") -}}
{{- $a := . -}}
{{- $errName := "err" -}}
{{- range $i, $v := .Tuple -}}
{{- if $i}}, {{end -}}
{{- if and (eq ($a.TypeName $v.Type) "error") (eq (inc $i) (len $a.Tuple)) -}}
{{$errName | $a.SpecifiedPlaceholder (len $a.Tuple)}}
{{- else -}}
{{$a.VarName $v.Type $v.Name | $a.Placeholder}}
{{- end -}}
{{- end}} := {{.X}}
if {{$errName | $a.SpecifiedPlaceholder (len $a.Tuple)}} != nil {
return {{range $i, $v := .FuncResults}}
{{- if $i}}, {{end -}}
{{- if eq ($a.TypeName $v.Type) "error" -}}
{{$errName | $a.SpecifiedPlaceholder (len $a.Tuple) |
$a.SpecifiedPlaceholder (inc (len $a.Tuple))}}
{{- else -}}
{{$a.Zero $v.Type}}
{{- end -}}
{{end}}
}
{{end}}// 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 unusedresult defines an analyzer that checks for unused
// results of calls to certain pure functions.
//
// # Analyzer unusedresult
//
// unusedresult: check for unused results of calls to some functions
//
// Some functions like fmt.Errorf return a result and have no side
// effects, so it is always a mistake to discard the result. Other
// functions may return an error that must not be ignored, or a cleanup
// operation that must be called. This analyzer reports calls to
// functions like these when the result of the call is ignored.
//
// The set of functions may be controlled using flags.
package unusedresult
// 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 simplifyrange defines an Analyzer that simplifies range statements.
// https://golang.org/cmd/gofmt/#hdr-The_simplify_command
// https://github.com/golang/go/blob/master/src/cmd/gofmt/simplify.go
//
// # Analyzer simplifyrange
//
// simplifyrange: check for range statement simplifications
//
// A range of the form:
//
// for x, _ = range v {...}
//
// will be simplified to:
//
// for x = range v {...}
//
// A range of the form:
//
// for _ = range v {...}
//
// will be simplified to:
//
// for range v {...}
//
// This is one of the simplifications that "gofmt -s" applies.
//
// This analyzer ignores generated code.
package simplifyrange
Map keys must be comparable, which precludes the use of byte slices.
This usually leads to using string keys and converting byte slices to
strings.
Normally, a conversion of a byte slice to a string needs to copy the data and
causes allocations. The compiler, however, recognizes \'m[string(b)]\' and
uses the data of \'b\' directly, without copying it, because it knows that
the data can't change during the map lookup. This leads to the
counter-intuitive situation that
k := string(b)
println(m[k])
println(m[k])
will be less efficient than
println(m[string(b)])
println(m[string(b)])
because the first version needs to copy and allocate, while the second
one does not.
For some history on this optimization, check out commit
f5f5a8b6209f84961687d993b93ea0d397f5d5bf in the Go repository.// 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 fillreturns defines an Analyzer that will attempt to
// automatically fill in a return statement that has missing
// values with zero value elements.
//
// # Analyzer fillreturns
//
// fillreturns: suggest fixes for errors due to an incorrect number of return values
//
// This checker provides suggested fixes for type errors of the
// type "wrong number of return values (want %d, got %d)". For example:
//
// func m() (int, string, *bool, error) {
// return
// }
//
// will turn into
//
// func m() (int, string, *bool, error) {
// return 0, "", nil, nil
// }
//
// This functionality is similar to https://github.com/sqs/goreturns.
package fillreturns
// 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 slog defines an Analyzer that checks for
// mismatched key-value pairs in log/slog calls.
//
// # Analyzer slog
//
// slog: check for invalid structured logging calls
//
// The slog checker looks for calls to functions from the log/slog
// package that take alternating key-value pairs. It reports calls
// where an argument in a key position is neither a string nor a
// slog.Attr, and where a final key is missing its value.
// For example,it would report
//
// slog.Warn("message", 11, "k") // slog.Warn arg "11" should be a string or a slog.Attr
//
// and
//
// slog.Info("message", "k1", v1, "k2") // call to slog.Info missing a final value
package slog
The codelens command lists or executes code lenses for the specified
file, or line within a file. A code lens is a command associated with
a position in the code.
With an optional title argument, only code lenses matching that
title are considered.
By default, the codelens command lists the available lenses for the
specified file or line within a file, including the title and
title of the command. With the -exec flag, the first matching command
is executed, and its output is printed to stdout.
Example:
$ gopls codelens a_test.go # list code lenses in a file
$ gopls codelens a_test.go:10 # list code lenses on line 10
$ gopls codelens a_test.go "run test" # list gopls.run_tests commands
$ gopls codelens -exec a_test.go:10 "run test" # run a specific test
codelens-flags:
// 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 testinggoroutine defines an Analyzerfor detecting calls to
// Fatal from a test goroutine.
//
// # Analyzer testinggoroutine
//
// testinggoroutine: report calls to (*testing.T).Fatal from goroutines started by a test
//
// Functions that abruptly terminate a test, such as the Fatal, Fatalf, FailNow, and
// Skip{,f,Now} methods of *testing.T, must be called from the test goroutine itself.
// This checker detects calls to these functions that occur within a goroutine
// started by the test. For example:
//
// func TestFoo(t *testing.T) {
// go func() {
// t.Fatal("oops") // error: (*T).Fatal called from non-test goroutine
// }()
// }
package testinggoroutine
// 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 ifaceassert defines an Analyzer that flags
// impossible interface-interface type assertions.
//
// # Analyzer ifaceassert
//
// ifaceassert: detect impossible interface-to-interface type assertions
//
// This checker flags type assertions v.(T) and corresponding type-switch cases
// in which the static type V of v is an interface that cannot possibly implement
// the target interface T. This occurs when V and T contain methods with the same
// name but different signatures. Example:
//
// var v interface {
// Read()
// }
// _ = v.(io.Reader)
//
// The Read method in v has a different signature than the Read method in
// io.Reader, so this assertion cannot succeed.
package ifaceassert
Dot imports that aren't in external test packages are discouraged.
The \'dot_import_whitelist\' option can be used to whitelist certain
imports.
Quoting Go Code Review Comments:
> The \'import .\' form can be useful in tests that, due to circular
> dependencies, cannot be made part of the package being tested:
>
> package foo_test
>
> import (
> "bar/testutil" // also imports "foo"
> . "foo"
> )
>
> In this case, the test file cannot be in package foo because it
> uses \'bar/testutil\', which imports \'foo\'. So we use the \'import .\'
> form to let the file pretend to be part of package foo even though
> it is not. Except for this one case, do not use \'import .\' in your
> programs. It makes the programs much harder to read because it is
> unclear whether a name like \'Quux\' is a top-level identifier in the
> current package or in an imported package.// Copyright 2024 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 waitgroup defines an Analyzer that detects simple misuses
// of sync.WaitGroup.
//
// # Analyzer waitgroup
//
// waitgroup: check for misuses of sync.WaitGroup
//
// This analyzer detects mistaken calls to the (*sync.WaitGroup).Add
// method from inside a new goroutine, causing Add to race with Wait:
//
// // WRONG
// var wg sync.WaitGroup
// go func() {
// wg.Add(1) // "WaitGroup.Add called from inside new goroutine"
// defer wg.Done()
// ...
// }()
// wg.Wait() // (may return prematurely before new goroutine starts)
//
// The correct code calls Add before starting the goroutine:
//
// // RIGHT
// var wg sync.WaitGroup
// wg.Add(1)
// go func() {
// defer wg.Done()
// ...
// }()
// wg.Wait()
package waitgroup
// Copyright 2024 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.
// httpGET requests a URL for its effects only.
// (It is needed for /open URLs; see objHTML.)
function httpGET(url) {
var x = new XMLHttpRequest();
x.open("GET", url, true);
x.send();
return false; // disable usual behavior
}
// disconnect banner
window.addEventListener('load', function() {
// Create a hidden element.
var banner = document.createElement("div");
banner.id = "disconnected";
banner.innerText = "Gopls server has terminated. Page is inactive.";
document.body.appendChild(banner);
// Start a GET /hang request. If it ever completes, the server
// has disconnected. Reveal the banner in that case.
var x = new XMLHttpRequest();
x.open("GET", "/hang", true);
x.onloadend = () => { banner.style.display = "block"; };
x.send();
});
*A symbol is "free" if it is referenced within the selection but declared
outside of it.
The free variables are approximately the set of parameters that
would be needed if the block were extracted into its own function in
the same package.
Free identifiers may include local types and control labels as well.
Even when you don't intend to extract a block into a new function,
this information can help you to tell at a glance what names a block
of code depends on.
Each dotted path of identifiers (such as file.Name.Pos) is reported
as a separate item, so that you can see which parts of a complex
type are actually needed.
The free symbols referenced by the body of a function may
reveal that only a small part (a single field of a struct, say) of
one of the function's parameters is used, allowing you to simplify
and generalize the function by choosing a different type for that
parameter.
// Copyright 2025 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 maprange defines an Analyzer that checks for redundant use
// of the functions maps.Keys and maps.Values in "for" statements with
// "range" clauses.
//
// # Analyzer maprange
//
// maprange: checks for unnecessary calls to maps.Keys and maps.Values in range statements
//
// Consider a loop written like this:
//
// for val := range maps.Values(m) {
// fmt.Println(val)
// }
//
// This should instead be written without the call to maps.Values:
//
// for _, val := range m {
// fmt.Println(val)
// }
//
// golang.org/x/exp/maps returns slices for Keys/Values instead of iterators,
// but unnecessary calls should similarly be removed:
//
// for _, key := range maps.Keys(m) {
// fmt.Println(key)
// }
//
// should be rewritten as:
//
// for key := range m {
// fmt.Println(key)
// }
package maprange
// 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 unusedwrite checks for unused writes to the elements of a struct or array object.
//
// # Analyzer unusedwrite
//
// unusedwrite: checks for unused writes
//
// The analyzer reports instances of writes to struct fields and
// arrays that are never read. Specifically, when a struct object
// or an array is copied, its elements are copied implicitly by
// the compiler, and any element write to this copy does nothing
// with the original object.
//
// For example:
//
// type T struct { x int }
//
// func f(input []T) {
// for i, v := range input { // v is a copy
// v.x = i // unused write to field x
// }
// }
//
// Another example is about non-pointer receiver:
//
// type T struct { x int }
//
// func (t T) f() { // t is a copy
// t.x = i // unused write to field x
// }
package unusedwrite
{{template "title" .}}
{{block "head" .}}{{end}}
Main
Info
Memory
Profiling
Metrics
RPC
Trace
Flight recorder
Analysis
{{template "title" .}}
{{block "body" .}}
Unknown page
{{end}}