Skip to content

Commit 6defff5

Browse files
committed
cmd/vet: add stdversion analyzer
+ release note, test Fixes #46136 Change-Id: Ib157c5343dde379f8d6f67bdfa64b3f6a6432bab Reviewed-on: https://go-review.googlesource.com/c/go/+/582556 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Michael Matloob <[email protected]>
1 parent 344075d commit 6defff5

File tree

6 files changed

+56
-0
lines changed

6 files changed

+56
-0
lines changed

doc/next/3-tools.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,19 @@ Distributions that install the `go` command to a location other than
88
`$GOROOT/bin/go` should install a symlink instead of relocating
99
or copying the `go` binary.
1010

11+
### Vet {#vet}
12+
13+
The `go vet` subcommand now includes the
14+
[stdversion](https://beta.pkg.go.dev/golang.org/x/tools/go/analysis/passes/stdversion)
15+
analyzer, which flags references to symbols that are too new for the version
16+
of Go in effect in the referring file. (The effective version is determined
17+
by the `go` directive in the file's enclosing `go.mod` file, and
18+
by any [`//go:build` constraints](https://pkg.go.dev/cmd/go#hdr-Build_constraints)
19+
in the file.)
20+
21+
For example, it will report a diagnostic for a reference to the
22+
`reflect.TypeFor` function (introduced in go1.22) from a file in a
23+
module whose go.mod file specifies `go 1.21`.
24+
1125
### Cgo {#cgo}
1226

src/cmd/go/internal/test/flagdefs.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cmd/vet/main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
"golang.org/x/tools/go/analysis/passes/sigchanyzer"
3333
"golang.org/x/tools/go/analysis/passes/slog"
3434
"golang.org/x/tools/go/analysis/passes/stdmethods"
35+
"golang.org/x/tools/go/analysis/passes/stdversion"
3536
"golang.org/x/tools/go/analysis/passes/stringintconv"
3637
"golang.org/x/tools/go/analysis/passes/structtag"
3738
"golang.org/x/tools/go/analysis/passes/testinggoroutine"
@@ -70,6 +71,7 @@ func main() {
7071
sigchanyzer.Analyzer,
7172
slog.Analyzer,
7273
stdmethods.Analyzer,
74+
stdversion.Analyzer,
7375
stringintconv.Analyzer,
7476
structtag.Analyzer,
7577
tests.Analyzer,
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module stdversion
2+
3+
go 1.21
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package stdversion
2+
3+
import "reflect"
4+
5+
var _ = reflect.TypeFor[int]() // ERROR "reflect.TypeFor requires go1.22 or later \(module is go1.21\)"

src/cmd/vet/vet_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,37 @@ func TestVet(t *testing.T) {
152152
t.Log("vet stderr:\n", cmd.Stderr)
153153
}
154154
})
155+
156+
// The stdversion analyzer requires a lower-than-tip go
157+
// version in its go.mod file for it to report anything.
158+
// So again we use a testdata go.mod file to "downgrade".
159+
t.Run("stdversion", func(t *testing.T) {
160+
cmd := testenv.Command(t, testenv.GoToolPath(t), "vet", "-vettool="+vetPath(t), ".")
161+
cmd.Env = append(os.Environ(), "GOWORK=off")
162+
cmd.Dir = "testdata/stdversion"
163+
cmd.Stderr = new(strings.Builder) // all vet output goes to stderr
164+
cmd.Run()
165+
stderr := cmd.Stderr.(fmt.Stringer).String()
166+
167+
filename := filepath.FromSlash("testdata/stdversion/stdversion.go")
168+
169+
// Unlike the tests above, which runs vet in cmd/vet/, this one
170+
// runs it in subdirectory, so the "full names" in the output
171+
// are in fact short "./rangeloop.go".
172+
// But we can't just pass "./rangeloop.go" as the "full name"
173+
// argument to errorCheck as it does double duty as both a
174+
// string that appears in the output, and as file name
175+
// openable relative to the test directory, containing text
176+
// expectations.
177+
//
178+
// So, we munge the file.
179+
stderr = strings.ReplaceAll(stderr, filepath.FromSlash("./stdversion.go"), filename)
180+
181+
if err := errorCheck(stderr, false, filename, filepath.Base(filename)); err != nil {
182+
t.Errorf("error check failed: %s", err)
183+
t.Log("vet stderr:\n", cmd.Stderr)
184+
}
185+
})
155186
}
156187

157188
func cgoEnabled(t *testing.T) bool {

0 commit comments

Comments
 (0)