|
| 1 | +// Copyright 2022 The Go Authors. All rights reserved. |
| 2 | +// Use of this source code is governed by a BSD-style |
| 3 | +// license that can be found in the LICENSE file. |
| 4 | + |
| 5 | +package misc |
| 6 | + |
| 7 | +import ( |
| 8 | + "testing" |
| 9 | + |
| 10 | + "golang.org/x/tools/internal/testenv" |
| 11 | + |
| 12 | + . "golang.org/x/tools/internal/lsp/regtest" |
| 13 | +) |
| 14 | + |
| 15 | +func TestStaticcheckGenerics(t *testing.T) { |
| 16 | + testenv.NeedsGo1Point(t, 18) // generics were introduced in Go 1.18 |
| 17 | + |
| 18 | + const files = ` |
| 19 | +-- go.mod -- |
| 20 | +module mod.com |
| 21 | +
|
| 22 | +go 1.18 |
| 23 | +-- a/a.go -- |
| 24 | +package a |
| 25 | +
|
| 26 | +import ( |
| 27 | + "errors" |
| 28 | + "sort" |
| 29 | + "strings" |
| 30 | +) |
| 31 | +
|
| 32 | +func Zero[P any]() P { |
| 33 | + var p P |
| 34 | + return p |
| 35 | +} |
| 36 | +
|
| 37 | +type Inst[P any] struct { |
| 38 | + Field P |
| 39 | +} |
| 40 | +
|
| 41 | +func testGenerics[P *T, T any](p P) { |
| 42 | + // Calls to instantiated functions should not break checks. |
| 43 | + slice := Zero[string]() |
| 44 | + sort.Slice(slice, func(i, j int) bool { |
| 45 | + return slice[i] < slice[j] |
| 46 | + }) |
| 47 | +
|
| 48 | + // Usage of instantiated fields should not break checks. |
| 49 | + g := Inst[string]{"hello"} |
| 50 | + g.Field = strings.TrimLeft(g.Field, "12234") |
| 51 | +
|
| 52 | + // Use of type parameters should not break checks. |
| 53 | + var q P |
| 54 | + p = q // SA4009: p is overwritten before its first use |
| 55 | + q = &*p // SA4001: &* will be simplified |
| 56 | +} |
| 57 | +
|
| 58 | +
|
| 59 | +// FooErr should be called ErrFoo (ST1012) |
| 60 | +var FooErr error = errors.New("foo") |
| 61 | +` |
| 62 | + |
| 63 | + WithOptions(EditorConfig{ |
| 64 | + Settings: map[string]interface{}{ |
| 65 | + "staticcheck": true, |
| 66 | + }, |
| 67 | + }).Run(t, files, func(t *testing.T, env *Env) { |
| 68 | + env.OpenFile("a/a.go") |
| 69 | + env.Await( |
| 70 | + env.DiagnosticAtRegexpFromSource("a/a.go", "sort.Slice", "sortslice"), |
| 71 | + env.DiagnosticAtRegexpFromSource("a/a.go", "sort.Slice.(slice)", "SA1028"), |
| 72 | + env.DiagnosticAtRegexpFromSource("a/a.go", "var (FooErr)", "ST1012"), |
| 73 | + env.DiagnosticAtRegexpFromSource("a/a.go", `"12234"`, "SA1024"), |
| 74 | + env.DiagnosticAtRegexpFromSource("a/a.go", "testGenerics.*(p P)", "SA4009"), |
| 75 | + env.DiagnosticAtRegexpFromSource("a/a.go", "q = (&\\*p)", "SA4001"), |
| 76 | + ) |
| 77 | + }) |
| 78 | +} |
0 commit comments