diff -pruN 2022.1-1/analysis/code/code.go 2022.1.3-1/analysis/code/code.go
--- 2022.1-1/analysis/code/code.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/analysis/code/code.go	2022-07-31 15:38:22.000000000 +0000
@@ -10,7 +10,9 @@ import (
 	"go/types"
 	"strings"
 
-	"honnef.co/go/tools/analysis/facts"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/facts/purity"
+	"honnef.co/go/tools/analysis/facts/tokenfile"
 	"honnef.co/go/tools/go/ast/astutil"
 	"honnef.co/go/tools/go/types/typeutil"
 	"honnef.co/go/tools/pattern"
@@ -195,7 +197,7 @@ func IsCallToAny(pass *analysis.Pass, no
 }
 
 func File(pass *analysis.Pass, node Positioner) *ast.File {
-	m := pass.ResultOf[facts.TokenFile].(map[*token.File]*ast.File)
+	m := pass.ResultOf[tokenfile.Analyzer].(map[*token.File]*ast.File)
 	return m[pass.Fset.File(node.Pos())]
 }
 
@@ -208,9 +210,9 @@ func IsGenerated(pass *analysis.Pass, po
 
 // Generator returns the generator that generated the file containing
 // pos. It ignores //line directives.
-func Generator(pass *analysis.Pass, pos token.Pos) (facts.Generator, bool) {
+func Generator(pass *analysis.Pass, pos token.Pos) (generated.Generator, bool) {
 	file := pass.Fset.PositionFor(pos, false).Filename
-	m := pass.ResultOf[facts.Generated].(map[string]facts.Generator)
+	m := pass.ResultOf[generated.Analyzer].(map[string]generated.Generator)
 	g, ok := m[file]
 	return g, ok
 }
@@ -220,7 +222,7 @@ func Generator(pass *analysis.Pass, pos
 // syntactic check, meaning that any function call may have side
 // effects, regardless of the called function's body. Otherwise,
 // purity will be consulted to determine the purity of function calls.
-func MayHaveSideEffects(pass *analysis.Pass, expr ast.Expr, purity facts.PurityResult) bool {
+func MayHaveSideEffects(pass *analysis.Pass, expr ast.Expr, purity purity.Result) bool {
 	switch expr := expr.(type) {
 	case *ast.BadExpr:
 		return true
@@ -340,3 +342,17 @@ func IsIntegerLiteral(pass *analysis.Pas
 	}
 	return constant.Compare(tv.Value, token.EQL, value)
 }
+
+// IsMethod reports whether expr is a method call of a named method with signature meth.
+// If name is empty, it is not checked.
+// For now, method expressions (Type.Method(recv, ..)) are not considered method calls.
+func IsMethod(pass *analysis.Pass, expr *ast.SelectorExpr, name string, meth *types.Signature) bool {
+	if name != "" && expr.Sel.Name != name {
+		return false
+	}
+	sel, ok := pass.TypesInfo.Selections[expr]
+	if !ok || sel.Kind() != types.MethodVal {
+		return false
+	}
+	return types.Identical(sel.Type(), meth)
+}
diff -pruN 2022.1-1/analysis/facts/deprecated/deprecated.go 2022.1.3-1/analysis/facts/deprecated/deprecated.go
--- 2022.1-1/analysis/facts/deprecated/deprecated.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/analysis/facts/deprecated/deprecated.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,145 @@
+package deprecated
+
+import (
+	"go/ast"
+	"go/token"
+	"go/types"
+	"reflect"
+	"strings"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+type IsDeprecated struct{ Msg string }
+
+func (*IsDeprecated) AFact()           {}
+func (d *IsDeprecated) String() string { return "Deprecated: " + d.Msg }
+
+type Result struct {
+	Objects  map[types.Object]*IsDeprecated
+	Packages map[*types.Package]*IsDeprecated
+}
+
+var Analyzer = &analysis.Analyzer{
+	Name:       "fact_deprecated",
+	Doc:        "Mark deprecated objects",
+	Run:        deprecated,
+	FactTypes:  []analysis.Fact{(*IsDeprecated)(nil)},
+	ResultType: reflect.TypeOf(Result{}),
+}
+
+func deprecated(pass *analysis.Pass) (interface{}, error) {
+	var names []*ast.Ident
+
+	extractDeprecatedMessage := func(docs []*ast.CommentGroup) string {
+		for _, doc := range docs {
+			if doc == nil {
+				continue
+			}
+			parts := strings.Split(doc.Text(), "\n\n")
+			for _, part := range parts {
+				if !strings.HasPrefix(part, "Deprecated: ") {
+					continue
+				}
+				alt := part[len("Deprecated: "):]
+				alt = strings.Replace(alt, "\n", " ", -1)
+				return alt
+			}
+		}
+		return ""
+	}
+	doDocs := func(names []*ast.Ident, docs []*ast.CommentGroup) {
+		alt := extractDeprecatedMessage(docs)
+		if alt == "" {
+			return
+		}
+
+		for _, name := range names {
+			obj := pass.TypesInfo.ObjectOf(name)
+			pass.ExportObjectFact(obj, &IsDeprecated{alt})
+		}
+	}
+
+	var docs []*ast.CommentGroup
+	for _, f := range pass.Files {
+		docs = append(docs, f.Doc)
+	}
+	if alt := extractDeprecatedMessage(docs); alt != "" {
+		// Don't mark package syscall as deprecated, even though
+		// it is. A lot of people still use it for simple
+		// constants like SIGKILL, and I am not comfortable
+		// telling them to use x/sys for that.
+		if pass.Pkg.Path() != "syscall" {
+			pass.ExportPackageFact(&IsDeprecated{alt})
+		}
+	}
+
+	docs = docs[:0]
+	for _, f := range pass.Files {
+		fn := func(node ast.Node) bool {
+			if node == nil {
+				return true
+			}
+			var ret bool
+			switch node := node.(type) {
+			case *ast.GenDecl:
+				switch node.Tok {
+				case token.TYPE, token.CONST, token.VAR:
+					docs = append(docs, node.Doc)
+					return true
+				default:
+					return false
+				}
+			case *ast.FuncDecl:
+				docs = append(docs, node.Doc)
+				names = []*ast.Ident{node.Name}
+				ret = false
+			case *ast.TypeSpec:
+				docs = append(docs, node.Doc)
+				names = []*ast.Ident{node.Name}
+				ret = true
+			case *ast.ValueSpec:
+				docs = append(docs, node.Doc)
+				names = node.Names
+				ret = false
+			case *ast.File:
+				return true
+			case *ast.StructType:
+				for _, field := range node.Fields.List {
+					doDocs(field.Names, []*ast.CommentGroup{field.Doc})
+				}
+				return false
+			case *ast.InterfaceType:
+				for _, field := range node.Methods.List {
+					doDocs(field.Names, []*ast.CommentGroup{field.Doc})
+				}
+				return false
+			default:
+				return false
+			}
+			if len(names) == 0 || len(docs) == 0 {
+				return ret
+			}
+			doDocs(names, docs)
+
+			docs = docs[:0]
+			names = nil
+			return ret
+		}
+		ast.Inspect(f, fn)
+	}
+
+	out := Result{
+		Objects:  map[types.Object]*IsDeprecated{},
+		Packages: map[*types.Package]*IsDeprecated{},
+	}
+
+	for _, fact := range pass.AllObjectFacts() {
+		out.Objects[fact.Object] = fact.Fact.(*IsDeprecated)
+	}
+	for _, fact := range pass.AllPackageFacts() {
+		out.Packages[fact.Package] = fact.Fact.(*IsDeprecated)
+	}
+
+	return out, nil
+}
diff -pruN 2022.1-1/analysis/facts/deprecated/deprecated_test.go 2022.1.3-1/analysis/facts/deprecated/deprecated_test.go
--- 2022.1-1/analysis/facts/deprecated/deprecated_test.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/analysis/facts/deprecated/deprecated_test.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,11 @@
+package deprecated
+
+import (
+	"testing"
+
+	"golang.org/x/tools/go/analysis/analysistest"
+)
+
+func TestDeprecated(t *testing.T) {
+	analysistest.Run(t, analysistest.TestData(), Analyzer, "Deprecated")
+}
diff -pruN 2022.1-1/analysis/facts/deprecated/testdata/src/Deprecated/Deprecated.go 2022.1.3-1/analysis/facts/deprecated/testdata/src/Deprecated/Deprecated.go
--- 2022.1-1/analysis/facts/deprecated/testdata/src/Deprecated/Deprecated.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/analysis/facts/deprecated/testdata/src/Deprecated/Deprecated.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,13 @@
+package pkg
+
+// Deprecated: Don't use this.
+func fn2() { // want fn2:`Deprecated: Don't use this\.`
+}
+
+// This is a function.
+//
+// Deprecated: Don't use this.
+//
+// Here is how you might use it instead.
+func fn3() { // want fn3:`Deprecated: Don't use this\.`
+}
diff -pruN 2022.1-1/analysis/facts/deprecated.go 2022.1.3-1/analysis/facts/deprecated.go
--- 2022.1-1/analysis/facts/deprecated.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/analysis/facts/deprecated.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,145 +0,0 @@
-package facts
-
-import (
-	"go/ast"
-	"go/token"
-	"go/types"
-	"reflect"
-	"strings"
-
-	"golang.org/x/tools/go/analysis"
-)
-
-type IsDeprecated struct{ Msg string }
-
-func (*IsDeprecated) AFact()           {}
-func (d *IsDeprecated) String() string { return "Deprecated: " + d.Msg }
-
-type DeprecatedResult struct {
-	Objects  map[types.Object]*IsDeprecated
-	Packages map[*types.Package]*IsDeprecated
-}
-
-var Deprecated = &analysis.Analyzer{
-	Name:       "fact_deprecated",
-	Doc:        "Mark deprecated objects",
-	Run:        deprecated,
-	FactTypes:  []analysis.Fact{(*IsDeprecated)(nil)},
-	ResultType: reflect.TypeOf(DeprecatedResult{}),
-}
-
-func deprecated(pass *analysis.Pass) (interface{}, error) {
-	var names []*ast.Ident
-
-	extractDeprecatedMessage := func(docs []*ast.CommentGroup) string {
-		for _, doc := range docs {
-			if doc == nil {
-				continue
-			}
-			parts := strings.Split(doc.Text(), "\n\n")
-			for _, part := range parts {
-				if !strings.HasPrefix(part, "Deprecated: ") {
-					continue
-				}
-				alt := part[len("Deprecated: "):]
-				alt = strings.Replace(alt, "\n", " ", -1)
-				return alt
-			}
-		}
-		return ""
-	}
-	doDocs := func(names []*ast.Ident, docs []*ast.CommentGroup) {
-		alt := extractDeprecatedMessage(docs)
-		if alt == "" {
-			return
-		}
-
-		for _, name := range names {
-			obj := pass.TypesInfo.ObjectOf(name)
-			pass.ExportObjectFact(obj, &IsDeprecated{alt})
-		}
-	}
-
-	var docs []*ast.CommentGroup
-	for _, f := range pass.Files {
-		docs = append(docs, f.Doc)
-	}
-	if alt := extractDeprecatedMessage(docs); alt != "" {
-		// Don't mark package syscall as deprecated, even though
-		// it is. A lot of people still use it for simple
-		// constants like SIGKILL, and I am not comfortable
-		// telling them to use x/sys for that.
-		if pass.Pkg.Path() != "syscall" {
-			pass.ExportPackageFact(&IsDeprecated{alt})
-		}
-	}
-
-	docs = docs[:0]
-	for _, f := range pass.Files {
-		fn := func(node ast.Node) bool {
-			if node == nil {
-				return true
-			}
-			var ret bool
-			switch node := node.(type) {
-			case *ast.GenDecl:
-				switch node.Tok {
-				case token.TYPE, token.CONST, token.VAR:
-					docs = append(docs, node.Doc)
-					return true
-				default:
-					return false
-				}
-			case *ast.FuncDecl:
-				docs = append(docs, node.Doc)
-				names = []*ast.Ident{node.Name}
-				ret = false
-			case *ast.TypeSpec:
-				docs = append(docs, node.Doc)
-				names = []*ast.Ident{node.Name}
-				ret = true
-			case *ast.ValueSpec:
-				docs = append(docs, node.Doc)
-				names = node.Names
-				ret = false
-			case *ast.File:
-				return true
-			case *ast.StructType:
-				for _, field := range node.Fields.List {
-					doDocs(field.Names, []*ast.CommentGroup{field.Doc})
-				}
-				return false
-			case *ast.InterfaceType:
-				for _, field := range node.Methods.List {
-					doDocs(field.Names, []*ast.CommentGroup{field.Doc})
-				}
-				return false
-			default:
-				return false
-			}
-			if len(names) == 0 || len(docs) == 0 {
-				return ret
-			}
-			doDocs(names, docs)
-
-			docs = docs[:0]
-			names = nil
-			return ret
-		}
-		ast.Inspect(f, fn)
-	}
-
-	out := DeprecatedResult{
-		Objects:  map[types.Object]*IsDeprecated{},
-		Packages: map[*types.Package]*IsDeprecated{},
-	}
-
-	for _, fact := range pass.AllObjectFacts() {
-		out.Objects[fact.Object] = fact.Fact.(*IsDeprecated)
-	}
-	for _, fact := range pass.AllPackageFacts() {
-		out.Packages[fact.Package] = fact.Fact.(*IsDeprecated)
-	}
-
-	return out, nil
-}
diff -pruN 2022.1-1/analysis/facts/directives/directives.go 2022.1.3-1/analysis/facts/directives/directives.go
--- 2022.1-1/analysis/facts/directives/directives.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/analysis/facts/directives/directives.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,20 @@
+package directives
+
+import (
+	"reflect"
+
+	"golang.org/x/tools/go/analysis"
+	"honnef.co/go/tools/analysis/lint"
+)
+
+func directives(pass *analysis.Pass) (interface{}, error) {
+	return lint.ParseDirectives(pass.Files, pass.Fset), nil
+}
+
+var Analyzer = &analysis.Analyzer{
+	Name:             "directives",
+	Doc:              "extracts linter directives",
+	Run:              directives,
+	RunDespiteErrors: true,
+	ResultType:       reflect.TypeOf([]lint.Directive{}),
+}
diff -pruN 2022.1-1/analysis/facts/directives.go 2022.1.3-1/analysis/facts/directives.go
--- 2022.1-1/analysis/facts/directives.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/analysis/facts/directives.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,20 +0,0 @@
-package facts
-
-import (
-	"reflect"
-
-	"golang.org/x/tools/go/analysis"
-	"honnef.co/go/tools/analysis/lint"
-)
-
-func directives(pass *analysis.Pass) (interface{}, error) {
-	return lint.ParseDirectives(pass.Files, pass.Fset), nil
-}
-
-var Directives = &analysis.Analyzer{
-	Name:             "directives",
-	Doc:              "extracts linter directives",
-	Run:              directives,
-	RunDespiteErrors: true,
-	ResultType:       reflect.TypeOf([]lint.Directive{}),
-}
diff -pruN 2022.1-1/analysis/facts/facts_test.go 2022.1.3-1/analysis/facts/facts_test.go
--- 2022.1-1/analysis/facts/facts_test.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/analysis/facts/facts_test.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,15 +0,0 @@
-package facts
-
-import (
-	"testing"
-
-	"golang.org/x/tools/go/analysis/analysistest"
-)
-
-func TestDeprecated(t *testing.T) {
-	analysistest.Run(t, analysistest.TestData(), Deprecated, "Deprecated")
-}
-
-func TestPurity(t *testing.T) {
-	analysistest.Run(t, analysistest.TestData(), Purity, "Purity")
-}
diff -pruN 2022.1-1/analysis/facts/generated/generated.go 2022.1.3-1/analysis/facts/generated/generated.go
--- 2022.1-1/analysis/facts/generated/generated.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/analysis/facts/generated/generated.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,97 @@
+package generated
+
+import (
+	"bufio"
+	"bytes"
+	"io"
+	"os"
+	"reflect"
+	"strings"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+type Generator int
+
+// A list of known generators we can detect
+const (
+	Unknown Generator = iota
+	Goyacc
+	Cgo
+	Stringer
+	ProtocGenGo
+)
+
+var (
+	// used by cgo before Go 1.11
+	oldCgo = []byte("// Created by cgo - DO NOT EDIT")
+	prefix = []byte("// Code generated ")
+	suffix = []byte(" DO NOT EDIT.")
+	nl     = []byte("\n")
+	crnl   = []byte("\r\n")
+)
+
+func isGenerated(path string) (Generator, bool) {
+	f, err := os.Open(path)
+	if err != nil {
+		return 0, false
+	}
+	defer f.Close()
+	br := bufio.NewReader(f)
+	for {
+		s, err := br.ReadBytes('\n')
+		if err != nil && err != io.EOF {
+			return 0, false
+		}
+		s = bytes.TrimSuffix(s, crnl)
+		s = bytes.TrimSuffix(s, nl)
+		if bytes.HasPrefix(s, prefix) && bytes.HasSuffix(s, suffix) {
+			if len(s)-len(suffix) < len(prefix) {
+				return Unknown, true
+			}
+
+			text := string(s[len(prefix) : len(s)-len(suffix)])
+			switch text {
+			case "by goyacc.":
+				return Goyacc, true
+			case "by cmd/cgo;":
+				return Cgo, true
+			case "by protoc-gen-go.":
+				return ProtocGenGo, true
+			}
+			if strings.HasPrefix(text, `by "stringer `) {
+				return Stringer, true
+			}
+			if strings.HasPrefix(text, `by goyacc `) {
+				return Goyacc, true
+			}
+
+			return Unknown, true
+		}
+		if bytes.Equal(s, oldCgo) {
+			return Cgo, true
+		}
+		if err == io.EOF {
+			break
+		}
+	}
+	return 0, false
+}
+
+var Analyzer = &analysis.Analyzer{
+	Name: "isgenerated",
+	Doc:  "annotate file names that have been code generated",
+	Run: func(pass *analysis.Pass) (interface{}, error) {
+		m := map[string]Generator{}
+		for _, f := range pass.Files {
+			path := pass.Fset.PositionFor(f.Pos(), false).Filename
+			g, ok := isGenerated(path)
+			if ok {
+				m[path] = g
+			}
+		}
+		return m, nil
+	},
+	RunDespiteErrors: true,
+	ResultType:       reflect.TypeOf(map[string]Generator{}),
+}
diff -pruN 2022.1-1/analysis/facts/generated.go 2022.1.3-1/analysis/facts/generated.go
--- 2022.1-1/analysis/facts/generated.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/analysis/facts/generated.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,97 +0,0 @@
-package facts
-
-import (
-	"bufio"
-	"bytes"
-	"io"
-	"os"
-	"reflect"
-	"strings"
-
-	"golang.org/x/tools/go/analysis"
-)
-
-type Generator int
-
-// A list of known generators we can detect
-const (
-	Unknown Generator = iota
-	Goyacc
-	Cgo
-	Stringer
-	ProtocGenGo
-)
-
-var (
-	// used by cgo before Go 1.11
-	oldCgo = []byte("// Created by cgo - DO NOT EDIT")
-	prefix = []byte("// Code generated ")
-	suffix = []byte(" DO NOT EDIT.")
-	nl     = []byte("\n")
-	crnl   = []byte("\r\n")
-)
-
-func isGenerated(path string) (Generator, bool) {
-	f, err := os.Open(path)
-	if err != nil {
-		return 0, false
-	}
-	defer f.Close()
-	br := bufio.NewReader(f)
-	for {
-		s, err := br.ReadBytes('\n')
-		if err != nil && err != io.EOF {
-			return 0, false
-		}
-		s = bytes.TrimSuffix(s, crnl)
-		s = bytes.TrimSuffix(s, nl)
-		if bytes.HasPrefix(s, prefix) && bytes.HasSuffix(s, suffix) {
-			if len(s)-len(suffix) < len(prefix) {
-				return Unknown, true
-			}
-
-			text := string(s[len(prefix) : len(s)-len(suffix)])
-			switch text {
-			case "by goyacc.":
-				return Goyacc, true
-			case "by cmd/cgo;":
-				return Cgo, true
-			case "by protoc-gen-go.":
-				return ProtocGenGo, true
-			}
-			if strings.HasPrefix(text, `by "stringer `) {
-				return Stringer, true
-			}
-			if strings.HasPrefix(text, `by goyacc `) {
-				return Goyacc, true
-			}
-
-			return Unknown, true
-		}
-		if bytes.Equal(s, oldCgo) {
-			return Cgo, true
-		}
-		if err == io.EOF {
-			break
-		}
-	}
-	return 0, false
-}
-
-var Generated = &analysis.Analyzer{
-	Name: "isgenerated",
-	Doc:  "annotate file names that have been code generated",
-	Run: func(pass *analysis.Pass) (interface{}, error) {
-		m := map[string]Generator{}
-		for _, f := range pass.Files {
-			path := pass.Fset.PositionFor(f.Pos(), false).Filename
-			g, ok := isGenerated(path)
-			if ok {
-				m[path] = g
-			}
-		}
-		return m, nil
-	},
-	RunDespiteErrors: true,
-	ResultType:       reflect.TypeOf(map[string]Generator{}),
-}
diff -pruN 2022.1-1/analysis/facts/purity/purity.go 2022.1.3-1/analysis/facts/purity/purity.go
--- 2022.1-1/analysis/facts/purity/purity.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/analysis/facts/purity/purity.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,178 @@
+package purity
+
+import (
+	"go/types"
+	"reflect"
+
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/go/ir/irutil"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+type IsPure struct{}
+
+func (*IsPure) AFact()           {}
+func (d *IsPure) String() string { return "is pure" }
+
+type Result map[*types.Func]*IsPure
+
+var Analyzer = &analysis.Analyzer{
+	Name:       "fact_purity",
+	Doc:        "Mark pure functions",
+	Run:        purity,
+	Requires:   []*analysis.Analyzer{buildir.Analyzer},
+	FactTypes:  []analysis.Fact{(*IsPure)(nil)},
+	ResultType: reflect.TypeOf(Result{}),
+}
+
+var pureStdlib = map[string]struct{}{
+	"errors.New":                      {},
+	"fmt.Errorf":                      {},
+	"fmt.Sprintf":                     {},
+	"fmt.Sprint":                      {},
+	"sort.Reverse":                    {},
+	"strings.Map":                     {},
+	"strings.Repeat":                  {},
+	"strings.Replace":                 {},
+	"strings.Title":                   {},
+	"strings.ToLower":                 {},
+	"strings.ToLowerSpecial":          {},
+	"strings.ToTitle":                 {},
+	"strings.ToTitleSpecial":          {},
+	"strings.ToUpper":                 {},
+	"strings.ToUpperSpecial":          {},
+	"strings.Trim":                    {},
+	"strings.TrimFunc":                {},
+	"strings.TrimLeft":                {},
+	"strings.TrimLeftFunc":            {},
+	"strings.TrimPrefix":              {},
+	"strings.TrimRight":               {},
+	"strings.TrimRightFunc":           {},
+	"strings.TrimSpace":               {},
+	"strings.TrimSuffix":              {},
+	"(*net/http.Request).WithContext": {},
+}
+
+func purity(pass *analysis.Pass) (interface{}, error) {
+	seen := map[*ir.Function]struct{}{}
+	irpkg := pass.ResultOf[buildir.Analyzer].(*buildir.IR).Pkg
+	var check func(fn *ir.Function) (ret bool)
+	check = func(fn *ir.Function) (ret bool) {
+		if fn.Object() == nil {
+			// TODO(dh): support closures
+			return false
+		}
+		if pass.ImportObjectFact(fn.Object(), new(IsPure)) {
+			return true
+		}
+		if fn.Pkg != irpkg {
+			// Function is in another package but wasn't marked as
+			// pure, ergo it isn't pure
+			return false
+		}
+		// Break recursion
+		if _, ok := seen[fn]; ok {
+			return false
+		}
+
+		seen[fn] = struct{}{}
+		defer func() {
+			if ret {
+				pass.ExportObjectFact(fn.Object(), &IsPure{})
+			}
+		}()
+
+		if irutil.IsStub(fn) {
+			return false
+		}
+
+		if _, ok := pureStdlib[fn.Object().(*types.Func).FullName()]; ok {
+			return true
+		}
+
+		if fn.Signature.Results().Len() == 0 {
+			// A function with no return values is empty or is doing some
+			// work we cannot see (for example because of build tags);
+			// don't consider it pure.
+			return false
+		}
+
+		for _, param := range fn.Params {
+			// TODO(dh): this may not be strictly correct. pure code
+			// can, to an extent, operate on non-basic types.
+			if _, ok := param.Type().Underlying().(*types.Basic); !ok {
+				return false
+			}
+		}
+
+		// Don't consider external functions pure.
+		if fn.Blocks == nil {
+			return false
+		}
+		checkCall := func(common *ir.CallCommon) bool {
+			if common.IsInvoke() {
+				return false
+			}
+			builtin, ok := common.Value.(*ir.Builtin)
+			if !ok {
+				if common.StaticCallee() != fn {
+					if common.StaticCallee() == nil {
+						return false
+					}
+					if !check(common.StaticCallee()) {
+						return false
+					}
+				}
+			} else {
+				switch builtin.Name() {
+				case "len", "cap":
+				default:
+					return false
+				}
+			}
+			return true
+		}
+		for _, b := range fn.Blocks {
+			for _, ins := range b.Instrs {
+				switch ins := ins.(type) {
+				case *ir.Call:
+					if !checkCall(ins.Common()) {
+						return false
+					}
+				case *ir.Defer:
+					if !checkCall(&ins.Call) {
+						return false
+					}
+				case *ir.Select:
+					return false
+				case *ir.Send:
+					return false
+				case *ir.Go:
+					return false
+				case *ir.Panic:
+					return false
+				case *ir.Store:
+					return false
+				case *ir.FieldAddr:
+					return false
+				case *ir.Alloc:
+					return false
+				case *ir.Load:
+					return false
+				}
+			}
+		}
+		return true
+	}
+	for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
+		check(fn)
+	}
+
+	out := Result{}
+	for _, fact := range pass.AllObjectFacts() {
+		out[fact.Object.(*types.Func)] = fact.Fact.(*IsPure)
+	}
+	return out, nil
+}
diff -pruN 2022.1-1/analysis/facts/purity/purity_test.go 2022.1.3-1/analysis/facts/purity/purity_test.go
--- 2022.1-1/analysis/facts/purity/purity_test.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/analysis/facts/purity/purity_test.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,11 @@
+package purity
+
+import (
+	"testing"
+
+	"golang.org/x/tools/go/analysis/analysistest"
+)
+
+func TestPurity(t *testing.T) {
+	analysistest.Run(t, analysistest.TestData(), Analyzer, "Purity")
+}
diff -pruN 2022.1-1/analysis/facts/purity/testdata/src/Purity/CheckPureFunctions.go 2022.1.3-1/analysis/facts/purity/testdata/src/Purity/CheckPureFunctions.go
--- 2022.1-1/analysis/facts/purity/testdata/src/Purity/CheckPureFunctions.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/analysis/facts/purity/testdata/src/Purity/CheckPureFunctions.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,26 @@
+package pkg
+
+func foo(a, b int) int { return a + b } // want foo:"is pure"
+func bar(a, b int) int {
+	println(a + b)
+	return a + b
+}
+
+func empty()            {}
+func stubPointer() *int { return nil }
+func stubInt() int      { return 0 }
+
+func fn3() {
+	empty()
+	stubPointer()
+	stubInt()
+}
+
+func ptr1() *int { return new(int) }
+func ptr2() *int { var x int; return &x }
+func lit() []int { return []int{} }
+
+var X int
+
+func load() int        { _ = X; return 0 }
+func assign(x int) int { _ = x; return 0 } // want assign:"is pure"
diff -pruN 2022.1-1/analysis/facts/purity.go 2022.1.3-1/analysis/facts/purity.go
--- 2022.1-1/analysis/facts/purity.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/analysis/facts/purity.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,178 +0,0 @@
-package facts
-
-import (
-	"go/types"
-	"reflect"
-
-	"honnef.co/go/tools/go/ir"
-	"honnef.co/go/tools/go/ir/irutil"
-	"honnef.co/go/tools/internal/passes/buildir"
-
-	"golang.org/x/tools/go/analysis"
-)
-
-type IsPure struct{}
-
-func (*IsPure) AFact()           {}
-func (d *IsPure) String() string { return "is pure" }
-
-type PurityResult map[*types.Func]*IsPure
-
-var Purity = &analysis.Analyzer{
-	Name:       "fact_purity",
-	Doc:        "Mark pure functions",
-	Run:        purity,
-	Requires:   []*analysis.Analyzer{buildir.Analyzer},
-	FactTypes:  []analysis.Fact{(*IsPure)(nil)},
-	ResultType: reflect.TypeOf(PurityResult{}),
-}
-
-var pureStdlib = map[string]struct{}{
-	"errors.New":                      {},
-	"fmt.Errorf":                      {},
-	"fmt.Sprintf":                     {},
-	"fmt.Sprint":                      {},
-	"sort.Reverse":                    {},
-	"strings.Map":                     {},
-	"strings.Repeat":                  {},
-	"strings.Replace":                 {},
-	"strings.Title":                   {},
-	"strings.ToLower":                 {},
-	"strings.ToLowerSpecial":          {},
-	"strings.ToTitle":                 {},
-	"strings.ToTitleSpecial":          {},
-	"strings.ToUpper":                 {},
-	"strings.ToUpperSpecial":          {},
-	"strings.Trim":                    {},
-	"strings.TrimFunc":                {},
-	"strings.TrimLeft":                {},
-	"strings.TrimLeftFunc":            {},
-	"strings.TrimPrefix":              {},
-	"strings.TrimRight":               {},
-	"strings.TrimRightFunc":           {},
-	"strings.TrimSpace":               {},
-	"strings.TrimSuffix":              {},
-	"(*net/http.Request).WithContext": {},
-}
-
-func purity(pass *analysis.Pass) (interface{}, error) {
-	seen := map[*ir.Function]struct{}{}
-	irpkg := pass.ResultOf[buildir.Analyzer].(*buildir.IR).Pkg
-	var check func(fn *ir.Function) (ret bool)
-	check = func(fn *ir.Function) (ret bool) {
-		if fn.Object() == nil {
-			// TODO(dh): support closures
-			return false
-		}
-		if pass.ImportObjectFact(fn.Object(), new(IsPure)) {
-			return true
-		}
-		if fn.Pkg != irpkg {
-			// Function is in another package but wasn't marked as
-			// pure, ergo it isn't pure
-			return false
-		}
-		// Break recursion
-		if _, ok := seen[fn]; ok {
-			return false
-		}
-
-		seen[fn] = struct{}{}
-		defer func() {
-			if ret {
-				pass.ExportObjectFact(fn.Object(), &IsPure{})
-			}
-		}()
-
-		if irutil.IsStub(fn) {
-			return false
-		}
-
-		if _, ok := pureStdlib[fn.Object().(*types.Func).FullName()]; ok {
-			return true
-		}
-
-		if fn.Signature.Results().Len() == 0 {
-			// A function with no return values is empty or is doing some
-			// work we cannot see (for example because of build tags);
-			// don't consider it pure.
-			return false
-		}
-
-		for _, param := range fn.Params {
-			// TODO(dh): this may not be strictly correct. pure code
-			// can, to an extent, operate on non-basic types.
-			if _, ok := param.Type().Underlying().(*types.Basic); !ok {
-				return false
-			}
-		}
-
-		// Don't consider external functions pure.
-		if fn.Blocks == nil {
-			return false
-		}
-		checkCall := func(common *ir.CallCommon) bool {
-			if common.IsInvoke() {
-				return false
-			}
-			builtin, ok := common.Value.(*ir.Builtin)
-			if !ok {
-				if common.StaticCallee() != fn {
-					if common.StaticCallee() == nil {
-						return false
-					}
-					if !check(common.StaticCallee()) {
-						return false
-					}
-				}
-			} else {
-				switch builtin.Name() {
-				case "len", "cap":
-				default:
-					return false
-				}
-			}
-			return true
-		}
-		for _, b := range fn.Blocks {
-			for _, ins := range b.Instrs {
-				switch ins := ins.(type) {
-				case *ir.Call:
-					if !checkCall(ins.Common()) {
-						return false
-					}
-				case *ir.Defer:
-					if !checkCall(&ins.Call) {
-						return false
-					}
-				case *ir.Select:
-					return false
-				case *ir.Send:
-					return false
-				case *ir.Go:
-					return false
-				case *ir.Panic:
-					return false
-				case *ir.Store:
-					return false
-				case *ir.FieldAddr:
-					return false
-				case *ir.Alloc:
-					return false
-				case *ir.Load:
-					return false
-				}
-			}
-		}
-		return true
-	}
-	for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
-		check(fn)
-	}
-
-	out := PurityResult{}
-	for _, fact := range pass.AllObjectFacts() {
-		out[fact.Object.(*types.Func)] = fact.Fact.(*IsPure)
-	}
-	return out, nil
-}
diff -pruN 2022.1-1/analysis/facts/testdata/src/Deprecated/Deprecated.go 2022.1.3-1/analysis/facts/testdata/src/Deprecated/Deprecated.go
--- 2022.1-1/analysis/facts/testdata/src/Deprecated/Deprecated.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/analysis/facts/testdata/src/Deprecated/Deprecated.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,13 +0,0 @@
-package pkg
-
-// Deprecated: Don't use this.
-func fn2() { // want fn2:`Deprecated: Don't use this\.`
-}
-
-// This is a function.
-//
-// Deprecated: Don't use this.
-//
-// Here is how you might use it instead.
-func fn3() { // want fn3:`Deprecated: Don't use this\.`
-}
diff -pruN 2022.1-1/analysis/facts/testdata/src/Purity/CheckPureFunctions.go 2022.1.3-1/analysis/facts/testdata/src/Purity/CheckPureFunctions.go
--- 2022.1-1/analysis/facts/testdata/src/Purity/CheckPureFunctions.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/analysis/facts/testdata/src/Purity/CheckPureFunctions.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,26 +0,0 @@
-package pkg
-
-func foo(a, b int) int { return a + b } // want foo:"is pure"
-func bar(a, b int) int {
-	println(a + b)
-	return a + b
-}
-
-func empty()            {}
-func stubPointer() *int { return nil }
-func stubInt() int      { return 0 }
-
-func fn3() {
-	empty()
-	stubPointer()
-	stubInt()
-}
-
-func ptr1() *int { return new(int) }
-func ptr2() *int { var x int; return &x }
-func lit() []int { return []int{} }
-
-var X int
-
-func load() int        { _ = X; return 0 }
-func assign(x int) int { _ = x; return 0 } // want assign:"is pure"
diff -pruN 2022.1-1/analysis/facts/tokenfile/token.go 2022.1.3-1/analysis/facts/tokenfile/token.go
--- 2022.1-1/analysis/facts/tokenfile/token.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/analysis/facts/tokenfile/token.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,24 @@
+package tokenfile
+
+import (
+	"go/ast"
+	"go/token"
+	"reflect"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var Analyzer = &analysis.Analyzer{
+	Name: "tokenfileanalyzer",
+	Doc:  "creates a mapping of *token.File to *ast.File",
+	Run: func(pass *analysis.Pass) (interface{}, error) {
+		m := map[*token.File]*ast.File{}
+		for _, af := range pass.Files {
+			tf := pass.Fset.File(af.Pos())
+			m[tf] = af
+		}
+		return m, nil
+	},
+	RunDespiteErrors: true,
+	ResultType:       reflect.TypeOf(map[*token.File]*ast.File{}),
+}
diff -pruN 2022.1-1/analysis/facts/token.go 2022.1.3-1/analysis/facts/token.go
--- 2022.1-1/analysis/facts/token.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/analysis/facts/token.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,24 +0,0 @@
-package facts
-
-import (
-	"go/ast"
-	"go/token"
-	"reflect"
-
-	"golang.org/x/tools/go/analysis"
-)
-
-var TokenFile = &analysis.Analyzer{
-	Name: "tokenfileanalyzer",
-	Doc:  "creates a mapping of *token.File to *ast.File",
-	Run: func(pass *analysis.Pass) (interface{}, error) {
-		m := map[*token.File]*ast.File{}
-		for _, af := range pass.Files {
-			tf := pass.Fset.File(af.Pos())
-			m[tf] = af
-		}
-		return m, nil
-	},
-	RunDespiteErrors: true,
-	ResultType:       reflect.TypeOf(map[*token.File]*ast.File{}),
-}
diff -pruN 2022.1-1/analysis/facts/typedness/typedness.go 2022.1.3-1/analysis/facts/typedness/typedness.go
--- 2022.1-1/analysis/facts/typedness/typedness.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/analysis/facts/typedness/typedness.go	2022-07-31 15:38:22.000000000 +0000
@@ -212,6 +212,15 @@ func impl(pass *analysis.Pass, fn *ir.Fu
 			}
 			return true
 		case *ir.MakeInterface:
+			terms, err := typeparams.NormalTerms(v.X.Type())
+			if len(terms) == 0 || err != nil {
+				// Type is a type parameter with no type terms (or we couldn't determine the terms). Such a type
+				// _can_ be nil when put in an interface value.
+				//
+				// There is no instruction that can create a guaranteed non-nil instance of a type parameter without
+				// type constraints, so we return false right away, without checking v.X's typedness.
+				return false
+			}
 			return true
 		case *ir.TypeAssert:
 			// type assertions fail for untyped nils. Either we have a
diff -pruN 2022.1-1/analysis/lint/testutil/check.go 2022.1.3-1/analysis/lint/testutil/check.go
--- 2022.1-1/analysis/lint/testutil/check.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/analysis/lint/testutil/check.go	2022-07-31 15:38:22.000000000 +0000
@@ -11,101 +11,19 @@ import (
 	"fmt"
 	"go/format"
 	"go/token"
-	"io/ioutil"
 	"os"
-	"path/filepath"
 	"regexp"
 	"sort"
-	"strconv"
 	"strings"
 	"testing"
-	"text/scanner"
 
 	"honnef.co/go/tools/internal/diff/myers"
 	"honnef.co/go/tools/lintcmd/runner"
 
+	"golang.org/x/tools/go/expect"
 	"golang.org/x/tools/txtar"
 )
 
-type expectation struct {
-	kind string // either "fact" or "diagnostic"
-	name string // name of object to which fact belongs, or "package" ("fact" only)
-	rx   *regexp.Regexp
-}
-
-func (ex expectation) String() string {
-	return fmt.Sprintf("%s %s:%q", ex.kind, ex.name, ex.rx) // for debugging
-}
-
-// sanitize removes the GOPATH portion of the filename,
-// typically a gnarly /tmp directory, and returns the rest.
-func sanitize(gopath, filename string) string {
-	prefix := gopath + string(os.PathSeparator) + "src" + string(os.PathSeparator)
-	return filepath.ToSlash(strings.TrimPrefix(filename, prefix))
-}
-
-// parseExpectations parses the content of a "// want ..." comment
-// and returns the expectations, a mixture of diagnostics ("rx") and
-// facts (name:"rx").
-func parseExpectations(text string) (lineDelta int, expects []expectation, err error) {
-	var scanErr string
-	sc := new(scanner.Scanner).Init(strings.NewReader(text))
-	sc.Error = func(s *scanner.Scanner, msg string) {
-		scanErr = msg // e.g. bad string escape
-	}
-	sc.Mode = scanner.ScanIdents | scanner.ScanStrings | scanner.ScanRawStrings | scanner.ScanInts
-
-	scanRegexp := func(tok rune) (*regexp.Regexp, error) {
-		if tok != scanner.String && tok != scanner.RawString {
-			return nil, fmt.Errorf("got %s, want regular expression",
-				scanner.TokenString(tok))
-		}
-		pattern, _ := strconv.Unquote(sc.TokenText()) // can't fail
-		return regexp.Compile(pattern)
-	}
-
-	for {
-		tok := sc.Scan()
-		switch tok {
-		case '+':
-			tok = sc.Scan()
-			if tok != scanner.Int {
-				return 0, nil, fmt.Errorf("got +%s, want +Int", scanner.TokenString(tok))
-			}
-			lineDelta, _ = strconv.Atoi(sc.TokenText())
-		case scanner.String, scanner.RawString:
-			rx, err := scanRegexp(tok)
-			if err != nil {
-				return 0, nil, err
-			}
-			expects = append(expects, expectation{"diagnostic", "", rx})
-
-		case scanner.Ident:
-			name := sc.TokenText()
-			tok = sc.Scan()
-			if tok != ':' {
-				return 0, nil, fmt.Errorf("got %s after %s, want ':'",
-					scanner.TokenString(tok), name)
-			}
-			tok = sc.Scan()
-			rx, err := scanRegexp(tok)
-			if err != nil {
-				return 0, nil, err
-			}
-			expects = append(expects, expectation{"fact", name, rx})
-
-		case scanner.EOF:
-			if scanErr != "" {
-				return 0, nil, fmt.Errorf("%s", scanErr)
-			}
-			return lineDelta, expects, nil
-
-		default:
-			return 0, nil, fmt.Errorf("unexpected %s", scanner.TokenString(tok))
-		}
-	}
-}
-
 func CheckSuggestedFixes(t *testing.T, diagnostics []runner.Diagnostic) {
 	// Process each result (package) separately, matching up the suggested
 	// fixes into a diff, which we will compare to the .golden file.  We have
@@ -139,7 +57,7 @@ func CheckSuggestedFixes(t *testing.T, d
 					continue
 				}
 				if _, ok := fileContents[edit.Position.Filename]; !ok {
-					contents, err := ioutil.ReadFile(edit.Position.Filename)
+					contents, err := os.ReadFile(edit.Position.Filename)
 					if err != nil {
 						t.Errorf("error reading %s: %v", edit.Position.Filename, err)
 					}
@@ -247,67 +165,84 @@ func CheckSuggestedFixes(t *testing.T, d
 	}
 }
 
-func Check(t *testing.T, gopath string, diagnostics []runner.Diagnostic, wants []runner.Want, facts []runner.TestFact) {
+func Check(t *testing.T, gopath string, diagnostics []runner.Diagnostic, facts []runner.TestFact) {
 	type key struct {
 		file string
 		line int
 	}
 
-	want := make(map[key][]expectation)
+	want := make(map[key][]*expect.Note)
+
+	fset := token.NewFileSet()
+	seen := map[string]struct{}{}
+	for _, diag := range diagnostics {
+		file := diag.Position.Filename
+		if _, ok := seen[file]; !ok {
+			seen[file] = struct{}{}
 
-	// processComment parses expectations out of comments.
-	processComment := func(filename string, linenum int, text string) {
-		text = strings.TrimSpace(text)
-
-		// Any comment starting with "want" is treated
-		// as an expectation, even without following whitespace.
-		if rest := strings.TrimPrefix(text, "want"); rest != text {
-			lineDelta, expects, err := parseExpectations(rest)
+			notes, err := expect.Parse(fset, file, nil)
 			if err != nil {
-				t.Errorf("%s:%d: in 'want' comment: %s", filename, linenum, err)
-				return
+				t.Fatal(err)
 			}
-			if expects != nil {
-				want[key{filename, linenum + lineDelta}] = expects
+			for _, note := range notes {
+				k := key{
+					file: file,
+					line: fset.PositionFor(note.Pos, false).Line,
+				}
+				want[k] = append(want[k], note)
 			}
 		}
 	}
 
-	for _, want := range wants {
-		filename := sanitize(gopath, want.Position.Filename)
-		processComment(filename, want.Position.Line, want.Comment)
-	}
-
-	checkMessage := func(posn token.Position, kind, name, message string) {
-		posn.Filename = sanitize(gopath, posn.Filename)
+	check := func(posn token.Position, message string, kind string, argIdx int, identifier string) {
 		k := key{posn.Filename, posn.Line}
 		expects := want[k]
 		var unmatched []string
 		for i, exp := range expects {
-			if exp.kind == kind && exp.name == name {
-				if exp.rx.MatchString(message) {
+			if exp.Name == kind {
+				if kind == "fact" && exp.Args[0] != expect.Identifier(identifier) {
+					continue
+				}
+				matched := false
+				switch arg := exp.Args[argIdx].(type) {
+				case string:
+					matched = strings.Contains(message, arg)
+				case *regexp.Regexp:
+					matched = arg.MatchString(message)
+				default:
+					t.Fatalf("unexpected argument type %T", arg)
+				}
+				if matched {
 					// matched: remove the expectation.
 					expects[i] = expects[len(expects)-1]
 					expects = expects[:len(expects)-1]
 					want[k] = expects
 					return
 				}
-				unmatched = append(unmatched, fmt.Sprintf("%q", exp.rx))
+				unmatched = append(unmatched, fmt.Sprintf("%q", exp.Args[argIdx]))
 			}
 		}
 		if unmatched == nil {
-			t.Errorf("%v: unexpected %s: %v", posn, kind, message)
+			t.Errorf("%v: unexpected diag: %v", posn, message)
 		} else {
-			t.Errorf("%v: %s %q does not match pattern %s",
-				posn, kind, message, strings.Join(unmatched, " or "))
+			t.Errorf("%v: diag %q does not match pattern %s",
+				posn, message, strings.Join(unmatched, " or "))
 		}
 	}
 
+	checkDiag := func(posn token.Position, message string) {
+		check(posn, message, "diag", 0, "")
+	}
+
+	checkFact := func(posn token.Position, name, message string) {
+		check(posn, message, "fact", 1, name)
+	}
+
 	// Check the diagnostics match expectations.
 	for _, f := range diagnostics {
 		// TODO(matloob): Support ranges in analysistest.
 		posn := f.Position
-		checkMessage(posn, "diagnostic", "", f.Message)
+		checkDiag(posn, f.Message)
 	}
 
 	// Check the facts match expectations.
@@ -319,7 +254,7 @@ func Check(t *testing.T, gopath string,
 			posn.Line = 1
 		}
 
-		checkMessage(posn, "fact", name, fact.FactString)
+		checkFact(posn, name, fact.FactString)
 	}
 
 	// Reject surplus expectations.
@@ -332,7 +267,7 @@ func Check(t *testing.T, gopath string,
 	var surplus []string
 	for key, expects := range want {
 		for _, exp := range expects {
-			err := fmt.Sprintf("%s:%d: no %s was reported matching %q", key.file, key.line, exp.kind, exp.rx)
+			err := fmt.Sprintf("%s:%d: no %s was reported matching %q", key.file, key.line, exp.Name, exp.Args)
 			surplus = append(surplus, err)
 		}
 	}
diff -pruN 2022.1-1/analysis/lint/testutil/util.go 2022.1.3-1/analysis/lint/testutil/util.go
--- 2022.1-1/analysis/lint/testutil/util.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/analysis/lint/testutil/util.go	2022-07-31 15:38:22.000000000 +0000
@@ -188,7 +188,7 @@ func Run(t *testing.T, analyzers []*lint
 					relevantFacts = append(relevantFacts, fact)
 				}
 
-				Check(t, testdata, relevantDiags, tdata.Wants, relevantFacts)
+				Check(t, testdata, relevantDiags, relevantFacts)
 				CheckSuggestedFixes(t, relevantDiags)
 			}
 		}
diff -pruN 2022.1-1/analysis/report/report.go 2022.1.3-1/analysis/report/report.go
--- 2022.1-1/analysis/report/report.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/analysis/report/report.go	2022-07-31 15:38:22.000000000 +0000
@@ -10,7 +10,7 @@ import (
 	"strconv"
 	"strings"
 
-	"honnef.co/go/tools/analysis/facts"
+	"honnef.co/go/tools/analysis/facts/generated"
 	"honnef.co/go/tools/go/ast/astutil"
 
 	"golang.org/x/tools/go/analysis"
@@ -172,7 +172,7 @@ func Report(pass *analysis.Pass, node Po
 
 	file := DisplayPosition(pass.Fset, node.Pos()).Filename
 	if cfg.FilterGenerated {
-		m := pass.ResultOf[facts.Generated].(map[string]facts.Generator)
+		m := pass.ResultOf[generated.Analyzer].(map[string]generated.Generator)
 		if _, ok := m[file]; ok {
 			return
 		}
diff -pruN 2022.1-1/cmd/structlayout/main.go 2022.1.3-1/cmd/structlayout/main.go
--- 2022.1-1/cmd/structlayout/main.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/cmd/structlayout/main.go	2022-07-31 15:38:22.000000000 +0000
@@ -42,7 +42,7 @@ func main() {
 	}
 
 	cfg := &packages.Config{
-		Mode:  packages.NeedImports | packages.NeedExportsFile | packages.NeedTypes | packages.NeedSyntax,
+		Mode:  packages.NeedImports | packages.NeedExportFile | packages.NeedTypes | packages.NeedSyntax,
 		Tests: true,
 	}
 	pkgs, err := packages.Load(cfg, flag.Args()[0])
diff -pruN 2022.1-1/debian/changelog 2022.1.3-1/debian/changelog
--- 2022.1-1/debian/changelog	2022-03-30 17:06:48.000000000 +0000
+++ 2022.1.3-1/debian/changelog	2022-07-31 15:39:45.000000000 +0000
@@ -1,3 +1,34 @@
+golang-honnef-go-tools (2022.1.3-1) unstable; urgency=medium
+
+  * New upstream version 2022.1.3
+  * Add myself to Uploaders
+
+ -- Shengjing Zhu <zhsj@debian.org>  Sun, 31 Jul 2022 23:39:45 +0800
+
+golang-honnef-go-tools (2022.1.2-3) unstable; urgency=medium
+
+  * Team upload
+  * Fix CheckAtomicAlignment test on s390x
+
+ -- Shengjing Zhu <zhsj@debian.org>  Mon, 20 Jun 2022 03:31:41 +0800
+
+golang-honnef-go-tools (2022.1.2-2) unstable; urgency=medium
+
+  * Team upload
+  * Fix DH_GOLANG_EXCLUDES pattern
+
+ -- Shengjing Zhu <zhsj@debian.org>  Sun, 19 Jun 2022 15:31:54 +0800
+
+golang-honnef-go-tools (2022.1.2-1) unstable; urgency=medium
+
+  * Team upload.
+  * New upstream version 2022.1.2
+  * Update Standards-Version to 4.6.1 (no changes)
+  * USe DH_GOLANG_EXCLUDES to exclude binaries
+  * Bump golang-golang-x-tools-dev to 1:0.1.11~
+
+ -- Shengjing Zhu <zhsj@debian.org>  Sat, 18 Jun 2022 16:17:52 +0800
+
 golang-honnef-go-tools (2022.1-1) unstable; urgency=medium
 
   * Team upload.
diff -pruN 2022.1-1/debian/clean 2022.1.3-1/debian/clean
--- 2022.1-1/debian/clean	2022-03-30 17:06:48.000000000 +0000
+++ 2022.1.3-1/debian/clean	1970-01-01 00:00:00.000000000 +0000
@@ -1,4 +0,0 @@
-cmd/go-module-query/
-# Using incompatible golang-golang-x-tools-dev version
-ir/source_test.go
-ir/identical_test.go
diff -pruN 2022.1-1/debian/control 2022.1.3-1/debian/control
--- 2022.1-1/debian/control	2022-03-30 17:06:48.000000000 +0000
+++ 2022.1.3-1/debian/control	2022-07-31 15:39:45.000000000 +0000
@@ -1,6 +1,7 @@
 Source: golang-honnef-go-tools
 Maintainer: Debian Go Packaging Team <team+pkg-go@tracker.debian.org>
 Uploaders: Pirate Praveen <praveen@debian.org>,
+           Shengjing Zhu <zhsj@debian.org>,
 Section: golang
 Testsuite: autopkgtest-pkg-go
 Priority: optional
@@ -9,8 +10,8 @@ Build-Depends: debhelper-compat (= 13),
                golang-any,
                golang-github-burntsushi-toml-dev,
                golang-golang-x-exp-dev (>= 0.0~git20220328~),
-               golang-golang-x-tools-dev,
-Standards-Version: 4.6.0
+               golang-golang-x-tools-dev (>= 1:0.1.11~),
+Standards-Version: 4.6.1
 Vcs-Browser: https://salsa.debian.org/go-team/packages/golang-honnef-go-tools
 Vcs-Git: https://salsa.debian.org/go-team/packages/golang-honnef-go-tools.git
 Homepage: https://github.com/dominikh/go-tools
@@ -22,7 +23,7 @@ Architecture: all
 Multi-Arch: foreign
 Depends: golang-github-burntsushi-toml-dev,
          golang-golang-x-exp-dev (>= 0.0~git20220328~),
-         golang-golang-x-tools-dev,
+         golang-golang-x-tools-dev (>= 1:0.1.11~),
          ${misc:Depends},
 Description: Collection of golang tools and libraries
  keyify: Transforms an unkeyed struct literal into a keyed one.
diff -pruN 2022.1-1/debian/patches/0001-Fix-CheckAtomicAlignment-test-on-s390x.patch 2022.1.3-1/debian/patches/0001-Fix-CheckAtomicAlignment-test-on-s390x.patch
--- 2022.1-1/debian/patches/0001-Fix-CheckAtomicAlignment-test-on-s390x.patch	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/debian/patches/0001-Fix-CheckAtomicAlignment-test-on-s390x.patch	2022-07-31 15:39:45.000000000 +0000
@@ -0,0 +1,18 @@
+From: Shengjing Zhu <zhsj@debian.org>
+Date: Mon, 20 Jun 2022 03:31:01 +0800
+Subject: Fix CheckAtomicAlignment test on s390x
+
+---
+ staticcheck/testdata/src/CheckAtomicAlignment/atomic64.go | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/staticcheck/testdata/src/CheckAtomicAlignment/atomic64.go b/staticcheck/testdata/src/CheckAtomicAlignment/atomic64.go
+index 9af815c..9f52411 100644
+--- a/staticcheck/testdata/src/CheckAtomicAlignment/atomic64.go
++++ b/staticcheck/testdata/src/CheckAtomicAlignment/atomic64.go
+@@ -1,4 +1,4 @@
+-// +build amd64 amd64p32 arm64 ppc64 ppc64le mips64 mips64le mips64p32 mips64p32le sparc64 riscv64
++// +build amd64 amd64p32 arm64 ppc64 ppc64le mips64 mips64le mips64p32 mips64p32le sparc64 riscv64 s390x
+ 
+ package pkg
+ 
diff -pruN 2022.1-1/debian/patches/series 2022.1.3-1/debian/patches/series
--- 2022.1-1/debian/patches/series	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/debian/patches/series	2022-07-31 15:39:45.000000000 +0000
@@ -0,0 +1 @@
+0001-Fix-CheckAtomicAlignment-test-on-s390x.patch
diff -pruN 2022.1-1/debian/rules 2022.1.3-1/debian/rules
--- 2022.1-1/debian/rules	2022-03-30 17:06:48.000000000 +0000
+++ 2022.1.3-1/debian/rules	2022-07-31 15:39:45.000000000 +0000
@@ -1,11 +1,11 @@
 #!/usr/bin/make -f
 
+# Don't use "cmd", as it will match "lincmd".
+export DH_GOLANG_EXCLUDES := website internal/cmd internal/gosmith $(wildcard cmd/*)
+
 %:
 	dh $@ --builddirectory=_build --buildsystem=golang --with=golang
 
-override_dh_auto_install:
-	dh_auto_install -- --no-binaries
-
 ifneq (,$(filter $(DEB_HOST_ARCH), armhf))
 override_dh_auto_test:
 	# run out of memory: cannot allocate 4194304-byte block (3459678208 in use)
diff -pruN 2022.1-1/.gitattributes 2022.1.3-1/.gitattributes
--- 2022.1-1/.gitattributes	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/.gitattributes	2022-07-31 15:38:22.000000000 +0000
@@ -1,2 +1,3 @@
 *.golden -text
 *.svg binary
+**/testdata/** -text
diff -pruN 2022.1-1/.github/workflows/ci.yml 2022.1.3-1/.github/workflows/ci.yml
--- 2022.1-1/.github/workflows/ci.yml	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/.github/workflows/ci.yml	2022-07-31 15:38:22.000000000 +0000
@@ -19,9 +19,38 @@ jobs:
         go-version: ${{ matrix.go }}
     - run: "go test ./..."
     - run: "go vet ./..."
-    - uses: dominikh/staticcheck-action@v1.0.0
+    - uses: dominikh/staticcheck-action@9f77055cca7bfaafb836cbd6720865187f5fbf51
       with:
-        version: 274e0ee95850bc820301bfe5961eed9ebc8cb9e1
-        min-go-version: "1.16"
+        version: "3d6c86f0908ab82d6ff280219e2968ee65f83b2e"
+        min-go-version: "1.17"
         install-go: false
         cache-key: ${{ matrix.go }}
+        output-format: binary
+        output-file: "./staticcheck.bin"
+    - uses: actions/upload-artifact@v3
+      with:
+        name: "staticcheck-${{ github.sha }}-${{ matrix.go }}-${{ matrix.os }}.bin"
+        path: "./staticcheck.bin"
+        retention-days: 1
+        if-no-files-found: warn
+  output:
+    name: "Output Staticcheck findings"
+    needs: ci
+    runs-on: "ubuntu-latest"
+    steps:
+    - uses: WillAbides/setup-go-faster@v1.7.0
+      with:
+        go-version: "1.18.x"
+    # this downloads all artifacts of the current workflow into the current working directory, creating one directory per artifact
+    - uses: actions/download-artifact@v3
+    - id: glob
+      run: |
+        # We replace newliens with %0A, which GitHub apparently magically turns back into newlines
+        out=$(ls -1 ./staticcheck-*.bin/*.bin)
+        echo "::set-output name=files::${out//$'\n'/%0A}"
+    - uses: dominikh/staticcheck-action@9f77055cca7bfaafb836cbd6720865187f5fbf51
+      with:
+        version: "3d6c86f0908ab82d6ff280219e2968ee65f83b2e"
+        min-go-version: "1.17"
+        install-go: false
+        merge-files: ${{ steps.glob.outputs.files }}
diff -pruN 2022.1-1/.gitignore 2022.1.3-1/.gitignore
--- 2022.1-1/.gitignore	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/.gitignore	2022-07-31 15:38:22.000000000 +0000
@@ -10,3 +10,4 @@
 /website/resources
 /website/assets/img/sponsors
 /website/data/sponsors.toml
+/website/data/copyrights.toml
diff -pruN 2022.1-1/go/ast/astutil/util.go 2022.1.3-1/go/ast/astutil/util.go
--- 2022.1-1/go/ast/astutil/util.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/go/ast/astutil/util.go	2022-07-31 15:38:22.000000000 +0000
@@ -218,8 +218,8 @@ func CopyExpr(node ast.Expr) (ast.Expr,
 	case *ast.StructType:
 		cp := *node
 		return &cp, true
-	case *ast.FuncLit:
-		// TODO(dh): implement copying of function literals.
+	case *ast.FuncLit, *ast.FuncType:
+		// TODO(dh): implement copying of function literals and types.
 		return nil, false
 	case *ast.ChanType:
 		var ok bool
diff -pruN 2022.1-1/go/ir/builder.go 2022.1.3-1/go/ir/builder.go
--- 2022.1-1/go/ir/builder.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/go/ir/builder.go	2022-07-31 15:38:22.000000000 +0000
@@ -669,17 +669,24 @@ func (b *builder) expr0(fn *Function, e
 		}
 
 	case *ast.SliceExpr:
-		var low, high, max Value
 		var x Value
-		switch typeutil.CoreType(fn.Pkg.typeOf(e.X)).Underlying().(type) {
-		case *types.Array:
-			// Potentially escaping.
-			x = b.addr(fn, e.X, true).address(fn)
-		case *types.Basic, *types.Slice, *types.Pointer: // *array
+		if core := typeutil.CoreType(fn.Pkg.typeOf(e.X)); core != nil {
+			switch core.Underlying().(type) {
+			case *types.Array:
+				// Potentially escaping.
+				x = b.addr(fn, e.X, true).address(fn)
+			case *types.Basic, *types.Slice, *types.Pointer: // *array
+				x = b.expr(fn, e.X)
+			default:
+				panic("unreachable")
+			}
+		} else {
+			// We're indexing a string | []byte. Note that other combinations such as []byte | [4]byte are currently not
+			// allowed by the language.
 			x = b.expr(fn, e.X)
-		default:
-			panic("unreachable")
 		}
+
+		var low, high, max Value
 		if e.High != nil {
 			high = b.expr(fn, e.High)
 		}
diff -pruN 2022.1-1/go/loader/loader.go 2022.1.3-1/go/loader/loader.go
--- 2022.1-1/go/loader/loader.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/go/loader/loader.go	2022-07-31 15:38:22.000000000 +0000
@@ -73,7 +73,7 @@ func Graph(c *cache.Cache, cfg *packages
 	dcfg.Mode = packages.NeedName |
 		packages.NeedImports |
 		packages.NeedDeps |
-		packages.NeedExportsFile |
+		packages.NeedExportFile |
 		packages.NeedFiles |
 		packages.NeedCompiledGoFiles |
 		packages.NeedTypesSizes |
diff -pruN 2022.1-1/go/types/typeutil/typeparams.go 2022.1.3-1/go/types/typeutil/typeparams.go
--- 2022.1-1/go/types/typeutil/typeparams.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/go/types/typeutil/typeparams.go	2022-07-31 15:38:22.000000000 +0000
@@ -52,6 +52,10 @@ func (ts TypeSet) CoreType() types.Type
 			// typ is currently a bidirectional channel. The term's type is either also bidirectional, or
 			// unidirectional. Use the term's type.
 			typ = ut
+		} else if ch2.Dir() == types.SendRecv {
+			// typ is currently a unidirectional channel and the term's type is bidirectional, which means it has no
+			// effect.
+			continue
 		} else if ch1.Dir() != ch2.Dir() {
 			// typ is not bidirectional and typ and term disagree about the direction
 			return nil
diff -pruN 2022.1-1/go.mod 2022.1.3-1/go.mod
--- 2022.1-1/go.mod	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/go.mod	2022-07-31 15:38:22.000000000 +0000
@@ -6,10 +6,7 @@ require (
 	github.com/BurntSushi/toml v0.4.1
 	golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e
 	golang.org/x/sys v0.0.0-20211019181941-9d821ace8654
-	golang.org/x/tools v0.1.11-0.20220316014157-77aa08bb151a
+	golang.org/x/tools v0.1.11-0.20220513221640-090b14e8501f
 )
 
-require (
-	golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect
-	golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
-)
+require golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
diff -pruN 2022.1-1/go.sum 2022.1.3-1/go.sum
--- 2022.1-1/go.sum	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/go.sum	2022-07-31 15:38:22.000000000 +0000
@@ -5,8 +5,8 @@ golang.org/x/crypto v0.0.0-2019030822171
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e h1:qyrTQ++p1afMkO4DPEeLGq/3oTsdlvdH4vqZUBWzUKM=
 golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
-golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o=
-golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
@@ -25,9 +25,6 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.1.11-0.20220316014157-77aa08bb151a h1:ofrrl6c6NG5/IOSx/R1cyiQxxjqlur0h/TvbUhkH0II=
-golang.org/x/tools v0.1.11-0.20220316014157-77aa08bb151a/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
+golang.org/x/tools v0.1.11-0.20220513221640-090b14e8501f h1:OKYpQQVE3DKSc3r3zHVzq46vq5YH7x8xpR3/k9ixmUg=
+golang.org/x/tools v0.1.11-0.20220513221640-090b14e8501f/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
-golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff -pruN 2022.1-1/internal/cmd/ast-to-pattern/main.go 2022.1.3-1/internal/cmd/ast-to-pattern/main.go
--- 2022.1-1/internal/cmd/ast-to-pattern/main.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/internal/cmd/ast-to-pattern/main.go	2022-07-31 15:38:22.000000000 +0000
@@ -4,14 +4,14 @@ import (
 	"fmt"
 	"go/ast"
 	"go/token"
-	"io/ioutil"
+	"io"
 	"os"
 
 	"honnef.co/go/tools/pattern"
 )
 
 func main() {
-	src, err := ioutil.ReadAll(os.Stdin)
+	src, err := io.ReadAll(os.Stdin)
 	if err != nil {
 		fmt.Fprintln(os.Stderr, err)
 		os.Exit(1)
diff -pruN 2022.1-1/internal/renameio/renameio_test.go 2022.1.3-1/internal/renameio/renameio_test.go
--- 2022.1-1/internal/renameio/renameio_test.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/internal/renameio/renameio_test.go	2022-07-31 15:38:22.000000000 +0000
@@ -10,7 +10,6 @@ package renameio
 import (
 	"encoding/binary"
 	"errors"
-	"io/ioutil"
 	"math/rand"
 	"os"
 	"path/filepath"
@@ -25,7 +24,7 @@ import (
 )
 
 func TestConcurrentReadsAndWrites(t *testing.T) {
-	dir, err := ioutil.TempDir("", "renameio")
+	dir, err := os.MkdirTemp("", "renameio")
 	if err != nil {
 		t.Fatal(err)
 	}
diff -pruN 2022.1-1/internal/renameio/umask_test.go 2022.1.3-1/internal/renameio/umask_test.go
--- 2022.1-1/internal/renameio/umask_test.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/internal/renameio/umask_test.go	2022-07-31 15:38:22.000000000 +0000
@@ -8,7 +8,6 @@
 package renameio
 
 import (
-	"io/ioutil"
 	"os"
 	"path/filepath"
 	"syscall"
@@ -16,7 +15,7 @@ import (
 )
 
 func TestWriteFileModeAppliesUmask(t *testing.T) {
-	dir, err := ioutil.TempDir("", "renameio")
+	dir, err := os.MkdirTemp("", "renameio")
 	if err != nil {
 		t.Fatalf("Failed to create temporary directory: %v", err)
 	}
diff -pruN 2022.1-1/internal/robustio/robustio_other.go 2022.1.3-1/internal/robustio/robustio_other.go
--- 2022.1-1/internal/robustio/robustio_other.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/internal/robustio/robustio_other.go	2022-07-31 15:38:22.000000000 +0000
@@ -8,7 +8,6 @@
 package robustio
 
 import (
-	"io/ioutil"
 	"os"
 )
 
@@ -17,7 +16,7 @@ func rename(oldpath, newpath string) err
 }
 
 func readFile(filename string) ([]byte, error) {
-	return ioutil.ReadFile(filename)
+	return os.ReadFile(filename)
 }
 
 func removeAll(path string) error {
diff -pruN 2022.1-1/internal/sharedcheck/lint.go 2022.1.3-1/internal/sharedcheck/lint.go
--- 2022.1-1/internal/sharedcheck/lint.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/internal/sharedcheck/lint.go	2022-07-31 15:38:22.000000000 +0000
@@ -8,7 +8,8 @@ import (
 
 	"honnef.co/go/tools/analysis/code"
 	"honnef.co/go/tools/analysis/edit"
-	"honnef.co/go/tools/analysis/facts"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/facts/tokenfile"
 	"honnef.co/go/tools/analysis/report"
 	"honnef.co/go/tools/go/ast/astutil"
 	"honnef.co/go/tools/go/ir"
@@ -118,7 +119,7 @@ func RedundantTypeInDeclarationChecker(v
 			}
 
 			gen, _ := code.Generator(pass, decl.Pos())
-			if gen == facts.Cgo {
+			if gen == generated.Cgo {
 				// TODO(dh): remove this exception once we can use UsesCgo
 				return
 			}
@@ -203,6 +204,6 @@ func RedundantTypeInDeclarationChecker(v
 
 	return &analysis.Analyzer{
 		Run:      fn,
-		Requires: []*analysis.Analyzer{facts.Generated, inspect.Analyzer, facts.TokenFile, facts.Generated},
+		Requires: []*analysis.Analyzer{generated.Analyzer, inspect.Analyzer, tokenfile.Analyzer},
 	}
 }
diff -pruN 2022.1-1/internal/testenv/testenv.go 2022.1.3-1/internal/testenv/testenv.go
--- 2022.1-1/internal/testenv/testenv.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/internal/testenv/testenv.go	2022-07-31 15:38:22.000000000 +0000
@@ -10,7 +10,6 @@ import (
 	"bytes"
 	"fmt"
 	"go/build"
-	"io/ioutil"
 	"os"
 	"runtime"
 	"strings"
@@ -62,7 +61,7 @@ func hasTool(tool string) error {
 	switch tool {
 	case "patch":
 		// check that the patch tools supports the -o argument
-		temp, err := ioutil.TempFile("", "patch-test")
+		temp, err := os.CreateTemp("", "patch-test")
 		if err != nil {
 			return err
 		}
diff -pruN 2022.1-1/knowledge/signatures.go 2022.1.3-1/knowledge/signatures.go
--- 2022.1-1/knowledge/signatures.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/knowledge/signatures.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,107 @@
+package knowledge
+
+import (
+	"go/token"
+	"go/types"
+)
+
+var Signatures = map[string]*types.Signature{
+	"(io.Seeker).Seek": types.NewSignature(nil,
+		types.NewTuple(
+			types.NewParam(token.NoPos, nil, "", types.Typ[types.Int64]),
+			types.NewParam(token.NoPos, nil, "", types.Typ[types.Int]),
+		),
+		types.NewTuple(
+			types.NewParam(token.NoPos, nil, "", types.Typ[types.Int64]),
+			types.NewParam(token.NoPos, nil, "", types.Universe.Lookup("error").Type()),
+		),
+		false,
+	),
+
+	"(io.Writer).Write": types.NewSignature(nil,
+		types.NewTuple(
+			types.NewParam(token.NoPos, nil, "", types.NewSlice(types.Typ[types.Byte])),
+		),
+		types.NewTuple(
+			types.NewParam(token.NoPos, nil, "", types.Typ[types.Int]),
+			types.NewParam(token.NoPos, nil, "", types.Universe.Lookup("error").Type()),
+		),
+		false,
+	),
+
+	"(io.StringWriter).WriteString": types.NewSignature(nil,
+		types.NewTuple(
+			types.NewParam(token.NoPos, nil, "", types.Typ[types.String]),
+		),
+		types.NewTuple(
+			types.NewParam(token.NoPos, nil, "", types.Typ[types.Int]),
+			types.NewParam(token.NoPos, nil, "", types.Universe.Lookup("error").Type()),
+		),
+		false,
+	),
+
+	"(encoding.TextMarshaler).MarshalText": types.NewSignature(nil,
+		types.NewTuple(),
+		types.NewTuple(
+			types.NewParam(token.NoPos, nil, "", types.NewSlice(types.Typ[types.Byte])),
+			types.NewParam(token.NoPos, nil, "", types.Universe.Lookup("error").Type()),
+		),
+		false,
+	),
+
+	"(encoding/json.Marshaler).MarshalJSON": types.NewSignature(nil,
+		types.NewTuple(),
+		types.NewTuple(
+			types.NewParam(token.NoPos, nil, "", types.NewSlice(types.Typ[types.Byte])),
+			types.NewParam(token.NoPos, nil, "", types.Universe.Lookup("error").Type()),
+		),
+		false,
+	),
+
+	"(fmt.Stringer).String": types.NewSignature(nil,
+		types.NewTuple(),
+		types.NewTuple(
+			types.NewParam(token.NoPos, nil, "", types.Typ[types.String]),
+		),
+		false,
+	),
+}
+
+var Interfaces = map[string]*types.Interface{
+	"fmt.Stringer": types.NewInterfaceType(
+		[]*types.Func{
+			types.NewFunc(token.NoPos, nil, "String", Signatures["(fmt.Stringer).String"]),
+		},
+		nil,
+	).Complete(),
+
+	"error": types.Universe.Lookup("error").Type().Underlying().(*types.Interface),
+
+	"io.Writer": types.NewInterfaceType(
+		[]*types.Func{
+			types.NewFunc(token.NoPos, nil, "Write", Signatures["(io.Writer).Write"]),
+		},
+		nil,
+	).Complete(),
+
+	"io.StringWriter": types.NewInterfaceType(
+		[]*types.Func{
+			types.NewFunc(token.NoPos, nil, "WriteString", Signatures["(io.StringWriter).WriteString"]),
+		},
+		nil,
+	).Complete(),
+
+	"encoding.TextMarshaler": types.NewInterfaceType(
+		[]*types.Func{
+			types.NewFunc(token.NoPos, nil, "MarshalText", Signatures["(encoding.TextMarshaler).MarshalText"]),
+		},
+		nil,
+	).Complete(),
+
+	"encoding/json.Marshaler": types.NewInterfaceType(
+		[]*types.Func{
+			types.NewFunc(token.NoPos, nil, "MarshalJSON", Signatures["(encoding/json.Marshaler).MarshalJSON"]),
+		},
+		nil,
+	).Complete(),
+}
diff -pruN 2022.1-1/lintcmd/cache/cache.go 2022.1.3-1/lintcmd/cache/cache.go
--- 2022.1-1/lintcmd/cache/cache.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/lintcmd/cache/cache.go	2022-07-31 15:38:22.000000000 +0000
@@ -15,7 +15,6 @@ import (
 	"errors"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"os"
 	"path/filepath"
 	"strconv"
@@ -247,7 +246,7 @@ func (c *Cache) GetBytes(id ActionID) ([
 	if err != nil {
 		return nil, entry, err
 	}
-	data, _ := ioutil.ReadFile(c.OutputFile(entry.OutputID))
+	data, _ := os.ReadFile(c.OutputFile(entry.OutputID))
 	if sha256.Sum256(data) != entry.OutputID {
 		return nil, entry, &entryNotFoundError{Err: errors.New("bad checksum")}
 	}
diff -pruN 2022.1-1/lintcmd/cache/cache_test.go 2022.1.3-1/lintcmd/cache/cache_test.go
--- 2022.1-1/lintcmd/cache/cache_test.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/lintcmd/cache/cache_test.go	2022-07-31 15:38:22.000000000 +0000
@@ -8,7 +8,6 @@ import (
 	"bytes"
 	"encoding/binary"
 	"fmt"
-	"io/ioutil"
 	"os"
 	"path/filepath"
 	"testing"
@@ -20,7 +19,7 @@ func init() {
 }
 
 func TestBasic(t *testing.T) {
-	dir, err := ioutil.TempDir("", "cachetest-")
+	dir, err := os.MkdirTemp("", "cachetest-")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -65,7 +64,7 @@ func TestBasic(t *testing.T) {
 }
 
 func TestGrowth(t *testing.T) {
-	dir, err := ioutil.TempDir("", "cachetest-")
+	dir, err := os.MkdirTemp("", "cachetest-")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -118,7 +117,7 @@ func TestVerifyPanic(t *testing.T) {
 		t.Fatal("initEnv did not set verify")
 	}
 
-	dir, err := ioutil.TempDir("", "cachetest-")
+	dir, err := os.MkdirTemp("", "cachetest-")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -151,7 +150,7 @@ func dummyID(x int) [HashSize]byte {
 }
 
 func TestCacheTrim(t *testing.T) {
-	dir, err := ioutil.TempDir("", "cachetest-")
+	dir, err := os.MkdirTemp("", "cachetest-")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -207,7 +206,7 @@ func TestCacheTrim(t *testing.T) {
 		t.Fatal(err)
 	}
 	c.OutputFile(entry.OutputID)
-	data, err := ioutil.ReadFile(filepath.Join(dir, "trim.txt"))
+	data, err := os.ReadFile(filepath.Join(dir, "trim.txt"))
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -220,7 +219,7 @@ func TestCacheTrim(t *testing.T) {
 		t.Fatal(err)
 	}
 	c.OutputFile(entry.OutputID)
-	data2, err := ioutil.ReadFile(filepath.Join(dir, "trim.txt"))
+	data2, err := os.ReadFile(filepath.Join(dir, "trim.txt"))
 	if err != nil {
 		t.Fatal(err)
 	}
diff -pruN 2022.1-1/lintcmd/cache/default.go 2022.1.3-1/lintcmd/cache/default.go
--- 2022.1-1/lintcmd/cache/default.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/lintcmd/cache/default.go	2022-07-31 15:38:22.000000000 +0000
@@ -6,7 +6,6 @@ package cache
 
 import (
 	"fmt"
-	"io/ioutil"
 	"log"
 	"os"
 	"path/filepath"
@@ -39,7 +38,7 @@ func initDefaultCache() {
 	}
 	if _, err := os.Stat(filepath.Join(dir, "README")); err != nil {
 		// Best effort.
-		ioutil.WriteFile(filepath.Join(dir, "README"), []byte(cacheREADME), 0666)
+		os.WriteFile(filepath.Join(dir, "README"), []byte(cacheREADME), 0666)
 	}
 
 	c, err := Open(dir)
diff -pruN 2022.1-1/lintcmd/cache/hash_test.go 2022.1.3-1/lintcmd/cache/hash_test.go
--- 2022.1-1/lintcmd/cache/hash_test.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/lintcmd/cache/hash_test.go	2022-07-31 15:38:22.000000000 +0000
@@ -6,7 +6,6 @@ package cache
 
 import (
 	"fmt"
-	"io/ioutil"
 	"os"
 	"testing"
 )
@@ -23,7 +22,7 @@ func TestHash(t *testing.T) {
 }
 
 func TestHashFile(t *testing.T) {
-	f, err := ioutil.TempFile("", "cmd-go-test-")
+	f, err := os.CreateTemp("", "cmd-go-test-")
 	if err != nil {
 		t.Fatal(err)
 	}
diff -pruN 2022.1-1/lintcmd/cmd.go 2022.1.3-1/lintcmd/cmd.go
--- 2022.1-1/lintcmd/cmd.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/lintcmd/cmd.go	2022-07-31 15:38:22.000000000 +0000
@@ -11,6 +11,7 @@ import (
 	"io"
 	"log"
 	"os"
+	"path/filepath"
 	"reflect"
 	"runtime"
 	"runtime/pprof"
@@ -392,8 +393,8 @@ func (cmd *Command) Run() {
 			var err error
 			bconfs, err = parseBuildConfigs(os.Stdin)
 			if err != nil {
-				if err, ok := err.(parseBuildConfigError); ok {
-					fmt.Fprintf(os.Stderr, "<stdin>:%d couldn't parse build matrix: %s\n", err.line, err.err)
+				if perr, ok := err.(parseBuildConfigError); ok {
+					fmt.Fprintf(os.Stderr, "<stdin>:%d couldn't parse build matrix: %s\n", perr.line, perr.err)
 				} else {
 					fmt.Fprintln(os.Stderr, err)
 				}
@@ -436,7 +437,46 @@ func (cmd *Command) Run() {
 				fmt.Fprintln(os.Stderr, "warning:", w)
 			}
 
+			cwd, err := os.Getwd()
+			if err != nil {
+				cwd = ""
+			}
+			relPath := func(s string) string {
+				if cwd == "" {
+					return filepath.ToSlash(s)
+				}
+				out, err := filepath.Rel(cwd, s)
+				if err != nil {
+					return filepath.ToSlash(s)
+				}
+				return filepath.ToSlash(out)
+			}
+
 			if cmd.flags.formatter == "binary" {
+				for i, s := range res.CheckedFiles {
+					res.CheckedFiles[i] = relPath(s)
+				}
+				for i := range res.Diagnostics {
+					// We turn all paths into relative, /-separated paths. This is to make -merge work correctly when
+					// merging runs from different OSs, with different absolute paths.
+					//
+					// We zero out Offset, because checkouts of code on different OSs may have different kinds of
+					// newlines and thus different offsets. We don't ever make use of the Offset, anyway. Line and
+					// column numbers are precomputed.
+
+					d := &res.Diagnostics[i]
+					d.Position.Filename = relPath(d.Position.Filename)
+					d.Position.Offset = 0
+					d.End.Filename = relPath(d.End.Filename)
+					d.End.Offset = 0
+					for j := range d.Related {
+						r := &d.Related[j]
+						r.Position.Filename = relPath(r.Position.Filename)
+						r.Position.Offset = 0
+						r.End.Filename = relPath(r.End.Filename)
+						r.End.Offset = 0
+					}
+				}
 				err := gob.NewEncoder(os.Stdout).Encode(res)
 				if err != nil {
 					fmt.Fprintf(os.Stderr, "failed writing output: %s\n", err)
@@ -497,6 +537,7 @@ func (cmd *Command) exit(code int) {
 	os.Exit(code)
 }
 
+// printDiagnostics prints the diagnostics and exits the process.
 func (cmd *Command) printDiagnostics(cs []*lint.Analyzer, diagnostics []diagnostic) {
 	if len(diagnostics) > 1 {
 		sort.Slice(diagnostics, func(i, j int) bool {
diff -pruN 2022.1-1/lintcmd/lint.go 2022.1.3-1/lintcmd/lint.go
--- 2022.1-1/lintcmd/lint.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/lintcmd/lint.go	2022-07-31 15:38:22.000000000 +0000
@@ -31,6 +31,7 @@ import (
 type linter struct {
 	Analyzers map[string]*lint.Analyzer
 	Runner    *runner.Runner
+	cache     *cache.Cache
 }
 
 func computeSalt() ([]byte, error) {
@@ -74,6 +75,7 @@ func newLinter(cfg config.Config) (*lint
 	r.FallbackGoVersion = defaultGoVersion()
 	return &linter{
 		Runner: r,
+		cache:  c,
 	}, nil
 }
 
@@ -519,6 +521,7 @@ func doLint(as []*lint.Analyzer, paths [
 	if err != nil {
 		return LintResult{}, err
 	}
+	defer l.cache.Trim()
 	analyzers := make(map[string]*lint.Analyzer, len(as))
 	for _, a := range as {
 		analyzers[a.Analyzer.Name] = a
diff -pruN 2022.1-1/lintcmd/runner/runner.go 2022.1.3-1/lintcmd/runner/runner.go
--- 2022.1-1/lintcmd/runner/runner.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/lintcmd/runner/runner.go	2022-07-31 15:38:22.000000000 +0000
@@ -118,7 +118,6 @@ import (
 	"go/token"
 	"go/types"
 	"io"
-	"io/ioutil"
 	"os"
 	"reflect"
 	"runtime"
@@ -231,16 +230,8 @@ func (r Result) Load() (ResultData, erro
 	return out, err
 }
 
-type Want struct {
-	Position token.Position
-	Comment  string
-}
-
 // TestData contains extra information about analysis runs that is only available in test mode.
 type TestData struct {
-	// Wants contains a list of '// want' comments extracted from Go files.
-	// These comments are used in unit tests.
-	Wants []Want
 	// Facts contains facts produced by analyzers for a package.
 	// Unlike vetx, this list only contains facts specific to this package,
 	// not all facts for the transitive closure of dependencies.
@@ -634,7 +625,6 @@ func (r *subrunner) do(act action) error
 
 		if r.TestMode {
 			out := TestData{
-				Wants: result.wants,
 				Facts: result.testFacts,
 			}
 			a.testData, err = r.writeCacheGob(a, "testdata", out)
@@ -666,7 +656,7 @@ func (r *Runner) writeCacheReader(a *pac
 }
 
 func (r *Runner) writeCacheGob(a *packageAction, kind string, data interface{}) (string, error) {
-	f, err := ioutil.TempFile("", "staticcheck")
+	f, err := os.CreateTemp("", "staticcheck")
 	if err != nil {
 		return "", err
 	}
@@ -691,7 +681,6 @@ type packageActionResult struct {
 
 	// Only set when using test mode
 	testFacts []TestFact
-	wants     []Want
 }
 
 func (r *subrunner) doUncached(a *packageAction) (packageActionResult, error) {
@@ -727,41 +716,9 @@ func (r *subrunner) doUncached(a *packag
 	}
 	res, err := r.runAnalyzers(a, pkg)
 
-	var wants []Want
-	if r.TestMode {
-		// Extract 'want' comments from parsed Go files.
-		for _, f := range pkg.Syntax {
-			for _, cgroup := range f.Comments {
-				for _, c := range cgroup.List {
-
-					text := strings.TrimPrefix(c.Text, "//")
-					if text == c.Text { // not a //-comment.
-						text = strings.TrimPrefix(text, "/*")
-						text = strings.TrimSuffix(text, "*/")
-					}
-
-					// Hack: treat a comment of the form "//...// want..."
-					// or "/*...// want... */
-					// as if it starts at 'want'.
-					// This allows us to add comments on comments,
-					// as required when testing the buildtag analyzer.
-					if i := strings.Index(text, "// want"); i >= 0 {
-						text = text[i+len("// "):]
-					}
-
-					posn := pkg.Fset.Position(c.Pos())
-					wants = append(wants, Want{Position: posn, Comment: text})
-				}
-			}
-		}
-
-		// TODO(dh): add support for non-Go files
-	}
-
 	return packageActionResult{
 		facts:     res.facts,
 		testFacts: res.testFacts,
-		wants:     wants,
 		diags:     res.diagnostics,
 		unused:    res.unused,
 		dirs:      dirs,
diff -pruN 2022.1-1/lintcmd/version/version.go 2022.1.3-1/lintcmd/version/version.go
--- 2022.1-1/lintcmd/version/version.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/lintcmd/version/version.go	2022-07-31 15:38:22.000000000 +0000
@@ -7,8 +7,8 @@ import (
 	"runtime"
 )
 
-const Version = "2022.1"
-const MachineVersion = "v0.3.0"
+const Version = "2022.1.3"
+const MachineVersion = "v0.3.3"
 
 // version returns a version descriptor and reports whether the
 // version is a known release.
diff -pruN 2022.1-1/pattern/convert.go 2022.1.3-1/pattern/convert.go
--- 2022.1-1/pattern/convert.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/pattern/convert.go	2022-07-31 15:38:22.000000000 +0000
@@ -148,7 +148,7 @@ func NodeToAST(node Node, state State) i
 		default:
 			return v
 		}
-	case Builtin, Any, Object, Function, Not, Or:
+	case Builtin, Any, Object, Symbol, Not, Or:
 		panic("XXX")
 	case List:
 		if (node == List{}) {
diff -pruN 2022.1-1/pattern/doc.go 2022.1.3-1/pattern/doc.go
--- 2022.1-1/pattern/doc.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/pattern/doc.go	2022-07-31 15:38:22.000000000 +0000
@@ -185,15 +185,15 @@ Subsequent occurrences of 'true' no long
 (Object name) matches an identifier by name, but yields the
 types.Object it refers to.
 
-(Function name) matches ast.Idents and ast.SelectorExprs that refer to a function with a given fully qualified name.
+(Symbol name) matches ast.Idents and ast.SelectorExprs that refer to a symbol with a given fully qualified name.
 For example, "net/url.PathEscape" matches the PathEscape function in the net/url package,
 and "(net/url.EscapeError).Error" refers to the Error method on the net/url.EscapeError type,
 either on an instance of the type, or on the type itself.
 
 For example, the following patterns match the following lines of code:
 
-	(CallExpr (Function "fmt.Println") _) // pattern 1
-	(CallExpr (Function "(net/url.EscapeError).Error") _) // pattern 2
+	(CallExpr (Symbol "fmt.Println") _) // pattern 1
+	(CallExpr (Symbol "(net/url.EscapeError).Error") _) // pattern 2
 
 	fmt.Println("hello, world") // matches pattern 1
 	var x url.EscapeError
diff -pruN 2022.1-1/pattern/match.go 2022.1.3-1/pattern/match.go
--- 2022.1-1/pattern/match.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/pattern/match.go	2022-07-31 15:38:22.000000000 +0000
@@ -474,7 +474,7 @@ func (obj Object) Match(m *Matcher, node
 	return id, ok
 }
 
-func (fn Function) Match(m *Matcher, node interface{}) (interface{}, bool) {
+func (fn Symbol) Match(m *Matcher, node interface{}) (interface{}, bool) {
 	var name string
 	var obj types.Object
 
@@ -503,31 +503,37 @@ func (fn Function) Match(m *Matcher, nod
 	switch fun := fun.(type) {
 	case *ast.Ident:
 		obj = m.TypesInfo.ObjectOf(fun)
-		switch obj := obj.(type) {
-		case *types.Func:
-			// OPT(dh): optimize this similar to code.FuncName
-			name = obj.FullName()
-		case *types.Builtin:
-			name = obj.Name()
-		case *types.TypeName:
-			name = types.TypeString(obj.Type(), nil)
-		default:
-			return nil, false
-		}
 	case *ast.SelectorExpr:
 		obj = m.TypesInfo.ObjectOf(fun.Sel)
-		switch obj := obj.(type) {
-		case *types.Func:
-			// OPT(dh): optimize this similar to code.FuncName
-			name = obj.FullName()
-		case *types.TypeName:
-			name = types.TypeString(obj.Type(), nil)
-		default:
+	default:
+		panic("unreachable")
+	}
+	switch obj := obj.(type) {
+	case *types.Func:
+		// OPT(dh): optimize this similar to code.FuncName
+		name = obj.FullName()
+	case *types.Builtin:
+		name = obj.Name()
+	case *types.TypeName:
+		if obj.Pkg() == nil {
+			return nil, false
+		}
+		if obj.Parent() != obj.Pkg().Scope() {
 			return nil, false
 		}
+		name = types.TypeString(obj.Type(), nil)
+	case *types.Const, *types.Var:
+		if obj.Pkg() == nil {
+			return nil, false
+		}
+		if obj.Parent() != obj.Pkg().Scope() {
+			return nil, false
+		}
+		name = fmt.Sprintf("%s.%s", obj.Pkg().Path(), obj.Name())
 	default:
-		panic("unreachable")
+		return nil, false
 	}
+
 	_, ok = match(m, fn.Name, name)
 	return obj, ok
 }
@@ -612,7 +618,7 @@ var (
 	_ matcher = Nil{}
 	_ matcher = Builtin{}
 	_ matcher = Object{}
-	_ matcher = Function{}
+	_ matcher = Symbol{}
 	_ matcher = Or{}
 	_ matcher = Not{}
 	_ matcher = IntegerLiteral{}
diff -pruN 2022.1-1/pattern/parser.go 2022.1.3-1/pattern/parser.go
--- 2022.1-1/pattern/parser.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/pattern/parser.go	2022-07-31 15:38:22.000000000 +0000
@@ -97,7 +97,7 @@ var nodeToASTTypes = map[reflect.Type][]
 	reflect.TypeOf(List{}):                    {reflect.TypeOf((*ast.BlockStmt)(nil)), reflect.TypeOf((*ast.FieldList)(nil))},
 	reflect.TypeOf(Builtin{}):                 {reflect.TypeOf((*ast.Ident)(nil))},
 	reflect.TypeOf(Object{}):                  {reflect.TypeOf((*ast.Ident)(nil))},
-	reflect.TypeOf(Function{}):                {reflect.TypeOf((*ast.Ident)(nil)), reflect.TypeOf((*ast.SelectorExpr)(nil))},
+	reflect.TypeOf(Symbol{}):                  {reflect.TypeOf((*ast.Ident)(nil)), reflect.TypeOf((*ast.SelectorExpr)(nil))},
 	reflect.TypeOf(Any{}):                     allTypes,
 	reflect.TypeOf(RangeStmt{}):               {reflect.TypeOf((*ast.RangeStmt)(nil))},
 	reflect.TypeOf(AssignStmt{}):              {reflect.TypeOf((*ast.AssignStmt)(nil))},
@@ -145,9 +145,11 @@ var nodeToASTTypes = map[reflect.Type][]
 }
 
 var requiresTypeInfo = map[string]bool{
-	"Function": true,
-	"Builtin":  true,
-	"Object":   true,
+	"Symbol":                  true,
+	"Builtin":                 true,
+	"Object":                  true,
+	"IntegerLiteral":          true,
+	"TrulyConstantExpression": true,
 }
 
 type Parser struct {
@@ -355,7 +357,7 @@ var structNodes = map[string]reflect.Typ
 	"IncDecStmt":              reflect.TypeOf(IncDecStmt{}),
 	"BasicLit":                reflect.TypeOf(BasicLit{}),
 	"Object":                  reflect.TypeOf(Object{}),
-	"Function":                reflect.TypeOf(Function{}),
+	"Symbol":                  reflect.TypeOf(Symbol{}),
 	"Or":                      reflect.TypeOf(Or{}),
 	"Not":                     reflect.TypeOf(Not{}),
 	"IntegerLiteral":          reflect.TypeOf(IntegerLiteral{}),
diff -pruN 2022.1-1/pattern/pattern.go 2022.1.3-1/pattern/pattern.go
--- 2022.1-1/pattern/pattern.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/pattern/pattern.go	2022-07-31 15:38:22.000000000 +0000
@@ -59,14 +59,14 @@ var (
 	_ Node = BasicLit{}
 	_ Node = Nil{}
 	_ Node = Object{}
-	_ Node = Function{}
+	_ Node = Symbol{}
 	_ Node = Not{}
 	_ Node = Or{}
 	_ Node = IntegerLiteral{}
 	_ Node = TrulyConstantExpression{}
 )
 
-type Function struct {
+type Symbol struct {
 	Name Node
 }
 
@@ -401,7 +401,7 @@ func (stmt TypeSwitchStmt) String() stri
 func (nil Nil) String() string                      { return "nil" }
 func (builtin Builtin) String() string              { return stringify(builtin) }
 func (obj Object) String() string                   { return stringify(obj) }
-func (fn Function) String() string                  { return stringify(fn) }
+func (fn Symbol) String() string                    { return stringify(fn) }
 func (el Ellipsis) String() string                  { return stringify(el) }
 func (not Not) String() string                      { return stringify(not) }
 func (lit IntegerLiteral) String() string           { return stringify(lit) }
@@ -509,7 +509,7 @@ func (TypeSwitchStmt) isNode()
 func (Nil) isNode()                     {}
 func (Builtin) isNode()                 {}
 func (Object) isNode()                  {}
-func (Function) isNode()                {}
+func (Symbol) isNode()                  {}
 func (Ellipsis) isNode()                {}
 func (Or) isNode()                      {}
 func (List) isNode()                    {}
diff -pruN 2022.1-1/pattern/testdata/fuzz/FuzzParse/02f183192c9bcfbb22db5afa08e5a9a84babfca022726d0121f42c68d3feecee 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/02f183192c9bcfbb22db5afa08e5a9a84babfca022726d0121f42c68d3feecee
--- 2022.1-1/pattern/testdata/fuzz/FuzzParse/02f183192c9bcfbb22db5afa08e5a9a84babfca022726d0121f42c68d3feecee	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/02f183192c9bcfbb22db5afa08e5a9a84babfca022726d0121f42c68d3feecee	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,2 @@
+go test fuzz v1
+[]byte("go test fuzz v1\n[]byte(\"(CallExpr (Symbol \\\"math.Pow\\\") [x (IntegerLiteral n)])\")")
\ No newline at end of file
diff -pruN 2022.1-1/pattern/testdata/fuzz/FuzzParse/04fca5bfcc4a67c0d97de75fd6dc13a4a3e5c2dc68e5061f7bcb7e19852efe56 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/04fca5bfcc4a67c0d97de75fd6dc13a4a3e5c2dc68e5061f7bcb7e19852efe56
--- 2022.1-1/pattern/testdata/fuzz/FuzzParse/04fca5bfcc4a67c0d97de75fd6dc13a4a3e5c2dc68e5061f7bcb7e19852efe56	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/04fca5bfcc4a67c0d97de75fd6dc13a4a3e5c2dc68e5061f7bcb7e19852efe56	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,2 @@
+go test fuzz v1
+[]byte("go test fuzz v1\n[]byte(\"\\n\\t\\t(Or\\n\\t\\t\\t(CallExpr\\n\\t\\t\\t\\tfn@(Or\\n\\t\\t\\t\\t\\t(Symbol \\\"fmt.Print\\\")\\n\\t\\t\\t\\t\\t(Symbol \\\"fmt.Sprint\\\")\\n\\t\\t\\t\\t\\t(Symbol \\\"fmt.Println\\\")\\n\\t\\t\\t\\t\\t(Symbol \\\"fmt.Sprintln\\\"))\\n\\t\\t\\t\\t[(CallExpr (Symbol \\\"fmt.Sprintf\\\") f:_)])\\n\\t\\t\\t(CallExpr\\n\\t\\t\\t\\tfn@(Or\\n\\t\\t\\t\\t\\t(Symbol \\\"fmt.Fprint\\\")\\n\\t\\t\\t\\t\\t(Symbol \\\"fmt.Fprintln\\\"))\\n\\t\\t\\t\\t[_ (CallExpr (Symbol \\\"fmt.Sprintf\\\") f:_)]))\")")
\ No newline at end of file
diff -pruN 2022.1-1/pattern/testdata/fuzz/FuzzParse/0ce7ffb3713ec9373531b2903b8f8751e280cdae2b625dcf35dc1fcd88c592bf 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/0ce7ffb3713ec9373531b2903b8f8751e280cdae2b625dcf35dc1fcd88c592bf
--- 2022.1-1/pattern/testdata/fuzz/FuzzParse/0ce7ffb3713ec9373531b2903b8f8751e280cdae2b625dcf35dc1fcd88c592bf	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/0ce7ffb3713ec9373531b2903b8f8751e280cdae2b625dcf35dc1fcd88c592bf	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,2 @@
+go test fuzz v1
+[]byte("go test fuzz v1\n[]byte(\"\\n\\t(CallExpr\\n\\t\\tfn@(Or\\n\\t\\t\\t(Symbol \\\"fmt.Sprint\\\")\\n\\t\\t\\t(Symbol \\\"fmt.Sprintf\\\"))\\n\\t\\t[lit@(BasicLit \\\"STRING\\\" _)])\")")
\ No newline at end of file
diff -pruN 2022.1-1/pattern/testdata/fuzz/FuzzParse/2bac99d4a450641e3ae239588965c64323b1ee9eb2351cc53019d430d3a59efa 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/2bac99d4a450641e3ae239588965c64323b1ee9eb2351cc53019d430d3a59efa
--- 2022.1-1/pattern/testdata/fuzz/FuzzParse/2bac99d4a450641e3ae239588965c64323b1ee9eb2351cc53019d430d3a59efa	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/2bac99d4a450641e3ae239588965c64323b1ee9eb2351cc53019d430d3a59efa	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,2 @@
+go test fuzz v1
+[]byte("go test fuzz v1\n[]byte(\"\\n\\t(CallExpr\\n\\t\\t(SelectorExpr recv (Ident \\\"Write\\\"))\\n\\t\\t(CallExpr (ArrayType nil (Ident \\\"byte\\\"))\\n\\t\\t\\t(CallExpr\\n\\t\\t\\t\\tfn@(Or\\n\\t\\t\\t\\t\\t(Symbol \\\"fmt.Sprint\\\")\\n\\t\\t\\t\\t\\t(Symbol \\\"fmt.Sprintf\\\")\\n\\t\\t\\t\\t\\t(Symbol \\\"fmt.Sprintln\\\"))\\n\\t\\t\\t\\targs)\\n\\t))\")")
\ No newline at end of file
diff -pruN 2022.1-1/pattern/testdata/fuzz/FuzzParse/3a3ef35129ccc131fc582363751397ad5723fb8ae891c31eaa5ad86ba402a27e 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/3a3ef35129ccc131fc582363751397ad5723fb8ae891c31eaa5ad86ba402a27e
--- 2022.1-1/pattern/testdata/fuzz/FuzzParse/3a3ef35129ccc131fc582363751397ad5723fb8ae891c31eaa5ad86ba402a27e	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/3a3ef35129ccc131fc582363751397ad5723fb8ae891c31eaa5ad86ba402a27e	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,2 @@
+go test fuzz v1
+[]byte("go test fuzz v1\n[]byte(\"(CallExpr (Symbol \\\"fmt.Sprintf\\\") [format arg])\")")
\ No newline at end of file
diff -pruN 2022.1-1/pattern/testdata/fuzz/FuzzParse/47857edd56b46ac9c16e788e9295d1dafb910c345899aafd618ddaa12793f4f9 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/47857edd56b46ac9c16e788e9295d1dafb910c345899aafd618ddaa12793f4f9
--- 2022.1-1/pattern/testdata/fuzz/FuzzParse/47857edd56b46ac9c16e788e9295d1dafb910c345899aafd618ddaa12793f4f9	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/47857edd56b46ac9c16e788e9295d1dafb910c345899aafd618ddaa12793f4f9	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,2 @@
+go test fuzz v1
+[]byte("go test fuzz v1\n[]byte(\"(CallExpr (Symbol \\\"errors.New\\\") [(CallExpr (Symbol \\\"fmt.Sprintf\\\") args)])\")")
\ No newline at end of file
diff -pruN 2022.1-1/pattern/testdata/fuzz/FuzzParse/4dec90e6083b5e195501df63d8e1ed6813b623bef60ad8d9e0a1df1f251a58f3 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/4dec90e6083b5e195501df63d8e1ed6813b623bef60ad8d9e0a1df1f251a58f3
--- 2022.1-1/pattern/testdata/fuzz/FuzzParse/4dec90e6083b5e195501df63d8e1ed6813b623bef60ad8d9e0a1df1f251a58f3	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/4dec90e6083b5e195501df63d8e1ed6813b623bef60ad8d9e0a1df1f251a58f3	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,2 @@
+go test fuzz v1
+[]byte("go test fuzz v1\n[]byte(\"\\n\\t(CallExpr\\n\\t\\t(Symbol\\n\\t\\t\\tname@(Or\\n\\t\\t\\t\\t\\\"math/rand.Int31n\\\"\\n\\t\\t\\t\\t\\\"math/rand.Int63n\\\"\\n\\t\\t\\t\\t\\\"math/rand.Intn\\\"\\n\\t\\t\\t\\t\\\"(*math/rand.Rand).Int31n\\\"\\n\\t\\t\\t\\t\\\"(*math/rand.Rand).Int63n\\\"\\n\\t\\t\\t\\t\\\"(*math/rand.Rand).Intn\\\"))\\n\\t\\t[(IntegerLiteral \\\"1\\\")])\")")
\ No newline at end of file
diff -pruN 2022.1-1/pattern/testdata/fuzz/FuzzParse/53da8fdd88cd66de33bbdbbf564e2b14b69d02f32102d8a96171ed4b05dbc92e 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/53da8fdd88cd66de33bbdbbf564e2b14b69d02f32102d8a96171ed4b05dbc92e
--- 2022.1-1/pattern/testdata/fuzz/FuzzParse/53da8fdd88cd66de33bbdbbf564e2b14b69d02f32102d8a96171ed4b05dbc92e	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/53da8fdd88cd66de33bbdbbf564e2b14b69d02f32102d8a96171ed4b05dbc92e	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,2 @@
+go test fuzz v1
+[]byte("go test fuzz v1\n[]byte(\"\\n\\t\\t(CallExpr\\n\\t\\t\\t(Symbol\\n\\t\\t\\t\\t(Or\\n\\t\\t\\t\\t\\t\\\"log.Fatal\\\"\\n\\t\\t\\t\\t\\t\\\"log.Fatalln\\\"\\n\\t\\t\\t\\t\\t\\\"log.Panic\\\"\\n\\t\\t\\t\\t\\t\\\"log.Panicln\\\"\\n\\t\\t\\t\\t\\t\\\"log.Print\\\"\\n\\t\\t\\t\\t\\t\\\"log.Println\\\"))\\n\\t\\t\\t[(CallExpr (Symbol \\\"fmt.Sprintf\\\") args)])\")")
\ No newline at end of file
diff -pruN 2022.1-1/pattern/testdata/fuzz/FuzzParse/5e8383a425cf9bc34f43d60f7586184ae7a544e3ad10405ef7aca57246c2ab66 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/5e8383a425cf9bc34f43d60f7586184ae7a544e3ad10405ef7aca57246c2ab66
--- 2022.1-1/pattern/testdata/fuzz/FuzzParse/5e8383a425cf9bc34f43d60f7586184ae7a544e3ad10405ef7aca57246c2ab66	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/5e8383a425cf9bc34f43d60f7586184ae7a544e3ad10405ef7aca57246c2ab66	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,2 @@
+go test fuzz v1
+[]byte("go test fuzz v1\n[]byte(\"\\n\\t(BinaryExpr\\n\\t\\t(CallExpr fun@(Symbol (Or \\\"strings.ToLower\\\" \\\"strings.ToUpper\\\")) [a])\\n \\t\\ttok@(Or \\\"==\\\" \\\"!=\\\")\\n \\t\\t(CallExpr fun [b]))\")")
\ No newline at end of file
diff -pruN 2022.1-1/pattern/testdata/fuzz/FuzzParse/614ea1474d223cb45716d531aa8afac2dfd52938aeb38c64b70a351f0cf509b2 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/614ea1474d223cb45716d531aa8afac2dfd52938aeb38c64b70a351f0cf509b2
--- 2022.1-1/pattern/testdata/fuzz/FuzzParse/614ea1474d223cb45716d531aa8afac2dfd52938aeb38c64b70a351f0cf509b2	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/614ea1474d223cb45716d531aa8afac2dfd52938aeb38c64b70a351f0cf509b2	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,2 @@
+go test fuzz v1
+[]byte("go test fuzz v1\n[]byte(\"(CallExpr (SelectorExpr (CallExpr (Symbol \\\"time.Now\\\") []) (Symbol \\\"(time.Time).Sub\\\")) [arg])\")")
\ No newline at end of file
diff -pruN 2022.1-1/pattern/testdata/fuzz/FuzzParse/6ac1f5e27fbe6d979efae1abf9b2439a824b83f4b2a27508dbeb5dc95b4f9960 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/6ac1f5e27fbe6d979efae1abf9b2439a824b83f4b2a27508dbeb5dc95b4f9960
--- 2022.1-1/pattern/testdata/fuzz/FuzzParse/6ac1f5e27fbe6d979efae1abf9b2439a824b83f4b2a27508dbeb5dc95b4f9960	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/6ac1f5e27fbe6d979efae1abf9b2439a824b83f4b2a27508dbeb5dc95b4f9960	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,2 @@
+go test fuzz v1
+[]byte("go test fuzz v1\n[]byte(\"\\n\\t(Or\\n\\t\\t(CallExpr\\n\\t\\t\\t(Symbol (Or\\n\\t\\t\\t\\t\\\"fmt.Print\\\"\\n\\t\\t\\t\\t\\\"fmt.Println\\\"\\n\\t\\t\\t\\t\\\"fmt.Sprint\\\"\\n\\t\\t\\t\\t\\\"fmt.Sprintln\\\"\\n\\t\\t\\t\\t\\\"log.Fatal\\\"\\n\\t\\t\\t\\t\\\"log.Fatalln\\\"\\n\\t\\t\\t\\t\\\"log.Panic\\\"\\n\\t\\t\\t\\t\\\"log.Panicln\\\"\\n\\t\\t\\t\\t\\\"log.Print\\\"\\n\\t\\t\\t\\t\\\"log.Println\\\"\\n\\t\\t\\t\\t\\\"(*log.Logger).Fatal\\\"\\n\\t\\t\\t\\t\\\"(*log.Logger).Fatalln\\\"\\n\\t\\t\\t\\t\\\"(*log.Logger).Panic\\\"\\n\\t\\t\\t\\t\\\"(*log.Logger).Panicln\\\"\\n\\t\\t\\t\\t\\\"(*log.Logger).Print\\\"\\n\\t\\t\\t\\t\\\"(*log.Logger).Println\\\")) args)\\n\\n\\t\\t(CallExpr (Symbol (Or\\n\\t\\t\\t\\\"fmt.Fprint\\\"\\n\\t\\t\\t\\\"fmt.Fprintln\\\")) _:args))\")")
\ No newline at end of file
diff -pruN 2022.1-1/pattern/testdata/fuzz/FuzzParse/6fa1e1e283fd220866a9e5878510db574b761fbd5a0e863e66f40fd4acbbaf07 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/6fa1e1e283fd220866a9e5878510db574b761fbd5a0e863e66f40fd4acbbaf07
--- 2022.1-1/pattern/testdata/fuzz/FuzzParse/6fa1e1e283fd220866a9e5878510db574b761fbd5a0e863e66f40fd4acbbaf07	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/6fa1e1e283fd220866a9e5878510db574b761fbd5a0e863e66f40fd4acbbaf07	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,2 @@
+go test fuzz v1
+[]byte("go test fuzz v1\n[]byte(\"(SelectStmt (CommClause (UnaryExpr \\\"<-\\\" (CallExpr (Symbol \\\"time.After\\\") [arg])) body))\")")
\ No newline at end of file
diff -pruN 2022.1-1/pattern/testdata/fuzz/FuzzParse/76d91998f39bf2e25bd361453a73968274ffe16677cf02d872222d4c799552f8 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/76d91998f39bf2e25bd361453a73968274ffe16677cf02d872222d4c799552f8
--- 2022.1-1/pattern/testdata/fuzz/FuzzParse/76d91998f39bf2e25bd361453a73968274ffe16677cf02d872222d4c799552f8	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/76d91998f39bf2e25bd361453a73968274ffe16677cf02d872222d4c799552f8	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,2 @@
+go test fuzz v1
+[]byte("go test fuzz v1\n[]byte(\"(Or\\n\\t(CallExpr fn@(Symbol \\\"strings.Replace\\\") [_ _ _ lit@(IntegerLiteral \\\"-1\\\")])\\n\\t(CallExpr fn@(Symbol \\\"strings.SplitN\\\") [_ _ lit@(IntegerLiteral \\\"-1\\\")])\\n\\t(CallExpr fn@(Symbol \\\"strings.SplitAfterN\\\") [_ _ lit@(IntegerLiteral \\\"-1\\\")])\\n\\t(CallExpr fn@(Symbol \\\"bytes.Replace\\\") [_ _ _ lit@(IntegerLiteral \\\"-1\\\")])\\n\\t(CallExpr fn@(Symbol \\\"bytes.SplitN\\\") [_ _ lit@(IntegerLiteral \\\"-1\\\")])\\n\\t(CallExpr fn@(Symbol \\\"bytes.SplitAfterN\\\") [_ _ lit@(IntegerLiteral \\\"-1\\\")]))\")")
\ No newline at end of file
diff -pruN 2022.1-1/pattern/testdata/fuzz/FuzzParse/7ba6359207886a1c2c7bbe254835555e87a037ecd3af0301a11a43ec2287c487 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/7ba6359207886a1c2c7bbe254835555e87a037ecd3af0301a11a43ec2287c487
--- 2022.1-1/pattern/testdata/fuzz/FuzzParse/7ba6359207886a1c2c7bbe254835555e87a037ecd3af0301a11a43ec2287c487	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/7ba6359207886a1c2c7bbe254835555e87a037ecd3af0301a11a43ec2287c487	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,2 @@
+go test fuzz v1
+[]byte("go test fuzz v1\n[]byte(\"(CallExpr fun@(Symbol _) (Builtin \\\"nil\\\"):_)\")")
\ No newline at end of file
diff -pruN 2022.1-1/pattern/testdata/fuzz/FuzzParse/7ec87621ab148929b69125a04edd13ff104007ca0d8dff12f281753ea93ffb80 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/7ec87621ab148929b69125a04edd13ff104007ca0d8dff12f281753ea93ffb80
--- 2022.1-1/pattern/testdata/fuzz/FuzzParse/7ec87621ab148929b69125a04edd13ff104007ca0d8dff12f281753ea93ffb80	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/7ec87621ab148929b69125a04edd13ff104007ca0d8dff12f281753ea93ffb80	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,2 @@
+go test fuzz v1
+[]byte("go test fuzz v1\n[]byte(\"(BinaryExpr (CallExpr (Symbol \\\"bytes.Compare\\\") args) op@(Or \\\"==\\\" \\\"!=\\\") (IntegerLiteral \\\"0\\\"))\")")
\ No newline at end of file
diff -pruN 2022.1-1/pattern/testdata/fuzz/FuzzParse/9437b751fb0f1f07f5dcb8c8a10d0f3d4470a77b7ec77df6be872a109184bd1b 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/9437b751fb0f1f07f5dcb8c8a10d0f3d4470a77b7ec77df6be872a109184bd1b
--- 2022.1-1/pattern/testdata/fuzz/FuzzParse/9437b751fb0f1f07f5dcb8c8a10d0f3d4470a77b7ec77df6be872a109184bd1b	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/9437b751fb0f1f07f5dcb8c8a10d0f3d4470a77b7ec77df6be872a109184bd1b	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,2 @@
+go test fuzz v1
+[]byte("go test fuzz v1\n[]byte(\"(CallExpr (Symbol \\\"time.Sleep\\\") lit@(IntegerLiteral value))\")")
\ No newline at end of file
diff -pruN 2022.1-1/pattern/testdata/fuzz/FuzzParse/9d603847ed1c030c81f2289ee576971cd63564cc811afb5c18d5a51db7aefa76 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/9d603847ed1c030c81f2289ee576971cd63564cc811afb5c18d5a51db7aefa76
--- 2022.1-1/pattern/testdata/fuzz/FuzzParse/9d603847ed1c030c81f2289ee576971cd63564cc811afb5c18d5a51db7aefa76	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/9d603847ed1c030c81f2289ee576971cd63564cc811afb5c18d5a51db7aefa76	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,2 @@
+go test fuzz v1
+[]byte("go test fuzz v1\n[]byte(\"\\n\\t\\t(CallExpr\\n\\t\\t\\tsel@(SelectorExpr\\n\\t\\t\\t\\trecv\\n\\t\\t\\t\\t(Ident\\n\\t\\t\\t\\t\\tname@(Or\\n\\t\\t\\t\\t\\t\\t\\\"Error\\\"\\n\\t\\t\\t\\t\\t\\t\\\"Fatal\\\"\\n\\t\\t\\t\\t\\t\\t\\\"Fatalln\\\"\\n\\t\\t\\t\\t\\t\\t\\\"Log\\\"\\n\\t\\t\\t\\t\\t\\t\\\"Panic\\\"\\n\\t\\t\\t\\t\\t\\t\\\"Panicln\\\"\\n\\t\\t\\t\\t\\t\\t\\\"Print\\\"\\n\\t\\t\\t\\t\\t\\t\\\"Println\\\"\\n\\t\\t\\t\\t\\t\\t\\\"Skip\\\")))\\n\\t\\t\\t[(CallExpr (Symbol \\\"fmt.Sprintf\\\") args)])\")")
\ No newline at end of file
diff -pruN 2022.1-1/pattern/testdata/fuzz/FuzzParse/ac1b69c690b399207dd7fe32f03a12d2731fa2d1704f6b15cfdc7f772b0f3187 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/ac1b69c690b399207dd7fe32f03a12d2731fa2d1704f6b15cfdc7f772b0f3187
--- 2022.1-1/pattern/testdata/fuzz/FuzzParse/ac1b69c690b399207dd7fe32f03a12d2731fa2d1704f6b15cfdc7f772b0f3187	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/ac1b69c690b399207dd7fe32f03a12d2731fa2d1704f6b15cfdc7f772b0f3187	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,2 @@
+go test fuzz v1
+[]byte("go test fuzz v1\n[]byte(\"\\n\\t(CallExpr\\n\\t\\t(SelectorExpr recv (Ident \\\"WriteString\\\"))\\n\\t\\t(CallExpr\\n\\t\\t\\tfn@(Or\\n\\t\\t\\t\\t(Symbol \\\"fmt.Sprint\\\")\\n\\t\\t\\t\\t(Symbol \\\"fmt.Sprintf\\\")\\n\\t\\t\\t\\t(Symbol \\\"fmt.Sprintln\\\"))\\n\\t\\t\\targs))\")")
\ No newline at end of file
diff -pruN 2022.1-1/pattern/testdata/fuzz/FuzzParse/ad86b3632aca0a27fef3d6d79de5c2bcf1c21f7a6caa1260aab964edc21f3f65 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/ad86b3632aca0a27fef3d6d79de5c2bcf1c21f7a6caa1260aab964edc21f3f65
--- 2022.1-1/pattern/testdata/fuzz/FuzzParse/ad86b3632aca0a27fef3d6d79de5c2bcf1c21f7a6caa1260aab964edc21f3f65	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/ad86b3632aca0a27fef3d6d79de5c2bcf1c21f7a6caa1260aab964edc21f3f65	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,2 @@
+go test fuzz v1
+[]byte("go test fuzz v1\n[]byte(\"\\n\\t(GoStmt\\n\\t\\t(CallExpr\\n\\t\\t\\t(FuncLit\\n\\t\\t\\t\\t_\\n\\t\\t\\t\\tcall@(CallExpr (Symbol \\\"(*sync.WaitGroup).Add\\\") _):_) _))\")")
\ No newline at end of file
diff -pruN 2022.1-1/pattern/testdata/fuzz/FuzzParse/afe5949d38d9171e39ad413d31abfab6bf45d066b700b4e84a232a6b3aa53085 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/afe5949d38d9171e39ad413d31abfab6bf45d066b700b4e84a232a6b3aa53085
--- 2022.1-1/pattern/testdata/fuzz/FuzzParse/afe5949d38d9171e39ad413d31abfab6bf45d066b700b4e84a232a6b3aa53085	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/afe5949d38d9171e39ad413d31abfab6bf45d066b700b4e84a232a6b3aa53085	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,2 @@
+go test fuzz v1
+[]byte("go test fuzz v1\n[]byte(\"\\n\\t\\t(Or\\n\\t\\t\\t(RangeStmt\\n\\t\\t\\t\\tkey@(Ident _) value@(Ident _) \\\":=\\\" src\\n\\t\\t\\t\\t[(AssignStmt (IndexExpr dst key) \\\"=\\\" value)])\\n\\t\\t\\t(RangeStmt\\n\\t\\t\\t\\tkey@(Ident _) nil \\\":=\\\" src\\n\\t\\t\\t\\t[(AssignStmt (IndexExpr dst key) \\\"=\\\" (IndexExpr src key))])\\n\\t\\t\\t(ForStmt\\n\\t\\t\\t\\t(AssignStmt key@(Ident _) \\\":=\\\" (IntegerLiteral \\\"0\\\"))\\n\\t\\t\\t\\t(BinaryExpr key \\\"<\\\" (CallExpr (Symbol \\\"len\\\") [src]))\\n\\t\\t\\t\\t(IncDecStmt key \\\"++\\\")\\n\\t\\t\\t\\t[(AssignStmt (IndexExpr dst key) \\\"=\\\" (IndexExpr src key))]))\")")
\ No newline at end of file
diff -pruN 2022.1-1/pattern/testdata/fuzz/FuzzParse/c30ca6d4801d71144c641960df6919115149d2b6fae5f7d9b2bac2b8cd6b8d25 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/c30ca6d4801d71144c641960df6919115149d2b6fae5f7d9b2bac2b8cd6b8d25
--- 2022.1-1/pattern/testdata/fuzz/FuzzParse/c30ca6d4801d71144c641960df6919115149d2b6fae5f7d9b2bac2b8cd6b8d25	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/c30ca6d4801d71144c641960df6919115149d2b6fae5f7d9b2bac2b8cd6b8d25	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,2 @@
+go test fuzz v1
+[]byte("go test fuzz v1\n[]byte(\"(AssignStmt target@(Ident _) \\\"=\\\" (CallExpr typ@(Symbol (Or \\\"sort.Float64Slice\\\" \\\"sort.IntSlice\\\" \\\"sort.StringSlice\\\")) [target]))\")")
\ No newline at end of file
diff -pruN 2022.1-1/pattern/testdata/fuzz/FuzzParse/e027a03ee012e289def51d770ead1e8a136b60989d3d1fb9388a394da2f595da 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/e027a03ee012e289def51d770ead1e8a136b60989d3d1fb9388a394da2f595da
--- 2022.1-1/pattern/testdata/fuzz/FuzzParse/e027a03ee012e289def51d770ead1e8a136b60989d3d1fb9388a394da2f595da	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/pattern/testdata/fuzz/FuzzParse/e027a03ee012e289def51d770ead1e8a136b60989d3d1fb9388a394da2f595da	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,2 @@
+go test fuzz v1
+[]byte("go test fuzz v1\n[]byte(\"(CallExpr (Symbol \\\"(time.Time).Sub\\\") [(CallExpr (Symbol \\\"time.Now\\\") [])])\")")
\ No newline at end of file
diff -pruN 2022.1-1/quickfix/analysis.go 2022.1.3-1/quickfix/analysis.go
--- 2022.1-1/quickfix/analysis.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/analysis.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,7 +1,7 @@
 package quickfix
 
 import (
-	"honnef.co/go/tools/analysis/facts"
+	"honnef.co/go/tools/analysis/facts/tokenfile"
 	"honnef.co/go/tools/analysis/lint"
 	"honnef.co/go/tools/internal/sharedcheck"
 
@@ -40,7 +40,7 @@ var Analyzers = lint.InitializeAnalyzers
 	},
 	"QF1008": {
 		Run:      CheckExplicitEmbeddedSelector,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.TokenFile},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, tokenfile.Analyzer},
 	},
 	"QF1009": {
 		Run:      CheckTimeEquality,
diff -pruN 2022.1-1/quickfix/lint.go 2022.1.3-1/quickfix/lint.go
--- 2022.1-1/quickfix/lint.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/lint.go	2022-07-31 15:38:22.000000000 +0000
@@ -13,6 +13,7 @@ import (
 	"honnef.co/go/tools/analysis/report"
 	"honnef.co/go/tools/go/ast/astutil"
 	"honnef.co/go/tools/go/types/typeutil"
+	"honnef.co/go/tools/knowledge"
 	"honnef.co/go/tools/pattern"
 
 	"golang.org/x/tools/go/analysis"
@@ -423,12 +424,12 @@ func CheckIfElseToSwitch(pass *analysis.
 }
 
 var stringsReplaceAllQ = pattern.MustParse(`(Or
-	(CallExpr fn@(Function "strings.Replace") [_ _ _ lit@(IntegerLiteral "-1")])
-	(CallExpr fn@(Function "strings.SplitN") [_ _ lit@(IntegerLiteral "-1")])
-	(CallExpr fn@(Function "strings.SplitAfterN") [_ _ lit@(IntegerLiteral "-1")])
-	(CallExpr fn@(Function "bytes.Replace") [_ _ _ lit@(IntegerLiteral "-1")])
-	(CallExpr fn@(Function "bytes.SplitN") [_ _ lit@(IntegerLiteral "-1")])
-	(CallExpr fn@(Function "bytes.SplitAfterN") [_ _ lit@(IntegerLiteral "-1")]))`)
+	(CallExpr fn@(Symbol "strings.Replace") [_ _ _ lit@(IntegerLiteral "-1")])
+	(CallExpr fn@(Symbol "strings.SplitN") [_ _ lit@(IntegerLiteral "-1")])
+	(CallExpr fn@(Symbol "strings.SplitAfterN") [_ _ lit@(IntegerLiteral "-1")])
+	(CallExpr fn@(Symbol "bytes.Replace") [_ _ _ lit@(IntegerLiteral "-1")])
+	(CallExpr fn@(Symbol "bytes.SplitN") [_ _ lit@(IntegerLiteral "-1")])
+	(CallExpr fn@(Symbol "bytes.SplitAfterN") [_ _ lit@(IntegerLiteral "-1")]))`)
 
 func CheckStringsReplaceAll(pass *analysis.Pass) (interface{}, error) {
 	// XXX respect minimum Go version
@@ -469,7 +470,7 @@ func CheckStringsReplaceAll(pass *analys
 	return nil, nil
 }
 
-var mathPowQ = pattern.MustParse(`(CallExpr (Function "math.Pow") [x (IntegerLiteral n)])`)
+var mathPowQ = pattern.MustParse(`(CallExpr (Symbol "math.Pow") [x (IntegerLiteral n)])`)
 
 func CheckMathPow(pass *analysis.Pass) (interface{}, error) {
 	fn := func(node ast.Node) {
@@ -781,7 +782,7 @@ func CheckTimeEquality(pass *analysis.Pa
 var byteSlicePrintingQ = pattern.MustParse(`
 	(Or
 		(CallExpr
-			(Function (Or
+			(Symbol (Or
 				"fmt.Print"
 				"fmt.Println"
 				"fmt.Sprint"
@@ -799,36 +800,13 @@ var byteSlicePrintingQ = pattern.MustPar
 				"(*log.Logger).Print"
 				"(*log.Logger).Println")) args)
 
-		(CallExpr (Function (Or
+		(CallExpr (Symbol (Or
 			"fmt.Fprint"
 			"fmt.Fprintln")) _:args))`)
 
 var byteSlicePrintingR = pattern.MustParse(`(CallExpr (Ident "string") [arg])`)
 
 func CheckByteSlicePrinting(pass *analysis.Pass) (interface{}, error) {
-	isStringer := func(T types.Type, ms *types.MethodSet) bool {
-		sel := ms.Lookup(nil, "String")
-		if sel == nil {
-			return false
-		}
-		fn, ok := sel.Obj().(*types.Func)
-		if !ok {
-			// should be unreachable
-			return false
-		}
-		sig := fn.Type().(*types.Signature)
-		if sig.Params().Len() != 0 {
-			return false
-		}
-		if sig.Results().Len() != 1 {
-			return false
-		}
-		if !typeutil.IsType(sig.Results().At(0).Type(), "string") {
-			return false
-		}
-		return true
-	}
-
 	fn := func(node ast.Node) {
 		m, ok := code.Match(pass, byteSlicePrintingQ, node)
 		if !ok {
@@ -838,10 +816,8 @@ func CheckByteSlicePrinting(pass *analys
 		for _, arg := range args {
 			T := pass.TypesInfo.TypeOf(arg)
 			if typeutil.IsType(T.Underlying(), "[]byte") {
-				ms := types.NewMethodSet(T)
-
 				// don't convert arguments that implement fmt.Stringer
-				if isStringer(T, ms) {
+				if types.Implements(T, knowledge.Interfaces["fmt.Stringer"]) {
 					continue
 				}
 
@@ -861,9 +837,9 @@ var (
 		(CallExpr (ArrayType nil (Ident "byte"))
 			(CallExpr
 				fn@(Or
-					(Function "fmt.Sprint")
-					(Function "fmt.Sprintf")
-					(Function "fmt.Sprintln"))
+					(Symbol "fmt.Sprint")
+					(Symbol "fmt.Sprintf")
+					(Symbol "fmt.Sprintln"))
 				args)
 	))`)
 
@@ -872,32 +848,10 @@ var (
 		(SelectorExpr recv (Ident "WriteString"))
 		(CallExpr
 			fn@(Or
-				(Function "fmt.Sprint")
-				(Function "fmt.Sprintf")
-				(Function "fmt.Sprintln"))
+				(Symbol "fmt.Sprint")
+				(Symbol "fmt.Sprintf")
+				(Symbol "fmt.Sprintln"))
 			args))`)
-
-	writerInterface = types.NewInterfaceType([]*types.Func{
-		types.NewFunc(token.NoPos, nil, "Write", types.NewSignature(nil,
-			types.NewTuple(types.NewVar(token.NoPos, nil, "", types.NewSlice(types.Typ[types.Byte]))),
-			types.NewTuple(
-				types.NewVar(token.NoPos, nil, "", types.Typ[types.Int]),
-				types.NewVar(token.NoPos, nil, "", types.Universe.Lookup("error").Type()),
-			),
-			false,
-		)),
-	}, nil).Complete()
-
-	stringWriterInterface = types.NewInterfaceType([]*types.Func{
-		types.NewFunc(token.NoPos, nil, "WriteString", types.NewSignature(nil,
-			types.NewTuple(types.NewVar(token.NoPos, nil, "", types.Universe.Lookup("string").Type())),
-			types.NewTuple(
-				types.NewVar(token.NoPos, nil, "", types.Typ[types.Int]),
-				types.NewVar(token.NoPos, nil, "", types.Universe.Lookup("error").Type()),
-			),
-			false,
-		)),
-	}, nil).Complete()
 )
 
 func CheckWriteBytesSprintf(pass *analysis.Pass) (interface{}, error) {
@@ -905,7 +859,7 @@ func CheckWriteBytesSprintf(pass *analys
 		if m, ok := code.Match(pass, checkWriteBytesSprintfQ, node); ok {
 			recv := m.State["recv"].(ast.Expr)
 			recvT := pass.TypesInfo.TypeOf(recv)
-			if !types.Implements(recvT, writerInterface) {
+			if !types.Implements(recvT, knowledge.Interfaces["io.Writer"]) {
 				return
 			}
 
@@ -925,12 +879,12 @@ func CheckWriteBytesSprintf(pass *analys
 		} else if m, ok := code.Match(pass, checkWriteStringSprintfQ, node); ok {
 			recv := m.State["recv"].(ast.Expr)
 			recvT := pass.TypesInfo.TypeOf(recv)
-			if !types.Implements(recvT, stringWriterInterface) {
+			if !types.Implements(recvT, knowledge.Interfaces["io.StringWriter"]) {
 				return
 			}
 			// The type needs to implement both StringWriter and Writer.
 			// If it doesn't implement Writer, then we cannot pass it to fmt.Fprint.
-			if !types.Implements(recvT, writerInterface) {
+			if !types.Implements(recvT, knowledge.Interfaces["io.Writer"]) {
 				return
 			}
 
diff -pruN 2022.1-1/quickfix/testdata/src/CheckByteSlicePrinting/CheckByteSlicePrinting.go 2022.1.3-1/quickfix/testdata/src/CheckByteSlicePrinting/CheckByteSlicePrinting.go
--- 2022.1-1/quickfix/testdata/src/CheckByteSlicePrinting/CheckByteSlicePrinting.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckByteSlicePrinting/CheckByteSlicePrinting.go	2022-07-31 15:38:22.000000000 +0000
@@ -14,11 +14,11 @@ func fn() {
 	var b4 Stringable
 
 	var s string
-	fmt.Print(1, b1, 2, []byte(""), b2, s)       // want `could convert argument to string` `could convert argument to string` `could convert argument to string`
-	fmt.Fprint(nil, 1, b1, 2, []byte(""), b2, s) // want `could convert argument to string` `could convert argument to string` `could convert argument to string`
+	fmt.Print(1, b1, 2, []byte(""), b2, s)       //@ diag(`could convert argument to string`), diag(`could convert argument to string`), diag(`could convert argument to string`)
+	fmt.Fprint(nil, 1, b1, 2, []byte(""), b2, s) //@ diag(`could convert argument to string`), diag(`could convert argument to string`), diag(`could convert argument to string`)
 	fmt.Print()
 	fmt.Fprint(nil)
 
 	fmt.Println(b3)
-	fmt.Println(b4) // want `could convert argument to string`
+	fmt.Println(b4) //@ diag(`could convert argument to string`)
 }
diff -pruN 2022.1-1/quickfix/testdata/src/CheckByteSlicePrinting/CheckByteSlicePrinting.go.golden 2022.1.3-1/quickfix/testdata/src/CheckByteSlicePrinting/CheckByteSlicePrinting.go.golden
--- 2022.1-1/quickfix/testdata/src/CheckByteSlicePrinting/CheckByteSlicePrinting.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckByteSlicePrinting/CheckByteSlicePrinting.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -14,11 +14,11 @@ func fn() {
 	var b4 Stringable
 
 	var s string
-	fmt.Print(1, string(b1), 2, string([]byte("")), string(b2), s)       // want `could convert argument to string` `could convert argument to string` `could convert argument to string`
-	fmt.Fprint(nil, 1, string(b1), 2, string([]byte("")), string(b2), s) // want `could convert argument to string` `could convert argument to string` `could convert argument to string`
+	fmt.Print(1, string(b1), 2, string([]byte("")), string(b2), s)       //@ diag(`could convert argument to string`), diag(`could convert argument to string`), diag(`could convert argument to string`)
+	fmt.Fprint(nil, 1, string(b1), 2, string([]byte("")), string(b2), s) //@ diag(`could convert argument to string`), diag(`could convert argument to string`), diag(`could convert argument to string`)
 	fmt.Print()
 	fmt.Fprint(nil)
 
 	fmt.Println(b3)
-	fmt.Println(string(b4)) // want `could convert argument to string`
+	fmt.Println(string(b4)) //@ diag(`could convert argument to string`)
 }
diff -pruN 2022.1-1/quickfix/testdata/src/CheckConditionalAssignment/CheckConditionalAssignment.go 2022.1.3-1/quickfix/testdata/src/CheckConditionalAssignment/CheckConditionalAssignment.go
--- 2022.1-1/quickfix/testdata/src/CheckConditionalAssignment/CheckConditionalAssignment.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckConditionalAssignment/CheckConditionalAssignment.go	2022-07-31 15:38:22.000000000 +0000
@@ -6,7 +6,7 @@ var bar bool
 var baz bool
 
 func fn() {
-	x := false // want `merge conditional assignment`
+	x := false //@ diag(`merge conditional assignment`)
 	if foo() || (bar && !baz) {
 		x = true
 	}
@@ -32,7 +32,7 @@ func fn() {
 		x = true
 	}
 
-	b := true // want `merge conditional assignment`
+	b := true //@ diag(`merge conditional assignment`)
 	if foo() || (bar && !baz) {
 		b = false
 	}
diff -pruN 2022.1-1/quickfix/testdata/src/CheckConditionalAssignment/CheckConditionalAssignment.go.golden 2022.1.3-1/quickfix/testdata/src/CheckConditionalAssignment/CheckConditionalAssignment.go.golden
--- 2022.1-1/quickfix/testdata/src/CheckConditionalAssignment/CheckConditionalAssignment.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckConditionalAssignment/CheckConditionalAssignment.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -6,7 +6,7 @@ var bar bool
 var baz bool
 
 func fn() {
-	x := foo() || (bar && !baz) // want `merge conditional assignment`
+	x := foo() || (bar && !baz) //@ diag(`merge conditional assignment`)
 
 	x = false
 	if foo() || (bar && !baz) {
@@ -29,7 +29,7 @@ func fn() {
 		x = true
 	}
 
-	b := !(foo() || (bar && !baz)) // want `merge conditional assignment`
+	b := !(foo() || (bar && !baz)) //@ diag(`merge conditional assignment`)
 
 	c := false
 	if true {
diff -pruN 2022.1-1/quickfix/testdata/src/CheckDeMorgan/CheckDeMorgan.go 2022.1.3-1/quickfix/testdata/src/CheckDeMorgan/CheckDeMorgan.go
--- 2022.1-1/quickfix/testdata/src/CheckDeMorgan/CheckDeMorgan.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckDeMorgan/CheckDeMorgan.go	2022-07-31 15:38:22.000000000 +0000
@@ -5,6 +5,6 @@ func fn() {
 	var e, f, g int
 	var h, i float64
 
-	_ = !(a && b && (!c || e > f) && g == f) // want `could apply De Morgan's law`
+	_ = !(a && b && (!c || e > f) && g == f) //@ diag(`could apply De Morgan's law`)
 	_ = !(a && h > i)
 }
diff -pruN 2022.1-1/quickfix/testdata/src/CheckDeMorgan/CheckDeMorgan.go.golden 2022.1.3-1/quickfix/testdata/src/CheckDeMorgan/CheckDeMorgan.go.golden
--- 2022.1-1/quickfix/testdata/src/CheckDeMorgan/CheckDeMorgan.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckDeMorgan/CheckDeMorgan.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -6,7 +6,7 @@ func fn() {
 	var e, f, g int
 	var h, i float64
 
-	_ = !a || !b || !(!c || e > f) || g != f // want `could apply De Morgan's law`
+	_ = !a || !b || !(!c || e > f) || g != f //@ diag(`could apply De Morgan's law`)
 	_ = !(a && h > i)
 }
 
@@ -18,7 +18,7 @@ func fn() {
 	var e, f, g int
 	var h, i float64
 
-	_ = !a || !b || (c && e <= f) || g != f // want `could apply De Morgan's law`
+	_ = !a || !b || (c && e <= f) || g != f //@ diag(`could apply De Morgan's law`)
 	_ = !(a && h > i)
 }
 
@@ -30,6 +30,6 @@ func fn() {
 	var e, f, g int
 	var h, i float64
 
-	_ = !a || !b || c && e <= f || g != f // want `could apply De Morgan's law`
+	_ = !a || !b || c && e <= f || g != f //@ diag(`could apply De Morgan's law`)
 	_ = !(a && h > i)
 }
diff -pruN 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-anon.go 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-anon.go
--- 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-anon.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-anon.go	2022-07-31 15:38:22.000000000 +0000
@@ -5,6 +5,6 @@ type AnonInner struct{ F4 struct{ F5 int
 
 func fnAnon() {
 	var anon AnonOuter
-	_ = anon.AnonInner.F4.F5 // want `could remove embedded field "AnonInner" from selector`
+	_ = anon.AnonInner.F4.F5 //@ diag(`could remove embedded field "AnonInner" from selector`)
 	_ = anon.F4.F5           // minimal form
 }
diff -pruN 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-anon.go.golden 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-anon.go.golden
--- 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-anon.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-anon.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -5,6 +5,6 @@ type AnonInner struct{ F4 struct{ F5 int
 
 func fnAnon() {
 	var anon AnonOuter
-	_ = anon.F4.F5 // want `could remove embedded field "AnonInner" from selector`
+	_ = anon.F4.F5 //@ diag(`could remove embedded field "AnonInner" from selector`)
 	_ = anon.F4.F5 // minimal form
 }
diff -pruN 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-basic.go 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-basic.go
--- 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-basic.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-basic.go	2022-07-31 15:38:22.000000000 +0000
@@ -5,6 +5,6 @@ type BasicInner struct{ F1 int }
 
 func fnBasic() {
 	var basic BasicOuter
-	_ = basic.BasicInner.F1 // want `could remove embedded field "BasicInner" from selector`
+	_ = basic.BasicInner.F1 //@ diag(`could remove embedded field "BasicInner" from selector`)
 	_ = basic.F1            // minimal form
 }
diff -pruN 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-basic.go.golden 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-basic.go.golden
--- 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-basic.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-basic.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -5,6 +5,6 @@ type BasicInner struct{ F1 int }
 
 func fnBasic() {
 	var basic BasicOuter
-	_ = basic.F1 // want `could remove embedded field "BasicInner" from selector`
+	_ = basic.F1 //@ diag(`could remove embedded field "BasicInner" from selector`)
 	_ = basic.F1 // minimal form
 }
diff -pruN 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-call.go 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-call.go
--- 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-call.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-call.go	2022-07-31 15:38:22.000000000 +0000
@@ -9,6 +9,6 @@ type FunctionCallContinuedInner struct{
 
 func fnCall() {
 	var call FunctionCallOuter
-	_ = call.FunctionCallInner.F8().FunctionCallContinuedInner.F9 // want `could remove embedded field "FunctionCallInner" from selector` `could remove embedded field "FunctionCallContinuedInner" from selector` `could simplify selectors`
+	_ = call.FunctionCallInner.F8().FunctionCallContinuedInner.F9 //@ diag(`could remove embedded field "FunctionCallInner" from selector`), diag(`could remove embedded field "FunctionCallContinuedInner" from selector`), diag(`could simplify selectors`)
 	_ = call.F8().F9                                              // minimal form
 }
diff -pruN 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-call.go.golden 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-call.go.golden
--- 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-call.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-call.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -10,7 +10,7 @@ type FunctionCallContinuedInner struct{
 
 func fnCall() {
 	var call FunctionCallOuter
-	_ = call.F8().FunctionCallContinuedInner.F9 // want `could remove embedded field "FunctionCallInner" from selector` `could remove embedded field "FunctionCallContinuedInner" from selector` `could simplify selectors`
+	_ = call.F8().FunctionCallContinuedInner.F9 //@ diag(`could remove embedded field "FunctionCallInner" from selector`), diag(`could remove embedded field "FunctionCallContinuedInner" from selector`), diag(`could simplify selectors`)
 	_ = call.F8().F9                            // minimal form
 }
 
@@ -26,7 +26,7 @@ type FunctionCallContinuedInner struct{
 
 func fnCall() {
 	var call FunctionCallOuter
-	_ = call.FunctionCallInner.F8().F9 // want `could remove embedded field "FunctionCallInner" from selector` `could remove embedded field "FunctionCallContinuedInner" from selector` `could simplify selectors`
+	_ = call.FunctionCallInner.F8().F9 //@ diag(`could remove embedded field "FunctionCallInner" from selector`), diag(`could remove embedded field "FunctionCallContinuedInner" from selector`), diag(`could simplify selectors`)
 	_ = call.F8().F9                   // minimal form
 }
 
@@ -42,6 +42,6 @@ type FunctionCallContinuedInner struct{
 
 func fnCall() {
 	var call FunctionCallOuter
-	_ = call.F8().F9 // want `could remove embedded field "FunctionCallInner" from selector` `could remove embedded field "FunctionCallContinuedInner" from selector` `could simplify selectors`
+	_ = call.F8().F9 //@ diag(`could remove embedded field "FunctionCallInner" from selector`), diag(`could remove embedded field "FunctionCallContinuedInner" from selector`), diag(`could simplify selectors`)
 	_ = call.F8().F9 // minimal form
 }
diff -pruN 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-depth.go 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-depth.go
--- 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-depth.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-depth.go	2022-07-31 15:38:22.000000000 +0000
@@ -13,6 +13,6 @@ func fnDepth() {
 
 	var v T1
 	_ = v.F
-	_ = v.T2.F // want `could remove embedded field "T2" from selector`
+	_ = v.T2.F //@ diag(`could remove embedded field "T2" from selector`)
 	_ = v.T3.F
 }
diff -pruN 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-depth.go.golden 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-depth.go.golden
--- 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-depth.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-depth.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -13,6 +13,6 @@ func fnDepth() {
 
 	var v T1
 	_ = v.F
-	_ = v.F // want `could remove embedded field "T2" from selector`
+	_ = v.F //@ diag(`could remove embedded field "T2" from selector`)
 	_ = v.T3.F
 }
diff -pruN 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-multi.go 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-multi.go
--- 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-multi.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-multi.go	2022-07-31 15:38:22.000000000 +0000
@@ -4,8 +4,8 @@ type MultiLevel struct{ BasicOuter }
 
 func fnMulti() {
 	var multi MultiLevel
-	_ = multi.BasicOuter.BasicInner.F1 // want `could remove embedded field "BasicOuter" from selector` `could remove embedded field "BasicInner" from selector` `could simplify selectors`
-	_ = multi.BasicOuter.F1            // want `could remove embedded field "BasicOuter" from selector`
-	_ = multi.BasicInner.F1            // want `could remove embedded field "BasicInner" from selector`
+	_ = multi.BasicOuter.BasicInner.F1 //@ diag(`could remove embedded field "BasicOuter" from selector`), diag(`could remove embedded field "BasicInner" from selector`), diag(`could simplify selectors`)
+	_ = multi.BasicOuter.F1            //@ diag(`could remove embedded field "BasicOuter" from selector`)
+	_ = multi.BasicInner.F1            //@ diag(`could remove embedded field "BasicInner" from selector`)
 	_ = multi.F1                       // minimal form
 }
diff -pruN 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-multi.go.golden 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-multi.go.golden
--- 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-multi.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-multi.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -5,9 +5,9 @@ type MultiLevel struct{ BasicOuter }
 
 func fnMulti() {
 	var multi MultiLevel
-	_ = multi.BasicOuter.F1 // want `could remove embedded field "BasicOuter" from selector` `could remove embedded field "BasicInner" from selector` `could simplify selectors`
-	_ = multi.BasicOuter.F1 // want `could remove embedded field "BasicOuter" from selector`
-	_ = multi.F1            // want `could remove embedded field "BasicInner" from selector`
+	_ = multi.BasicOuter.F1 //@ diag(`could remove embedded field "BasicOuter" from selector`), diag(`could remove embedded field "BasicInner" from selector`), diag(`could simplify selectors`)
+	_ = multi.BasicOuter.F1 //@ diag(`could remove embedded field "BasicOuter" from selector`)
+	_ = multi.F1            //@ diag(`could remove embedded field "BasicInner" from selector`)
 	_ = multi.F1            // minimal form
 }
 
@@ -18,9 +18,9 @@ type MultiLevel struct{ BasicOuter }
 
 func fnMulti() {
 	var multi MultiLevel
-	_ = multi.BasicInner.F1 // want `could remove embedded field "BasicOuter" from selector` `could remove embedded field "BasicInner" from selector` `could simplify selectors`
-	_ = multi.F1            // want `could remove embedded field "BasicOuter" from selector`
-	_ = multi.BasicInner.F1 // want `could remove embedded field "BasicInner" from selector`
+	_ = multi.BasicInner.F1 //@ diag(`could remove embedded field "BasicOuter" from selector`), diag(`could remove embedded field "BasicInner" from selector`), diag(`could simplify selectors`)
+	_ = multi.F1            //@ diag(`could remove embedded field "BasicOuter" from selector`)
+	_ = multi.BasicInner.F1 //@ diag(`could remove embedded field "BasicInner" from selector`)
 	_ = multi.F1            // minimal form
 }
 
@@ -31,8 +31,8 @@ type MultiLevel struct{ BasicOuter }
 
 func fnMulti() {
 	var multi MultiLevel
-	_ = multi.F1            // want `could remove embedded field "BasicOuter" from selector` `could remove embedded field "BasicInner" from selector` `could simplify selectors`
-	_ = multi.BasicOuter.F1 // want `could remove embedded field "BasicOuter" from selector`
-	_ = multi.BasicInner.F1 // want `could remove embedded field "BasicInner" from selector`
+	_ = multi.F1            //@ diag(`could remove embedded field "BasicOuter" from selector`), diag(`could remove embedded field "BasicInner" from selector`), diag(`could simplify selectors`)
+	_ = multi.BasicOuter.F1 //@ diag(`could remove embedded field "BasicOuter" from selector`)
+	_ = multi.BasicInner.F1 //@ diag(`could remove embedded field "BasicInner" from selector`)
 	_ = multi.F1            // minimal form
 }
diff -pruN 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-partial-multi.go 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-partial-multi.go
--- 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-partial-multi.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-partial-multi.go	2022-07-31 15:38:22.000000000 +0000
@@ -8,11 +8,11 @@ type PartialMultiLevel2Inner2 struct{ F7
 
 func fnPartialMulti() {
 	var partialMulti PartialMultiLevel
-	_ = partialMulti.F3.BasicOuter.F1            // want `could remove embedded field "BasicOuter" from selector`
-	_ = partialMulti.F3.BasicOuter.BasicInner.F1 // want `could remove embedded field "BasicOuter" from selector` `could remove embedded field "BasicInner" from selector` `could simplify selectors`
+	_ = partialMulti.F3.BasicOuter.F1            //@ diag(`could remove embedded field "BasicOuter" from selector`)
+	_ = partialMulti.F3.BasicOuter.BasicInner.F1 //@ diag(`could remove embedded field "BasicOuter" from selector`), diag(`could remove embedded field "BasicInner" from selector`), diag(`could simplify selectors`)
 	_ = partialMulti.F3.F1                       // minimal form
 
 	var partialMulti2 PartialMultiLevel2Outer
-	_ = partialMulti2.PartialMultiLevel2Inner.F6.PartialMultiLevel2Inner2.F7 // want `could remove embedded field "PartialMultiLevel2Inner2" from selector` `could remove embedded field "PartialMultiLevel2Inner" from selector` `could simplify selectors`
+	_ = partialMulti2.PartialMultiLevel2Inner.F6.PartialMultiLevel2Inner2.F7 //@ diag(`could remove embedded field "PartialMultiLevel2Inner2" from selector`), diag(`could remove embedded field "PartialMultiLevel2Inner" from selector`), diag(`could simplify selectors`)
 	_ = partialMulti2.F6.F7                                                  // minimal form
 }
diff -pruN 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-partial-multi.go.golden 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-partial-multi.go.golden
--- 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-partial-multi.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-partial-multi.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -9,12 +9,12 @@ type PartialMultiLevel2Inner2 struct{ F7
 
 func fnPartialMulti() {
 	var partialMulti PartialMultiLevel
-	_ = partialMulti.F3.F1            // want `could remove embedded field "BasicOuter" from selector`
-	_ = partialMulti.F3.BasicInner.F1 // want `could remove embedded field "BasicOuter" from selector` `could remove embedded field "BasicInner" from selector` `could simplify selectors`
+	_ = partialMulti.F3.F1            //@ diag(`could remove embedded field "BasicOuter" from selector`)
+	_ = partialMulti.F3.BasicInner.F1 //@ diag(`could remove embedded field "BasicOuter" from selector`), diag(`could remove embedded field "BasicInner" from selector`), diag(`could simplify selectors`)
 	_ = partialMulti.F3.F1            // minimal form
 
 	var partialMulti2 PartialMultiLevel2Outer
-	_ = partialMulti2.PartialMultiLevel2Inner.F6.PartialMultiLevel2Inner2.F7 // want `could remove embedded field "PartialMultiLevel2Inner2" from selector` `could remove embedded field "PartialMultiLevel2Inner" from selector` `could simplify selectors`
+	_ = partialMulti2.PartialMultiLevel2Inner.F6.PartialMultiLevel2Inner2.F7 //@ diag(`could remove embedded field "PartialMultiLevel2Inner2" from selector`), diag(`could remove embedded field "PartialMultiLevel2Inner" from selector`), diag(`could simplify selectors`)
 	_ = partialMulti2.F6.F7                                                  // minimal form
 }
 
@@ -29,12 +29,12 @@ type PartialMultiLevel2Inner2 struct{ F7
 
 func fnPartialMulti() {
 	var partialMulti PartialMultiLevel
-	_ = partialMulti.F3.BasicOuter.F1 // want `could remove embedded field "BasicOuter" from selector`
-	_ = partialMulti.F3.BasicOuter.F1 // want `could remove embedded field "BasicOuter" from selector` `could remove embedded field "BasicInner" from selector` `could simplify selectors`
+	_ = partialMulti.F3.BasicOuter.F1 //@ diag(`could remove embedded field "BasicOuter" from selector`)
+	_ = partialMulti.F3.BasicOuter.F1 //@ diag(`could remove embedded field "BasicOuter" from selector`), diag(`could remove embedded field "BasicInner" from selector`), diag(`could simplify selectors`)
 	_ = partialMulti.F3.F1            // minimal form
 
 	var partialMulti2 PartialMultiLevel2Outer
-	_ = partialMulti2.PartialMultiLevel2Inner.F6.PartialMultiLevel2Inner2.F7 // want `could remove embedded field "PartialMultiLevel2Inner2" from selector` `could remove embedded field "PartialMultiLevel2Inner" from selector` `could simplify selectors`
+	_ = partialMulti2.PartialMultiLevel2Inner.F6.PartialMultiLevel2Inner2.F7 //@ diag(`could remove embedded field "PartialMultiLevel2Inner2" from selector`), diag(`could remove embedded field "PartialMultiLevel2Inner" from selector`), diag(`could simplify selectors`)
 	_ = partialMulti2.F6.F7                                                  // minimal form
 }
 
@@ -49,12 +49,12 @@ type PartialMultiLevel2Inner2 struct{ F7
 
 func fnPartialMulti() {
 	var partialMulti PartialMultiLevel
-	_ = partialMulti.F3.BasicOuter.F1            // want `could remove embedded field "BasicOuter" from selector`
-	_ = partialMulti.F3.BasicOuter.BasicInner.F1 // want `could remove embedded field "BasicOuter" from selector` `could remove embedded field "BasicInner" from selector` `could simplify selectors`
+	_ = partialMulti.F3.BasicOuter.F1            //@ diag(`could remove embedded field "BasicOuter" from selector`)
+	_ = partialMulti.F3.BasicOuter.BasicInner.F1 //@ diag(`could remove embedded field "BasicOuter" from selector`), diag(`could remove embedded field "BasicInner" from selector`), diag(`could simplify selectors`)
 	_ = partialMulti.F3.F1                       // minimal form
 
 	var partialMulti2 PartialMultiLevel2Outer
-	_ = partialMulti2.PartialMultiLevel2Inner.F6.F7 // want `could remove embedded field "PartialMultiLevel2Inner2" from selector` `could remove embedded field "PartialMultiLevel2Inner" from selector` `could simplify selectors`
+	_ = partialMulti2.PartialMultiLevel2Inner.F6.F7 //@ diag(`could remove embedded field "PartialMultiLevel2Inner2" from selector`), diag(`could remove embedded field "PartialMultiLevel2Inner" from selector`), diag(`could simplify selectors`)
 	_ = partialMulti2.F6.F7                         // minimal form
 }
 
@@ -69,12 +69,12 @@ type PartialMultiLevel2Inner2 struct{ F7
 
 func fnPartialMulti() {
 	var partialMulti PartialMultiLevel
-	_ = partialMulti.F3.BasicOuter.F1            // want `could remove embedded field "BasicOuter" from selector`
-	_ = partialMulti.F3.BasicOuter.BasicInner.F1 // want `could remove embedded field "BasicOuter" from selector` `could remove embedded field "BasicInner" from selector` `could simplify selectors`
+	_ = partialMulti.F3.BasicOuter.F1            //@ diag(`could remove embedded field "BasicOuter" from selector`)
+	_ = partialMulti.F3.BasicOuter.BasicInner.F1 //@ diag(`could remove embedded field "BasicOuter" from selector`), diag(`could remove embedded field "BasicInner" from selector`), diag(`could simplify selectors`)
 	_ = partialMulti.F3.F1                       // minimal form
 
 	var partialMulti2 PartialMultiLevel2Outer
-	_ = partialMulti2.F6.PartialMultiLevel2Inner2.F7 // want `could remove embedded field "PartialMultiLevel2Inner2" from selector` `could remove embedded field "PartialMultiLevel2Inner" from selector` `could simplify selectors`
+	_ = partialMulti2.F6.PartialMultiLevel2Inner2.F7 //@ diag(`could remove embedded field "PartialMultiLevel2Inner2" from selector`), diag(`could remove embedded field "PartialMultiLevel2Inner" from selector`), diag(`could simplify selectors`)
 	_ = partialMulti2.F6.F7                          // minimal form
 }
 
@@ -89,11 +89,11 @@ type PartialMultiLevel2Inner2 struct{ F7
 
 func fnPartialMulti() {
 	var partialMulti PartialMultiLevel
-	_ = partialMulti.F3.BasicOuter.F1 // want `could remove embedded field "BasicOuter" from selector`
-	_ = partialMulti.F3.F1            // want `could remove embedded field "BasicOuter" from selector` `could remove embedded field "BasicInner" from selector` `could simplify selectors`
+	_ = partialMulti.F3.BasicOuter.F1 //@ diag(`could remove embedded field "BasicOuter" from selector`)
+	_ = partialMulti.F3.F1            //@ diag(`could remove embedded field "BasicOuter" from selector`), diag(`could remove embedded field "BasicInner" from selector`), diag(`could simplify selectors`)
 	_ = partialMulti.F3.F1            // minimal form
 
 	var partialMulti2 PartialMultiLevel2Outer
-	_ = partialMulti2.F6.F7 // want `could remove embedded field "PartialMultiLevel2Inner2" from selector` `could remove embedded field "PartialMultiLevel2Inner" from selector` `could simplify selectors`
+	_ = partialMulti2.F6.F7 //@ diag(`could remove embedded field "PartialMultiLevel2Inner2" from selector`), diag(`could remove embedded field "PartialMultiLevel2Inner" from selector`), diag(`could simplify selectors`)
 	_ = partialMulti2.F6.F7 // minimal form
 }
diff -pruN 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-qualified.go 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-qualified.go
--- 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-qualified.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-qualified.go	2022-07-31 15:38:22.000000000 +0000
@@ -7,6 +7,6 @@ import (
 
 func fnQualified() {
 	_ = io.EOF.Error  // minimal form
-	_ = assist.V.T2.F // want `could remove embedded field "T2" from selector`
+	_ = assist.V.T2.F //@ diag(`could remove embedded field "T2" from selector`)
 	_ = assist.V.F    // minimal form
 }
diff -pruN 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-qualified.go.golden 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-qualified.go.golden
--- 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-qualified.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-qualified.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -7,6 +7,6 @@ import (
 
 func fnQualified() {
 	_ = io.EOF.Error // minimal form
-	_ = assist.V.F   // want `could remove embedded field "T2" from selector`
+	_ = assist.V.F   //@ diag(`could remove embedded field "T2" from selector`)
 	_ = assist.V.F   // minimal form
 }
diff -pruN 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-recursive.go 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-recursive.go
--- 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-recursive.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-recursive.go	2022-07-31 15:38:22.000000000 +0000
@@ -23,5 +23,5 @@ func fn() {
 	_ = t1.Next.Foo
 	_ = t2.T2.Foo
 	_ = t2.T2.F
-	_ = t2.T3.F2 // want `could remove embedded field "T3" from selector`
+	_ = t2.T3.F2 //@ diag(`could remove embedded field "T3" from selector`)
 }
diff -pruN 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-recursive.go.golden 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-recursive.go.golden
--- 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-recursive.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-recursive.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -23,5 +23,5 @@ func fn() {
 	_ = t1.Next.Foo
 	_ = t2.T2.Foo
 	_ = t2.T2.F
-	_ = t2.F2 // want `could remove embedded field "T3" from selector`
+	_ = t2.F2 //@ diag(`could remove embedded field "T3" from selector`)
 }
diff -pruN 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-unexported.go 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-unexported.go
--- 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-unexported.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-unexported.go	2022-07-31 15:38:22.000000000 +0000
@@ -10,6 +10,6 @@ type unexportedSamePackageInner struct {
 
 func fnUnexported() {
 	var unexportedSame UnexportedSamePackageOuter
-	_ = unexportedSame.unexportedSamePackageInner.F10 // want `could remove embedded field "unexportedSamePackageInner" from selector`
+	_ = unexportedSame.unexportedSamePackageInner.F10 //@ diag(`could remove embedded field "unexportedSamePackageInner" from selector`)
 	_ = unexportedSame.F10                            // minimal form
 }
diff -pruN 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-unexported.go.golden 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-unexported.go.golden
--- 2022.1-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-unexported.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckExplicitEmbeddedSelector/CheckExplicitEmbeddedSelector-unexported.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -10,6 +10,6 @@ type unexportedSamePackageInner struct {
 
 func fnUnexported() {
 	var unexportedSame UnexportedSamePackageOuter
-	_ = unexportedSame.F10 // want `could remove embedded field "unexportedSamePackageInner" from selector`
+	_ = unexportedSame.F10 //@ diag(`could remove embedded field "unexportedSamePackageInner" from selector`)
 	_ = unexportedSame.F10 // minimal form
 }
diff -pruN 2022.1-1/quickfix/testdata/src/CheckForLoopIfBreak/CheckForLoopIfBreak.go 2022.1.3-1/quickfix/testdata/src/CheckForLoopIfBreak/CheckForLoopIfBreak.go
--- 2022.1-1/quickfix/testdata/src/CheckForLoopIfBreak/CheckForLoopIfBreak.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckForLoopIfBreak/CheckForLoopIfBreak.go	2022-07-31 15:38:22.000000000 +0000
@@ -7,31 +7,31 @@ var x bool
 
 func fn() {
 	for {
-		if done() { // want `could lift into loop condition`
+		if done() { //@ diag(`could lift into loop condition`)
 			break
 		}
 	}
 
 	for {
-		if !done() { // want `could lift into loop condition`
+		if !done() { //@ diag(`could lift into loop condition`)
 			break
 		}
 	}
 
 	for {
-		if a > b || b > a { // want `could lift into loop condition`
+		if a > b || b > a { //@ diag(`could lift into loop condition`)
 			break
 		}
 	}
 
 	for {
-		if x && (a == b) { // want `could lift into loop condition`
+		if x && (a == b) { //@ diag(`could lift into loop condition`)
 			break
 		}
 	}
 
 	for {
-		if done() { // want `could lift into loop condition`
+		if done() { //@ diag(`could lift into loop condition`)
 			break
 		}
 		println()
diff -pruN 2022.1-1/quickfix/testdata/src/CheckIfElseToSwitch/CheckIfElseToSwitch.go 2022.1.3-1/quickfix/testdata/src/CheckIfElseToSwitch/CheckIfElseToSwitch.go
--- 2022.1-1/quickfix/testdata/src/CheckIfElseToSwitch/CheckIfElseToSwitch.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckIfElseToSwitch/CheckIfElseToSwitch.go	2022-07-31 15:38:22.000000000 +0000
@@ -5,11 +5,11 @@ func fn() {
 	var z []int
 	var a bool
 
-	if x == 1 || x == 2 { // want `could use tagged switch on x`
+	if x == 1 || x == 2 { //@ diag(`could use tagged switch on x`)
 	} else if x == 3 {
 	}
 
-	if x == 1 || x == 2 { // want `could use tagged switch on x`
+	if x == 1 || x == 2 { //@ diag(`could use tagged switch on x`)
 	} else if x == 3 {
 	} else {
 	}
@@ -19,16 +19,16 @@ func fn() {
 	} else {
 	}
 
-	if a == (x == y) { // want `could use tagged switch on a`
+	if a == (x == y) { //@ diag(`could use tagged switch on a`)
 	} else if a == (x != y) {
 	}
 
-	if z[0] == 1 || z[0] == 2 { // want `could use tagged switch on z\[0\]`
+	if z[0] == 1 || z[0] == 2 { //@ diag(`could use tagged switch on z[0]`)
 	} else if z[0] == 3 {
 	}
 
 	for {
-		if x == 1 || x == 2 { // want `could use tagged switch on x`
+		if x == 1 || x == 2 { //@ diag(`could use tagged switch on x`)
 		} else if x == 3 {
 		}
 	}
diff -pruN 2022.1-1/quickfix/testdata/src/CheckIfElseToSwitch/CheckIfElseToSwitch.go.golden 2022.1.3-1/quickfix/testdata/src/CheckIfElseToSwitch/CheckIfElseToSwitch.go.golden
--- 2022.1-1/quickfix/testdata/src/CheckIfElseToSwitch/CheckIfElseToSwitch.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckIfElseToSwitch/CheckIfElseToSwitch.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -6,12 +6,12 @@ func fn() {
 	var a bool
 
 	switch x {
-	case 1, 2: // want `could use tagged switch on x`
+	case 1, 2: //@ diag(`could use tagged switch on x`)
 	case 3:
 	}
 
 	switch x {
-	case 1, 2: // want `could use tagged switch on x`
+	case 1, 2: //@ diag(`could use tagged switch on x`)
 	case 3:
 	default:
 	}
@@ -22,18 +22,18 @@ func fn() {
 	}
 
 	switch a {
-	case x == y: // want `could use tagged switch on a`
+	case x == y: //@ diag(`could use tagged switch on a`)
 	case x != y:
 	}
 
 	switch z[0] {
-	case 1, 2: // want `could use tagged switch on z\[0\]`
+	case 1, 2: //@ diag(`could use tagged switch on z[0]`)
 	case 3:
 	}
 
 	for {
 		switch x {
-		case 1, 2: // want `could use tagged switch on x`
+		case 1, 2: //@ diag(`could use tagged switch on x`)
 		case 3:
 		}
 	}
diff -pruN 2022.1-1/quickfix/testdata/src/CheckMathPow/CheckMathPow.go 2022.1.3-1/quickfix/testdata/src/CheckMathPow/CheckMathPow.go
--- 2022.1-1/quickfix/testdata/src/CheckMathPow/CheckMathPow.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckMathPow/CheckMathPow.go	2022-07-31 15:38:22.000000000 +0000
@@ -5,23 +5,23 @@ import "math"
 func fn() {
 	var x float64
 
-	_ = math.Pow(x, 0) // want `could expand call to math.Pow`
-	_ = math.Pow(x, 1) // want `could expand call to math.Pow`
-	_ = math.Pow(x, 2) // want `could expand call to math.Pow`
-	_ = math.Pow(x, 3) // want `could expand call to math.Pow`
+	_ = math.Pow(x, 0) //@ diag(`could expand call to math.Pow`)
+	_ = math.Pow(x, 1) //@ diag(`could expand call to math.Pow`)
+	_ = math.Pow(x, 2) //@ diag(`could expand call to math.Pow`)
+	_ = math.Pow(x, 3) //@ diag(`could expand call to math.Pow`)
 	_ = math.Pow(x, 6)
 
 	const a = 2
 	const b = 2.0
 	const c float64 = 2
 
-	_ = math.Pow(a, 2)     // want `could expand call to math.Pow`
-	_ = math.Pow(b, 2)     // want `could expand call to math.Pow`
-	_ = math.Pow(c, 2)     // want `could expand call to math.Pow`
-	_ = math.Pow(a*1.0, 2) // want `could expand call to math.Pow`
+	_ = math.Pow(a, 2)     //@ diag(`could expand call to math.Pow`)
+	_ = math.Pow(b, 2)     //@ diag(`could expand call to math.Pow`)
+	_ = math.Pow(c, 2)     //@ diag(`could expand call to math.Pow`)
+	_ = math.Pow(a*1.0, 2) //@ diag(`could expand call to math.Pow`)
 
-	_ = math.Pow(x*2, 2) // want `could expand call to math.Pow`
-	_ = math.Pow(x+2, 2) // want `could expand call to math.Pow`
+	_ = math.Pow(x*2, 2) //@ diag(`could expand call to math.Pow`)
+	_ = math.Pow(x+2, 2) //@ diag(`could expand call to math.Pow`)
 
 	_ = math.Pow(x, x)
 	_ = math.Pow(x, -1)
diff -pruN 2022.1-1/quickfix/testdata/src/CheckMathPow/CheckMathPow.go.golden 2022.1.3-1/quickfix/testdata/src/CheckMathPow/CheckMathPow.go.golden
--- 2022.1-1/quickfix/testdata/src/CheckMathPow/CheckMathPow.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckMathPow/CheckMathPow.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -5,23 +5,23 @@ import "math"
 func fn() {
 	var x float64
 
-	_ = 1.0       // want `could expand call to math.Pow`
-	_ = x         // want `could expand call to math.Pow`
-	_ = x * x     // want `could expand call to math.Pow`
-	_ = x * x * x // want `could expand call to math.Pow`
+	_ = 1.0       //@ diag(`could expand call to math.Pow`)
+	_ = x         //@ diag(`could expand call to math.Pow`)
+	_ = x * x     //@ diag(`could expand call to math.Pow`)
+	_ = x * x * x //@ diag(`could expand call to math.Pow`)
 	_ = math.Pow(x, 6)
 
 	const a = 2
 	const b = 2.0
 	const c float64 = 2
 
-	_ = float64(a * a)    // want `could expand call to math.Pow`
-	_ = b * b             // want `could expand call to math.Pow`
-	_ = c * c             // want `could expand call to math.Pow`
-	_ = a * 1.0 * a * 1.0 // want `could expand call to math.Pow`
+	_ = float64(a * a)    //@ diag(`could expand call to math.Pow`)
+	_ = b * b             //@ diag(`could expand call to math.Pow`)
+	_ = c * c             //@ diag(`could expand call to math.Pow`)
+	_ = a * 1.0 * a * 1.0 //@ diag(`could expand call to math.Pow`)
 
-	_ = x * 2 * x * 2     // want `could expand call to math.Pow`
-	_ = (x + 2) * (x + 2) // want `could expand call to math.Pow`
+	_ = x * 2 * x * 2     //@ diag(`could expand call to math.Pow`)
+	_ = (x + 2) * (x + 2) //@ diag(`could expand call to math.Pow`)
 
 	_ = math.Pow(x, x)
 	_ = math.Pow(x, -1)
diff -pruN 2022.1-1/quickfix/testdata/src/CheckRedundantTypeInDeclaration/CheckRedundantTypeInDeclaration.go 2022.1.3-1/quickfix/testdata/src/CheckRedundantTypeInDeclaration/CheckRedundantTypeInDeclaration.go
--- 2022.1-1/quickfix/testdata/src/CheckRedundantTypeInDeclaration/CheckRedundantTypeInDeclaration.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckRedundantTypeInDeclaration/CheckRedundantTypeInDeclaration.go	2022-07-31 15:38:22.000000000 +0000
@@ -18,20 +18,20 @@ func gen3() MyInt         { return 0 }
 var a int = gen1()
 
 func fn() {
-	var _ int = gen1()           // want `could omit type int`
-	var a int = Y                // want `could omit type int`
-	var b int = 1                // want `could omit type int`
+	var _ int = gen1()           //@ diag(`could omit type int`)
+	var a int = Y                //@ diag(`could omit type int`)
+	var b int = 1                //@ diag(`could omit type int`)
 	var c int = 1.0              // different default type
 	var d MyInt = 1              // different default type
-	var e io.ReadCloser = gen2() // want `could omit type io.ReadCloser`
+	var e io.ReadCloser = gen2() //@ diag(`could omit type io.ReadCloser`)
 	var f io.Reader = gen2()     // different interface type
-	var g float64 = math.Pi      // want `could omit type float64`
-	var h bool = true            // want `could omit type bool`
-	var i string = ""            // want `could omit type string`
-	var j MyInt = gen3()         // want `could omit type MyInt`
+	var g float64 = math.Pi      //@ diag(`could omit type float64`)
+	var h bool = true            //@ diag(`could omit type bool`)
+	var i string = ""            //@ diag(`could omit type string`)
+	var j MyInt = gen3()         //@ diag(`could omit type MyInt`)
 	var k uint8 = Y              // different default type on constant
 	var l uint8 = (Y + Y) / 2    // different default type on rhs
-	var m int = (Y + Y) / 2      // want `could omit type int`
+	var m int = (Y + Y) / 2      //@ diag(`could omit type int`)
 
 	_, _, _, _, _, _, _, _, _, _, _, _, _ = a, b, c, d, e, f, g, h, i, j, k, l, m
 }
diff -pruN 2022.1-1/quickfix/testdata/src/CheckRedundantTypeInDeclaration/CheckRedundantTypeInDeclaration.go.golden 2022.1.3-1/quickfix/testdata/src/CheckRedundantTypeInDeclaration/CheckRedundantTypeInDeclaration.go.golden
--- 2022.1-1/quickfix/testdata/src/CheckRedundantTypeInDeclaration/CheckRedundantTypeInDeclaration.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckRedundantTypeInDeclaration/CheckRedundantTypeInDeclaration.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -18,20 +18,20 @@ func gen3() MyInt         { return 0 }
 var a int = gen1()
 
 func fn() {
-	var _ = gen1()            // want `could omit type int`
-	var a = Y                 // want `could omit type int`
-	var b = 1                 // want `could omit type int`
+	var _ = gen1()            //@ diag(`could omit type int`)
+	var a = Y                 //@ diag(`could omit type int`)
+	var b = 1                 //@ diag(`could omit type int`)
 	var c int = 1.0           // different default type
 	var d MyInt = 1           // different default type
-	var e = gen2()            // want `could omit type io.ReadCloser`
+	var e = gen2()            //@ diag(`could omit type io.ReadCloser`)
 	var f io.Reader = gen2()  // different interface type
-	var g = math.Pi           // want `could omit type float64`
-	var h = true              // want `could omit type bool`
-	var i = ""                // want `could omit type string`
-	var j = gen3()            // want `could omit type MyInt`
+	var g = math.Pi           //@ diag(`could omit type float64`)
+	var h = true              //@ diag(`could omit type bool`)
+	var i = ""                //@ diag(`could omit type string`)
+	var j = gen3()            //@ diag(`could omit type MyInt`)
 	var k uint8 = Y           // different default type on constant
 	var l uint8 = (Y + Y) / 2 // different default type on rhs
-	var m = (Y + Y) / 2       // want `could omit type int`
+	var m = (Y + Y) / 2       //@ diag(`could omit type int`)
 
 	_, _, _, _, _, _, _, _, _, _, _, _, _ = a, b, c, d, e, f, g, h, i, j, k, l, m
 }
diff -pruN 2022.1-1/quickfix/testdata/src/CheckStringsReplaceAll/CheckStringsReplaceAll.go 2022.1.3-1/quickfix/testdata/src/CheckStringsReplaceAll/CheckStringsReplaceAll.go
--- 2022.1-1/quickfix/testdata/src/CheckStringsReplaceAll/CheckStringsReplaceAll.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckStringsReplaceAll/CheckStringsReplaceAll.go	2022-07-31 15:38:22.000000000 +0000
@@ -6,27 +6,27 @@ import (
 )
 
 func fn() {
-	strings.Replace("", "", "", -1) // want `could use strings.ReplaceAll instead`
+	strings.Replace("", "", "", -1) //@ diag(`could use strings.ReplaceAll instead`)
 	strings.Replace("", "", "", 0)
 	strings.Replace("", "", "", 1)
 
-	strings.SplitN("", "", -1) // want `could use strings.Split instead`
+	strings.SplitN("", "", -1) //@ diag(`could use strings.Split instead`)
 	strings.SplitN("", "", 0)
 	strings.SplitN("", "", 1)
 
-	strings.SplitAfterN("", "", -1) // want `could use strings.SplitAfter instead`
+	strings.SplitAfterN("", "", -1) //@ diag(`could use strings.SplitAfter instead`)
 	strings.SplitAfterN("", "", 0)
 	strings.SplitAfterN("", "", 1)
 
-	bytes.Replace(nil, nil, nil, -1) // want `could use bytes.ReplaceAll instead`
+	bytes.Replace(nil, nil, nil, -1) //@ diag(`could use bytes.ReplaceAll instead`)
 	bytes.Replace(nil, nil, nil, 0)
 	bytes.Replace(nil, nil, nil, 1)
 
-	bytes.SplitN(nil, nil, -1) // want `could use bytes.Split instead`
+	bytes.SplitN(nil, nil, -1) //@ diag(`could use bytes.Split instead`)
 	bytes.SplitN(nil, nil, 0)
 	bytes.SplitN(nil, nil, 1)
 
-	bytes.SplitAfterN(nil, nil, -1) // want `could use bytes.SplitAfter instead`
+	bytes.SplitAfterN(nil, nil, -1) //@ diag(`could use bytes.SplitAfter instead`)
 	bytes.SplitAfterN(nil, nil, 0)
 	bytes.SplitAfterN(nil, nil, 1)
 }
diff -pruN 2022.1-1/quickfix/testdata/src/CheckStringsReplaceAll/CheckStringsReplaceAll.go.golden 2022.1.3-1/quickfix/testdata/src/CheckStringsReplaceAll/CheckStringsReplaceAll.go.golden
--- 2022.1-1/quickfix/testdata/src/CheckStringsReplaceAll/CheckStringsReplaceAll.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckStringsReplaceAll/CheckStringsReplaceAll.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -6,27 +6,27 @@ import (
 )
 
 func fn() {
-	strings.ReplaceAll("", "", "") // want `could use strings.ReplaceAll instead`
+	strings.ReplaceAll("", "", "") //@ diag(`could use strings.ReplaceAll instead`)
 	strings.Replace("", "", "", 0)
 	strings.Replace("", "", "", 1)
 
-	strings.Split("", "") // want `could use strings.Split instead`
+	strings.Split("", "") //@ diag(`could use strings.Split instead`)
 	strings.SplitN("", "", 0)
 	strings.SplitN("", "", 1)
 
-	strings.SplitAfter("", "") // want `could use strings.SplitAfter instead`
+	strings.SplitAfter("", "") //@ diag(`could use strings.SplitAfter instead`)
 	strings.SplitAfterN("", "", 0)
 	strings.SplitAfterN("", "", 1)
 
-	bytes.ReplaceAll(nil, nil, nil) // want `could use bytes.ReplaceAll instead`
+	bytes.ReplaceAll(nil, nil, nil) //@ diag(`could use bytes.ReplaceAll instead`)
 	bytes.Replace(nil, nil, nil, 0)
 	bytes.Replace(nil, nil, nil, 1)
 
-	bytes.Split(nil, nil) // want `could use bytes.Split instead`
+	bytes.Split(nil, nil) //@ diag(`could use bytes.Split instead`)
 	bytes.SplitN(nil, nil, 0)
 	bytes.SplitN(nil, nil, 1)
 
-	bytes.SplitAfter(nil, nil) // want `could use bytes.SplitAfter instead`
+	bytes.SplitAfter(nil, nil) //@ diag(`could use bytes.SplitAfter instead`)
 	bytes.SplitAfterN(nil, nil, 0)
 	bytes.SplitAfterN(nil, nil, 1)
 }
diff -pruN 2022.1-1/quickfix/testdata/src/CheckTaglessSwitch/CheckTaglessSwitch.go 2022.1.3-1/quickfix/testdata/src/CheckTaglessSwitch/CheckTaglessSwitch.go
--- 2022.1-1/quickfix/testdata/src/CheckTaglessSwitch/CheckTaglessSwitch.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckTaglessSwitch/CheckTaglessSwitch.go	2022-07-31 15:38:22.000000000 +0000
@@ -7,22 +7,22 @@ func fn1() {
 	var z map[string][]int
 	var a bool
 
-	switch { // want `could use tagged switch on x`
+	switch { //@ diag(`could use tagged switch on x`)
 	case x == 4: // comment
 	case x == 1 || x == 2, x == 3:
 	}
 
-	switch { // want `could use tagged switch on x`
+	switch { //@ diag(`could use tagged switch on x`)
 	case x == 1 || x == 2, x == 3:
 	case x == 4:
 	default:
 	}
 
-	switch { // want `could use tagged switch on z\[""\]\[0\]`
+	switch { //@ diag(`could use tagged switch on z[""][0]`)
 	case z[""][0] == 1 || z[""][0] == 2:
 	}
 
-	switch { // want `could use tagged switch on a`
+	switch { //@ diag(`could use tagged switch on a`)
 	case a == (x == y) || a == (x != y):
 	}
 
diff -pruN 2022.1-1/quickfix/testdata/src/CheckTaglessSwitch/CheckTaglessSwitch.go.golden 2022.1.3-1/quickfix/testdata/src/CheckTaglessSwitch/CheckTaglessSwitch.go.golden
--- 2022.1-1/quickfix/testdata/src/CheckTaglessSwitch/CheckTaglessSwitch.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckTaglessSwitch/CheckTaglessSwitch.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -7,22 +7,22 @@ func fn1() {
 	var z map[string][]int
 	var a bool
 
-	switch x { // want `could use tagged switch on x`
+	switch x { //@ diag(`could use tagged switch on x`)
 	case 4: // comment
 	case 1, 2, 3:
 	}
 
-	switch x { // want `could use tagged switch on x`
+	switch x { //@ diag(`could use tagged switch on x`)
 	case 1, 2, 3:
 	case 4:
 	default:
 	}
 
-	switch z[""][0] { // want `could use tagged switch on z\[""\]\[0\]`
+	switch z[""][0] { //@ diag(`could use tagged switch on z[""][0]`)
 	case 1, 2:
 	}
 
-	switch a { // want `could use tagged switch on a`
+	switch a { //@ diag(`could use tagged switch on a`)
 	case x == y, x != y:
 	}
 
diff -pruN 2022.1-1/quickfix/testdata/src/CheckTimeEquality/CheckTimeEquality.go 2022.1.3-1/quickfix/testdata/src/CheckTimeEquality/CheckTimeEquality.go
--- 2022.1-1/quickfix/testdata/src/CheckTimeEquality/CheckTimeEquality.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckTimeEquality/CheckTimeEquality.go	2022-07-31 15:38:22.000000000 +0000
@@ -7,9 +7,9 @@ func bar() time.Time { return time.Time{
 
 func fn() {
 	var t1, t2 time.Time
-	if t1 == t2 { // want `probably want to use time.Time.Equal instead`
+	if t1 == t2 { //@ diag(`probably want to use time.Time.Equal instead`)
 	}
 
-	if foo() == bar() { // want `probably want to use time.Time.Equal instead`
+	if foo() == bar() { //@ diag(`probably want to use time.Time.Equal instead`)
 	}
 }
diff -pruN 2022.1-1/quickfix/testdata/src/CheckTimeEquality/CheckTimeEquality.go.golden 2022.1.3-1/quickfix/testdata/src/CheckTimeEquality/CheckTimeEquality.go.golden
--- 2022.1-1/quickfix/testdata/src/CheckTimeEquality/CheckTimeEquality.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckTimeEquality/CheckTimeEquality.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -7,9 +7,9 @@ func bar() time.Time { return time.Time{
 
 func fn() {
 	var t1, t2 time.Time
-	if t1.Equal(t2) { // want `probably want to use time.Time.Equal instead`
+	if t1.Equal(t2) { //@ diag(`probably want to use time.Time.Equal instead`)
 	}
 
-	if foo().Equal(bar()) { // want `probably want to use time.Time.Equal instead`
+	if foo().Equal(bar()) { //@ diag(`probably want to use time.Time.Equal instead`)
 	}
 }
diff -pruN 2022.1-1/quickfix/testdata/src/CheckWriteBytesSprintf/CheckWriteBytesSprintf.go 2022.1.3-1/quickfix/testdata/src/CheckWriteBytesSprintf/CheckWriteBytesSprintf.go
--- 2022.1-1/quickfix/testdata/src/CheckWriteBytesSprintf/CheckWriteBytesSprintf.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckWriteBytesSprintf/CheckWriteBytesSprintf.go	2022-07-31 15:38:22.000000000 +0000
@@ -14,9 +14,9 @@ func fn1() {
 	var w io.Writer
 	var w2 NotAWriter
 
-	w.Write([]byte(fmt.Sprint("abc", "de")))   // want `Use fmt.Fprint`
-	w.Write([]byte(fmt.Sprintf("%T", w)))      // want `Use fmt.Fprintf`
-	w.Write([]byte(fmt.Sprintln("abc", "de"))) // want `Use fmt.Fprintln`
+	w.Write([]byte(fmt.Sprint("abc", "de")))   //@ diag(`Use fmt.Fprint`)
+	w.Write([]byte(fmt.Sprintf("%T", w)))      //@ diag(`Use fmt.Fprintf`)
+	w.Write([]byte(fmt.Sprintln("abc", "de"))) //@ diag(`Use fmt.Fprintln`)
 
 	w2.Write([]byte(fmt.Sprint("abc", "de")))
 }
@@ -25,9 +25,9 @@ func fn2() {
 	buf := new(bytes.Buffer)
 	var sw io.StringWriter
 
-	buf.WriteString(fmt.Sprint("abc", "de"))   // want `Use fmt.Fprint`
-	buf.WriteString(fmt.Sprintf("%T", 0))      // want `Use fmt.Fprintf`
-	buf.WriteString(fmt.Sprintln("abc", "de")) // want `Use fmt.Fprintln`
+	buf.WriteString(fmt.Sprint("abc", "de"))   //@ diag(`Use fmt.Fprint`)
+	buf.WriteString(fmt.Sprintf("%T", 0))      //@ diag(`Use fmt.Fprintf`)
+	buf.WriteString(fmt.Sprintln("abc", "de")) //@ diag(`Use fmt.Fprintln`)
 
 	// We can't suggest fmt.Fprint here. We don't know if sw implements io.Writer.
 	sw.WriteString(fmt.Sprint("abc", "de"))
diff -pruN 2022.1-1/quickfix/testdata/src/CheckWriteBytesSprintf/CheckWriteBytesSprintf.go.golden 2022.1.3-1/quickfix/testdata/src/CheckWriteBytesSprintf/CheckWriteBytesSprintf.go.golden
--- 2022.1-1/quickfix/testdata/src/CheckWriteBytesSprintf/CheckWriteBytesSprintf.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/quickfix/testdata/src/CheckWriteBytesSprintf/CheckWriteBytesSprintf.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -14,9 +14,9 @@ func fn1() {
 	var w io.Writer
 	var w2 NotAWriter
 
-	fmt.Fprint(w, "abc", "de")   // want `Use fmt.Fprint`
-	fmt.Fprintf(w, "%T", w)      // want `Use fmt.Fprintf`
-	fmt.Fprintln(w, "abc", "de") // want `Use fmt.Fprintln`
+	fmt.Fprint(w, "abc", "de")   //@ diag(`Use fmt.Fprint`)
+	fmt.Fprintf(w, "%T", w)      //@ diag(`Use fmt.Fprintf`)
+	fmt.Fprintln(w, "abc", "de") //@ diag(`Use fmt.Fprintln`)
 
 	w2.Write([]byte(fmt.Sprint("abc", "de")))
 }
@@ -25,9 +25,9 @@ func fn2() {
 	buf := new(bytes.Buffer)
 	var sw io.StringWriter
 
-	fmt.Fprint(buf, "abc", "de")   // want `Use fmt.Fprint`
-	fmt.Fprintf(buf, "%T", 0)      // want `Use fmt.Fprintf`
-	fmt.Fprintln(buf, "abc", "de") // want `Use fmt.Fprintln`
+	fmt.Fprint(buf, "abc", "de")   //@ diag(`Use fmt.Fprint`)
+	fmt.Fprintf(buf, "%T", 0)      //@ diag(`Use fmt.Fprintf`)
+	fmt.Fprintln(buf, "abc", "de") //@ diag(`Use fmt.Fprintln`)
 
 	// We can't suggest fmt.Fprint here. We don't know if sw implements io.Writer.
 	sw.WriteString(fmt.Sprint("abc", "de"))
diff -pruN 2022.1-1/simple/analysis.go 2022.1.3-1/simple/analysis.go
--- 2022.1-1/simple/analysis.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/analysis.go	2022-07-31 15:38:22.000000000 +0000
@@ -3,7 +3,7 @@ package simple
 import (
 	"golang.org/x/tools/go/analysis"
 	"golang.org/x/tools/go/analysis/passes/inspect"
-	"honnef.co/go/tools/analysis/facts"
+	"honnef.co/go/tools/analysis/facts/generated"
 	"honnef.co/go/tools/analysis/lint"
 	"honnef.co/go/tools/internal/passes/buildir"
 )
@@ -11,95 +11,95 @@ import (
 var Analyzers = lint.InitializeAnalyzers(Docs, map[string]*analysis.Analyzer{
 	"S1000": {
 		Run:      CheckSingleCaseSelect,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
 	},
 	"S1001": {
 		Run:      CheckLoopCopy,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
 	},
 	"S1002": {
 		Run:      CheckIfBoolCmp,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
 	},
 	"S1003": {
 		Run:      CheckStringsContains,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
 	},
 	"S1004": {
 		Run:      CheckBytesCompare,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
 	},
 	"S1005": {
 		Run:      CheckUnnecessaryBlank,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
 	},
 	"S1006": {
 		Run:      CheckForTrue,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
 	},
 	"S1007": {
 		Run:      CheckRegexpRaw,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
 	},
 	"S1008": {
 		Run:      CheckIfReturn,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
 	},
 	"S1009": {
 		Run:      CheckRedundantNilCheckWithLen,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
 	},
 	"S1010": {
 		Run:      CheckSlicing,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
 	},
 	"S1011": {
 		Run:      CheckLoopAppend,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
 	},
 	"S1012": {
 		Run:      CheckTimeSince,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
 	},
 	"S1016": {
 		Run:      CheckSimplerStructConversion,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
 	},
 	"S1017": {
 		Run:      CheckTrim,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
 	},
 	"S1018": {
 		Run:      CheckLoopSlide,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
 	},
 	"S1019": {
 		Run:      CheckMakeLenCap,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
 	},
 	"S1020": {
 		Run:      CheckAssertNotNil,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
 	},
 	"S1021": {
 		Run:      CheckDeclareAssign,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
 	},
 	"S1023": {
 		Run:      CheckRedundantBreak,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
 	},
 	"S1024": {
 		Run:      CheckTimeUntil,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
 	},
 	"S1025": {
 		Run:      CheckRedundantSprintf,
-		Requires: []*analysis.Analyzer{buildir.Analyzer, inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{buildir.Analyzer, inspect.Analyzer, generated.Analyzer},
 	},
 	"S1028": {
 		Run:      CheckErrorsNewSprintf,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
 	},
 	"S1029": {
 		Run:      CheckRangeStringRunes,
@@ -107,27 +107,27 @@ var Analyzers = lint.InitializeAnalyzers
 	},
 	"S1030": {
 		Run:      CheckBytesBufferConversions,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
 	},
 	"S1031": {
 		Run:      CheckNilCheckAroundRange,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
 	},
 	"S1032": {
 		Run:      CheckSortHelpers,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
 	},
 	"S1033": {
 		Run:      CheckGuardedDelete,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
 	},
 	"S1034": {
 		Run:      CheckSimplifyTypeSwitch,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
 	},
 	"S1035": {
 		Run:      CheckRedundantCanonicalHeaderKey,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
 	},
 	"S1036": {
 		Run:      CheckUnnecessaryGuard,
@@ -135,18 +135,18 @@ var Analyzers = lint.InitializeAnalyzers
 	},
 	"S1037": {
 		Run:      CheckElaborateSleep,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
 	},
 	"S1038": {
 		Run:      CheckPrintSprintf,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
 	},
 	"S1039": {
 		Run:      CheckSprintLiteral,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
 	},
 	"S1040": {
 		Run:      CheckSameTypeTypeAssertion,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
 	},
 })
diff -pruN 2022.1-1/simple/lint.go 2022.1.3-1/simple/lint.go
--- 2022.1-1/simple/lint.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/lint.go	2022-07-31 15:38:22.000000000 +0000
@@ -68,7 +68,7 @@ var (
 				[(AssignStmt (IndexExpr dst key) "=" (IndexExpr src key))])
 			(ForStmt
 				(AssignStmt key@(Ident _) ":=" (IntegerLiteral "0"))
-				(BinaryExpr key "<" (CallExpr (Function "len") [src]))
+				(BinaryExpr key "<" (CallExpr (Symbol "len") [src]))
 				(IncDecStmt key "++")
 				[(AssignStmt (IndexExpr dst key) "=" (IndexExpr src key))]))`)
 )
@@ -385,7 +385,7 @@ func CheckStringsContains(pass *analysis
 }
 
 var (
-	checkBytesCompareQ  = pattern.MustParse(`(BinaryExpr (CallExpr (Function "bytes.Compare") args) op@(Or "==" "!=") (IntegerLiteral "0"))`)
+	checkBytesCompareQ  = pattern.MustParse(`(BinaryExpr (CallExpr (Symbol "bytes.Compare") args) op@(Or "==" "!=") (IntegerLiteral "0"))`)
 	checkBytesCompareRe = pattern.MustParse(`(CallExpr (SelectorExpr (Ident "bytes") (Ident "Equal")) args)`)
 	checkBytesCompareRn = pattern.MustParse(`(UnaryExpr "!" (CallExpr (SelectorExpr (Ident "bytes") (Ident "Equal")) args))`)
 )
@@ -659,8 +659,7 @@ func CheckRedundantNilCheckWithLen(pass
 		if !ok {
 			return
 		}
-		yxFun, ok := yx.Fun.(*ast.Ident)
-		if !ok || yxFun.Name != "len" || len(yx.Args) != 1 {
+		if !code.IsCallTo(pass, yx, "len") {
 			return
 		}
 		yxArg, ok := yx.Args[knowledge.Arg("len.v")].(*ast.Ident)
@@ -817,7 +816,7 @@ func CheckLoopAppend(pass *analysis.Pass
 }
 
 var (
-	checkTimeSinceQ = pattern.MustParse(`(CallExpr (SelectorExpr (CallExpr (Function "time.Now") []) (Function "(time.Time).Sub")) [arg])`)
+	checkTimeSinceQ = pattern.MustParse(`(CallExpr (SelectorExpr (CallExpr (Symbol "time.Now") []) (Symbol "(time.Time).Sub")) [arg])`)
 	checkTimeSinceR = pattern.MustParse(`(CallExpr (SelectorExpr (Ident "time") (Ident "Since")) [arg])`)
 )
 
@@ -834,7 +833,7 @@ func CheckTimeSince(pass *analysis.Pass)
 }
 
 var (
-	checkTimeUntilQ = pattern.MustParse(`(CallExpr (Function "(time.Time).Sub") [(CallExpr (Function "time.Now") [])])`)
+	checkTimeUntilQ = pattern.MustParse(`(CallExpr (Symbol "(time.Time).Sub") [(CallExpr (Symbol "time.Now") [])])`)
 	checkTimeUntilR = pattern.MustParse(`(CallExpr (SelectorExpr (Ident "time") (Ident "Until")) [arg])`)
 )
 
@@ -1488,30 +1487,6 @@ func CheckRedundantBreak(pass *analysis.
 	return nil, nil
 }
 
-func isStringer(T types.Type, msCache *typeutil.MethodSetCache) bool {
-	ms := msCache.MethodSet(T)
-	sel := ms.Lookup(nil, "String")
-	if sel == nil {
-		return false
-	}
-	fn, ok := sel.Obj().(*types.Func)
-	if !ok {
-		// should be unreachable
-		return false
-	}
-	sig := fn.Type().(*types.Signature)
-	if sig.Params().Len() != 0 {
-		return false
-	}
-	if sig.Results().Len() != 1 {
-		return false
-	}
-	if !typeutil.IsType(sig.Results().At(0).Type(), "string") {
-		return false
-	}
-	return true
-}
-
 func isFormatter(T types.Type, msCache *typeutil.MethodSetCache) bool {
 	// TODO(dh): this function also exists in staticcheck/lint.go – deduplicate.
 
@@ -1537,7 +1512,7 @@ func isFormatter(T types.Type, msCache *
 	return true
 }
 
-var checkRedundantSprintfQ = pattern.MustParse(`(CallExpr (Function "fmt.Sprintf") [format arg])`)
+var checkRedundantSprintfQ = pattern.MustParse(`(CallExpr (Symbol "fmt.Sprintf") [format arg])`)
 
 func CheckRedundantSprintf(pass *analysis.Pass) (interface{}, error) {
 	fn := func(node ast.Node) {
@@ -1571,7 +1546,7 @@ func CheckRedundantSprintf(pass *analysi
 			return
 		}
 
-		if isStringer(typ, &irpkg.Prog.MethodSets) {
+		if types.Implements(typ, knowledge.Interfaces["fmt.Stringer"]) {
 			replacement := &ast.CallExpr{
 				Fun: &ast.SelectorExpr{
 					X:   arg,
@@ -1609,7 +1584,7 @@ func CheckRedundantSprintf(pass *analysi
 }
 
 var (
-	checkErrorsNewSprintfQ = pattern.MustParse(`(CallExpr (Function "errors.New") [(CallExpr (Function "fmt.Sprintf") args)])`)
+	checkErrorsNewSprintfQ = pattern.MustParse(`(CallExpr (Symbol "errors.New") [(CallExpr (Symbol "fmt.Sprintf") args)])`)
 	checkErrorsNewSprintfR = pattern.MustParse(`(CallExpr (SelectorExpr (Ident "fmt") (Ident "Errorf")) args)`)
 )
 
@@ -1923,7 +1898,7 @@ func CheckUnnecessaryGuard(pass *analysi
 }
 
 var (
-	checkElaborateSleepQ = pattern.MustParse(`(SelectStmt (CommClause (UnaryExpr "<-" (CallExpr (Function "time.After") [arg])) body))`)
+	checkElaborateSleepQ = pattern.MustParse(`(SelectStmt (CommClause (UnaryExpr "<-" (CallExpr (Symbol "time.After") [arg])) body))`)
 	checkElaborateSleepR = pattern.MustParse(`(CallExpr (SelectorExpr (Ident "time") (Ident "Sleep")) [arg])`)
 )
 
@@ -1953,16 +1928,16 @@ var (
 		(Or
 			(CallExpr
 				fn@(Or
-					(Function "fmt.Print")
-					(Function "fmt.Sprint")
-					(Function "fmt.Println")
-					(Function "fmt.Sprintln"))
-				[(CallExpr (Function "fmt.Sprintf") f:_)])
+					(Symbol "fmt.Print")
+					(Symbol "fmt.Sprint")
+					(Symbol "fmt.Println")
+					(Symbol "fmt.Sprintln"))
+				[(CallExpr (Symbol "fmt.Sprintf") f:_)])
 			(CallExpr
 				fn@(Or
-					(Function "fmt.Fprint")
-					(Function "fmt.Fprintln"))
-				[_ (CallExpr (Function "fmt.Sprintf") f:_)]))`)
+					(Symbol "fmt.Fprint")
+					(Symbol "fmt.Fprintln"))
+				[_ (CallExpr (Symbol "fmt.Sprintf") f:_)]))`)
 
 	checkTestingErrorSprintfQ = pattern.MustParse(`
 		(CallExpr
@@ -1979,11 +1954,11 @@ var (
 						"Print"
 						"Println"
 						"Skip")))
-			[(CallExpr (Function "fmt.Sprintf") args)])`)
+			[(CallExpr (Symbol "fmt.Sprintf") args)])`)
 
 	checkLogSprintfQ = pattern.MustParse(`
 		(CallExpr
-			(Function
+			(Symbol
 				(Or
 					"log.Fatal"
 					"log.Fatalln"
@@ -1991,7 +1966,7 @@ var (
 					"log.Panicln"
 					"log.Print"
 					"log.Println"))
-			[(CallExpr (Function "fmt.Sprintf") args)])`)
+			[(CallExpr (Symbol "fmt.Sprintf") args)])`)
 
 	checkSprintfMapping = map[string]struct {
 		recv        string
@@ -2106,8 +2081,8 @@ func CheckPrintSprintf(pass *analysis.Pa
 var checkSprintLiteralQ = pattern.MustParse(`
 	(CallExpr
 		fn@(Or
-			(Function "fmt.Sprint")
-			(Function "fmt.Sprintf"))
+			(Symbol "fmt.Sprint")
+			(Symbol "fmt.Sprintf"))
 		[lit@(BasicLit "STRING" _)])`)
 
 func CheckSprintLiteral(pass *analysis.Pass) (interface{}, error) {
diff -pruN 2022.1-1/simple/lint_test.go 2022.1.3-1/simple/lint_test.go
--- 2022.1-1/simple/lint_test.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/lint_test.go	2022-07-31 15:38:22.000000000 +0000
@@ -8,25 +8,29 @@ import (
 
 func TestAll(t *testing.T) {
 	checks := map[string][]testutil.Test{
-		"S1000": {{Dir: "single-case-select"}},
-		"S1001": {{Dir: "copy"}},
-		"S1002": {{Dir: "bool-cmp"}},
-		"S1003": {{Dir: "contains"}},
-		"S1004": {{Dir: "compare"}},
-		"S1005": {{Dir: "CheckBlankOK"}, {Dir: "receive-blank"}, {Dir: "range_go13", Version: "1.3"}, {Dir: "range_go14", Version: "1.4"}},
-		"S1006": {{Dir: "for-true"}, {Dir: "generated"}},
-		"S1007": {{Dir: "regexp-raw"}},
-		"S1008": {{Dir: "if-return"}},
-		"S1009": {{Dir: "nil-len"}},
-		"S1010": {{Dir: "slicing"}},
-		"S1011": {{Dir: "loop-append"}},
-		"S1012": {{Dir: "time-since"}},
+		"S1000": {{Dir: "CheckSingleCaseSelect"}},
+		"S1001": {{Dir: "CheckLoopCopy"}},
+		"S1002": {{Dir: "CheckIfBoolCmp"}},
+		"S1003": {{Dir: "CheckStringsContains"}},
+		"S1004": {{Dir: "CheckBytesCompare"}},
+		"S1005": {
+			{Dir: "CheckUnnecessaryBlank"},
+			{Dir: "CheckUnnecessaryBlank_go13", Version: "1.3"},
+			{Dir: "CheckUnnecessaryBlank_go14", Version: "1.4"},
+		},
+		"S1006": {{Dir: "CheckForTrue"}},
+		"S1007": {{Dir: "CheckRegexpRaw"}},
+		"S1008": {{Dir: "CheckIfReturn"}},
+		"S1009": {{Dir: "CheckRedundantNilCheckWithLen"}},
+		"S1010": {{Dir: "CheckSlicing"}},
+		"S1011": {{Dir: "CheckLoopAppend"}},
+		"S1012": {{Dir: "CheckTimeSince"}},
 		"S1016": {
-			{Dir: "convert"},
-			{Dir: "convert_go17", Version: "1.7"},
-			{Dir: "convert_go18", Version: "1.8"},
+			{Dir: "CheckSimplerStructConversion"},
+			{Dir: "CheckSimplerStructConversion_go17", Version: "1.7"},
+			{Dir: "CheckSimplerStructConversion_go18", Version: "1.8"},
 		},
-		"S1017": {{Dir: "trim"}},
+		"S1017": {{Dir: "CheckTrim"}},
 		"S1018": {{Dir: "CheckLoopSlide"}},
 		"S1019": {{Dir: "CheckMakeLenCap"}},
 		"S1020": {{Dir: "CheckAssertNotNil"}},
diff -pruN 2022.1-1/simple/testdata/src/bool-cmp/bool-cmp_generics.go 2022.1.3-1/simple/testdata/src/bool-cmp/bool-cmp_generics.go
--- 2022.1-1/simple/testdata/src/bool-cmp/bool-cmp_generics.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/bool-cmp/bool-cmp_generics.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,29 +0,0 @@
-//go:build go1.18
-
-package pkg
-
-func tpfn1[T any]() T { var zero T; return zero }
-
-func tpfn() {
-	if tpfn1[bool]() == true { // want `simplified to tpfn1\[bool\]\(\)`
-	}
-	if tpfn1[any]() == true {
-	}
-}
-
-func tpfn2[T bool](x T) {
-	if x == true { // want `omit comparison to bool constant`
-	}
-}
-
-func tpfn3[T ~bool](x T) {
-	if x == true { // want `omit comparison to bool constant`
-	}
-}
-
-type MyBool bool
-
-func tpfn4[T bool | MyBool](x T) {
-	if x == true { // want `omit comparison to bool constant`
-	}
-}
diff -pruN 2022.1-1/simple/testdata/src/bool-cmp/bool-cmp_generics.go.golden 2022.1.3-1/simple/testdata/src/bool-cmp/bool-cmp_generics.go.golden
--- 2022.1-1/simple/testdata/src/bool-cmp/bool-cmp_generics.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/bool-cmp/bool-cmp_generics.go.golden	1970-01-01 00:00:00.000000000 +0000
@@ -1,29 +0,0 @@
-//go:build go1.18
-
-package pkg
-
-func tpfn1[T any]() T { var zero T; return zero }
-
-func tpfn() {
-	if tpfn1[bool]() { // want `simplified to tpfn1\[bool\]\(\)`
-	}
-	if tpfn1[any]() == true {
-	}
-}
-
-func tpfn2[T bool](x T) {
-	if x { // want `omit comparison to bool constant`
-	}
-}
-
-func tpfn3[T ~bool](x T) {
-	if x { // want `omit comparison to bool constant`
-	}
-}
-
-type MyBool bool
-
-func tpfn4[T bool | MyBool](x T) {
-	if x { // want `omit comparison to bool constant`
-	}
-}
diff -pruN 2022.1-1/simple/testdata/src/bool-cmp/bool-cmp.go 2022.1.3-1/simple/testdata/src/bool-cmp/bool-cmp.go
--- 2022.1-1/simple/testdata/src/bool-cmp/bool-cmp.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/bool-cmp/bool-cmp.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,55 +0,0 @@
-package pkg
-
-func fn1() bool { return false }
-func fn2() bool { return false }
-
-func fn() {
-	type T bool
-	var x T
-	const t T = false
-	if x == t {
-	}
-	if fn1() == true { // want `simplified to fn1\(\)`
-	}
-	if fn1() != true { // want `simplified to !fn1\(\)`
-	}
-	if fn1() == false { // want `simplified to !fn1\(\)`
-	}
-	if fn1() != false { // want `simplified to fn1\(\)`
-	}
-	if fn1() && (fn1() || fn1()) || (fn1() && fn1()) == true { // want `simplified to \(fn1\(\) && fn1\(\)\)`
-	}
-
-	if (fn1() && fn2()) == false { // want `simplified to !\(fn1\(\) && fn2\(\)\)`
-	}
-
-	var y bool
-	for y != true { // want `simplified to !y`
-	}
-	if !y == true { // want `simplified to !y`
-	}
-	if !y == false { // want `simplified to y`
-	}
-	if !y != true { // want `simplified to y`
-	}
-	if !y != false { // want `simplified to !y`
-	}
-	if !!y == false { // want `simplified to !y`
-	}
-	if !!!y == false { // want `simplified to y`
-	}
-	if !!y == true { // want `simplified to y`
-	}
-	if !!!y == true { // want `simplified to !y`
-	}
-	if !!y != true { // want `simplified to !y`
-	}
-	if !!!y != true { // want `simplified to y`
-	}
-	if !y == !false { // not matched because we expect true/false on one side, not !false
-	}
-
-	var z interface{}
-	if z == true {
-	}
-}
diff -pruN 2022.1-1/simple/testdata/src/bool-cmp/bool-cmp.go.golden 2022.1.3-1/simple/testdata/src/bool-cmp/bool-cmp.go.golden
--- 2022.1-1/simple/testdata/src/bool-cmp/bool-cmp.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/bool-cmp/bool-cmp.go.golden	1970-01-01 00:00:00.000000000 +0000
@@ -1,55 +0,0 @@
-package pkg
-
-func fn1() bool { return false }
-func fn2() bool { return false }
-
-func fn() {
-	type T bool
-	var x T
-	const t T = false
-	if x == t {
-	}
-	if fn1() { // want `simplified to fn1\(\)`
-	}
-	if !fn1() { // want `simplified to !fn1\(\)`
-	}
-	if !fn1() { // want `simplified to !fn1\(\)`
-	}
-	if fn1() { // want `simplified to fn1\(\)`
-	}
-	if fn1() && (fn1() || fn1()) || (fn1() && fn1()) { // want `simplified to \(fn1\(\) && fn1\(\)\)`
-	}
-
-	if !(fn1() && fn2()) { // want `simplified to !\(fn1\(\) && fn2\(\)\)`
-	}
-
-	var y bool
-	for !y { // want `simplified to !y`
-	}
-	if !y { // want `simplified to !y`
-	}
-	if y { // want `simplified to y`
-	}
-	if y { // want `simplified to y`
-	}
-	if !y { // want `simplified to !y`
-	}
-	if !y { // want `simplified to !y`
-	}
-	if y { // want `simplified to y`
-	}
-	if y { // want `simplified to y`
-	}
-	if !y { // want `simplified to !y`
-	}
-	if !y { // want `simplified to !y`
-	}
-	if y { // want `simplified to y`
-	}
-	if !y == !false { // not matched because we expect true/false on one side, not !false
-	}
-
-	var z interface{}
-	if z == true {
-	}
-}
diff -pruN 2022.1-1/simple/testdata/src/bool-cmp/bool-cmp_test.go 2022.1.3-1/simple/testdata/src/bool-cmp/bool-cmp_test.go
--- 2022.1-1/simple/testdata/src/bool-cmp/bool-cmp_test.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/bool-cmp/bool-cmp_test.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,8 +0,0 @@
-package pkg
-
-import "testing"
-
-func TestFoo(t *testing.T) {
-	if fn1() == true {
-	}
-}
diff -pruN 2022.1-1/simple/testdata/src/CheckAssertNotNil/LintAssertNotNil.go 2022.1.3-1/simple/testdata/src/CheckAssertNotNil/LintAssertNotNil.go
--- 2022.1-1/simple/testdata/src/CheckAssertNotNil/LintAssertNotNil.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckAssertNotNil/LintAssertNotNil.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,9 +1,9 @@
 package pkg
 
 func fn(i interface{}, x interface{}) {
-	if _, ok := i.(string); ok && i != nil { // want `when ok is true, i can't be nil`
+	if _, ok := i.(string); ok && i != nil { //@ diag(`when ok is true, i can't be nil`)
 	}
-	if _, ok := i.(string); i != nil && ok { // want `when ok is true, i can't be nil`
+	if _, ok := i.(string); i != nil && ok { //@ diag(`when ok is true, i can't be nil`)
 	}
 	if _, ok := i.(string); i != nil || ok {
 	}
@@ -12,12 +12,12 @@ func fn(i interface{}, x interface{}) {
 	if _, ok := i.(string); i == nil && ok {
 	}
 	if i != nil {
-		if _, ok := i.(string); ok { // want `when ok is true, i can't be nil`
+		if _, ok := i.(string); ok { //@ diag(`when ok is true, i can't be nil`)
 		}
 	}
 	if i != nil {
 		// This gets flagged because of https://github.com/dominikh/go-tools/issues/1047
-		if _, ok := i.(string); ok { // want `when ok is true, i can't be nil`
+		if _, ok := i.(string); ok { //@ diag(`when ok is true, i can't be nil`)
 		} else {
 			//
 		}
diff -pruN 2022.1-1/simple/testdata/src/CheckBlankOK/LintBlankOK.go 2022.1.3-1/simple/testdata/src/CheckBlankOK/LintBlankOK.go
--- 2022.1-1/simple/testdata/src/CheckBlankOK/LintBlankOK.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckBlankOK/LintBlankOK.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,12 +0,0 @@
-package pkg
-
-func fn() {
-	var m map[int]int
-	var ch chan int
-	var fn func() (int, bool)
-
-	x, _ := m[0] // want `unnecessary assignment to the blank identifier`
-	x, _ = <-ch  // want `unnecessary assignment to the blank identifier`
-	x, _ = fn()
-	_ = x
-}
diff -pruN 2022.1-1/simple/testdata/src/CheckBlankOK/LintBlankOK.go.golden 2022.1.3-1/simple/testdata/src/CheckBlankOK/LintBlankOK.go.golden
--- 2022.1-1/simple/testdata/src/CheckBlankOK/LintBlankOK.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckBlankOK/LintBlankOK.go.golden	1970-01-01 00:00:00.000000000 +0000
@@ -1,12 +0,0 @@
-package pkg
-
-func fn() {
-	var m map[int]int
-	var ch chan int
-	var fn func() (int, bool)
-
-	x := m[0] // want `unnecessary assignment to the blank identifier`
-	x = <-ch  // want `unnecessary assignment to the blank identifier`
-	x, _ = fn()
-	_ = x
-}
diff -pruN 2022.1-1/simple/testdata/src/CheckBytesBufferConversions/LintBytesBufferConversions.go 2022.1.3-1/simple/testdata/src/CheckBytesBufferConversions/LintBytesBufferConversions.go
--- 2022.1-1/simple/testdata/src/CheckBytesBufferConversions/LintBytesBufferConversions.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckBytesBufferConversions/LintBytesBufferConversions.go	2022-07-31 15:38:22.000000000 +0000
@@ -6,12 +6,12 @@ import (
 
 func fn() {
 	buf := bytes.NewBufferString("str")
-	_ = string(buf.Bytes())  // want `should use buf\.String\(\) instead of string\(buf\.Bytes\(\)\)`
-	_ = []byte(buf.String()) // want `should use buf\.Bytes\(\) instead of \[\]byte\(buf\.String\(\)\)`
+	_ = string(buf.Bytes())  //@ diag(`should use buf.String() instead of string(buf.Bytes())`)
+	_ = []byte(buf.String()) //@ diag(`should use buf.Bytes() instead of []byte(buf.String())`)
 
 	m := map[string]*bytes.Buffer{"key": buf}
-	_ = string(m["key"].Bytes())  // want `should use m\["key"\]\.String\(\) instead of string\(m\["key"\]\.Bytes\(\)\)`
-	_ = []byte(m["key"].String()) // want `should use m\["key"\]\.Bytes\(\) instead of \[\]byte\(m\["key"\]\.String\(\)\)`
+	_ = string(m["key"].Bytes())  //@ diag(`should use m["key"].String() instead of string(m["key"].Bytes())`)
+	_ = []byte(m["key"].String()) //@ diag(`should use m["key"].Bytes() instead of []byte(m["key"].String())`)
 
 	var m2 map[string]int
 	_ = m2[string(buf.Bytes())] // no warning, this is more efficient than buf.String()
diff -pruN 2022.1-1/simple/testdata/src/CheckBytesBufferConversions/LintBytesBufferConversions.go.golden 2022.1.3-1/simple/testdata/src/CheckBytesBufferConversions/LintBytesBufferConversions.go.golden
--- 2022.1-1/simple/testdata/src/CheckBytesBufferConversions/LintBytesBufferConversions.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckBytesBufferConversions/LintBytesBufferConversions.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -6,12 +6,12 @@ import (
 
 func fn() {
 	buf := bytes.NewBufferString("str")
-	_ = buf.String() // want `should use buf\.String\(\) instead of string\(buf\.Bytes\(\)\)`
-	_ = buf.Bytes()  // want `should use buf\.Bytes\(\) instead of \[\]byte\(buf\.String\(\)\)`
+	_ = buf.String() //@ diag(`should use buf.String() instead of string(buf.Bytes())`)
+	_ = buf.Bytes()  //@ diag(`should use buf.Bytes() instead of []byte(buf.String())`)
 
 	m := map[string]*bytes.Buffer{"key": buf}
-	_ = m["key"].String() // want `should use m\["key"\]\.String\(\) instead of string\(m\["key"\]\.Bytes\(\)\)`
-	_ = m["key"].Bytes()  // want `should use m\["key"\]\.Bytes\(\) instead of \[\]byte\(m\["key"\]\.String\(\)\)`
+	_ = m["key"].String() //@ diag(`should use m["key"].String() instead of string(m["key"].Bytes())`)
+	_ = m["key"].Bytes()  //@ diag(`should use m["key"].Bytes() instead of []byte(m["key"].String())`)
 
 	var m2 map[string]int
 	_ = m2[string(buf.Bytes())] // no warning, this is more efficient than buf.String()
diff -pruN 2022.1-1/simple/testdata/src/CheckBytesCompare/compare.go 2022.1.3-1/simple/testdata/src/CheckBytesCompare/compare.go
--- 2022.1-1/simple/testdata/src/CheckBytesCompare/compare.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckBytesCompare/compare.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,10 @@
+package pkg
+
+import "bytes"
+
+func fn() {
+	_ = bytes.Compare(nil, nil) == 0 //@ diag(` bytes.Equal`)
+	_ = bytes.Compare(nil, nil) != 0 //@ diag(`!bytes.Equal`)
+	_ = bytes.Compare(nil, nil) > 0
+	_ = bytes.Compare(nil, nil) < 0
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckBytesCompare/compare.go.golden 2022.1.3-1/simple/testdata/src/CheckBytesCompare/compare.go.golden
--- 2022.1-1/simple/testdata/src/CheckBytesCompare/compare.go.golden	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckBytesCompare/compare.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,10 @@
+package pkg
+
+import "bytes"
+
+func fn() {
+	_ = bytes.Equal(nil, nil)  //@ diag(` bytes.Equal`)
+	_ = !bytes.Equal(nil, nil) //@ diag(`!bytes.Equal`)
+	_ = bytes.Compare(nil, nil) > 0
+	_ = bytes.Compare(nil, nil) < 0
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckDeclareAssign/LintDeclareAssign.go 2022.1.3-1/simple/testdata/src/CheckDeclareAssign/LintDeclareAssign.go
--- 2022.1-1/simple/testdata/src/CheckDeclareAssign/LintDeclareAssign.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckDeclareAssign/LintDeclareAssign.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,16 +1,16 @@
 package pkg
 
 func fn() {
-	var x int // want `should merge variable declaration with assignment on next line`
+	var x int //@ diag(`should merge variable declaration with assignment on next line`)
 	x = 1
 	_ = x
 
-	var y interface{} // want `should merge variable declaration with assignment on next line`
+	var y interface{} //@ diag(`should merge variable declaration with assignment on next line`)
 	y = 1
 	_ = y
 
 	if true {
-		var x string // want `should merge variable declaration with assignment on next line`
+		var x string //@ diag(`should merge variable declaration with assignment on next line`)
 		x = ""
 		_ = x
 	}
diff -pruN 2022.1-1/simple/testdata/src/CheckElaborateSleep/LintElaborateSleep.go 2022.1.3-1/simple/testdata/src/CheckElaborateSleep/LintElaborateSleep.go
--- 2022.1-1/simple/testdata/src/CheckElaborateSleep/LintElaborateSleep.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckElaborateSleep/LintElaborateSleep.go	2022-07-31 15:38:22.000000000 +0000
@@ -8,17 +8,17 @@ import (
 func fn() {
 	time.Sleep(0)
 
-	select { // want `should use time.Sleep`
+	select { //@ diag(`should use time.Sleep`)
 	case <-time.After(0):
 	}
 
-	select { // want `should use time.Sleep`
+	select { //@ diag(`should use time.Sleep`)
 	case <-time.After(0):
 		fmt.Println("yay")
 	}
 
 	const d = 0
-	select { // want `should use time.Sleep`
+	select { //@ diag(`should use time.Sleep`)
 	case <-time.After(d):
 	}
 
diff -pruN 2022.1-1/simple/testdata/src/CheckElaborateSleep/LintElaborateSleep.go.golden 2022.1.3-1/simple/testdata/src/CheckElaborateSleep/LintElaborateSleep.go.golden
--- 2022.1-1/simple/testdata/src/CheckElaborateSleep/LintElaborateSleep.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckElaborateSleep/LintElaborateSleep.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -10,7 +10,7 @@ func fn() {
 
 	time.Sleep(0)
 
-	select { // want `should use time.Sleep`
+	select { //@ diag(`should use time.Sleep`)
 	case <-time.After(0):
 		fmt.Println("yay")
 	}
diff -pruN 2022.1-1/simple/testdata/src/CheckErrorsNewSprintf/LintErrorsNewSprintf.go 2022.1.3-1/simple/testdata/src/CheckErrorsNewSprintf/LintErrorsNewSprintf.go
--- 2022.1-1/simple/testdata/src/CheckErrorsNewSprintf/LintErrorsNewSprintf.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckErrorsNewSprintf/LintErrorsNewSprintf.go	2022-07-31 15:38:22.000000000 +0000
@@ -8,5 +8,5 @@ import (
 func fn() {
 	_ = fmt.Errorf("%d", 0)
 	_ = errors.New("")
-	_ = errors.New(fmt.Sprintf("%d", 0)) // want `should use fmt\.Errorf`
+	_ = errors.New(fmt.Sprintf("%d", 0)) //@ diag(`should use fmt.Errorf`)
 }
diff -pruN 2022.1-1/simple/testdata/src/CheckErrorsNewSprintf/LintErrorsNewSprintf.go.golden 2022.1.3-1/simple/testdata/src/CheckErrorsNewSprintf/LintErrorsNewSprintf.go.golden
--- 2022.1-1/simple/testdata/src/CheckErrorsNewSprintf/LintErrorsNewSprintf.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckErrorsNewSprintf/LintErrorsNewSprintf.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -8,5 +8,5 @@ import (
 func fn() {
 	_ = fmt.Errorf("%d", 0)
 	_ = errors.New("")
-	_ = fmt.Errorf("%d", 0) // want `should use fmt\.Errorf`
+	_ = fmt.Errorf("%d", 0) //@ diag(`should use fmt.Errorf`)
 }
diff -pruN 2022.1-1/simple/testdata/src/CheckForTrue/for-true.go 2022.1.3-1/simple/testdata/src/CheckForTrue/for-true.go
--- 2022.1-1/simple/testdata/src/CheckForTrue/for-true.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckForTrue/for-true.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,12 @@
+package pkg
+
+func fn() {
+	for false {
+	}
+	for true { //@ diag(`should use for`)
+	}
+	for {
+	}
+	for i := 0; true; i++ {
+	}
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckForTrue/generated.go 2022.1.3-1/simple/testdata/src/CheckForTrue/generated.go
--- 2022.1-1/simple/testdata/src/CheckForTrue/generated.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckForTrue/generated.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,14 @@
+// Code generated by a clever monkey. DO NOT EDIT.
+
+package pkg
+
+func fn3() {
+	for true {
+	}
+}
+
+//line input.go:2
+func fn2() {
+	for true {
+	}
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckForTrue/input.go 2022.1.3-1/simple/testdata/src/CheckForTrue/input.go
--- 2022.1-1/simple/testdata/src/CheckForTrue/input.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckForTrue/input.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,6 @@
+package pkg
+
+//@ diag(`should use for {}`)
+
+// the error is produced by generated.go, which pretends that its
+// broken code came from this file.
diff -pruN 2022.1-1/simple/testdata/src/CheckGuardedDelete/LintGuardedDelete.go 2022.1.3-1/simple/testdata/src/CheckGuardedDelete/LintGuardedDelete.go
--- 2022.1-1/simple/testdata/src/CheckGuardedDelete/LintGuardedDelete.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckGuardedDelete/LintGuardedDelete.go	2022-07-31 15:38:22.000000000 +0000
@@ -2,7 +2,7 @@
 package pkg
 
 func fn(m map[int]int) {
-	if _, ok := m[0]; ok { // want `unnecessary guard`
+	if _, ok := m[0]; ok { //@ diag(`unnecessary guard`)
 		delete(m, 0)
 	}
 	if _, ok := m[0]; !ok {
@@ -17,7 +17,7 @@ func fn(m map[int]int) {
 	}
 
 	var key int
-	if _, ok := m[key]; ok { // want `unnecessary guard`
+	if _, ok := m[key]; ok { //@ diag(`unnecessary guard`)
 		delete(m, key)
 	}
 	if _, ok := m[key]; ok {
diff -pruN 2022.1-1/simple/testdata/src/CheckIfBoolCmp/bool-cmp_generics.go 2022.1.3-1/simple/testdata/src/CheckIfBoolCmp/bool-cmp_generics.go
--- 2022.1-1/simple/testdata/src/CheckIfBoolCmp/bool-cmp_generics.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckIfBoolCmp/bool-cmp_generics.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,29 @@
+//go:build go1.18
+
+package pkg
+
+func tpfn1[T any]() T { var zero T; return zero }
+
+func tpfn() {
+	if tpfn1[bool]() == true { //@ diag(`simplified to tpfn1[bool]()`)
+	}
+	if tpfn1[any]() == true {
+	}
+}
+
+func tpfn2[T bool](x T) {
+	if x == true { //@ diag(`omit comparison to bool constant`)
+	}
+}
+
+func tpfn3[T ~bool](x T) {
+	if x == true { //@ diag(`omit comparison to bool constant`)
+	}
+}
+
+type MyBool bool
+
+func tpfn4[T bool | MyBool](x T) {
+	if x == true { //@ diag(`omit comparison to bool constant`)
+	}
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckIfBoolCmp/bool-cmp_generics.go.golden 2022.1.3-1/simple/testdata/src/CheckIfBoolCmp/bool-cmp_generics.go.golden
--- 2022.1-1/simple/testdata/src/CheckIfBoolCmp/bool-cmp_generics.go.golden	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckIfBoolCmp/bool-cmp_generics.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,29 @@
+//go:build go1.18
+
+package pkg
+
+func tpfn1[T any]() T { var zero T; return zero }
+
+func tpfn() {
+	if tpfn1[bool]() { //@ diag(`simplified to tpfn1[bool]()`)
+	}
+	if tpfn1[any]() == true {
+	}
+}
+
+func tpfn2[T bool](x T) {
+	if x { //@ diag(`omit comparison to bool constant`)
+	}
+}
+
+func tpfn3[T ~bool](x T) {
+	if x { //@ diag(`omit comparison to bool constant`)
+	}
+}
+
+type MyBool bool
+
+func tpfn4[T bool | MyBool](x T) {
+	if x { //@ diag(`omit comparison to bool constant`)
+	}
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckIfBoolCmp/bool-cmp.go 2022.1.3-1/simple/testdata/src/CheckIfBoolCmp/bool-cmp.go
--- 2022.1-1/simple/testdata/src/CheckIfBoolCmp/bool-cmp.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckIfBoolCmp/bool-cmp.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,55 @@
+package pkg
+
+func fn1() bool { return false }
+func fn2() bool { return false }
+
+func fn() {
+	type T bool
+	var x T
+	const t T = false
+	if x == t {
+	}
+	if fn1() == true { //@ diag(`simplified to fn1()`)
+	}
+	if fn1() != true { //@ diag(`simplified to !fn1()`)
+	}
+	if fn1() == false { //@ diag(`simplified to !fn1()`)
+	}
+	if fn1() != false { //@ diag(`simplified to fn1()`)
+	}
+	if fn1() && (fn1() || fn1()) || (fn1() && fn1()) == true { //@ diag(`simplified to (fn1() && fn1())`)
+	}
+
+	if (fn1() && fn2()) == false { //@ diag(`simplified to !(fn1() && fn2())`)
+	}
+
+	var y bool
+	for y != true { //@ diag(`simplified to !y`)
+	}
+	if !y == true { //@ diag(`simplified to !y`)
+	}
+	if !y == false { //@ diag(`simplified to y`)
+	}
+	if !y != true { //@ diag(`simplified to y`)
+	}
+	if !y != false { //@ diag(`simplified to !y`)
+	}
+	if !!y == false { //@ diag(`simplified to !y`)
+	}
+	if !!!y == false { //@ diag(`simplified to y`)
+	}
+	if !!y == true { //@ diag(`simplified to y`)
+	}
+	if !!!y == true { //@ diag(`simplified to !y`)
+	}
+	if !!y != true { //@ diag(`simplified to !y`)
+	}
+	if !!!y != true { //@ diag(`simplified to y`)
+	}
+	if !y == !false { // not matched because we expect true/false on one side, not !false
+	}
+
+	var z interface{}
+	if z == true {
+	}
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckIfBoolCmp/bool-cmp.go.golden 2022.1.3-1/simple/testdata/src/CheckIfBoolCmp/bool-cmp.go.golden
--- 2022.1-1/simple/testdata/src/CheckIfBoolCmp/bool-cmp.go.golden	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckIfBoolCmp/bool-cmp.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,55 @@
+package pkg
+
+func fn1() bool { return false }
+func fn2() bool { return false }
+
+func fn() {
+	type T bool
+	var x T
+	const t T = false
+	if x == t {
+	}
+	if fn1() { //@ diag(`simplified to fn1()`)
+	}
+	if !fn1() { //@ diag(`simplified to !fn1()`)
+	}
+	if !fn1() { //@ diag(`simplified to !fn1()`)
+	}
+	if fn1() { //@ diag(`simplified to fn1()`)
+	}
+	if fn1() && (fn1() || fn1()) || (fn1() && fn1()) { //@ diag(`simplified to (fn1() && fn1())`)
+	}
+
+	if !(fn1() && fn2()) { //@ diag(`simplified to !(fn1() && fn2())`)
+	}
+
+	var y bool
+	for !y { //@ diag(`simplified to !y`)
+	}
+	if !y { //@ diag(`simplified to !y`)
+	}
+	if y { //@ diag(`simplified to y`)
+	}
+	if y { //@ diag(`simplified to y`)
+	}
+	if !y { //@ diag(`simplified to !y`)
+	}
+	if !y { //@ diag(`simplified to !y`)
+	}
+	if y { //@ diag(`simplified to y`)
+	}
+	if y { //@ diag(`simplified to y`)
+	}
+	if !y { //@ diag(`simplified to !y`)
+	}
+	if !y { //@ diag(`simplified to !y`)
+	}
+	if y { //@ diag(`simplified to y`)
+	}
+	if !y == !false { // not matched because we expect true/false on one side, not !false
+	}
+
+	var z interface{}
+	if z == true {
+	}
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckIfBoolCmp/bool-cmp_test.go 2022.1.3-1/simple/testdata/src/CheckIfBoolCmp/bool-cmp_test.go
--- 2022.1-1/simple/testdata/src/CheckIfBoolCmp/bool-cmp_test.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckIfBoolCmp/bool-cmp_test.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,8 @@
+package pkg
+
+import "testing"
+
+func TestFoo(t *testing.T) {
+	if fn1() == true {
+	}
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckIfReturn/if-return.go 2022.1.3-1/simple/testdata/src/CheckIfReturn/if-return.go
--- 2022.1-1/simple/testdata/src/CheckIfReturn/if-return.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckIfReturn/if-return.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,155 @@
+package pkg
+
+func fn() bool { return true }
+func fn1() bool {
+	x := true
+	if x { //@ diag(`should use 'return x'`)
+		return true
+	}
+	return false
+}
+
+func fn2() bool {
+	x := true
+	if !x {
+		return true
+	}
+	if x {
+		return true
+	}
+	return false
+}
+
+func fn3() int {
+	var x bool
+	if x {
+		return 1
+	}
+	return 2
+}
+
+func fn4() bool { return true }
+
+func fn5() bool {
+	if fn() { //@ diag(`should use 'return !fn()'`)
+		return false
+	}
+	return true
+}
+
+func fn6() bool {
+	if fn3() != fn3() { //@ diag(`should use 'return fn3() != fn3()'`)
+		return true
+	}
+	return false
+}
+
+func fn7() bool {
+	if 1 > 2 { //@ diag(`should use 'return 1 > 2'`)
+		return true
+	}
+	return false
+}
+
+func fn8() bool {
+	if fn() || fn() {
+		return true
+	}
+	return false
+}
+
+func fn9(x int) bool {
+	if x > 0 {
+		return true
+	}
+	return true
+}
+
+func fn10(x int) bool {
+	if x > 0 { //@ diag(`should use 'return x <= 0'`)
+		return false
+	}
+	return true
+}
+
+func fn11(x bool) bool {
+	if x { //@ diag(`should use 'return !x'`)
+		return false
+	}
+	return true
+}
+
+func fn12() bool {
+	var x []bool
+	if x[0] { //@ diag(`should use 'return !x[0]'`)
+		return false
+	}
+	return true
+}
+
+func fn13(a, b int) bool {
+	if a != b { //@ diag(`should use 'return a == b' instead of 'if a != b`)
+		return false
+	}
+	return true
+}
+
+func fn14(a, b int) bool {
+	if a >= b { //@ diag(`should use 'return a < b' instead of 'if a >= b`)
+		return false
+	}
+	return true
+}
+
+func fn15() bool {
+	if !fn() { //@ diag(`should use 'return fn()'`)
+		return false
+	}
+	return true
+}
+
+func fn16() <-chan bool {
+	x := make(chan bool, 1)
+	x <- true
+	return x
+}
+
+func fn17() bool {
+	if <-fn16() { //@ diag(`should use 'return !<-fn16()'`)
+		return false
+	}
+	return true
+}
+
+func fn18() *bool {
+	x := true
+	return &x
+}
+
+func fn19() bool {
+	if *fn18() { //@ diag(`should use 'return !*fn18()'`)
+		return false
+	}
+	return true
+}
+
+const a = true
+const b = false
+
+func fn20(x bool) bool {
+	// Don't match on constants other than the predeclared true and false. This protects us both from build tag woes,
+	// and from code that breaks when the constant values change.
+	if x {
+		return a
+	}
+	return b
+}
+
+func fn21(x bool) bool {
+	// Don't flag, 'true' isn't the predeclared identifier.
+	const true = false
+	if x {
+		return true
+	}
+	return false
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckLoopAppend/loop-append.go 2022.1.3-1/simple/testdata/src/CheckLoopAppend/loop-append.go
--- 2022.1-1/simple/testdata/src/CheckLoopAppend/loop-append.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckLoopAppend/loop-append.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,78 @@
+package pkg
+
+type T struct {
+	F string
+}
+
+func fn1() {
+	var x []interface{}
+	var y []int
+
+	for _, v := range y {
+		x = append(x, v)
+	}
+
+	var a, b []int
+	for _, v := range a { //@ diag(`should replace loop`)
+		b = append(b, v)
+	}
+
+	var m map[string]int
+	var c []int
+	for _, v := range m {
+		c = append(c, v)
+	}
+
+	var t []T
+	var m2 map[string][]T
+
+	for _, tt := range t {
+		m2[tt.F] = append(m2[tt.F], tt)
+	}
+
+	var out []T
+	for _, tt := range t {
+		out = append(m2[tt.F], tt)
+	}
+	_ = out
+}
+
+func fn2() {
+	var v struct {
+		V int
+	}
+	var in []int
+	var out []int
+
+	for _, v.V = range in {
+		out = append(out, v.V)
+	}
+}
+
+func fn3() {
+	var t []T
+	var out [][]T
+	var m2 map[string][]T
+
+	for _, tt := range t {
+		out = append(out, m2[tt.F])
+	}
+}
+
+func fn4() {
+	var a, b, c []int
+	for _, v := range a {
+		b = append(c, v)
+	}
+	_ = b
+}
+
+func fn5() {
+	var t []T
+	var m2 map[string][]T
+	var out []T
+	for _, tt := range t {
+		out = append(m2[tt.F], tt)
+	}
+	_ = out
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckLoopAppend/loop-append.go.golden 2022.1.3-1/simple/testdata/src/CheckLoopAppend/loop-append.go.golden
--- 2022.1-1/simple/testdata/src/CheckLoopAppend/loop-append.go.golden	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckLoopAppend/loop-append.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,76 @@
+package pkg
+
+type T struct {
+	F string
+}
+
+func fn1() {
+	var x []interface{}
+	var y []int
+
+	for _, v := range y {
+		x = append(x, v)
+	}
+
+	var a, b []int
+	b = append(b, a...)
+
+	var m map[string]int
+	var c []int
+	for _, v := range m {
+		c = append(c, v)
+	}
+
+	var t []T
+	var m2 map[string][]T
+
+	for _, tt := range t {
+		m2[tt.F] = append(m2[tt.F], tt)
+	}
+
+	var out []T
+	for _, tt := range t {
+		out = append(m2[tt.F], tt)
+	}
+	_ = out
+}
+
+func fn2() {
+	var v struct {
+		V int
+	}
+	var in []int
+	var out []int
+
+	for _, v.V = range in {
+		out = append(out, v.V)
+	}
+}
+
+func fn3() {
+	var t []T
+	var out [][]T
+	var m2 map[string][]T
+
+	for _, tt := range t {
+		out = append(out, m2[tt.F])
+	}
+}
+
+func fn4() {
+	var a, b, c []int
+	for _, v := range a {
+		b = append(c, v)
+	}
+	_ = b
+}
+
+func fn5() {
+	var t []T
+	var m2 map[string][]T
+	var out []T
+	for _, tt := range t {
+		out = append(m2[tt.F], tt)
+	}
+	_ = out
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckLoopCopy/copy_generics.go 2022.1.3-1/simple/testdata/src/CheckLoopCopy/copy_generics.go
--- 2022.1-1/simple/testdata/src/CheckLoopCopy/copy_generics.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckLoopCopy/copy_generics.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,127 @@
+//go:build go1.18
+
+package pkg
+
+func tpfn[T any]() {
+	var b1, b2 []T
+	for i, v := range b1 { //@ diag(`should use copy`)
+		b2[i] = v
+	}
+
+	for i := range b1 { //@ diag(`should use copy`)
+		b2[i] = b1[i]
+	}
+
+	type T2 [][16]T
+	var a T2
+	b := make([]any, len(a))
+	for i := range b {
+		b[i] = a[i]
+	}
+
+	var b3, b4 []*T
+	for i := range b3 { //@ diag(`should use copy`)
+		b4[i] = b3[i]
+	}
+
+	var m map[int]T
+	for i, v := range b1 {
+		m[i] = v
+	}
+
+}
+
+func tpsrc[T any]() []T { return nil }
+
+func tpfn1() {
+	// Don't flag this, the source is dynamic
+	var dst []any
+	for i := range tpsrc[any]() {
+		dst[i] = tpsrc[any]()[i]
+	}
+}
+
+func tpfn2[T any]() {
+	type T2 struct {
+		b []T
+	}
+
+	var src []T
+	var dst T2
+	for i, v := range src { //@ diag(`should use copy`)
+		dst.b[i] = v
+	}
+}
+
+func tpfn3[T any]() {
+	var src []T
+	var dst [][]T
+	for i, v := range src { //@ diag(`should use copy`)
+		dst[0][i] = v
+	}
+	for i, v := range src {
+		// Don't flag, destination depends on loop variable
+		dst[i][i] = v
+	}
+}
+
+func tpfn4[T any]() {
+	var b []T
+	var a1 [5]T
+	var a2 [10]T
+	var a3 [5]T
+
+	for i := range b { //@ diag(`should use copy`)
+		a1[i] = b[i]
+	}
+	for i := range a1 { //@ diag(`should use copy`)
+		b[i] = a1[i]
+	}
+	for i := range a1 { //@ diag(`should use copy`)
+		a2[i] = a1[i]
+	}
+	for i := range a1 { //@ diag(`should copy arrays using assignment`)
+		a3[i] = a1[i]
+	}
+
+	a1p := &a1
+	a2p := &a2
+	a3p := &a3
+	for i := range b { //@ diag(`should use copy`)
+		a1p[i] = b[i]
+	}
+	for i := range a1p { //@ diag(`should use copy`)
+		b[i] = a1p[i]
+	}
+	for i := range a1p { //@ diag(`should use copy`)
+		a2p[i] = a1p[i]
+	}
+	for i := range a1p { //@ diag(`should copy arrays using assignment`)
+		a3p[i] = a1p[i]
+	}
+
+	for i := range a1 { //@ diag(`should use copy`)
+		a2p[i] = a1[i]
+	}
+	for i := range a1 { //@ diag(`should copy arrays using assignment`)
+		a3p[i] = a1[i]
+	}
+	for i := range a1p { //@ diag(`should use copy`)
+		a2[i] = a1p[i]
+	}
+	for i := range a1p { //@ diag(`should copy arrays using assignment`)
+		a3[i] = a1p[i]
+	}
+}
+
+func tpfn5[T any]() {
+	var src, dst []T
+	for i := 0; i < len(src); i++ { //@ diag(`should use copy`)
+		dst[i] = src[i]
+	}
+
+	len := func([]T) int { return 0 }
+	for i := 0; i < len(src); i++ {
+		dst[i] = src[i]
+	}
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckLoopCopy/copy_generics.go.golden 2022.1.3-1/simple/testdata/src/CheckLoopCopy/copy_generics.go.golden
--- 2022.1-1/simple/testdata/src/CheckLoopCopy/copy_generics.go.golden	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckLoopCopy/copy_generics.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,91 @@
+//go:build go1.18
+
+package pkg
+
+func tpfn[T any]() {
+	var b1, b2 []T
+	copy(b2, b1)
+
+	copy(b2, b1)
+
+	type T2 [][16]T
+	var a T2
+	b := make([]any, len(a))
+	for i := range b {
+		b[i] = a[i]
+	}
+
+	var b3, b4 []*T
+	copy(b4, b3)
+
+	var m map[int]T
+	for i, v := range b1 {
+		m[i] = v
+	}
+
+}
+
+func tpsrc[T any]() []T { return nil }
+
+func tpfn1() {
+	// Don't flag this, the source is dynamic
+	var dst []any
+	for i := range tpsrc[any]() {
+		dst[i] = tpsrc[any]()[i]
+	}
+}
+
+func tpfn2[T any]() {
+	type T2 struct {
+		b []T
+	}
+
+	var src []T
+	var dst T2
+	copy(dst.b, src)
+}
+
+func tpfn3[T any]() {
+	var src []T
+	var dst [][]T
+	copy(dst[0], src)
+	for i, v := range src {
+		// Don't flag, destination depends on loop variable
+		dst[i][i] = v
+	}
+}
+
+func tpfn4[T any]() {
+	var b []T
+	var a1 [5]T
+	var a2 [10]T
+	var a3 [5]T
+
+	copy(a1[:], b)
+	copy(b, a1[:])
+	copy(a2[:], a1[:])
+	a3 = a1
+
+	a1p := &a1
+	a2p := &a2
+	a3p := &a3
+	copy(a1p[:], b)
+	copy(b, a1p[:])
+	copy(a2p[:], a1p[:])
+	*a3p = *a1p
+
+	copy(a2p[:], a1[:])
+	*a3p = a1
+	copy(a2[:], a1p[:])
+	a3 = *a1p
+}
+
+func tpfn5[T any]() {
+	var src, dst []T
+	copy(dst, src)
+
+	len := func([]T) int { return 0 }
+	for i := 0; i < len(src); i++ {
+		dst[i] = src[i]
+	}
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckLoopCopy/copy.go 2022.1.3-1/simple/testdata/src/CheckLoopCopy/copy.go
--- 2022.1-1/simple/testdata/src/CheckLoopCopy/copy.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckLoopCopy/copy.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,129 @@
+package pkg
+
+func fn() {
+	var b1, b2 []byte
+	for i, v := range b1 { //@ diag(`should use copy`)
+		b2[i] = v
+	}
+
+	for i := range b1 { //@ diag(`should use copy`)
+		b2[i] = b1[i]
+	}
+
+	type T [][16]byte
+	var a T
+	b := make([]interface{}, len(a))
+	for i := range b {
+		b[i] = a[i]
+	}
+
+	var b3, b4 []*byte
+	for i := range b3 { //@ diag(`should use copy`)
+		b4[i] = b3[i]
+	}
+
+	var m map[int]byte
+	for i, v := range b1 {
+		m[i] = v
+	}
+
+}
+
+func src() []interface{} { return nil }
+
+func fn1() {
+	// Don't flag this, the source is dynamic
+	var dst []interface{}
+	for i := range src() {
+		dst[i] = src()[i]
+	}
+}
+
+func fn2() {
+	type T struct {
+		b []byte
+	}
+
+	var src []byte
+	var dst T
+	for i, v := range src { //@ diag(`should use copy`)
+		dst.b[i] = v
+	}
+}
+
+func fn3() {
+	var src []byte
+	var dst [][]byte
+	for i, v := range src { //@ diag(`should use copy`)
+		dst[0][i] = v
+	}
+	for i, v := range src {
+		// Don't flag, destination depends on loop variable
+		dst[i][i] = v
+	}
+	for i, v := range src {
+		// Don't flag, destination depends on loop variable
+		dst[v][i] = v
+	}
+}
+
+func fn4() {
+	var b []byte
+	var a1 [5]byte
+	var a2 [10]byte
+	var a3 [5]byte
+
+	for i := range b { //@ diag(`should use copy`)
+		a1[i] = b[i]
+	}
+	for i := range a1 { //@ diag(`should use copy`)
+		b[i] = a1[i]
+	}
+	for i := range a1 { //@ diag(`should use copy`)
+		a2[i] = a1[i]
+	}
+	for i := range a1 { //@ diag(`should copy arrays using assignment`)
+		a3[i] = a1[i]
+	}
+
+	a1p := &a1
+	a2p := &a2
+	a3p := &a3
+	for i := range b { //@ diag(`should use copy`)
+		a1p[i] = b[i]
+	}
+	for i := range a1p { //@ diag(`should use copy`)
+		b[i] = a1p[i]
+	}
+	for i := range a1p { //@ diag(`should use copy`)
+		a2p[i] = a1p[i]
+	}
+	for i := range a1p { //@ diag(`should copy arrays using assignment`)
+		a3p[i] = a1p[i]
+	}
+
+	for i := range a1 { //@ diag(`should use copy`)
+		a2p[i] = a1[i]
+	}
+	for i := range a1 { //@ diag(`should copy arrays using assignment`)
+		a3p[i] = a1[i]
+	}
+	for i := range a1p { //@ diag(`should use copy`)
+		a2[i] = a1p[i]
+	}
+	for i := range a1p { //@ diag(`should copy arrays using assignment`)
+		a3[i] = a1p[i]
+	}
+}
+
+func fn5() {
+	var src, dst []byte
+	for i := 0; i < len(src); i++ { //@ diag(`should use copy`)
+		dst[i] = src[i]
+	}
+
+	len := func([]byte) int { return 0 }
+	for i := 0; i < len(src); i++ {
+		dst[i] = src[i]
+	}
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckLoopCopy/copy.go.golden 2022.1.3-1/simple/testdata/src/CheckLoopCopy/copy.go.golden
--- 2022.1-1/simple/testdata/src/CheckLoopCopy/copy.go.golden	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckLoopCopy/copy.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,93 @@
+package pkg
+
+func fn() {
+	var b1, b2 []byte
+	copy(b2, b1)
+
+	copy(b2, b1)
+
+	type T [][16]byte
+	var a T
+	b := make([]interface{}, len(a))
+	for i := range b {
+		b[i] = a[i]
+	}
+
+	var b3, b4 []*byte
+	copy(b4, b3)
+
+	var m map[int]byte
+	for i, v := range b1 {
+		m[i] = v
+	}
+
+}
+
+func src() []interface{} { return nil }
+
+func fn1() {
+	// Don't flag this, the source is dynamic
+	var dst []interface{}
+	for i := range src() {
+		dst[i] = src()[i]
+	}
+}
+
+func fn2() {
+	type T struct {
+		b []byte
+	}
+
+	var src []byte
+	var dst T
+	copy(dst.b, src)
+}
+
+func fn3() {
+	var src []byte
+	var dst [][]byte
+	copy(dst[0], src)
+	for i, v := range src {
+		// Don't flag, destination depends on loop variable
+		dst[i][i] = v
+	}
+	for i, v := range src {
+		// Don't flag, destination depends on loop variable
+		dst[v][i] = v
+	}
+}
+
+func fn4() {
+	var b []byte
+	var a1 [5]byte
+	var a2 [10]byte
+	var a3 [5]byte
+
+	copy(a1[:], b)
+	copy(b, a1[:])
+	copy(a2[:], a1[:])
+	a3 = a1
+
+	a1p := &a1
+	a2p := &a2
+	a3p := &a3
+	copy(a1p[:], b)
+	copy(b, a1p[:])
+	copy(a2p[:], a1p[:])
+	*a3p = *a1p
+
+	copy(a2p[:], a1[:])
+	*a3p = a1
+	copy(a2[:], a1p[:])
+	a3 = *a1p
+}
+
+func fn5() {
+	var src, dst []byte
+	copy(dst, src)
+
+	len := func([]byte) int { return 0 }
+	for i := 0; i < len(src); i++ {
+		dst[i] = src[i]
+	}
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckLoopSlide/generics.go 2022.1.3-1/simple/testdata/src/CheckLoopSlide/generics.go
--- 2022.1-1/simple/testdata/src/CheckLoopSlide/generics.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckLoopSlide/generics.go	2022-07-31 15:38:22.000000000 +0000
@@ -7,7 +7,7 @@ func tpfn[T []int]() {
 	var bs T
 	var offset int
 
-	for i := 0; i < n; i++ { // want `should use copy\(\) instead of loop for sliding slice elements`
+	for i := 0; i < n; i++ { //@ diag(`should use copy() instead of loop for sliding slice elements`)
 		bs[i] = bs[offset+i]
 	}
 }
diff -pruN 2022.1-1/simple/testdata/src/CheckLoopSlide/LintLoopSlide.go 2022.1.3-1/simple/testdata/src/CheckLoopSlide/LintLoopSlide.go
--- 2022.1-1/simple/testdata/src/CheckLoopSlide/LintLoopSlide.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckLoopSlide/LintLoopSlide.go	2022-07-31 15:38:22.000000000 +0000
@@ -5,7 +5,7 @@ func fn() {
 	var bs []int
 	var offset int
 
-	for i := 0; i < n; i++ { // want `should use copy\(\) instead of loop for sliding slice elements`
+	for i := 0; i < n; i++ { //@ diag(`should use copy() instead of loop for sliding slice elements`)
 		bs[i] = bs[offset+i]
 	}
 
diff -pruN 2022.1-1/simple/testdata/src/CheckMakeLenCap/CheckMakeLenCap_generics.go 2022.1.3-1/simple/testdata/src/CheckMakeLenCap/CheckMakeLenCap_generics.go
--- 2022.1-1/simple/testdata/src/CheckMakeLenCap/CheckMakeLenCap_generics.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckMakeLenCap/CheckMakeLenCap_generics.go	2022-07-31 15:38:22.000000000 +0000
@@ -3,20 +3,20 @@
 package pkg
 
 func fn1() {
-	_ = make(chan int, 0) // want `should use make\(chan int\) instead`
+	_ = make(chan int, 0) //@ diag(`should use make(chan int) instead`)
 }
 
 func fn2[T chan int]() {
-	_ = make(T, 0) // want `should use make\(T\) instead`
+	_ = make(T, 0) //@ diag(`should use make(T) instead`)
 }
 
 func fn3[T chan T]() {
-	_ = make(T, 0) // want `should use make\(T\) instead`
+	_ = make(T, 0) //@ diag(`should use make(T) instead`)
 }
 
 func fn4[T any, C chan T]() {
-	_ = make(chan T, 0) // want `should use make\(chan T\) instead`
-	_ = make(C, 0)      // want `should use make\(C\) instead`
+	_ = make(chan T, 0) //@ diag(`should use make(chan T) instead`)
+	_ = make(C, 0)      //@ diag(`should use make(C) instead`)
 }
 
 func fn5[T []int]() {
@@ -28,5 +28,5 @@ type I interface {
 }
 
 func fn6[T I]() {
-	_ = make(T, 0) // want `should use make\(T\) instead`
+	_ = make(T, 0) //@ diag(`should use make(T) instead`)
 }
diff -pruN 2022.1-1/simple/testdata/src/CheckMakeLenCap/LintMakeLenCap.go 2022.1.3-1/simple/testdata/src/CheckMakeLenCap/LintMakeLenCap.go
--- 2022.1-1/simple/testdata/src/CheckMakeLenCap/LintMakeLenCap.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckMakeLenCap/LintMakeLenCap.go	2022-07-31 15:38:22.000000000 +0000
@@ -9,11 +9,11 @@ func fn() {
 	_ = make([]int, 0)    // length is mandatory for slices, don't suggest removal
 	_ = make(s, 0)        // length is mandatory for slices, don't suggest removal
 	_ = make(chan int, c) // constant of 0 may be due to debugging, math or platform-specific code
-	_ = make(chan int, 0) // want `should use make\(chan int\) instead`
-	_ = make(ch, 0)       // want `should use make\(ch\) instead`
+	_ = make(chan int, 0) //@ diag(`should use make(chan int) instead`)
+	_ = make(ch, 0)       //@ diag(`should use make(ch) instead`)
 	_ = make(map[int]int, 0)
-	_ = make([]int, 1, 1) // want `should use make\(\[\]int, 1\) instead`
-	_ = make([]int, x, x) // want `should use make\(\[\]int, x\) instead`
+	_ = make([]int, 1, 1) //@ diag(`should use make([]int, 1) instead`)
+	_ = make([]int, x, x) //@ diag(`should use make([]int, x) instead`)
 	_ = make([]int, 1, 2)
 	_ = make([]int, x, y)
 }
diff -pruN 2022.1-1/simple/testdata/src/CheckNilCheckAroundRange/CheckNilCheckAroundRange_generics.go 2022.1.3-1/simple/testdata/src/CheckNilCheckAroundRange/CheckNilCheckAroundRange_generics.go
--- 2022.1-1/simple/testdata/src/CheckNilCheckAroundRange/CheckNilCheckAroundRange_generics.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckNilCheckAroundRange/CheckNilCheckAroundRange_generics.go	2022-07-31 15:38:22.000000000 +0000
@@ -3,21 +3,21 @@
 package pkg
 
 func _[T int | string](x []T) {
-	if x != nil { // want `unnecessary nil check around range`
+	if x != nil { //@ diag(`unnecessary nil check around range`)
 		for range x {
 		}
 	}
 }
 
 func _[T int | string, S []T](x S) {
-	if x != nil { // want `unnecessary nil check around range`
+	if x != nil { //@ diag(`unnecessary nil check around range`)
 		for range x {
 		}
 	}
 }
 
 func _[T []string](x T) {
-	if x != nil { // want `unnecessary nil check around range`
+	if x != nil { //@ diag(`unnecessary nil check around range`)
 		for range x {
 		}
 	}
diff -pruN 2022.1-1/simple/testdata/src/CheckNilCheckAroundRange/LintNilCheckAroundRange.go 2022.1.3-1/simple/testdata/src/CheckNilCheckAroundRange/LintNilCheckAroundRange.go
--- 2022.1-1/simple/testdata/src/CheckNilCheckAroundRange/LintNilCheckAroundRange.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckNilCheckAroundRange/LintNilCheckAroundRange.go	2022-07-31 15:38:22.000000000 +0000
@@ -18,14 +18,14 @@ func main() {
 		}
 	}
 
-	if str != nil { // want `unnecessary nil check around range`
+	if str != nil { //@ diag(`unnecessary nil check around range`)
 		for _, s := range str {
 			s = s + "A"
 		}
 	}
 
 	var nilMap map[string]int
-	if nilMap != nil { // want `unnecessary nil check around range`
+	if nilMap != nil { //@ diag(`unnecessary nil check around range`)
 		for key, value := range nilMap {
 			nilMap[key] = value + 1
 		}
diff -pruN 2022.1-1/simple/testdata/src/CheckPrintSprintf/CheckPrintSprintf.go 2022.1.3-1/simple/testdata/src/CheckPrintSprintf/CheckPrintSprintf.go
--- 2022.1-1/simple/testdata/src/CheckPrintSprintf/CheckPrintSprintf.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckPrintSprintf/CheckPrintSprintf.go	2022-07-31 15:38:22.000000000 +0000
@@ -7,12 +7,12 @@ import (
 )
 
 func fn() {
-	fmt.Print(fmt.Sprintf("%d", 1))         // want `should use fmt\.Printf`
-	fmt.Println(fmt.Sprintf("%d", 1))       // want `don't forget the newline`
-	fmt.Fprint(nil, fmt.Sprintf("%d", 1))   // want `should use fmt\.Fprintf`
-	fmt.Fprintln(nil, fmt.Sprintf("%d", 1)) // want `don't forget the newline`
-	fmt.Sprint(fmt.Sprintf("%d", 1))        // want `should use fmt\.Sprintf`
-	fmt.Sprintln(fmt.Sprintf("%d", 1))      // want `don't forget the newline`
+	fmt.Print(fmt.Sprintf("%d", 1))         //@ diag(`should use fmt.Printf`)
+	fmt.Println(fmt.Sprintf("%d", 1))       //@ diag(`don't forget the newline`)
+	fmt.Fprint(nil, fmt.Sprintf("%d", 1))   //@ diag(`should use fmt.Fprintf`)
+	fmt.Fprintln(nil, fmt.Sprintf("%d", 1)) //@ diag(`don't forget the newline`)
+	fmt.Sprint(fmt.Sprintf("%d", 1))        //@ diag(`should use fmt.Sprintf`)
+	fmt.Sprintln(fmt.Sprintf("%d", 1))      //@ diag(`don't forget the newline`)
 
 	arg := "%d"
 	fmt.Println(fmt.Sprintf(arg, 1))
@@ -46,55 +46,55 @@ func fn2() {
 	var tb testing.TB
 
 	// All of these are the basic cases that should be flagged
-	t.Error(fmt.Sprintf(""))  // want `use t\.Errorf\(\.\.\.\) instead of t\.Error\(fmt\.Sprintf\(\.\.\.\)\)`
-	b.Error(fmt.Sprintf(""))  // want `use b\.Errorf`
-	tb.Error(fmt.Sprintf("")) // want `use tb\.Errorf`
-	t.Fatal(fmt.Sprintf(""))  // want `use t\.Fatalf`
-	b.Fatal(fmt.Sprintf(""))  // want `use b\.Fatalf`
-	tb.Fatal(fmt.Sprintf("")) // want `use tb\.Fatalf`
-	t.Log(fmt.Sprintf(""))    // want `use t\.Logf`
-	b.Log(fmt.Sprintf(""))    // want `use b\.Logf`
-	tb.Log(fmt.Sprintf(""))   // want `use tb\.Logf`
-	t.Skip(fmt.Sprintf(""))   // want `use t\.Skipf`
-	b.Skip(fmt.Sprintf(""))   // want `use b\.Skipf`
-	tb.Skip(fmt.Sprintf(""))  // want `use tb\.Skipf`
+	t.Error(fmt.Sprintf(""))  //@ diag(`use t.Errorf(...) instead of t.Error(fmt.Sprintf(...))`)
+	b.Error(fmt.Sprintf(""))  //@ diag(`use b.Errorf`)
+	tb.Error(fmt.Sprintf("")) //@ diag(`use tb.Errorf`)
+	t.Fatal(fmt.Sprintf(""))  //@ diag(`use t.Fatalf`)
+	b.Fatal(fmt.Sprintf(""))  //@ diag(`use b.Fatalf`)
+	tb.Fatal(fmt.Sprintf("")) //@ diag(`use tb.Fatalf`)
+	t.Log(fmt.Sprintf(""))    //@ diag(`use t.Logf`)
+	b.Log(fmt.Sprintf(""))    //@ diag(`use b.Logf`)
+	tb.Log(fmt.Sprintf(""))   //@ diag(`use tb.Logf`)
+	t.Skip(fmt.Sprintf(""))   //@ diag(`use t.Skipf`)
+	b.Skip(fmt.Sprintf(""))   //@ diag(`use b.Skipf`)
+	tb.Skip(fmt.Sprintf(""))  //@ diag(`use tb.Skipf`)
 
 	var e1 Embedding1
 	var e2 Embedding2
 	var e3 Embedding3
 	var e4 Embedding4
 	// Error and Errorf are both of *testing.common -> flag
-	e1.Error(fmt.Sprintf("")) // want `use e1\.Errorf`
+	e1.Error(fmt.Sprintf("")) //@ diag(`use e1.Errorf`)
 	// Fatal and Fatalf are both of *testing.common -> flag
-	e1.Fatal(fmt.Sprintf("")) // want `use e1\.Fatalf`
+	e1.Fatal(fmt.Sprintf("")) //@ diag(`use e1.Fatalf`)
 	// Error is of *testing.common, but Errorf is Embedding2.Errorf -> don't flag
 	e2.Error(fmt.Sprintf(""))
 	// Fatal and Fatalf are both of *testing.common -> flag
-	e2.Fatal(fmt.Sprintf("")) // want `use e2\.Fatalf`
+	e2.Fatal(fmt.Sprintf("")) //@ diag(`use e2.Fatalf`)
 	// Error is Embedding3.Error and Errorf is of *testing.common -> don't flag
 	e3.Error(fmt.Sprintf(""))
 	// Fatal and Fatalf are both of *testing.common -> flag
-	e3.Fatal(fmt.Sprintf("")) // want `use e3\.Fatalf`
+	e3.Fatal(fmt.Sprintf("")) //@ diag(`use e3.Fatalf`)
 	// Error and Errorf are both of testing.TB -> flag
-	e4.Error(fmt.Sprintf("")) // want `use e4\.Errorf`
+	e4.Error(fmt.Sprintf("")) //@ diag(`use e4.Errorf`)
 	// Fatal and Fatalf are both of testing.TB -> flag
-	e4.Fatal(fmt.Sprintf("")) // want `use e4\.Fatalf`
+	e4.Fatal(fmt.Sprintf("")) //@ diag(`use e4.Fatalf`)
 
 	// Basic cases
-	log.Fatal(fmt.Sprintf(""))   // want `use log.Fatalf`
-	log.Fatalln(fmt.Sprintf("")) // want `use log.Fatalf`
-	log.Panic(fmt.Sprintf(""))   // want `use log.Panicf`
-	log.Panicln(fmt.Sprintf("")) // want `use log.Panicf`
-	log.Print(fmt.Sprintf(""))   // want `use log.Printf`
-	log.Println(fmt.Sprintf("")) // want `use log.Printf`
+	log.Fatal(fmt.Sprintf(""))   //@ diag(`use log.Fatalf`)
+	log.Fatalln(fmt.Sprintf("")) //@ diag(`use log.Fatalf`)
+	log.Panic(fmt.Sprintf(""))   //@ diag(`use log.Panicf`)
+	log.Panicln(fmt.Sprintf("")) //@ diag(`use log.Panicf`)
+	log.Print(fmt.Sprintf(""))   //@ diag(`use log.Printf`)
+	log.Println(fmt.Sprintf("")) //@ diag(`use log.Printf`)
 
 	var l *log.Logger
-	l.Fatal(fmt.Sprintf(""))   // want `use l.Fatalf\(\.\.\.\) instead of l\.Fatal\(fmt\.Sprintf\(\.\.\.\)`
-	l.Fatalln(fmt.Sprintf("")) // want `use l.Fatalf`
-	l.Panic(fmt.Sprintf(""))   // want `use l.Panicf`
-	l.Panicln(fmt.Sprintf("")) // want `use l.Panicf`
-	l.Print(fmt.Sprintf(""))   // want `use l.Printf`
-	l.Println(fmt.Sprintf("")) // want `use l.Printf`
+	l.Fatal(fmt.Sprintf(""))   //@ diag(`use l.Fatalf(...) instead of l.Fatal(fmt.Sprintf(...)`)
+	l.Fatalln(fmt.Sprintf("")) //@ diag(`use l.Fatalf`)
+	l.Panic(fmt.Sprintf(""))   //@ diag(`use l.Panicf`)
+	l.Panicln(fmt.Sprintf("")) //@ diag(`use l.Panicf`)
+	l.Print(fmt.Sprintf(""))   //@ diag(`use l.Printf`)
+	l.Println(fmt.Sprintf("")) //@ diag(`use l.Printf`)
 
 	// log.Logger and testing.T share a code path, no need to check embedding again
 }
diff -pruN 2022.1-1/simple/testdata/src/CheckRangeStringRunes/generics.go 2022.1.3-1/simple/testdata/src/CheckRangeStringRunes/generics.go
--- 2022.1-1/simple/testdata/src/CheckRangeStringRunes/generics.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckRangeStringRunes/generics.go	2022-07-31 15:38:22.000000000 +0000
@@ -3,13 +3,13 @@
 package pkg
 
 func tpfn1[T string](x T) {
-	for _, c := range []rune(x) { // want `should range over string`
+	for _, c := range []rune(x) { //@ diag(`should range over string`)
 		println(c)
 	}
 }
 
 func tpfn2[T1 string, T2 []rune](x T1) {
-	for _, c := range T2(x) { // want `should range over string`
+	for _, c := range T2(x) { //@ diag(`should range over string`)
 		println(c)
 	}
 }
diff -pruN 2022.1-1/simple/testdata/src/CheckRangeStringRunes/LintRangeStringRunes.go 2022.1.3-1/simple/testdata/src/CheckRangeStringRunes/LintRangeStringRunes.go
--- 2022.1-1/simple/testdata/src/CheckRangeStringRunes/LintRangeStringRunes.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckRangeStringRunes/LintRangeStringRunes.go	2022-07-31 15:38:22.000000000 +0000
@@ -7,7 +7,7 @@ func fn(s string, s2 String) {
 		println(r)
 	}
 
-	for _, r := range []rune(s) { // want `should range over string`
+	for _, r := range []rune(s) { //@ diag(`should range over string`)
 		println(r)
 	}
 
@@ -17,7 +17,7 @@ func fn(s string, s2 String) {
 	}
 
 	x := []rune(s)
-	for _, r := range x { // want `should range over string`
+	for _, r := range x { //@ diag(`should range over string`)
 		println(r)
 	}
 
@@ -27,7 +27,7 @@ func fn(s string, s2 String) {
 	}
 	println(y[0])
 
-	for _, r := range []rune(s2) { // want `should range over string`
+	for _, r := range []rune(s2) { //@ diag(`should range over string`)
 		println(r)
 	}
 }
diff -pruN 2022.1-1/simple/testdata/src/CheckRedundantBreak/LintRedundantBreak.go 2022.1.3-1/simple/testdata/src/CheckRedundantBreak/LintRedundantBreak.go
--- 2022.1-1/simple/testdata/src/CheckRedundantBreak/LintRedundantBreak.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckRedundantBreak/LintRedundantBreak.go	2022-07-31 15:38:22.000000000 +0000
@@ -4,7 +4,7 @@ func fn(x int) {
 	switch x {
 	case 1:
 		println()
-		break // want `redundant break`
+		break //@ diag(`redundant break`)
 	case 2:
 		println()
 	case 3:
diff -pruN 2022.1-1/simple/testdata/src/CheckRedundantCanonicalHeaderKey/LintRedundantCanonicalHeaderKey.go 2022.1.3-1/simple/testdata/src/CheckRedundantCanonicalHeaderKey/LintRedundantCanonicalHeaderKey.go
--- 2022.1-1/simple/testdata/src/CheckRedundantCanonicalHeaderKey/LintRedundantCanonicalHeaderKey.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckRedundantCanonicalHeaderKey/LintRedundantCanonicalHeaderKey.go	2022-07-31 15:38:22.000000000 +0000
@@ -9,10 +9,10 @@ func fn1() {
 	var headers http.Header
 
 	// Matches
-	headers.Add(http.CanonicalHeaderKey("test"), "test") // want `calling net/http.CanonicalHeaderKey on the 'key' argument of`
-	headers.Del(http.CanonicalHeaderKey("test"))         // want `calling net/http.CanonicalHeaderKey on the 'key' argument of`
-	headers.Get(http.CanonicalHeaderKey("test"))         // want `calling net/http.CanonicalHeaderKey on the 'key' argument of`
-	headers.Set(http.CanonicalHeaderKey("test"), "test") // want `calling net/http.CanonicalHeaderKey on the 'key' argument of`
+	headers.Add(http.CanonicalHeaderKey("test"), "test") //@ diag(`calling net/http.CanonicalHeaderKey on the 'key' argument of`)
+	headers.Del(http.CanonicalHeaderKey("test"))         //@ diag(`calling net/http.CanonicalHeaderKey on the 'key' argument of`)
+	headers.Get(http.CanonicalHeaderKey("test"))         //@ diag(`calling net/http.CanonicalHeaderKey on the 'key' argument of`)
+	headers.Set(http.CanonicalHeaderKey("test"), "test") //@ diag(`calling net/http.CanonicalHeaderKey on the 'key' argument of`)
 
 	// Non-matches
 	headers.Add("test", "test")
diff -pruN 2022.1-1/simple/testdata/src/CheckRedundantCanonicalHeaderKey/LintRedundantCanonicalHeaderKey.go.golden 2022.1.3-1/simple/testdata/src/CheckRedundantCanonicalHeaderKey/LintRedundantCanonicalHeaderKey.go.golden
--- 2022.1-1/simple/testdata/src/CheckRedundantCanonicalHeaderKey/LintRedundantCanonicalHeaderKey.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckRedundantCanonicalHeaderKey/LintRedundantCanonicalHeaderKey.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -9,10 +9,10 @@ func fn1() {
 	var headers http.Header
 
 	// Matches
-	headers.Add("test", "test") // want `calling net/http.CanonicalHeaderKey on the 'key' argument of`
-	headers.Del("test")         // want `calling net/http.CanonicalHeaderKey on the 'key' argument of`
-	headers.Get("test")         // want `calling net/http.CanonicalHeaderKey on the 'key' argument of`
-	headers.Set("test", "test") // want `calling net/http.CanonicalHeaderKey on the 'key' argument of`
+	headers.Add("test", "test") //@ diag(`calling net/http.CanonicalHeaderKey on the 'key' argument of`)
+	headers.Del("test")         //@ diag(`calling net/http.CanonicalHeaderKey on the 'key' argument of`)
+	headers.Get("test")         //@ diag(`calling net/http.CanonicalHeaderKey on the 'key' argument of`)
+	headers.Set("test", "test") //@ diag(`calling net/http.CanonicalHeaderKey on the 'key' argument of`)
 
 	// Non-matches
 	headers.Add("test", "test")
diff -pruN 2022.1-1/simple/testdata/src/CheckRedundantNilCheckWithLen/nil-len_generics.go 2022.1.3-1/simple/testdata/src/CheckRedundantNilCheckWithLen/nil-len_generics.go
--- 2022.1-1/simple/testdata/src/CheckRedundantNilCheckWithLen/nil-len_generics.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckRedundantNilCheckWithLen/nil-len_generics.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,13 @@
+//go:build go1.18
+
+package pkg
+
+func fn1[T []int | *[4]int](a T) {
+	if a != nil && len(a) > 0 { // don't flag, because of the pointer
+	}
+}
+
+func fn2[T []int | []string | map[string]int](a T) {
+	if a != nil && len(a) > 0 { //@ diag(`should omit nil check`)
+	}
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckRedundantNilCheckWithLen/nil-len.go 2022.1.3-1/simple/testdata/src/CheckRedundantNilCheckWithLen/nil-len.go
--- 2022.1-1/simple/testdata/src/CheckRedundantNilCheckWithLen/nil-len.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckRedundantNilCheckWithLen/nil-len.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,75 @@
+package pkg
+
+func fn() {
+	var pa *[5]int
+	var s []int
+	var m map[int]int
+	var ch chan int
+
+	if s == nil || len(s) == 0 { //@ diag(`should omit nil check`)
+	}
+	if m == nil || len(m) == 0 { //@ diag(`should omit nil check`)
+	}
+	if ch == nil || len(ch) == 0 { //@ diag(`should omit nil check`)
+	}
+
+	if s != nil && len(s) != 0 { //@ diag(`should omit nil check`)
+	}
+	if m != nil && len(m) > 0 { //@ diag(`should omit nil check`)
+	}
+	if s != nil && len(s) > 5 { //@ diag(`should omit nil check`)
+	}
+	if s != nil && len(s) >= 5 { //@ diag(`should omit nil check`)
+	}
+	const five = 5
+	if s != nil && len(s) == five { //@ diag(`should omit nil check`)
+	}
+
+	if ch != nil && len(ch) == 5 { //@ diag(`should omit nil check`)
+	}
+
+	if pa == nil || len(pa) == 0 { // nil check cannot be removed with pointer to an array
+	}
+	if s == nil || len(m) == 0 { // different variables
+	}
+	if s != nil && len(m) == 1 { // different variables
+	}
+
+	var ch2 chan int
+	if ch == ch2 || len(ch) == 0 { // not comparing with nil
+	}
+	if ch != ch2 && len(ch) != 0 { // not comparing with nil
+	}
+
+	const zero = 0
+	if s != nil && len(s) == zero { // nil check is not redundant here
+	}
+	if s != nil && len(s) == 0 { // nil check is not redundant here
+	}
+	if s != nil && len(s) >= 0 { // nil check is not redundant here (though len(s) >= 0 is)
+	}
+	one := 1
+	if s != nil && len(s) == one { // nil check is not redundant here
+	}
+	if s != nil && len(s) == len(m) { // nil check is not redundant here
+	}
+	if s != nil && len(s) != 1 { // nil check is not redundant here
+	}
+	if s != nil && len(s) < 5 { // nil check is not redundant here
+	}
+	if s != nil && len(s) <= 5 { // nil check is not redundant here
+	}
+	if s != nil && len(s) != len(ch) { // nil check is not redundant here
+	}
+}
+
+func fn3() {
+	var x []int
+
+	if x == nil || len(x) == 0 { //@ diag(`should omit nil check`)
+	}
+
+	len := func([]int) int { return 10 }
+	if x == nil || len(x) == 0 {
+	}
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckRedundantReturn/LintRedundantReturn.go 2022.1.3-1/simple/testdata/src/CheckRedundantReturn/LintRedundantReturn.go
--- 2022.1-1/simple/testdata/src/CheckRedundantReturn/LintRedundantReturn.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckRedundantReturn/LintRedundantReturn.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,11 +1,11 @@
 package pkg
 
 func fn1() {
-	return // want `redundant return`
+	return //@ diag(`redundant return`)
 }
 
 func fn2(a int) {
-	return // want `redundant return`
+	return //@ diag(`redundant return`)
 }
 
 func fn3() int {
@@ -30,11 +30,11 @@ func fn6() {
 func fn7() {
 	return
 	println("foo")
-	return // want `redundant return`
+	return //@ diag(`redundant return`)
 }
 
 func fn8() {
 	_ = func() {
-		return // want `redundant return`
+		return //@ diag(`redundant return`)
 	}
 }
diff -pruN 2022.1-1/simple/testdata/src/CheckRedundantSprintf/LintRedundantSprintf.go 2022.1.3-1/simple/testdata/src/CheckRedundantSprintf/LintRedundantSprintf.go
--- 2022.1-1/simple/testdata/src/CheckRedundantSprintf/LintRedundantSprintf.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckRedundantSprintf/LintRedundantSprintf.go	2022-07-31 15:38:22.000000000 +0000
@@ -39,17 +39,17 @@ func fn() {
 	var t9 T9
 	var t10 T10
 	var t11 T11
-	_ = fmt.Sprintf("%s", "test")      // want `is already a string`
-	_ = fmt.Sprintf("%s", t1)          // want `is a string`
-	_ = fmt.Sprintf("%s", t2)          // want `is a string`
-	_ = fmt.Sprintf("%s", t3)          // want `should use String\(\) instead of fmt\.Sprintf`
-	_ = fmt.Sprintf("%s", t3.String()) // want `is already a string`
+	_ = fmt.Sprintf("%s", "test")      //@ diag(`is already a string`)
+	_ = fmt.Sprintf("%s", t1)          //@ diag(`is a string`)
+	_ = fmt.Sprintf("%s", t2)          //@ diag(`is a string`)
+	_ = fmt.Sprintf("%s", t3)          //@ diag(`should use String() instead of fmt.Sprintf`)
+	_ = fmt.Sprintf("%s", t3.String()) //@ diag(`is already a string`)
 	_ = fmt.Sprintf("%s", t4)
 	_ = fmt.Sprintf("%s", t5)
 	_ = fmt.Sprintf("%s %s", t1, t2)
 	_ = fmt.Sprintf("%v", t1)
-	_ = fmt.Sprintf("%s", t6) // want `should use String\(\) instead of fmt\.Sprintf`
-	_ = fmt.Sprintf("%s", t7) // want `underlying type is a slice of bytes`
+	_ = fmt.Sprintf("%s", t6) //@ diag(`should use String() instead of fmt.Sprintf`)
+	_ = fmt.Sprintf("%s", t7) //@ diag(`underlying type is a slice of bytes`)
 	_ = fmt.Sprintf("%s", t8)
 
 	// don't simplify types that implement fmt.Formatter
diff -pruN 2022.1-1/simple/testdata/src/CheckRedundantSprintf/LintRedundantSprintf.go.golden 2022.1.3-1/simple/testdata/src/CheckRedundantSprintf/LintRedundantSprintf.go.golden
--- 2022.1-1/simple/testdata/src/CheckRedundantSprintf/LintRedundantSprintf.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckRedundantSprintf/LintRedundantSprintf.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -39,17 +39,17 @@ func fn() {
 	var t9 T9
 	var t10 T10
 	var t11 T11
-	_ = "test"      // want `is already a string`
-	_ = string(t1)  // want `is a string`
-	_ = string(t2)  // want `is a string`
-	_ = t3.String() // want `should use String\(\) instead of fmt\.Sprintf`
-	_ = t3.String() // want `is already a string`
+	_ = "test"      //@ diag(`is already a string`)
+	_ = string(t1)  //@ diag(`is a string`)
+	_ = string(t2)  //@ diag(`is a string`)
+	_ = t3.String() //@ diag(`should use String() instead of fmt.Sprintf`)
+	_ = t3.String() //@ diag(`is already a string`)
 	_ = fmt.Sprintf("%s", t4)
 	_ = fmt.Sprintf("%s", t5)
 	_ = fmt.Sprintf("%s %s", t1, t2)
 	_ = fmt.Sprintf("%v", t1)
-	_ = t6.String() // want `should use String\(\) instead of fmt\.Sprintf`
-	_ = string(t7)  // want `underlying type is a slice of bytes`
+	_ = t6.String() //@ diag(`should use String() instead of fmt.Sprintf`)
+	_ = string(t7)  //@ diag(`underlying type is a slice of bytes`)
 	_ = fmt.Sprintf("%s", t8)
 
 	// don't simplify types that implement fmt.Formatter
diff -pruN 2022.1-1/simple/testdata/src/CheckRegexpRaw/regexp-raw.go 2022.1.3-1/simple/testdata/src/CheckRegexpRaw/regexp-raw.go
--- 2022.1-1/simple/testdata/src/CheckRegexpRaw/regexp-raw.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckRegexpRaw/regexp-raw.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,19 @@
+package pkg
+
+import "regexp"
+
+func fn2() string { return "" }
+
+func fn() {
+	x := "abc"
+	const y = "abc"
+	regexp.MustCompile(`\\.`)
+	regexp.MustCompile("\\.") //@ diag(re`should use raw string.+\.MustCompile`)
+	regexp.Compile("\\.")     //@ diag(re`should use raw string.+\.Compile`)
+	regexp.Compile("\\.`")
+	regexp.MustCompile("(?m:^lease (.+?) {\n((?s).+?)\\n}\n)")
+	regexp.MustCompile("\\*/[ \t\n\r\f\v]*;")
+	regexp.MustCompile(fn2())
+	regexp.MustCompile(x)
+	regexp.MustCompile(y)
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckSameTypeTypeAssertion/CheckSameTypeTypeAssertion.go 2022.1.3-1/simple/testdata/src/CheckSameTypeTypeAssertion/CheckSameTypeTypeAssertion.go
--- 2022.1-1/simple/testdata/src/CheckSameTypeTypeAssertion/CheckSameTypeTypeAssertion.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckSameTypeTypeAssertion/CheckSameTypeTypeAssertion.go	2022-07-31 15:38:22.000000000 +0000
@@ -5,35 +5,35 @@ type SomeInterface interface {
 }
 
 func fn(x SomeInterface) {
-	_ = x.(SomeInterface)                   // want `type assertion to the same type: x already has type SomeInterface`
-	y := x.(SomeInterface)                  // want `type assertion to the same type`
-	y = x.(SomeInterface)                   // want `type assertion to the same type`
-	var a SomeInterface = x.(SomeInterface) // want `type assertion to the same type`
-	z, _ := x.(SomeInterface)               // want `type assertion to the same type`
-	z, _ = x.(SomeInterface)                // want `type assertion to the same type`
+	_ = x.(SomeInterface)                   //@ diag(`type assertion to the same type: x already has type SomeInterface`)
+	y := x.(SomeInterface)                  //@ diag(`type assertion to the same type`)
+	y = x.(SomeInterface)                   //@ diag(`type assertion to the same type`)
+	var a SomeInterface = x.(SomeInterface) //@ diag(`type assertion to the same type`)
+	z, _ := x.(SomeInterface)               //@ diag(`type assertion to the same type`)
+	z, _ = x.(SomeInterface)                //@ diag(`type assertion to the same type`)
 
-	_, ok := x.(SomeInterface) // want `type assertion to the same type`
-	_, ok = x.(SomeInterface)  // want `type assertion to the same type`
-	_, _ = x.(SomeInterface)   // want `type assertion to the same type`
+	_, ok := x.(SomeInterface) //@ diag(`type assertion to the same type`)
+	_, ok = x.(SomeInterface)  //@ diag(`type assertion to the same type`)
+	_, _ = x.(SomeInterface)   //@ diag(`type assertion to the same type`)
 
-	if z, ok := x.(SomeInterface); ok { // want `type assertion to the same type`
+	if z, ok := x.(SomeInterface); ok { //@ diag(`type assertion to the same type`)
 		_ = z
 	}
-	if _, ok := x.(SomeInterface); !ok { // want `type assertion to the same type`
+	if _, ok := x.(SomeInterface); !ok { //@ diag(`type assertion to the same type`)
 	}
-	if _, ok = x.(SomeInterface); !ok { // want `type assertion to the same type`
+	if _, ok = x.(SomeInterface); !ok { //@ diag(`type assertion to the same type`)
 	}
-	if z, ok = x.(SomeInterface); ok { // want `type assertion to the same type`
+	if z, ok = x.(SomeInterface); ok { //@ diag(`type assertion to the same type`)
 	}
-	if z := x.(SomeInterface); true { // want `type assertion to the same type`
+	if z := x.(SomeInterface); true { //@ diag(`type assertion to the same type`)
 		_ = z
 	}
-	if z, _ := x.(SomeInterface); true { // want `type assertion to the same type`
+	if z, _ := x.(SomeInterface); true { //@ diag(`type assertion to the same type`)
 		_ = z
 	}
-	if _, _ = x.(SomeInterface); true { // want `type assertion to the same type`
+	if _, _ = x.(SomeInterface); true { //@ diag(`type assertion to the same type`)
 	}
-	if _ = x.(SomeInterface); true { // want `type assertion to the same type`
+	if _ = x.(SomeInterface); true { //@ diag(`type assertion to the same type`)
 	}
 
 	switch x.(type) {
diff -pruN 2022.1-1/simple/testdata/src/CheckSimplerStructConversion/convert_generics.go 2022.1.3-1/simple/testdata/src/CheckSimplerStructConversion/convert_generics.go
--- 2022.1-1/simple/testdata/src/CheckSimplerStructConversion/convert_generics.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckSimplerStructConversion/convert_generics.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,36 @@
+//go:build go1.18
+
+package pkg
+
+type T1 struct {
+	A int
+	B int
+}
+
+type T2 struct {
+	A int
+	B int
+}
+
+type T3[T any] struct {
+	A T
+	B T
+}
+
+type T4[T any] struct {
+	A T
+	B T
+}
+
+func _() {
+	t1 := T1{0, 0}
+	t3 := T3[int]{0, 0}
+
+	_ = T2{t1.A, t1.B} //@ diag(`(type T1) to T2`)
+	_ = T2{t3.A, t3.B} //@ diag(`(type T3[int]) to T2`)
+
+	_ = T4[int]{t1.A, t1.B} //@ diag(`(type T1) to T4[int]`)
+	_ = T4[int]{t3.A, t3.B} //@ diag(`(type T3[int]) to T4[int]`)
+
+	_ = T4[any]{t3.A, t3.B}
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckSimplerStructConversion/convert_generics.go.golden 2022.1.3-1/simple/testdata/src/CheckSimplerStructConversion/convert_generics.go.golden
--- 2022.1-1/simple/testdata/src/CheckSimplerStructConversion/convert_generics.go.golden	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckSimplerStructConversion/convert_generics.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,36 @@
+//go:build go1.18
+
+package pkg
+
+type T1 struct {
+	A int
+	B int
+}
+
+type T2 struct {
+	A int
+	B int
+}
+
+type T3[T any] struct {
+	A T
+	B T
+}
+
+type T4[T any] struct {
+	A T
+	B T
+}
+
+func _() {
+	t1 := T1{0, 0}
+	t3 := T3[int]{0, 0}
+
+	_ = T2(t1) //@ diag(`(type T1) to T2`)
+	_ = T2(t3) //@ diag(`(type T3[int]) to T2`)
+
+	_ = T4[int](t1) //@ diag(`(type T1) to T4[int]`)
+	_ = T4[int](t3) //@ diag(`(type T3[int]) to T4[int]`)
+
+	_ = T4[any]{t3.A, t3.B}
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckSimplerStructConversion/convert.go 2022.1.3-1/simple/testdata/src/CheckSimplerStructConversion/convert.go
--- 2022.1-1/simple/testdata/src/CheckSimplerStructConversion/convert.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckSimplerStructConversion/convert.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,32 @@
+package pkg
+
+type t1 struct {
+	a int
+	b int
+}
+
+type t2 struct {
+	a int
+	b int
+}
+
+type t3 t1
+
+func fn() {
+	v1 := t1{1, 2}
+	v2 := t2{1, 2}
+	_ = t2{v1.a, v1.b}       //@ diag(`should convert v1`)
+	_ = t2{a: v1.a, b: v1.b} //@ diag(`should convert v1`)
+	_ = t2{b: v1.b, a: v1.a} //@ diag(`should convert v1`)
+	_ = t3{v1.a, v1.b}       //@ diag(`should convert v1`)
+
+	_ = t3{v1.a, v2.b}
+
+	_ = t2{v1.b, v1.a}
+	_ = t2{a: v1.b, b: v1.a}
+	_ = t2{a: v1.a}
+	_ = t1{v1.a, v1.b}
+
+	v := t1{1, 2}
+	_ = &t2{v.a, v.b}
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckSimplerStructConversion/convert.go.golden 2022.1.3-1/simple/testdata/src/CheckSimplerStructConversion/convert.go.golden
--- 2022.1-1/simple/testdata/src/CheckSimplerStructConversion/convert.go.golden	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckSimplerStructConversion/convert.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,32 @@
+package pkg
+
+type t1 struct {
+	a int
+	b int
+}
+
+type t2 struct {
+	a int
+	b int
+}
+
+type t3 t1
+
+func fn() {
+	v1 := t1{1, 2}
+	v2 := t2{1, 2}
+	_ = t2(v1) //@ diag(`should convert v1`)
+	_ = t2(v1) //@ diag(`should convert v1`)
+	_ = t2(v1) //@ diag(`should convert v1`)
+	_ = t3(v1) //@ diag(`should convert v1`)
+
+	_ = t3{v1.a, v2.b}
+
+	_ = t2{v1.b, v1.a}
+	_ = t2{a: v1.b, b: v1.a}
+	_ = t2{a: v1.a}
+	_ = t1{v1.a, v1.b}
+
+	v := t1{1, 2}
+	_ = &t2{v.a, v.b}
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckSimplerStructConversion_go17/convert.go 2022.1.3-1/simple/testdata/src/CheckSimplerStructConversion_go17/convert.go
--- 2022.1-1/simple/testdata/src/CheckSimplerStructConversion_go17/convert.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckSimplerStructConversion_go17/convert.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,22 @@
+package pkg
+
+type t1 struct {
+	a int
+	b int
+}
+
+type t2 struct {
+	a int
+	b int
+}
+
+type t3 struct {
+	a int `tag`
+	b int `tag`
+}
+
+func fn() {
+	v1 := t1{1, 2}
+	_ = t2{v1.a, v1.b} //@ diag(`should convert v1`)
+	_ = t3{v1.a, v1.b}
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckSimplerStructConversion_go17/convert.go.golden 2022.1.3-1/simple/testdata/src/CheckSimplerStructConversion_go17/convert.go.golden
--- 2022.1-1/simple/testdata/src/CheckSimplerStructConversion_go17/convert.go.golden	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckSimplerStructConversion_go17/convert.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,22 @@
+package pkg
+
+type t1 struct {
+	a int
+	b int
+}
+
+type t2 struct {
+	a int
+	b int
+}
+
+type t3 struct {
+	a int `tag`
+	b int `tag`
+}
+
+func fn() {
+	v1 := t1{1, 2}
+	_ = t2(v1) //@ diag(`should convert v1`)
+	_ = t3{v1.a, v1.b}
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckSimplerStructConversion_go18/convert.go 2022.1.3-1/simple/testdata/src/CheckSimplerStructConversion_go18/convert.go
--- 2022.1-1/simple/testdata/src/CheckSimplerStructConversion_go18/convert.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckSimplerStructConversion_go18/convert.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,22 @@
+package pkg
+
+type t1 struct {
+	a int
+	b int
+}
+
+type t2 struct {
+	a int
+	b int
+}
+
+type t3 struct {
+	a int `tag`
+	b int `tag`
+}
+
+func fn() {
+	v1 := t1{1, 2}
+	_ = t2{v1.a, v1.b} //@ diag(`should convert v1`)
+	_ = t3{v1.a, v1.b} //@ diag(`should convert v1`)
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckSimplerStructConversion_go18/convert.go.golden 2022.1.3-1/simple/testdata/src/CheckSimplerStructConversion_go18/convert.go.golden
--- 2022.1-1/simple/testdata/src/CheckSimplerStructConversion_go18/convert.go.golden	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckSimplerStructConversion_go18/convert.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,22 @@
+package pkg
+
+type t1 struct {
+	a int
+	b int
+}
+
+type t2 struct {
+	a int
+	b int
+}
+
+type t3 struct {
+	a int `tag`
+	b int `tag`
+}
+
+func fn() {
+	v1 := t1{1, 2}
+	_ = t2(v1) //@ diag(`should convert v1`)
+	_ = t3(v1) //@ diag(`should convert v1`)
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckSimplifyTypeSwitch/LintSimplifyTypeSwitch.go 2022.1.3-1/simple/testdata/src/CheckSimplifyTypeSwitch/LintSimplifyTypeSwitch.go
--- 2022.1-1/simple/testdata/src/CheckSimplifyTypeSwitch/LintSimplifyTypeSwitch.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckSimplifyTypeSwitch/LintSimplifyTypeSwitch.go	2022-07-31 15:38:22.000000000 +0000
@@ -14,7 +14,7 @@ func fn(x, y interface{}) {
 	case int:
 		fmt.Println(x.(int), y.(int))
 	}
-	switch x.(type) { // want `assigning the result of this type assertion`
+	switch x.(type) { //@ diag(`assigning the result of this type assertion`)
 	case int:
 		fmt.Println(x.(int))
 	}
diff -pruN 2022.1-1/simple/testdata/src/CheckSimplifyTypeSwitch/LintSimplifyTypeSwitch.go.golden 2022.1.3-1/simple/testdata/src/CheckSimplifyTypeSwitch/LintSimplifyTypeSwitch.go.golden
--- 2022.1-1/simple/testdata/src/CheckSimplifyTypeSwitch/LintSimplifyTypeSwitch.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckSimplifyTypeSwitch/LintSimplifyTypeSwitch.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -14,7 +14,7 @@ func fn(x, y interface{}) {
 	case int:
 		fmt.Println(x.(int), y.(int))
 	}
-	switch x := x.(type) { // want `assigning the result of this type assertion`
+	switch x := x.(type) { //@ diag(`assigning the result of this type assertion`)
 	case int:
 		fmt.Println(x)
 	}
diff -pruN 2022.1-1/simple/testdata/src/CheckSingleCaseSelect/single-case-select.go 2022.1.3-1/simple/testdata/src/CheckSingleCaseSelect/single-case-select.go
--- 2022.1-1/simple/testdata/src/CheckSingleCaseSelect/single-case-select.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckSingleCaseSelect/single-case-select.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,28 @@
+package pkg
+
+func fn() {
+	var ch chan int
+	select { //@ diag(`should use a simple channel send`)
+	case <-ch:
+	}
+outer:
+	for { //@ diag(`should use for range`)
+		select {
+		case <-ch:
+			break outer
+		}
+	}
+
+	for { //@ diag(`should use for range`)
+		select {
+		case x := <-ch:
+			_ = x
+		}
+	}
+
+	for {
+		select { //@ diag(`should use a simple channel send`)
+		case ch <- 0:
+		}
+	}
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckSlicing/slicing.go 2022.1.3-1/simple/testdata/src/CheckSlicing/slicing.go
--- 2022.1-1/simple/testdata/src/CheckSlicing/slicing.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckSlicing/slicing.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,9 @@
+package pkg
+
+func fn() {
+	var s [5]int
+	_ = s[:len(s)] //@ diag(`omit second index`)
+
+	len := func(s [5]int) int { return -1 }
+	_ = s[:len(s)]
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckSlicing/slicing.go.golden 2022.1.3-1/simple/testdata/src/CheckSlicing/slicing.go.golden
--- 2022.1-1/simple/testdata/src/CheckSlicing/slicing.go.golden	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckSlicing/slicing.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,9 @@
+package pkg
+
+func fn() {
+	var s [5]int
+	_ = s[:] //@ diag(`omit second index`)
+
+	len := func(s [5]int) int { return -1 }
+	_ = s[:len(s)]
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckSortHelpers/LintSortHelpers.go 2022.1.3-1/simple/testdata/src/CheckSortHelpers/LintSortHelpers.go
--- 2022.1-1/simple/testdata/src/CheckSortHelpers/LintSortHelpers.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckSortHelpers/LintSortHelpers.go	2022-07-31 15:38:22.000000000 +0000
@@ -10,17 +10,17 @@ func (s MyIntSlice) Swap(i, j int)
 
 func fn1() {
 	var a []int
-	sort.Sort(sort.IntSlice(a)) // want `sort\.Ints`
+	sort.Sort(sort.IntSlice(a)) //@ diag(`sort.Ints`)
 }
 
 func fn2() {
 	var b []float64
-	sort.Sort(sort.Float64Slice(b)) // want `sort\.Float64s`
+	sort.Sort(sort.Float64Slice(b)) //@ diag(`sort.Float64s`)
 }
 
 func fn3() {
 	var c []string
-	sort.Sort(sort.StringSlice(c)) // want `sort\.Strings`
+	sort.Sort(sort.StringSlice(c)) //@ diag(`sort.Strings`)
 }
 
 func fn4() {
@@ -49,18 +49,18 @@ func fn7() {
 
 func fn8() {
 	var a []int
-	sort.Sort(sort.IntSlice(a)) // want `sort\.Ints`
-	sort.Sort(sort.IntSlice(a)) // want `sort\.Ints`
+	sort.Sort(sort.IntSlice(a)) //@ diag(`sort.Ints`)
+	sort.Sort(sort.IntSlice(a)) //@ diag(`sort.Ints`)
 }
 
 func fn9() {
 	func() {
 		var a []int
-		sort.Sort(sort.IntSlice(a)) // want `sort\.Ints`
+		sort.Sort(sort.IntSlice(a)) //@ diag(`sort.Ints`)
 	}()
 }
 
 func fn10() {
 	var a MyIntSlice
-	sort.Sort(sort.IntSlice(a)) // want `sort\.Ints`
+	sort.Sort(sort.IntSlice(a)) //@ diag(`sort.Ints`)
 }
diff -pruN 2022.1-1/simple/testdata/src/CheckSprintLiteral/CheckSprintLiteral.go 2022.1.3-1/simple/testdata/src/CheckSprintLiteral/CheckSprintLiteral.go
--- 2022.1-1/simple/testdata/src/CheckSprintLiteral/CheckSprintLiteral.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckSprintLiteral/CheckSprintLiteral.go	2022-07-31 15:38:22.000000000 +0000
@@ -3,8 +3,8 @@ package pkg
 import "fmt"
 
 func fn() {
-	_ = fmt.Sprint("foo")  // want `unnecessary use of fmt\.Sprint`
-	_ = fmt.Sprintf("foo") // want `unnecessary use of fmt\.Sprintf`
+	_ = fmt.Sprint("foo")  //@ diag(`unnecessary use of fmt.Sprint`)
+	_ = fmt.Sprintf("foo") //@ diag(`unnecessary use of fmt.Sprintf`)
 	_ = fmt.Sprintf("foo %d")
 	_ = fmt.Sprintf("foo %d", 1)
 
diff -pruN 2022.1-1/simple/testdata/src/CheckSprintLiteral/CheckSprintLiteral.go.golden 2022.1.3-1/simple/testdata/src/CheckSprintLiteral/CheckSprintLiteral.go.golden
--- 2022.1-1/simple/testdata/src/CheckSprintLiteral/CheckSprintLiteral.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckSprintLiteral/CheckSprintLiteral.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -3,8 +3,8 @@ package pkg
 import "fmt"
 
 func fn() {
-	_ = "foo" // want `unnecessary use of fmt\.Sprint`
-	_ = "foo" // want `unnecessary use of fmt\.Sprintf`
+	_ = "foo" //@ diag(`unnecessary use of fmt.Sprint`)
+	_ = "foo" //@ diag(`unnecessary use of fmt.Sprintf`)
 	_ = fmt.Sprintf("foo %d")
 	_ = fmt.Sprintf("foo %d", 1)
 
diff -pruN 2022.1-1/simple/testdata/src/CheckStringsContains/contains.go 2022.1.3-1/simple/testdata/src/CheckStringsContains/contains.go
--- 2022.1-1/simple/testdata/src/CheckStringsContains/contains.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckStringsContains/contains.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,39 @@
+package pkg
+
+import (
+	"bytes"
+	"strings"
+)
+
+func fn() {
+	_ = strings.IndexRune("", 'x') > -1 //@ diag(` strings.ContainsRune`)
+	_ = strings.IndexRune("", 'x') >= 0 //@ diag(` strings.ContainsRune`)
+	_ = strings.IndexRune("", 'x') > 0
+	_ = strings.IndexRune("", 'x') >= -1
+	_ = strings.IndexRune("", 'x') != -1 //@ diag(` strings.ContainsRune`)
+	_ = strings.IndexRune("", 'x') == -1 //@ diag(`!strings.ContainsRune`)
+	_ = strings.IndexRune("", 'x') != 0
+	_ = strings.IndexRune("", 'x') < 0 //@ diag(`!strings.ContainsRune`)
+
+	_ = strings.IndexAny("", "") > -1 //@ diag(` strings.ContainsAny`)
+	_ = strings.IndexAny("", "") >= 0 //@ diag(` strings.ContainsAny`)
+	_ = strings.IndexAny("", "") > 0
+	_ = strings.IndexAny("", "") >= -1
+	_ = strings.IndexAny("", "") != -1 //@ diag(` strings.ContainsAny`)
+	_ = strings.IndexAny("", "") == -1 //@ diag(`!strings.ContainsAny`)
+	_ = strings.IndexAny("", "") != 0
+	_ = strings.IndexAny("", "") < 0 //@ diag(`!strings.ContainsAny`)
+
+	_ = strings.Index("", "") > -1 //@ diag(` strings.Contains`)
+	_ = strings.Index("", "") >= 0 //@ diag(` strings.Contains`)
+	_ = strings.Index("", "") > 0
+	_ = strings.Index("", "") >= -1
+	_ = strings.Index("", "") != -1 //@ diag(` strings.Contains`)
+	_ = strings.Index("", "") == -1 //@ diag(`!strings.Contains`)
+	_ = strings.Index("", "") != 0
+	_ = strings.Index("", "") < 0 //@ diag(`!strings.Contains`)
+
+	_ = bytes.IndexRune(nil, 'x') > -1 //@ diag(` bytes.ContainsRune`)
+	_ = bytes.IndexAny(nil, "") > -1   //@ diag(` bytes.ContainsAny`)
+	_ = bytes.Index(nil, nil) > -1     //@ diag(` bytes.Contains`)
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckStringsContains/contains.go.golden 2022.1.3-1/simple/testdata/src/CheckStringsContains/contains.go.golden
--- 2022.1-1/simple/testdata/src/CheckStringsContains/contains.go.golden	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckStringsContains/contains.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,39 @@
+package pkg
+
+import (
+	"bytes"
+	"strings"
+)
+
+func fn() {
+	_ = strings.ContainsRune("", 'x') //@ diag(` strings.ContainsRune`)
+	_ = strings.ContainsRune("", 'x') //@ diag(` strings.ContainsRune`)
+	_ = strings.IndexRune("", 'x') > 0
+	_ = strings.IndexRune("", 'x') >= -1
+	_ = strings.ContainsRune("", 'x')  //@ diag(` strings.ContainsRune`)
+	_ = !strings.ContainsRune("", 'x') //@ diag(`!strings.ContainsRune`)
+	_ = strings.IndexRune("", 'x') != 0
+	_ = !strings.ContainsRune("", 'x') //@ diag(`!strings.ContainsRune`)
+
+	_ = strings.ContainsAny("", "") //@ diag(` strings.ContainsAny`)
+	_ = strings.ContainsAny("", "") //@ diag(` strings.ContainsAny`)
+	_ = strings.IndexAny("", "") > 0
+	_ = strings.IndexAny("", "") >= -1
+	_ = strings.ContainsAny("", "")  //@ diag(` strings.ContainsAny`)
+	_ = !strings.ContainsAny("", "") //@ diag(`!strings.ContainsAny`)
+	_ = strings.IndexAny("", "") != 0
+	_ = !strings.ContainsAny("", "") //@ diag(`!strings.ContainsAny`)
+
+	_ = strings.Contains("", "") //@ diag(` strings.Contains`)
+	_ = strings.Contains("", "") //@ diag(` strings.Contains`)
+	_ = strings.Index("", "") > 0
+	_ = strings.Index("", "") >= -1
+	_ = strings.Contains("", "")  //@ diag(` strings.Contains`)
+	_ = !strings.Contains("", "") //@ diag(`!strings.Contains`)
+	_ = strings.Index("", "") != 0
+	_ = !strings.Contains("", "") //@ diag(`!strings.Contains`)
+
+	_ = bytes.ContainsRune(nil, 'x') //@ diag(` bytes.ContainsRune`)
+	_ = bytes.ContainsAny(nil, "")   //@ diag(` bytes.ContainsAny`)
+	_ = bytes.Contains(nil, nil)     //@ diag(` bytes.Contains`)
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckTimeSince/time-since.go 2022.1.3-1/simple/testdata/src/CheckTimeSince/time-since.go
--- 2022.1-1/simple/testdata/src/CheckTimeSince/time-since.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckTimeSince/time-since.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,9 @@
+package pkg
+
+import "time"
+
+func fn() {
+	t1 := time.Now()
+	_ = time.Now().Sub(t1) //@ diag(`time.Since`)
+	_ = time.Date(0, 0, 0, 0, 0, 0, 0, nil).Sub(t1)
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckTimeSince/time-since.go.golden 2022.1.3-1/simple/testdata/src/CheckTimeSince/time-since.go.golden
--- 2022.1-1/simple/testdata/src/CheckTimeSince/time-since.go.golden	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckTimeSince/time-since.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,9 @@
+package pkg
+
+import "time"
+
+func fn() {
+	t1 := time.Now()
+	_ = time.Since(t1) //@ diag(`time.Since`)
+	_ = time.Date(0, 0, 0, 0, 0, 0, 0, nil).Sub(t1)
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckTimeUntil_go18/LimeTimeUntil_go18.go 2022.1.3-1/simple/testdata/src/CheckTimeUntil_go18/LimeTimeUntil_go18.go
--- 2022.1-1/simple/testdata/src/CheckTimeUntil_go18/LimeTimeUntil_go18.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckTimeUntil_go18/LimeTimeUntil_go18.go	2022-07-31 15:38:22.000000000 +0000
@@ -3,7 +3,7 @@ package pkg
 import "time"
 
 func fn(t time.Time) {
-	t.Sub(time.Now()) // want `time\.Until`
+	t.Sub(time.Now()) //@ diag(`time.Until`)
 	t.Sub(t)
 	t2 := time.Now()
 	t.Sub(t2)
diff -pruN 2022.1-1/simple/testdata/src/CheckTimeUntil_go18/LimeTimeUntil_go18.go.golden 2022.1.3-1/simple/testdata/src/CheckTimeUntil_go18/LimeTimeUntil_go18.go.golden
--- 2022.1-1/simple/testdata/src/CheckTimeUntil_go18/LimeTimeUntil_go18.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckTimeUntil_go18/LimeTimeUntil_go18.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -3,7 +3,7 @@ package pkg
 import "time"
 
 func fn(t time.Time) {
-	time.Until(t) // want `time\.Until`
+	time.Until(t) //@ diag(`time.Until`)
 	t.Sub(t)
 	t2 := time.Now()
 	t.Sub(t2)
diff -pruN 2022.1-1/simple/testdata/src/CheckTrim/trim.go 2022.1.3-1/simple/testdata/src/CheckTrim/trim.go
--- 2022.1-1/simple/testdata/src/CheckTrim/trim.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckTrim/trim.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,184 @@
+package pkg
+
+import (
+	"bytes"
+	"strings"
+)
+
+func foo(s string) int { return 0 }
+func gen() string {
+	return ""
+}
+
+func fn() {
+	const s1 = "a string value"
+	var s2 = "a string value"
+	const n = 14
+
+	var id1 = "a string value"
+	var id2 string
+	if strings.HasPrefix(id1, s1) { //@ diag(re`should replace.*with.*strings\.TrimPrefix`)
+		id1 = id1[len(s1):]
+	}
+
+	if strings.HasPrefix(id1, s1) { //@ diag(re`should replace.*with.*strings\.TrimPrefix`)
+		id1 = strings.TrimPrefix(id1, s1)
+	}
+
+	if strings.HasPrefix(id1, s1) {
+		id1 = strings.TrimPrefix(id1, s2)
+	}
+
+	if strings.Contains(id1, s1) { //@ diag(re`should replace.*with.*strings\.Replace`)
+		id1 = strings.Replace(id1, s1, "something", 123)
+	}
+
+	if strings.HasSuffix(id1, s2) { //@ diag(re`should replace.*with.*strings\.TrimSuffix`)
+		id1 = id1[:len(id1)-len(s2)]
+	}
+
+	var x, y []string
+	var i int
+	if strings.HasPrefix(x[i], s1) { //@ diag(re`should replace.*with.*strings\.TrimPrefix`)
+		x[i] = x[i][len(s1):]
+	}
+
+	if strings.HasPrefix(x[i], y[i]) { //@ diag(re`should replace.*with.*strings\.TrimPrefix`)
+		x[i] = x[i][len(y[i]):]
+	}
+
+	var t struct{ x string }
+	if strings.HasPrefix(t.x, s1) { //@ diag(re`should replace.*with.*strings\.TrimPrefix`)
+		t.x = t.x[len(s1):]
+	}
+
+	if strings.HasPrefix(id1, "test") { //@ diag(re`should replace.*with.*strings\.TrimPrefix`)
+		id1 = id1[len("test"):]
+	}
+
+	if strings.HasPrefix(id1, "test") { //@ diag(re`should replace.*with.*strings\.TrimPrefix`)
+		id1 = id1[4:]
+	}
+
+	if strings.HasPrefix(id1, s1) { // not allowed, 14 and s1 aren't obviously connected
+		id1 = id1[14:]
+	}
+
+	if strings.HasPrefix(id1, s1) { // not allowed, s1 and n aren't obviously connected
+		id1 = id1[n:]
+	}
+
+	var b1, b2 []byte
+	if bytes.HasPrefix(b1, b2) { //@ diag(re`should replace.*with.*bytes\.TrimPrefix`)
+		b1 = b1[len(b2):]
+	}
+
+	id3 := s2
+	if strings.HasPrefix(id1, id3) { //@ diag(re`should replace.*with.*strings\.TrimPrefix`)
+		id1 = id1[len(id3):]
+	}
+
+	if strings.HasSuffix(id1, s2) {
+		id1 = id1[:len(id1)+len(s2)] // wrong operator
+	}
+
+	if strings.HasSuffix(id1, s2) {
+		id1 = id1[:len(s2)-len(id1)] // wrong math
+	}
+
+	if strings.HasSuffix(id1, s2) {
+		id1 = id1[:len(id1)-len(id1)] // wrong string length
+	}
+
+	if strings.HasPrefix(id1, gen()) {
+		id1 = id1[len(gen()):] // dynamic id3
+	}
+
+	if strings.HasPrefix(id1, s1) {
+		id1 = id1[foo(s1):] // wrong function
+	}
+
+	if strings.HasPrefix(id1, s1) {
+		id1 = id1[len(id1):] // len() on wrong value
+	}
+
+	if strings.HasPrefix(id1, "test") {
+		id1 = id1[5:] // wrong length
+	}
+
+	if strings.HasPrefix(id1, s1) {
+		id1 = id1[len(s1)+1:] // wrong length due to math
+	}
+
+	if strings.HasPrefix(id1, s1) {
+		id2 = id1[len(s1):] // assigning to the wrong variable
+	}
+
+	if strings.HasPrefix(id1, s1) {
+		id1 = id1[len(s1):15] // has a max
+	}
+
+	if strings.HasPrefix(id1, s1) {
+		id1 = id2[len(s1):] // assigning the wrong value
+	}
+
+	if strings.HasPrefix(id1, s1) {
+		id1 = id1[len(s1):]
+		id1 += "" // doing more work in the if
+	}
+
+	if strings.HasPrefix(id1, s1) {
+		id1 = id1[len(s1):]
+	} else {
+		id1 = "game over" // else branch
+	}
+
+	if strings.HasPrefix(id1, s1) {
+		// the conditional is guarding additional code
+		id1 = id1[len(s1):]
+		println(id1)
+	}
+
+	if strings.Contains(id1, s1) {
+		id1 = id1[:]
+	}
+}
+
+func fn2() {
+	var s string
+	const id = ".json"
+
+	if strings.HasSuffix(s, ".json") { //@ diag(re`should replace.*with.*strings\.TrimSuffix`)
+		s = strings.TrimSuffix(s, ".json")
+	}
+
+	if strings.HasSuffix(s, ".json") { //@ diag(re`should replace.*with.*strings\.TrimSuffix`)
+		s = s[:len(s)-len(".json")]
+	}
+
+	if strings.HasSuffix(s, ".json") { //@ diag(re`should replace.*with.*strings\.TrimSuffix`)
+		s = s[:len(s)-5]
+	}
+
+	if strings.HasSuffix(s, id) {
+		s = s[:len(s)-5] // second argument of HasSuffix it not a string literal
+	}
+
+	if strings.HasSuffix(s, ".json") {
+		s = s[:len(s)-4] // wrong length
+	}
+}
+
+func fn3() {
+	const s1 = "a string value"
+
+	var id1 = "a string value"
+	len := func(string) int { return 0 } // don't accept non-builtin definition of len
+	if strings.HasPrefix(id1, s1) {
+		id1 = id1[len(s1):]
+	}
+
+	if strings.HasSuffix(id1, s1) {
+		id1 = id1[:len(id1)-len(s1)]
+	}
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckUnnecessaryBlank/LintBlankOK.go 2022.1.3-1/simple/testdata/src/CheckUnnecessaryBlank/LintBlankOK.go
--- 2022.1-1/simple/testdata/src/CheckUnnecessaryBlank/LintBlankOK.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckUnnecessaryBlank/LintBlankOK.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,12 @@
+package pkg
+
+func fn() {
+	var m map[int]int
+	var ch chan int
+	var fn func() (int, bool)
+
+	x, _ := m[0] //@ diag(`unnecessary assignment to the blank identifier`)
+	x, _ = <-ch  //@ diag(`unnecessary assignment to the blank identifier`)
+	x, _ = fn()
+	_ = x
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckUnnecessaryBlank/LintBlankOK.go.golden 2022.1.3-1/simple/testdata/src/CheckUnnecessaryBlank/LintBlankOK.go.golden
--- 2022.1-1/simple/testdata/src/CheckUnnecessaryBlank/LintBlankOK.go.golden	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckUnnecessaryBlank/LintBlankOK.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,12 @@
+package pkg
+
+func fn() {
+	var m map[int]int
+	var ch chan int
+	var fn func() (int, bool)
+
+	x := m[0] //@ diag(`unnecessary assignment to the blank identifier`)
+	x = <-ch  //@ diag(`unnecessary assignment to the blank identifier`)
+	x, _ = fn()
+	_ = x
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckUnnecessaryBlank/receive-blank.go 2022.1.3-1/simple/testdata/src/CheckUnnecessaryBlank/receive-blank.go
--- 2022.1-1/simple/testdata/src/CheckUnnecessaryBlank/receive-blank.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckUnnecessaryBlank/receive-blank.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,15 @@
+package pkg
+
+func fn2() {
+	var ch chan int
+	<-ch
+	_ = <-ch //@ diag(`unnecessary assignment to the blank identifier`)
+	select {
+	case <-ch:
+	case _ = <-ch: //@ diag(`unnecessary assignment to the blank identifier`)
+	}
+	x := <-ch
+	y, _ := <-ch, <-ch
+	_, z := <-ch, <-ch
+	_, _, _ = x, y, z
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckUnnecessaryBlank/receive-blank.go.golden 2022.1.3-1/simple/testdata/src/CheckUnnecessaryBlank/receive-blank.go.golden
--- 2022.1-1/simple/testdata/src/CheckUnnecessaryBlank/receive-blank.go.golden	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckUnnecessaryBlank/receive-blank.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,15 @@
+package pkg
+
+func fn2() {
+	var ch chan int
+	<-ch
+	<-ch //@ diag(`unnecessary assignment to the blank identifier`)
+	select {
+	case <-ch:
+	case <-ch: //@ diag(`unnecessary assignment to the blank identifier`)
+	}
+	x := <-ch
+	y, _ := <-ch, <-ch
+	_, z := <-ch, <-ch
+	_, _, _ = x, y, z
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckUnnecessaryBlank_go13/range_go13.go 2022.1.3-1/simple/testdata/src/CheckUnnecessaryBlank_go13/range_go13.go
--- 2022.1-1/simple/testdata/src/CheckUnnecessaryBlank_go13/range_go13.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckUnnecessaryBlank_go13/range_go13.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,34 @@
+package pkg
+
+func fn() {
+	var m map[string]int
+
+	// with :=
+	for x, _ := range m {
+		_ = x
+	}
+	// with =
+	var y string
+	_ = y
+	for y, _ = range m {
+	}
+
+	// all OK:
+	for x := range m {
+		_ = x
+	}
+	for x, y := range m {
+		_, _ = x, y
+	}
+	for _, y := range m {
+		_ = y
+	}
+	var x int
+	_ = x
+	for y = range m {
+	}
+	for y, x = range m {
+	}
+	for _, x = range m {
+	}
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckUnnecessaryBlank_go14/range_go14.go 2022.1.3-1/simple/testdata/src/CheckUnnecessaryBlank_go14/range_go14.go
--- 2022.1-1/simple/testdata/src/CheckUnnecessaryBlank_go14/range_go14.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckUnnecessaryBlank_go14/range_go14.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,40 @@
+package pkg
+
+func fn() {
+	var m map[string]int
+
+	// with :=
+	for x, _ := range m { //@ diag(`unnecessary assignment to the blank identifier`)
+		_ = x
+	}
+	// with =
+	var y string
+	_ = y
+	for y, _ = range m { //@ diag(`unnecessary assignment to the blank identifier`)
+	}
+
+	for _ = range m { //@ diag(`unnecessary assignment to the blank identifier`)
+	}
+
+	for _, _ = range m { //@ diag(`unnecessary assignment to the blank identifier`)
+	}
+
+	// all OK:
+	for x := range m {
+		_ = x
+	}
+	for x, y := range m {
+		_, _ = x, y
+	}
+	for _, y := range m {
+		_ = y
+	}
+	var x int
+	_ = x
+	for y = range m {
+	}
+	for y, x = range m {
+	}
+	for _, x = range m {
+	}
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckUnnecessaryBlank_go14/range_go14.go.golden 2022.1.3-1/simple/testdata/src/CheckUnnecessaryBlank_go14/range_go14.go.golden
--- 2022.1-1/simple/testdata/src/CheckUnnecessaryBlank_go14/range_go14.go.golden	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckUnnecessaryBlank_go14/range_go14.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,40 @@
+package pkg
+
+func fn() {
+	var m map[string]int
+
+	// with :=
+	for x := range m { //@ diag(`unnecessary assignment to the blank identifier`)
+		_ = x
+	}
+	// with =
+	var y string
+	_ = y
+	for y = range m { //@ diag(`unnecessary assignment to the blank identifier`)
+	}
+
+	for range m { //@ diag(`unnecessary assignment to the blank identifier`)
+	}
+
+	for range m { //@ diag(`unnecessary assignment to the blank identifier`)
+	}
+
+	// all OK:
+	for x := range m {
+		_ = x
+	}
+	for x, y := range m {
+		_, _ = x, y
+	}
+	for _, y := range m {
+		_ = y
+	}
+	var x int
+	_ = x
+	for y = range m {
+	}
+	for y, x = range m {
+	}
+	for _, x = range m {
+	}
+}
diff -pruN 2022.1-1/simple/testdata/src/CheckUnnecessaryGuard/LintUnnecessaryGuard.go 2022.1.3-1/simple/testdata/src/CheckUnnecessaryGuard/LintUnnecessaryGuard.go
--- 2022.1-1/simple/testdata/src/CheckUnnecessaryGuard/LintUnnecessaryGuard.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/CheckUnnecessaryGuard/LintUnnecessaryGuard.go	2022-07-31 15:38:22.000000000 +0000
@@ -3,7 +3,7 @@ package pkg
 func fn() {
 	var m = map[string][]string{}
 
-	if _, ok := m["k1"]; ok { // want `unnecessary guard around map access`
+	if _, ok := m["k1"]; ok { //@ diag(`unnecessary guard around map access`)
 		m["k1"] = append(m["k1"], "v1", "v2")
 	} else {
 		m["k1"] = []string{"v1", "v2"}
@@ -22,7 +22,7 @@ func fn() {
 	}
 
 	k1 := "key"
-	if _, ok := m[k1]; ok { // want `unnecessary guard around map access`
+	if _, ok := m[k1]; ok { //@ diag(`unnecessary guard around map access`)
 		m[k1] = append(m[k1], "v1", "v2")
 	} else {
 		m[k1] = []string{"v1", "v2"}
@@ -37,7 +37,7 @@ func fn() {
 	}
 
 	var m2 map[string]int
-	if _, ok := m2["k"]; ok { // want `unnecessary guard around map access`
+	if _, ok := m2["k"]; ok { //@ diag(`unnecessary guard around map access`)
 		m2["k"] += 4
 	} else {
 		m2["k"] = 4
@@ -49,7 +49,7 @@ func fn() {
 		m2["k"] = 3
 	}
 
-	if _, ok := m2["k"]; ok { // want `unnecessary guard around map access`
+	if _, ok := m2["k"]; ok { //@ diag(`unnecessary guard around map access`)
 		m2["k"]++
 	} else {
 		m2["k"] = 1
diff -pruN 2022.1-1/simple/testdata/src/compare/compare.go 2022.1.3-1/simple/testdata/src/compare/compare.go
--- 2022.1-1/simple/testdata/src/compare/compare.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/compare/compare.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,10 +0,0 @@
-package pkg
-
-import "bytes"
-
-func fn() {
-	_ = bytes.Compare(nil, nil) == 0 // want ` bytes.Equal`
-	_ = bytes.Compare(nil, nil) != 0 // want `!bytes.Equal`
-	_ = bytes.Compare(nil, nil) > 0
-	_ = bytes.Compare(nil, nil) < 0
-}
diff -pruN 2022.1-1/simple/testdata/src/compare/compare.go.golden 2022.1.3-1/simple/testdata/src/compare/compare.go.golden
--- 2022.1-1/simple/testdata/src/compare/compare.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/compare/compare.go.golden	1970-01-01 00:00:00.000000000 +0000
@@ -1,10 +0,0 @@
-package pkg
-
-import "bytes"
-
-func fn() {
-	_ = bytes.Equal(nil, nil)  // want ` bytes.Equal`
-	_ = !bytes.Equal(nil, nil) // want `!bytes.Equal`
-	_ = bytes.Compare(nil, nil) > 0
-	_ = bytes.Compare(nil, nil) < 0
-}
diff -pruN 2022.1-1/simple/testdata/src/contains/contains.go 2022.1.3-1/simple/testdata/src/contains/contains.go
--- 2022.1-1/simple/testdata/src/contains/contains.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/contains/contains.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,39 +0,0 @@
-package pkg
-
-import (
-	"bytes"
-	"strings"
-)
-
-func fn() {
-	_ = strings.IndexRune("", 'x') > -1 // want ` strings\.ContainsRune`
-	_ = strings.IndexRune("", 'x') >= 0 // want ` strings\.ContainsRune`
-	_ = strings.IndexRune("", 'x') > 0
-	_ = strings.IndexRune("", 'x') >= -1
-	_ = strings.IndexRune("", 'x') != -1 // want ` strings\.ContainsRune`
-	_ = strings.IndexRune("", 'x') == -1 // want `!strings\.ContainsRune`
-	_ = strings.IndexRune("", 'x') != 0
-	_ = strings.IndexRune("", 'x') < 0 // want `!strings\.ContainsRune`
-
-	_ = strings.IndexAny("", "") > -1 // want ` strings\.ContainsAny`
-	_ = strings.IndexAny("", "") >= 0 // want ` strings\.ContainsAny`
-	_ = strings.IndexAny("", "") > 0
-	_ = strings.IndexAny("", "") >= -1
-	_ = strings.IndexAny("", "") != -1 // want ` strings\.ContainsAny`
-	_ = strings.IndexAny("", "") == -1 // want `!strings\.ContainsAny`
-	_ = strings.IndexAny("", "") != 0
-	_ = strings.IndexAny("", "") < 0 // want `!strings\.ContainsAny`
-
-	_ = strings.Index("", "") > -1 // want ` strings\.Contains`
-	_ = strings.Index("", "") >= 0 // want ` strings\.Contains`
-	_ = strings.Index("", "") > 0
-	_ = strings.Index("", "") >= -1
-	_ = strings.Index("", "") != -1 // want ` strings\.Contains`
-	_ = strings.Index("", "") == -1 // want `!strings\.Contains`
-	_ = strings.Index("", "") != 0
-	_ = strings.Index("", "") < 0 // want `!strings\.Contains`
-
-	_ = bytes.IndexRune(nil, 'x') > -1 // want ` bytes\.ContainsRune`
-	_ = bytes.IndexAny(nil, "") > -1   // want ` bytes\.ContainsAny`
-	_ = bytes.Index(nil, nil) > -1     // want ` bytes\.Contains`
-}
diff -pruN 2022.1-1/simple/testdata/src/contains/contains.go.golden 2022.1.3-1/simple/testdata/src/contains/contains.go.golden
--- 2022.1-1/simple/testdata/src/contains/contains.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/contains/contains.go.golden	1970-01-01 00:00:00.000000000 +0000
@@ -1,39 +0,0 @@
-package pkg
-
-import (
-	"bytes"
-	"strings"
-)
-
-func fn() {
-	_ = strings.ContainsRune("", 'x') // want ` strings\.ContainsRune`
-	_ = strings.ContainsRune("", 'x') // want ` strings\.ContainsRune`
-	_ = strings.IndexRune("", 'x') > 0
-	_ = strings.IndexRune("", 'x') >= -1
-	_ = strings.ContainsRune("", 'x')  // want ` strings\.ContainsRune`
-	_ = !strings.ContainsRune("", 'x') // want `!strings\.ContainsRune`
-	_ = strings.IndexRune("", 'x') != 0
-	_ = !strings.ContainsRune("", 'x') // want `!strings\.ContainsRune`
-
-	_ = strings.ContainsAny("", "") // want ` strings\.ContainsAny`
-	_ = strings.ContainsAny("", "") // want ` strings\.ContainsAny`
-	_ = strings.IndexAny("", "") > 0
-	_ = strings.IndexAny("", "") >= -1
-	_ = strings.ContainsAny("", "")  // want ` strings\.ContainsAny`
-	_ = !strings.ContainsAny("", "") // want `!strings\.ContainsAny`
-	_ = strings.IndexAny("", "") != 0
-	_ = !strings.ContainsAny("", "") // want `!strings\.ContainsAny`
-
-	_ = strings.Contains("", "") // want ` strings\.Contains`
-	_ = strings.Contains("", "") // want ` strings\.Contains`
-	_ = strings.Index("", "") > 0
-	_ = strings.Index("", "") >= -1
-	_ = strings.Contains("", "")  // want ` strings\.Contains`
-	_ = !strings.Contains("", "") // want `!strings\.Contains`
-	_ = strings.Index("", "") != 0
-	_ = !strings.Contains("", "") // want `!strings\.Contains`
-
-	_ = bytes.ContainsRune(nil, 'x') // want ` bytes\.ContainsRune`
-	_ = bytes.ContainsAny(nil, "")   // want ` bytes\.ContainsAny`
-	_ = bytes.Contains(nil, nil)     // want ` bytes\.Contains`
-}
diff -pruN 2022.1-1/simple/testdata/src/convert/convert_generics.go 2022.1.3-1/simple/testdata/src/convert/convert_generics.go
--- 2022.1-1/simple/testdata/src/convert/convert_generics.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/convert/convert_generics.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,36 +0,0 @@
-//go:build go1.18
-
-package pkg
-
-type T1 struct {
-	A int
-	B int
-}
-
-type T2 struct {
-	A int
-	B int
-}
-
-type T3[T any] struct {
-	A T
-	B T
-}
-
-type T4[T any] struct {
-	A T
-	B T
-}
-
-func _() {
-	t1 := T1{0, 0}
-	t3 := T3[int]{0, 0}
-
-	_ = T2{t1.A, t1.B} // want `\(type T1\) to T2`
-	_ = T2{t3.A, t3.B} // want `\(type T3\[int\]\) to T2`
-
-	_ = T4[int]{t1.A, t1.B} // want `\(type T1\) to T4\[int\]`
-	_ = T4[int]{t3.A, t3.B} // want `\(type T3\[int\]\) to T4\[int\]`
-
-	_ = T4[any]{t3.A, t3.B}
-}
diff -pruN 2022.1-1/simple/testdata/src/convert/convert_generics.go.golden 2022.1.3-1/simple/testdata/src/convert/convert_generics.go.golden
--- 2022.1-1/simple/testdata/src/convert/convert_generics.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/convert/convert_generics.go.golden	1970-01-01 00:00:00.000000000 +0000
@@ -1,36 +0,0 @@
-//go:build go1.18
-
-package pkg
-
-type T1 struct {
-	A int
-	B int
-}
-
-type T2 struct {
-	A int
-	B int
-}
-
-type T3[T any] struct {
-	A T
-	B T
-}
-
-type T4[T any] struct {
-	A T
-	B T
-}
-
-func _() {
-	t1 := T1{0, 0}
-	t3 := T3[int]{0, 0}
-
-	_ = T2(t1) // want `\(type T1\) to T2`
-	_ = T2(t3) // want `\(type T3\[int\]\) to T2`
-
-	_ = T4[int](t1) // want `\(type T1\) to T4\[int\]`
-	_ = T4[int](t3) // want `\(type T3\[int\]\) to T4\[int\]`
-
-	_ = T4[any]{t3.A, t3.B}
-}
diff -pruN 2022.1-1/simple/testdata/src/convert/convert.go 2022.1.3-1/simple/testdata/src/convert/convert.go
--- 2022.1-1/simple/testdata/src/convert/convert.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/convert/convert.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,32 +0,0 @@
-package pkg
-
-type t1 struct {
-	a int
-	b int
-}
-
-type t2 struct {
-	a int
-	b int
-}
-
-type t3 t1
-
-func fn() {
-	v1 := t1{1, 2}
-	v2 := t2{1, 2}
-	_ = t2{v1.a, v1.b}       // want `should convert v1`
-	_ = t2{a: v1.a, b: v1.b} // want `should convert v1`
-	_ = t2{b: v1.b, a: v1.a} // want `should convert v1`
-	_ = t3{v1.a, v1.b}       // want `should convert v1`
-
-	_ = t3{v1.a, v2.b}
-
-	_ = t2{v1.b, v1.a}
-	_ = t2{a: v1.b, b: v1.a}
-	_ = t2{a: v1.a}
-	_ = t1{v1.a, v1.b}
-
-	v := t1{1, 2}
-	_ = &t2{v.a, v.b}
-}
diff -pruN 2022.1-1/simple/testdata/src/convert/convert.go.golden 2022.1.3-1/simple/testdata/src/convert/convert.go.golden
--- 2022.1-1/simple/testdata/src/convert/convert.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/convert/convert.go.golden	1970-01-01 00:00:00.000000000 +0000
@@ -1,32 +0,0 @@
-package pkg
-
-type t1 struct {
-	a int
-	b int
-}
-
-type t2 struct {
-	a int
-	b int
-}
-
-type t3 t1
-
-func fn() {
-	v1 := t1{1, 2}
-	v2 := t2{1, 2}
-	_ = t2(v1) // want `should convert v1`
-	_ = t2(v1) // want `should convert v1`
-	_ = t2(v1) // want `should convert v1`
-	_ = t3(v1) // want `should convert v1`
-
-	_ = t3{v1.a, v2.b}
-
-	_ = t2{v1.b, v1.a}
-	_ = t2{a: v1.b, b: v1.a}
-	_ = t2{a: v1.a}
-	_ = t1{v1.a, v1.b}
-
-	v := t1{1, 2}
-	_ = &t2{v.a, v.b}
-}
diff -pruN 2022.1-1/simple/testdata/src/convert_go17/convert.go 2022.1.3-1/simple/testdata/src/convert_go17/convert.go
--- 2022.1-1/simple/testdata/src/convert_go17/convert.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/convert_go17/convert.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,22 +0,0 @@
-package pkg
-
-type t1 struct {
-	a int
-	b int
-}
-
-type t2 struct {
-	a int
-	b int
-}
-
-type t3 struct {
-	a int `tag`
-	b int `tag`
-}
-
-func fn() {
-	v1 := t1{1, 2}
-	_ = t2{v1.a, v1.b} // want `should convert v1`
-	_ = t3{v1.a, v1.b}
-}
diff -pruN 2022.1-1/simple/testdata/src/convert_go17/convert.go.golden 2022.1.3-1/simple/testdata/src/convert_go17/convert.go.golden
--- 2022.1-1/simple/testdata/src/convert_go17/convert.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/convert_go17/convert.go.golden	1970-01-01 00:00:00.000000000 +0000
@@ -1,22 +0,0 @@
-package pkg
-
-type t1 struct {
-	a int
-	b int
-}
-
-type t2 struct {
-	a int
-	b int
-}
-
-type t3 struct {
-	a int `tag`
-	b int `tag`
-}
-
-func fn() {
-	v1 := t1{1, 2}
-	_ = t2(v1) // want `should convert v1`
-	_ = t3{v1.a, v1.b}
-}
diff -pruN 2022.1-1/simple/testdata/src/convert_go18/convert.go 2022.1.3-1/simple/testdata/src/convert_go18/convert.go
--- 2022.1-1/simple/testdata/src/convert_go18/convert.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/convert_go18/convert.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,22 +0,0 @@
-package pkg
-
-type t1 struct {
-	a int
-	b int
-}
-
-type t2 struct {
-	a int
-	b int
-}
-
-type t3 struct {
-	a int `tag`
-	b int `tag`
-}
-
-func fn() {
-	v1 := t1{1, 2}
-	_ = t2{v1.a, v1.b} // want `should convert v1`
-	_ = t3{v1.a, v1.b} // want `should convert v1`
-}
diff -pruN 2022.1-1/simple/testdata/src/convert_go18/convert.go.golden 2022.1.3-1/simple/testdata/src/convert_go18/convert.go.golden
--- 2022.1-1/simple/testdata/src/convert_go18/convert.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/convert_go18/convert.go.golden	1970-01-01 00:00:00.000000000 +0000
@@ -1,22 +0,0 @@
-package pkg
-
-type t1 struct {
-	a int
-	b int
-}
-
-type t2 struct {
-	a int
-	b int
-}
-
-type t3 struct {
-	a int `tag`
-	b int `tag`
-}
-
-func fn() {
-	v1 := t1{1, 2}
-	_ = t2(v1) // want `should convert v1`
-	_ = t3(v1) // want `should convert v1`
-}
diff -pruN 2022.1-1/simple/testdata/src/copy/copy_generics.go 2022.1.3-1/simple/testdata/src/copy/copy_generics.go
--- 2022.1-1/simple/testdata/src/copy/copy_generics.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/copy/copy_generics.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,127 +0,0 @@
-//go:build go1.18
-
-package pkg
-
-func tpfn[T any]() {
-	var b1, b2 []T
-	for i, v := range b1 { // want `should use copy`
-		b2[i] = v
-	}
-
-	for i := range b1 { // want `should use copy`
-		b2[i] = b1[i]
-	}
-
-	type T2 [][16]T
-	var a T2
-	b := make([]any, len(a))
-	for i := range b {
-		b[i] = a[i]
-	}
-
-	var b3, b4 []*T
-	for i := range b3 { // want `should use copy`
-		b4[i] = b3[i]
-	}
-
-	var m map[int]T
-	for i, v := range b1 {
-		m[i] = v
-	}
-
-}
-
-func tpsrc[T any]() []T { return nil }
-
-func tpfn1() {
-	// Don't flag this, the source is dynamic
-	var dst []any
-	for i := range tpsrc[any]() {
-		dst[i] = tpsrc[any]()[i]
-	}
-}
-
-func tpfn2[T any]() {
-	type T2 struct {
-		b []T
-	}
-
-	var src []T
-	var dst T2
-	for i, v := range src { // want `should use copy`
-		dst.b[i] = v
-	}
-}
-
-func tpfn3[T any]() {
-	var src []T
-	var dst [][]T
-	for i, v := range src { // want `should use copy`
-		dst[0][i] = v
-	}
-	for i, v := range src {
-		// Don't flag, destination depends on loop variable
-		dst[i][i] = v
-	}
-}
-
-func tpfn4[T any]() {
-	var b []T
-	var a1 [5]T
-	var a2 [10]T
-	var a3 [5]T
-
-	for i := range b { // want `should use copy`
-		a1[i] = b[i]
-	}
-	for i := range a1 { // want `should use copy`
-		b[i] = a1[i]
-	}
-	for i := range a1 { // want `should use copy`
-		a2[i] = a1[i]
-	}
-	for i := range a1 { // want `should copy arrays using assignment`
-		a3[i] = a1[i]
-	}
-
-	a1p := &a1
-	a2p := &a2
-	a3p := &a3
-	for i := range b { // want `should use copy`
-		a1p[i] = b[i]
-	}
-	for i := range a1p { // want `should use copy`
-		b[i] = a1p[i]
-	}
-	for i := range a1p { // want `should use copy`
-		a2p[i] = a1p[i]
-	}
-	for i := range a1p { // want `should copy arrays using assignment`
-		a3p[i] = a1p[i]
-	}
-
-	for i := range a1 { // want `should use copy`
-		a2p[i] = a1[i]
-	}
-	for i := range a1 { // want `should copy arrays using assignment`
-		a3p[i] = a1[i]
-	}
-	for i := range a1p { // want `should use copy`
-		a2[i] = a1p[i]
-	}
-	for i := range a1p { // want `should copy arrays using assignment`
-		a3[i] = a1p[i]
-	}
-}
-
-func tpfn5[T any]() {
-	var src, dst []T
-	for i := 0; i < len(src); i++ { // want `should use copy`
-		dst[i] = src[i]
-	}
-
-	len := func([]T) int { return 0 }
-	for i := 0; i < len(src); i++ {
-		dst[i] = src[i]
-	}
-}
diff -pruN 2022.1-1/simple/testdata/src/copy/copy_generics.go.golden 2022.1.3-1/simple/testdata/src/copy/copy_generics.go.golden
--- 2022.1-1/simple/testdata/src/copy/copy_generics.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/copy/copy_generics.go.golden	1970-01-01 00:00:00.000000000 +0000
@@ -1,91 +0,0 @@
-//go:build go1.18
-
-package pkg
-
-func tpfn[T any]() {
-	var b1, b2 []T
-	copy(b2, b1)
-
-	copy(b2, b1)
-
-	type T2 [][16]T
-	var a T2
-	b := make([]any, len(a))
-	for i := range b {
-		b[i] = a[i]
-	}
-
-	var b3, b4 []*T
-	copy(b4, b3)
-
-	var m map[int]T
-	for i, v := range b1 {
-		m[i] = v
-	}
-
-}
-
-func tpsrc[T any]() []T { return nil }
-
-func tpfn1() {
-	// Don't flag this, the source is dynamic
-	var dst []any
-	for i := range tpsrc[any]() {
-		dst[i] = tpsrc[any]()[i]
-	}
-}
-
-func tpfn2[T any]() {
-	type T2 struct {
-		b []T
-	}
-
-	var src []T
-	var dst T2
-	copy(dst.b, src)
-}
-
-func tpfn3[T any]() {
-	var src []T
-	var dst [][]T
-	copy(dst[0], src)
-	for i, v := range src {
-		// Don't flag, destination depends on loop variable
-		dst[i][i] = v
-	}
-}
-
-func tpfn4[T any]() {
-	var b []T
-	var a1 [5]T
-	var a2 [10]T
-	var a3 [5]T
-
-	copy(a1[:], b)
-	copy(b, a1[:])
-	copy(a2[:], a1[:])
-	a3 = a1
-
-	a1p := &a1
-	a2p := &a2
-	a3p := &a3
-	copy(a1p[:], b)
-	copy(b, a1p[:])
-	copy(a2p[:], a1p[:])
-	*a3p = *a1p
-
-	copy(a2p[:], a1[:])
-	*a3p = a1
-	copy(a2[:], a1p[:])
-	a3 = *a1p
-}
-
-func tpfn5[T any]() {
-	var src, dst []T
-	copy(dst, src)
-
-	len := func([]T) int { return 0 }
-	for i := 0; i < len(src); i++ {
-		dst[i] = src[i]
-	}
-}
diff -pruN 2022.1-1/simple/testdata/src/copy/copy.go 2022.1.3-1/simple/testdata/src/copy/copy.go
--- 2022.1-1/simple/testdata/src/copy/copy.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/copy/copy.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,129 +0,0 @@
-package pkg
-
-func fn() {
-	var b1, b2 []byte
-	for i, v := range b1 { // want `should use copy`
-		b2[i] = v
-	}
-
-	for i := range b1 { // want `should use copy`
-		b2[i] = b1[i]
-	}
-
-	type T [][16]byte
-	var a T
-	b := make([]interface{}, len(a))
-	for i := range b {
-		b[i] = a[i]
-	}
-
-	var b3, b4 []*byte
-	for i := range b3 { // want `should use copy`
-		b4[i] = b3[i]
-	}
-
-	var m map[int]byte
-	for i, v := range b1 {
-		m[i] = v
-	}
-
-}
-
-func src() []interface{} { return nil }
-
-func fn1() {
-	// Don't flag this, the source is dynamic
-	var dst []interface{}
-	for i := range src() {
-		dst[i] = src()[i]
-	}
-}
-
-func fn2() {
-	type T struct {
-		b []byte
-	}
-
-	var src []byte
-	var dst T
-	for i, v := range src { // want `should use copy`
-		dst.b[i] = v
-	}
-}
-
-func fn3() {
-	var src []byte
-	var dst [][]byte
-	for i, v := range src { // want `should use copy`
-		dst[0][i] = v
-	}
-	for i, v := range src {
-		// Don't flag, destination depends on loop variable
-		dst[i][i] = v
-	}
-	for i, v := range src {
-		// Don't flag, destination depends on loop variable
-		dst[v][i] = v
-	}
-}
-
-func fn4() {
-	var b []byte
-	var a1 [5]byte
-	var a2 [10]byte
-	var a3 [5]byte
-
-	for i := range b { // want `should use copy`
-		a1[i] = b[i]
-	}
-	for i := range a1 { // want `should use copy`
-		b[i] = a1[i]
-	}
-	for i := range a1 { // want `should use copy`
-		a2[i] = a1[i]
-	}
-	for i := range a1 { // want `should copy arrays using assignment`
-		a3[i] = a1[i]
-	}
-
-	a1p := &a1
-	a2p := &a2
-	a3p := &a3
-	for i := range b { // want `should use copy`
-		a1p[i] = b[i]
-	}
-	for i := range a1p { // want `should use copy`
-		b[i] = a1p[i]
-	}
-	for i := range a1p { // want `should use copy`
-		a2p[i] = a1p[i]
-	}
-	for i := range a1p { // want `should copy arrays using assignment`
-		a3p[i] = a1p[i]
-	}
-
-	for i := range a1 { // want `should use copy`
-		a2p[i] = a1[i]
-	}
-	for i := range a1 { // want `should copy arrays using assignment`
-		a3p[i] = a1[i]
-	}
-	for i := range a1p { // want `should use copy`
-		a2[i] = a1p[i]
-	}
-	for i := range a1p { // want `should copy arrays using assignment`
-		a3[i] = a1p[i]
-	}
-}
-
-func fn5() {
-	var src, dst []byte
-	for i := 0; i < len(src); i++ { // want `should use copy`
-		dst[i] = src[i]
-	}
-
-	len := func([]byte) int { return 0 }
-	for i := 0; i < len(src); i++ {
-		dst[i] = src[i]
-	}
-}
diff -pruN 2022.1-1/simple/testdata/src/copy/copy.go.golden 2022.1.3-1/simple/testdata/src/copy/copy.go.golden
--- 2022.1-1/simple/testdata/src/copy/copy.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/copy/copy.go.golden	1970-01-01 00:00:00.000000000 +0000
@@ -1,93 +0,0 @@
-package pkg
-
-func fn() {
-	var b1, b2 []byte
-	copy(b2, b1)
-
-	copy(b2, b1)
-
-	type T [][16]byte
-	var a T
-	b := make([]interface{}, len(a))
-	for i := range b {
-		b[i] = a[i]
-	}
-
-	var b3, b4 []*byte
-	copy(b4, b3)
-
-	var m map[int]byte
-	for i, v := range b1 {
-		m[i] = v
-	}
-
-}
-
-func src() []interface{} { return nil }
-
-func fn1() {
-	// Don't flag this, the source is dynamic
-	var dst []interface{}
-	for i := range src() {
-		dst[i] = src()[i]
-	}
-}
-
-func fn2() {
-	type T struct {
-		b []byte
-	}
-
-	var src []byte
-	var dst T
-	copy(dst.b, src)
-}
-
-func fn3() {
-	var src []byte
-	var dst [][]byte
-	copy(dst[0], src)
-	for i, v := range src {
-		// Don't flag, destination depends on loop variable
-		dst[i][i] = v
-	}
-	for i, v := range src {
-		// Don't flag, destination depends on loop variable
-		dst[v][i] = v
-	}
-}
-
-func fn4() {
-	var b []byte
-	var a1 [5]byte
-	var a2 [10]byte
-	var a3 [5]byte
-
-	copy(a1[:], b)
-	copy(b, a1[:])
-	copy(a2[:], a1[:])
-	a3 = a1
-
-	a1p := &a1
-	a2p := &a2
-	a3p := &a3
-	copy(a1p[:], b)
-	copy(b, a1p[:])
-	copy(a2p[:], a1p[:])
-	*a3p = *a1p
-
-	copy(a2p[:], a1[:])
-	*a3p = a1
-	copy(a2[:], a1p[:])
-	a3 = *a1p
-}
-
-func fn5() {
-	var src, dst []byte
-	copy(dst, src)
-
-	len := func([]byte) int { return 0 }
-	for i := 0; i < len(src); i++ {
-		dst[i] = src[i]
-	}
-}
diff -pruN 2022.1-1/simple/testdata/src/for-true/for-true.go 2022.1.3-1/simple/testdata/src/for-true/for-true.go
--- 2022.1-1/simple/testdata/src/for-true/for-true.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/for-true/for-true.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,12 +0,0 @@
-package pkg
-
-func fn() {
-	for false {
-	}
-	for true { // want `should use for`
-	}
-	for {
-	}
-	for i := 0; true; i++ {
-	}
-}
diff -pruN 2022.1-1/simple/testdata/src/generated/generated.go 2022.1.3-1/simple/testdata/src/generated/generated.go
--- 2022.1-1/simple/testdata/src/generated/generated.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/generated/generated.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,14 +0,0 @@
-// Code generated by a clever monkey. DO NOT EDIT.
-
-package pkg
-
-func fn() {
-	for true {
-	}
-}
-
-//line input.go:2
-func fn2() {
-	for true {
-	}
-}
diff -pruN 2022.1-1/simple/testdata/src/generated/input.go 2022.1.3-1/simple/testdata/src/generated/input.go
--- 2022.1-1/simple/testdata/src/generated/input.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/generated/input.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,6 +0,0 @@
-package pkg
-
-// want `should use for \{\}`
-
-// the error is produced by generated.go, which pretends that its
-// broken code came from this file.
diff -pruN 2022.1-1/simple/testdata/src/if-return/if-return.go 2022.1.3-1/simple/testdata/src/if-return/if-return.go
--- 2022.1-1/simple/testdata/src/if-return/if-return.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/if-return/if-return.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,155 +0,0 @@
-package pkg
-
-func fn() bool { return true }
-func fn1() bool {
-	x := true
-	if x { // want `should use 'return x'`
-		return true
-	}
-	return false
-}
-
-func fn2() bool {
-	x := true
-	if !x {
-		return true
-	}
-	if x {
-		return true
-	}
-	return false
-}
-
-func fn3() int {
-	var x bool
-	if x {
-		return 1
-	}
-	return 2
-}
-
-func fn4() bool { return true }
-
-func fn5() bool {
-	if fn() { // want `should use 'return !fn\(\)'`
-		return false
-	}
-	return true
-}
-
-func fn6() bool {
-	if fn3() != fn3() { // want `should use 'return fn3\(\) != fn3\(\)'`
-		return true
-	}
-	return false
-}
-
-func fn7() bool {
-	if 1 > 2 { // want `should use 'return 1 > 2'`
-		return true
-	}
-	return false
-}
-
-func fn8() bool {
-	if fn() || fn() {
-		return true
-	}
-	return false
-}
-
-func fn9(x int) bool {
-	if x > 0 {
-		return true
-	}
-	return true
-}
-
-func fn10(x int) bool {
-	if x > 0 { // want `should use 'return x <= 0'`
-		return false
-	}
-	return true
-}
-
-func fn11(x bool) bool {
-	if x { // want `should use 'return !x'`
-		return false
-	}
-	return true
-}
-
-func fn12() bool {
-	var x []bool
-	if x[0] { // want `should use 'return !x\[0\]'`
-		return false
-	}
-	return true
-}
-
-func fn13(a, b int) bool {
-	if a != b { // want `should use 'return a == b' instead of 'if a != b`
-		return false
-	}
-	return true
-}
-
-func fn14(a, b int) bool {
-	if a >= b { // want `should use 'return a < b' instead of 'if a >= b`
-		return false
-	}
-	return true
-}
-
-func fn15() bool {
-	if !fn() { // want `should use 'return fn\(\)'`
-		return false
-	}
-	return true
-}
-
-func fn16() <-chan bool {
-	x := make(chan bool, 1)
-	x <- true
-	return x
-}
-
-func fn17() bool {
-	if <-fn16() { // want `should use 'return !<-fn16\(\)'`
-		return false
-	}
-	return true
-}
-
-func fn18() *bool {
-	x := true
-	return &x
-}
-
-func fn19() bool {
-	if *fn18() { // want `should use 'return !\*fn18\(\)'`
-		return false
-	}
-	return true
-}
-
-const a = true
-const b = false
-
-func fn20(x bool) bool {
-	// Don't match on constants other than the predeclared true and false. This protects us both from build tag woes,
-	// and from code that breaks when the constant values change.
-	if x {
-		return a
-	}
-	return b
-}
-
-func fn21(x bool) bool {
-	// Don't flag, 'true' isn't the predeclared identifier.
-	const true = false
-	if x {
-		return true
-	}
-	return false
-}
diff -pruN 2022.1-1/simple/testdata/src/loop-append/loop-append.go 2022.1.3-1/simple/testdata/src/loop-append/loop-append.go
--- 2022.1-1/simple/testdata/src/loop-append/loop-append.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/loop-append/loop-append.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,78 +0,0 @@
-package pkg
-
-type T struct {
-	F string
-}
-
-func fn1() {
-	var x []interface{}
-	var y []int
-
-	for _, v := range y {
-		x = append(x, v)
-	}
-
-	var a, b []int
-	for _, v := range a { // want `should replace loop`
-		b = append(b, v)
-	}
-
-	var m map[string]int
-	var c []int
-	for _, v := range m {
-		c = append(c, v)
-	}
-
-	var t []T
-	var m2 map[string][]T
-
-	for _, tt := range t {
-		m2[tt.F] = append(m2[tt.F], tt)
-	}
-
-	var out []T
-	for _, tt := range t {
-		out = append(m2[tt.F], tt)
-	}
-	_ = out
-}
-
-func fn2() {
-	var v struct {
-		V int
-	}
-	var in []int
-	var out []int
-
-	for _, v.V = range in {
-		out = append(out, v.V)
-	}
-}
-
-func fn3() {
-	var t []T
-	var out [][]T
-	var m2 map[string][]T
-
-	for _, tt := range t {
-		out = append(out, m2[tt.F])
-	}
-}
-
-func fn4() {
-	var a, b, c []int
-	for _, v := range a {
-		b = append(c, v)
-	}
-	_ = b
-}
-
-func fn5() {
-	var t []T
-	var m2 map[string][]T
-	var out []T
-	for _, tt := range t {
-		out = append(m2[tt.F], tt)
-	}
-	_ = out
-}
diff -pruN 2022.1-1/simple/testdata/src/loop-append/loop-append.go.golden 2022.1.3-1/simple/testdata/src/loop-append/loop-append.go.golden
--- 2022.1-1/simple/testdata/src/loop-append/loop-append.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/loop-append/loop-append.go.golden	1970-01-01 00:00:00.000000000 +0000
@@ -1,76 +0,0 @@
-package pkg
-
-type T struct {
-	F string
-}
-
-func fn1() {
-	var x []interface{}
-	var y []int
-
-	for _, v := range y {
-		x = append(x, v)
-	}
-
-	var a, b []int
-	b = append(b, a...)
-
-	var m map[string]int
-	var c []int
-	for _, v := range m {
-		c = append(c, v)
-	}
-
-	var t []T
-	var m2 map[string][]T
-
-	for _, tt := range t {
-		m2[tt.F] = append(m2[tt.F], tt)
-	}
-
-	var out []T
-	for _, tt := range t {
-		out = append(m2[tt.F], tt)
-	}
-	_ = out
-}
-
-func fn2() {
-	var v struct {
-		V int
-	}
-	var in []int
-	var out []int
-
-	for _, v.V = range in {
-		out = append(out, v.V)
-	}
-}
-
-func fn3() {
-	var t []T
-	var out [][]T
-	var m2 map[string][]T
-
-	for _, tt := range t {
-		out = append(out, m2[tt.F])
-	}
-}
-
-func fn4() {
-	var a, b, c []int
-	for _, v := range a {
-		b = append(c, v)
-	}
-	_ = b
-}
-
-func fn5() {
-	var t []T
-	var m2 map[string][]T
-	var out []T
-	for _, tt := range t {
-		out = append(m2[tt.F], tt)
-	}
-	_ = out
-}
diff -pruN 2022.1-1/simple/testdata/src/nil-len/nil-len_generics.go 2022.1.3-1/simple/testdata/src/nil-len/nil-len_generics.go
--- 2022.1-1/simple/testdata/src/nil-len/nil-len_generics.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/nil-len/nil-len_generics.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,13 +0,0 @@
-//go:build go1.18
-
-package pkg
-
-func fn1[T []int | *[4]int](a T) {
-	if a != nil && len(a) > 0 { // don't flag, because of the pointer
-	}
-}
-
-func fn2[T []int | []string | map[string]int](a T) {
-	if a != nil && len(a) > 0 { // want `should omit nil check`
-	}
-}
diff -pruN 2022.1-1/simple/testdata/src/nil-len/nil-len.go 2022.1.3-1/simple/testdata/src/nil-len/nil-len.go
--- 2022.1-1/simple/testdata/src/nil-len/nil-len.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/nil-len/nil-len.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,64 +0,0 @@
-package pkg
-
-func fn() {
-	var pa *[5]int
-	var s []int
-	var m map[int]int
-	var ch chan int
-
-	if s == nil || len(s) == 0 { // want `should omit nil check`
-	}
-	if m == nil || len(m) == 0 { // want `should omit nil check`
-	}
-	if ch == nil || len(ch) == 0 { // want `should omit nil check`
-	}
-
-	if s != nil && len(s) != 0 { // want `should omit nil check`
-	}
-	if m != nil && len(m) > 0 { // want `should omit nil check`
-	}
-	if s != nil && len(s) > 5 { // want `should omit nil check`
-	}
-	if s != nil && len(s) >= 5 { // want `should omit nil check`
-	}
-	const five = 5
-	if s != nil && len(s) == five { // want `should omit nil check`
-	}
-
-	if ch != nil && len(ch) == 5 { // want `should omit nil check`
-	}
-
-	if pa == nil || len(pa) == 0 { // nil check cannot be removed with pointer to an array
-	}
-	if s == nil || len(m) == 0 { // different variables
-	}
-	if s != nil && len(m) == 1 { // different variables
-	}
-
-	var ch2 chan int
-	if ch == ch2 || len(ch) == 0 { // not comparing with nil
-	}
-	if ch != ch2 && len(ch) != 0 { // not comparing with nil
-	}
-
-	const zero = 0
-	if s != nil && len(s) == zero { // nil check is not redundant here
-	}
-	if s != nil && len(s) == 0 { // nil check is not redundant here
-	}
-	if s != nil && len(s) >= 0 { // nil check is not redundant here (though len(s) >= 0 is)
-	}
-	one := 1
-	if s != nil && len(s) == one { // nil check is not redundant here
-	}
-	if s != nil && len(s) == len(m) { // nil check is not redundant here
-	}
-	if s != nil && len(s) != 1 { // nil check is not redundant here
-	}
-	if s != nil && len(s) < 5 { // nil check is not redundant here
-	}
-	if s != nil && len(s) <= 5 { // nil check is not redundant here
-	}
-	if s != nil && len(s) != len(ch) { // nil check is not redundant here
-	}
-}
diff -pruN 2022.1-1/simple/testdata/src/range_go13/range_go13.go 2022.1.3-1/simple/testdata/src/range_go13/range_go13.go
--- 2022.1-1/simple/testdata/src/range_go13/range_go13.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/range_go13/range_go13.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,34 +0,0 @@
-package pkg
-
-func fn() {
-	var m map[string]int
-
-	// with :=
-	for x, _ := range m {
-		_ = x
-	}
-	// with =
-	var y string
-	_ = y
-	for y, _ = range m {
-	}
-
-	// all OK:
-	for x := range m {
-		_ = x
-	}
-	for x, y := range m {
-		_, _ = x, y
-	}
-	for _, y := range m {
-		_ = y
-	}
-	var x int
-	_ = x
-	for y = range m {
-	}
-	for y, x = range m {
-	}
-	for _, x = range m {
-	}
-}
diff -pruN 2022.1-1/simple/testdata/src/range_go14/range_go14.go 2022.1.3-1/simple/testdata/src/range_go14/range_go14.go
--- 2022.1-1/simple/testdata/src/range_go14/range_go14.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/range_go14/range_go14.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,40 +0,0 @@
-package pkg
-
-func fn() {
-	var m map[string]int
-
-	// with :=
-	for x, _ := range m { // want `unnecessary assignment to the blank identifier`
-		_ = x
-	}
-	// with =
-	var y string
-	_ = y
-	for y, _ = range m { // want `unnecessary assignment to the blank identifier`
-	}
-
-	for _ = range m { // want `unnecessary assignment to the blank identifier`
-	}
-
-	for _, _ = range m { // want `unnecessary assignment to the blank identifier`
-	}
-
-	// all OK:
-	for x := range m {
-		_ = x
-	}
-	for x, y := range m {
-		_, _ = x, y
-	}
-	for _, y := range m {
-		_ = y
-	}
-	var x int
-	_ = x
-	for y = range m {
-	}
-	for y, x = range m {
-	}
-	for _, x = range m {
-	}
-}
diff -pruN 2022.1-1/simple/testdata/src/range_go14/range_go14.go.golden 2022.1.3-1/simple/testdata/src/range_go14/range_go14.go.golden
--- 2022.1-1/simple/testdata/src/range_go14/range_go14.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/range_go14/range_go14.go.golden	1970-01-01 00:00:00.000000000 +0000
@@ -1,40 +0,0 @@
-package pkg
-
-func fn() {
-	var m map[string]int
-
-	// with :=
-	for x := range m { // want `unnecessary assignment to the blank identifier`
-		_ = x
-	}
-	// with =
-	var y string
-	_ = y
-	for y = range m { // want `unnecessary assignment to the blank identifier`
-	}
-
-	for range m { // want `unnecessary assignment to the blank identifier`
-	}
-
-	for range m { // want `unnecessary assignment to the blank identifier`
-	}
-
-	// all OK:
-	for x := range m {
-		_ = x
-	}
-	for x, y := range m {
-		_, _ = x, y
-	}
-	for _, y := range m {
-		_ = y
-	}
-	var x int
-	_ = x
-	for y = range m {
-	}
-	for y, x = range m {
-	}
-	for _, x = range m {
-	}
-}
diff -pruN 2022.1-1/simple/testdata/src/receive-blank/receive-blank.go 2022.1.3-1/simple/testdata/src/receive-blank/receive-blank.go
--- 2022.1-1/simple/testdata/src/receive-blank/receive-blank.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/receive-blank/receive-blank.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,15 +0,0 @@
-package pkg
-
-func fn() {
-	var ch chan int
-	<-ch
-	_ = <-ch // want `unnecessary assignment to the blank identifier`
-	select {
-	case <-ch:
-	case _ = <-ch: // want `unnecessary assignment to the blank identifier`
-	}
-	x := <-ch
-	y, _ := <-ch, <-ch
-	_, z := <-ch, <-ch
-	_, _, _ = x, y, z
-}
diff -pruN 2022.1-1/simple/testdata/src/receive-blank/receive-blank.go.golden 2022.1.3-1/simple/testdata/src/receive-blank/receive-blank.go.golden
--- 2022.1-1/simple/testdata/src/receive-blank/receive-blank.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/receive-blank/receive-blank.go.golden	1970-01-01 00:00:00.000000000 +0000
@@ -1,15 +0,0 @@
-package pkg
-
-func fn() {
-	var ch chan int
-	<-ch
-	<-ch // want `unnecessary assignment to the blank identifier`
-	select {
-	case <-ch:
-	case <-ch: // want `unnecessary assignment to the blank identifier`
-	}
-	x := <-ch
-	y, _ := <-ch, <-ch
-	_, z := <-ch, <-ch
-	_, _, _ = x, y, z
-}
diff -pruN 2022.1-1/simple/testdata/src/regexp-raw/regexp-raw.go 2022.1.3-1/simple/testdata/src/regexp-raw/regexp-raw.go
--- 2022.1-1/simple/testdata/src/regexp-raw/regexp-raw.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/regexp-raw/regexp-raw.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,19 +0,0 @@
-package pkg
-
-import "regexp"
-
-func fn2() string { return "" }
-
-func fn() {
-	x := "abc"
-	const y = "abc"
-	regexp.MustCompile(`\\.`)
-	regexp.MustCompile("\\.") // want `should use raw string.+\.MustCompile`
-	regexp.Compile("\\.")     // want `should use raw string.+\.Compile`
-	regexp.Compile("\\.`")
-	regexp.MustCompile("(?m:^lease (.+?) {\n((?s).+?)\\n}\n)")
-	regexp.MustCompile("\\*/[ \t\n\r\f\v]*;")
-	regexp.MustCompile(fn2())
-	regexp.MustCompile(x)
-	regexp.MustCompile(y)
-}
diff -pruN 2022.1-1/simple/testdata/src/single-case-select/single-case-select.go 2022.1.3-1/simple/testdata/src/single-case-select/single-case-select.go
--- 2022.1-1/simple/testdata/src/single-case-select/single-case-select.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/single-case-select/single-case-select.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,28 +0,0 @@
-package pkg
-
-func fn() {
-	var ch chan int
-	select { // want `should use a simple channel send`
-	case <-ch:
-	}
-outer:
-	for { // want `should use for range`
-		select {
-		case <-ch:
-			break outer
-		}
-	}
-
-	for { // want `should use for range`
-		select {
-		case x := <-ch:
-			_ = x
-		}
-	}
-
-	for {
-		select { // want `should use a simple channel send`
-		case ch <- 0:
-		}
-	}
-}
diff -pruN 2022.1-1/simple/testdata/src/slicing/slicing.go 2022.1.3-1/simple/testdata/src/slicing/slicing.go
--- 2022.1-1/simple/testdata/src/slicing/slicing.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/slicing/slicing.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,9 +0,0 @@
-package pkg
-
-func fn() {
-	var s [5]int
-	_ = s[:len(s)] // want `omit second index`
-
-	len := func(s [5]int) int { return -1 }
-	_ = s[:len(s)]
-}
diff -pruN 2022.1-1/simple/testdata/src/slicing/slicing.go.golden 2022.1.3-1/simple/testdata/src/slicing/slicing.go.golden
--- 2022.1-1/simple/testdata/src/slicing/slicing.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/slicing/slicing.go.golden	1970-01-01 00:00:00.000000000 +0000
@@ -1,9 +0,0 @@
-package pkg
-
-func fn() {
-	var s [5]int
-	_ = s[:] // want `omit second index`
-
-	len := func(s [5]int) int { return -1 }
-	_ = s[:len(s)]
-}
diff -pruN 2022.1-1/simple/testdata/src/time-since/time-since.go 2022.1.3-1/simple/testdata/src/time-since/time-since.go
--- 2022.1-1/simple/testdata/src/time-since/time-since.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/time-since/time-since.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,9 +0,0 @@
-package pkg
-
-import "time"
-
-func fn() {
-	t1 := time.Now()
-	_ = time.Now().Sub(t1) // want `time\.Since`
-	_ = time.Date(0, 0, 0, 0, 0, 0, 0, nil).Sub(t1)
-}
diff -pruN 2022.1-1/simple/testdata/src/time-since/time-since.go.golden 2022.1.3-1/simple/testdata/src/time-since/time-since.go.golden
--- 2022.1-1/simple/testdata/src/time-since/time-since.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/time-since/time-since.go.golden	1970-01-01 00:00:00.000000000 +0000
@@ -1,9 +0,0 @@
-package pkg
-
-import "time"
-
-func fn() {
-	t1 := time.Now()
-	_ = time.Since(t1) // want `time\.Since`
-	_ = time.Date(0, 0, 0, 0, 0, 0, 0, nil).Sub(t1)
-}
diff -pruN 2022.1-1/simple/testdata/src/trim/trim.go 2022.1.3-1/simple/testdata/src/trim/trim.go
--- 2022.1-1/simple/testdata/src/trim/trim.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/simple/testdata/src/trim/trim.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,184 +0,0 @@
-package pkg
-
-import (
-	"bytes"
-	"strings"
-)
-
-func foo(s string) int { return 0 }
-func gen() string {
-	return ""
-}
-
-func fn() {
-	const s1 = "a string value"
-	var s2 = "a string value"
-	const n = 14
-
-	var id1 = "a string value"
-	var id2 string
-	if strings.HasPrefix(id1, s1) { // want `should replace.*with.*strings\.TrimPrefix`
-		id1 = id1[len(s1):]
-	}
-
-	if strings.HasPrefix(id1, s1) { // want `should replace.*with.*strings\.TrimPrefix`
-		id1 = strings.TrimPrefix(id1, s1)
-	}
-
-	if strings.HasPrefix(id1, s1) {
-		id1 = strings.TrimPrefix(id1, s2)
-	}
-
-	if strings.Contains(id1, s1) { // want `should replace.*with.*strings\.Replace`
-		id1 = strings.Replace(id1, s1, "something", 123)
-	}
-
-	if strings.HasSuffix(id1, s2) { // want `should replace.*with.*strings\.TrimSuffix`
-		id1 = id1[:len(id1)-len(s2)]
-	}
-
-	var x, y []string
-	var i int
-	if strings.HasPrefix(x[i], s1) { // want `should replace.*with.*strings\.TrimPrefix`
-		x[i] = x[i][len(s1):]
-	}
-
-	if strings.HasPrefix(x[i], y[i]) { // want `should replace.*with.*strings\.TrimPrefix`
-		x[i] = x[i][len(y[i]):]
-	}
-
-	var t struct{ x string }
-	if strings.HasPrefix(t.x, s1) { // want `should replace.*with.*strings\.TrimPrefix`
-		t.x = t.x[len(s1):]
-	}
-
-	if strings.HasPrefix(id1, "test") { // want `should replace.*with.*strings\.TrimPrefix`
-		id1 = id1[len("test"):]
-	}
-
-	if strings.HasPrefix(id1, "test") { // want `should replace.*with.*strings\.TrimPrefix`
-		id1 = id1[4:]
-	}
-
-	if strings.HasPrefix(id1, s1) { // not allowed, 14 and s1 aren't obviously connected
-		id1 = id1[14:]
-	}
-
-	if strings.HasPrefix(id1, s1) { // not allowed, s1 and n aren't obviously connected
-		id1 = id1[n:]
-	}
-
-	var b1, b2 []byte
-	if bytes.HasPrefix(b1, b2) { // want `should replace.*with.*bytes\.TrimPrefix`
-		b1 = b1[len(b2):]
-	}
-
-	id3 := s2
-	if strings.HasPrefix(id1, id3) { // want `should replace.*with.*strings\.TrimPrefix`
-		id1 = id1[len(id3):]
-	}
-
-	if strings.HasSuffix(id1, s2) {
-		id1 = id1[:len(id1)+len(s2)] // wrong operator
-	}
-
-	if strings.HasSuffix(id1, s2) {
-		id1 = id1[:len(s2)-len(id1)] // wrong math
-	}
-
-	if strings.HasSuffix(id1, s2) {
-		id1 = id1[:len(id1)-len(id1)] // wrong string length
-	}
-
-	if strings.HasPrefix(id1, gen()) {
-		id1 = id1[len(gen()):] // dynamic id3
-	}
-
-	if strings.HasPrefix(id1, s1) {
-		id1 = id1[foo(s1):] // wrong function
-	}
-
-	if strings.HasPrefix(id1, s1) {
-		id1 = id1[len(id1):] // len() on wrong value
-	}
-
-	if strings.HasPrefix(id1, "test") {
-		id1 = id1[5:] // wrong length
-	}
-
-	if strings.HasPrefix(id1, s1) {
-		id1 = id1[len(s1)+1:] // wrong length due to math
-	}
-
-	if strings.HasPrefix(id1, s1) {
-		id2 = id1[len(s1):] // assigning to the wrong variable
-	}
-
-	if strings.HasPrefix(id1, s1) {
-		id1 = id1[len(s1):15] // has a max
-	}
-
-	if strings.HasPrefix(id1, s1) {
-		id1 = id2[len(s1):] // assigning the wrong value
-	}
-
-	if strings.HasPrefix(id1, s1) {
-		id1 = id1[len(s1):]
-		id1 += "" // doing more work in the if
-	}
-
-	if strings.HasPrefix(id1, s1) {
-		id1 = id1[len(s1):]
-	} else {
-		id1 = "game over" // else branch
-	}
-
-	if strings.HasPrefix(id1, s1) {
-		// the conditional is guarding additional code
-		id1 = id1[len(s1):]
-		println(id1)
-	}
-
-	if strings.Contains(id1, s1) {
-		id1 = id1[:]
-	}
-}
-
-func fn2() {
-	var s string
-	const id = ".json"
-
-	if strings.HasSuffix(s, ".json") { // want `should replace.*with.*strings\.TrimSuffix`
-		s = strings.TrimSuffix(s, ".json")
-	}
-
-	if strings.HasSuffix(s, ".json") { // want `should replace.*with.*strings\.TrimSuffix`
-		s = s[:len(s)-len(".json")]
-	}
-
-	if strings.HasSuffix(s, ".json") { // want `should replace.*with.*strings\.TrimSuffix`
-		s = s[:len(s)-5]
-	}
-
-	if strings.HasSuffix(s, id) {
-		s = s[:len(s)-5] // second argument of HasSuffix it not a string literal
-	}
-
-	if strings.HasSuffix(s, ".json") {
-		s = s[:len(s)-4] // wrong length
-	}
-}
-
-func fn3() {
-	const s1 = "a string value"
-
-	var id1 = "a string value"
-	len := func(string) int { return 0 } // don't accept non-builtin definition of len
-	if strings.HasPrefix(id1, s1) {
-		id1 = id1[len(s1):]
-	}
-
-	if strings.HasSuffix(id1, s1) {
-		id1 = id1[:len(id1)-len(s1)]
-	}
-}
diff -pruN 2022.1-1/staticcheck/analysis.go 2022.1.3-1/staticcheck/analysis.go
--- 2022.1-1/staticcheck/analysis.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/analysis.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,8 +1,11 @@
 package staticcheck
 
 import (
-	"honnef.co/go/tools/analysis/facts"
+	"honnef.co/go/tools/analysis/facts/deprecated"
+	"honnef.co/go/tools/analysis/facts/generated"
 	"honnef.co/go/tools/analysis/facts/nilness"
+	"honnef.co/go/tools/analysis/facts/purity"
+	"honnef.co/go/tools/analysis/facts/tokenfile"
 	"honnef.co/go/tools/analysis/facts/typedness"
 	"honnef.co/go/tools/analysis/lint"
 	"honnef.co/go/tools/internal/passes/buildir"
@@ -12,7 +15,7 @@ import (
 )
 
 func makeCallCheckerAnalyzer(rules map[string]CallCheck, extraReqs ...*analysis.Analyzer) *analysis.Analyzer {
-	reqs := []*analysis.Analyzer{buildir.Analyzer, facts.TokenFile}
+	reqs := []*analysis.Analyzer{buildir.Analyzer, tokenfile.Analyzer}
 	reqs = append(reqs, extraReqs...)
 	return &analysis.Analyzer{
 		Run:      callChecker(rules),
@@ -68,7 +71,7 @@ var Analyzers = lint.InitializeAnalyzers
 	"SA1018": makeCallCheckerAnalyzer(checkStringsReplaceZeroRules),
 	"SA1019": {
 		Run:      CheckDeprecated,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Deprecated, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, deprecated.Analyzer, generated.Analyzer},
 	},
 	"SA1020": makeCallCheckerAnalyzer(checkListenAddressRules),
 	"SA1021": makeCallCheckerAnalyzer(checkBytesEqualIPRules),
@@ -115,7 +118,7 @@ var Analyzers = lint.InitializeAnalyzers
 
 	"SA4000": {
 		Run:      CheckLhsRhsIdentical,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.TokenFile, facts.Generated},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, tokenfile.Analyzer, generated.Analyzer},
 	},
 	"SA4001": {
 		Run:      CheckIneffectiveCopy,
@@ -135,7 +138,7 @@ var Analyzers = lint.InitializeAnalyzers
 	},
 	"SA4006": {
 		Run:      CheckUnreadVariableValues,
-		Requires: []*analysis.Analyzer{buildir.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{buildir.Analyzer, generated.Analyzer},
 	},
 	"SA4008": {
 		Run:      CheckLoopCondition,
@@ -168,19 +171,19 @@ var Analyzers = lint.InitializeAnalyzers
 	"SA4015": makeCallCheckerAnalyzer(checkMathIntRules),
 	"SA4016": {
 		Run:      CheckSillyBitwiseOps,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.TokenFile},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, tokenfile.Analyzer},
 	},
 	"SA4017": {
 		Run:      CheckPureFunctions,
-		Requires: []*analysis.Analyzer{buildir.Analyzer, facts.Purity},
+		Requires: []*analysis.Analyzer{buildir.Analyzer, purity.Analyzer},
 	},
 	"SA4018": {
 		Run:      CheckSelfAssignment,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated, facts.TokenFile, facts.Purity},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer, tokenfile.Analyzer, purity.Analyzer},
 	},
 	"SA4019": {
 		Run:      CheckDuplicateBuildConstraints,
-		Requires: []*analysis.Analyzer{facts.Generated},
+		Requires: []*analysis.Analyzer{generated.Analyzer},
 	},
 	"SA4020": {
 		Run:      CheckUnreachableTypeCases,
@@ -188,7 +191,7 @@ var Analyzers = lint.InitializeAnalyzers
 	},
 	"SA4021": {
 		Run:      CheckSingleArgAppend,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated, facts.TokenFile},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer, tokenfile.Analyzer},
 	},
 	"SA4022": {
 		Run:      CheckAddressIsNil,
@@ -228,7 +231,7 @@ var Analyzers = lint.InitializeAnalyzers
 	},
 	"SA4031": {
 		Run:      CheckAllocationNilCheck,
-		Requires: []*analysis.Analyzer{buildir.Analyzer, inspect.Analyzer, facts.TokenFile},
+		Requires: []*analysis.Analyzer{buildir.Analyzer, inspect.Analyzer, tokenfile.Analyzer},
 	},
 
 	"SA5000": {
@@ -266,7 +269,7 @@ var Analyzers = lint.InitializeAnalyzers
 	"SA5009": makeCallCheckerAnalyzer(checkPrintfRules),
 	"SA5010": {
 		Run:      CheckImpossibleTypeAssertion,
-		Requires: []*analysis.Analyzer{buildir.Analyzer, facts.TokenFile},
+		Requires: []*analysis.Analyzer{buildir.Analyzer, tokenfile.Analyzer},
 	},
 	"SA5011": {
 		Run:      CheckMaybeNil,
@@ -303,14 +306,14 @@ var Analyzers = lint.InitializeAnalyzers
 	},
 	"SA9003": {
 		Run:      CheckEmptyBranch,
-		Requires: []*analysis.Analyzer{buildir.Analyzer, facts.TokenFile, facts.Generated},
+		Requires: []*analysis.Analyzer{buildir.Analyzer, tokenfile.Analyzer, generated.Analyzer},
 	},
 	"SA9004": {
 		Run:      CheckMissingEnumTypesInDeclaration,
 		Requires: []*analysis.Analyzer{inspect.Analyzer},
 	},
 	// Filtering generated code because it may include empty structs generated from data models.
-	"SA9005": makeCallCheckerAnalyzer(checkNoopMarshal, facts.Generated),
+	"SA9005": makeCallCheckerAnalyzer(checkNoopMarshal, generated.Analyzer),
 	"SA9006": {
 		Run:      CheckStaticBitShift,
 		Requires: []*analysis.Analyzer{inspect.Analyzer},
@@ -322,6 +325,6 @@ var Analyzers = lint.InitializeAnalyzers
 
 	"SA9008": {
 		Run:      CheckTypeAssertionShadowingElse,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, buildir.Analyzer, facts.TokenFile},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, buildir.Analyzer, tokenfile.Analyzer},
 	},
 })
diff -pruN 2022.1-1/staticcheck/doc.go 2022.1.3-1/staticcheck/doc.go
--- 2022.1-1/staticcheck/doc.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/doc.go	2022-07-31 15:38:22.000000000 +0000
@@ -446,7 +446,7 @@ falsify results.`,
 		Title:    `The variable in the loop condition never changes, are you incrementing the wrong variable?`,
 		Since:    "2017.1",
 		Severity: lint.SeverityWarning,
-		MergeIf:  lint.MergeIfAny,
+		MergeIf:  lint.MergeIfAll,
 	},
 
 	"SA4009": {
diff -pruN 2022.1-1/staticcheck/fakejson/encode.go 2022.1.3-1/staticcheck/fakejson/encode.go
--- 2022.1-1/staticcheck/fakejson/encode.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/fakejson/encode.go	2022-07-31 15:38:22.000000000 +0000
@@ -11,12 +11,14 @@
 package fakejson
 
 import (
-	"go/token"
 	"go/types"
 	"sort"
 	"strings"
 	"unicode"
 
+	"golang.org/x/exp/typeparams"
+	"honnef.co/go/tools/go/types/typeutil"
+	"honnef.co/go/tools/knowledge"
 	"honnef.co/go/tools/staticcheck/fakereflect"
 )
 
@@ -30,9 +32,7 @@ func parseTag(tag string) string {
 }
 
 func Marshal(v types.Type) *UnsupportedTypeError {
-	enc := encoder{
-		seen: map[fakereflect.TypeAndCanAddr]struct{}{},
-	}
+	enc := encoder{}
 	return enc.newTypeEncoder(fakereflect.TypeAndCanAddr{Type: v}, "x")
 }
 
@@ -43,46 +43,35 @@ type UnsupportedTypeError struct {
 	Path string
 }
 
-var marshalerType = types.NewInterfaceType([]*types.Func{
-	types.NewFunc(token.NoPos, nil, "MarshalJSON", types.NewSignature(nil,
-		types.NewTuple(),
-		types.NewTuple(
-			types.NewVar(token.NoPos, nil, "", types.NewSlice(types.Typ[types.Byte])),
-			types.NewVar(0, nil, "", types.Universe.Lookup("error").Type())),
-		false,
-	)),
-}, nil).Complete()
-
-var textMarshalerType = types.NewInterfaceType([]*types.Func{
-	types.NewFunc(token.NoPos, nil, "MarshalText", types.NewSignature(nil,
-		types.NewTuple(),
-		types.NewTuple(
-			types.NewVar(token.NoPos, nil, "", types.NewSlice(types.Typ[types.Byte])),
-			types.NewVar(0, nil, "", types.Universe.Lookup("error").Type())),
-		false,
-	)),
-}, nil).Complete()
-
 type encoder struct {
-	seen map[fakereflect.TypeAndCanAddr]struct{}
+	// TODO we track addressable and non-addressable instances separately out of an abundance of caution. We don't know
+	// if this is actually required for correctness.
+	seenCanAddr  typeutil.Map
+	seenCantAddr typeutil.Map
 }
 
 func (enc *encoder) newTypeEncoder(t fakereflect.TypeAndCanAddr, stack string) *UnsupportedTypeError {
-	if _, ok := enc.seen[t]; ok {
+	var m *typeutil.Map
+	if t.CanAddr() {
+		m = &enc.seenCanAddr
+	} else {
+		m = &enc.seenCantAddr
+	}
+	if ok := m.At(t.Type); ok != nil {
 		return nil
 	}
-	enc.seen[t] = struct{}{}
+	m.Set(t.Type, struct{}{})
 
-	if t.Implements(marshalerType) {
+	if t.Implements(knowledge.Interfaces["encoding/json.Marshaler"]) {
 		return nil
 	}
-	if !t.IsPtr() && t.CanAddr() && fakereflect.PtrTo(t).Implements(marshalerType) {
+	if !t.IsPtr() && t.CanAddr() && fakereflect.PtrTo(t).Implements(knowledge.Interfaces["encoding/json.Marshaler"]) {
 		return nil
 	}
-	if t.Implements(textMarshalerType) {
+	if t.Implements(knowledge.Interfaces["encoding.TextMarshaler"]) {
 		return nil
 	}
-	if !t.IsPtr() && t.CanAddr() && fakereflect.PtrTo(t).Implements(textMarshalerType) {
+	if !t.IsPtr() && t.CanAddr() && fakereflect.PtrTo(t).Implements(knowledge.Interfaces["encoding.TextMarshaler"]) {
 		return nil
 	}
 
@@ -106,10 +95,18 @@ func (enc *encoder) newTypeEncoder(t fak
 }
 
 func (enc *encoder) newMapEncoder(t fakereflect.TypeAndCanAddr, stack string) *UnsupportedTypeError {
+	if typeparams.IsTypeParam(t.Key().Type) {
+		// We don't know enough about the concrete instantiation to say much about the key. The only time we could make
+		// a definite "this key is bad" statement is if the type parameter is constrained by type terms, none of which
+		// are tilde terms, none of which are a basic type. In all other cases, the key might implement TextMarshaler.
+		// It doesn't seem worth checking for that one single case.
+		return enc.newTypeEncoder(t.Elem(), stack+"[k]")
+	}
+
 	switch t.Key().Type.Underlying().(type) {
 	case *types.Basic:
 	default:
-		if !t.Key().Implements(textMarshalerType) {
+		if !t.Key().Implements(knowledge.Interfaces["encoding.TextMarshaler"]) {
 			return &UnsupportedTypeError{
 				Type: t.Type,
 				Path: stack,
@@ -124,7 +121,7 @@ func (enc *encoder) newSliceEncoder(t fa
 	basic, ok := t.Elem().Type.Underlying().(*types.Basic)
 	if ok && basic.Kind() == types.Uint8 {
 		p := fakereflect.PtrTo(t.Elem())
-		if !p.Implements(marshalerType) && !p.Implements(textMarshalerType) {
+		if !p.Implements(knowledge.Interfaces["encoding/json.Marshaler"]) && !p.Implements(knowledge.Interfaces["encoding.TextMarshaler"]) {
 			return nil
 		}
 	}
diff -pruN 2022.1-1/staticcheck/fakexml/marshal.go 2022.1.3-1/staticcheck/fakexml/marshal.go
--- 2022.1-1/staticcheck/fakexml/marshal.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/fakexml/marshal.go	2022-07-31 15:38:22.000000000 +0000
@@ -14,10 +14,10 @@ package fakexml
 
 import (
 	"fmt"
-	"go/token"
 	"go/types"
 
 	"honnef.co/go/tools/go/types/typeutil"
+	"honnef.co/go/tools/knowledge"
 	"honnef.co/go/tools/staticcheck/fakereflect"
 )
 
@@ -26,13 +26,14 @@ func Marshal(v types.Type) error {
 }
 
 type Encoder struct {
-	seen map[fakereflect.TypeAndCanAddr]struct{}
+	// TODO we track addressable and non-addressable instances separately out of an abundance of caution. We don't know
+	// if this is actually required for correctness.
+	seenCanAddr  typeutil.Map
+	seenCantAddr typeutil.Map
 }
 
 func NewEncoder() *Encoder {
-	e := &Encoder{
-		seen: map[fakereflect.TypeAndCanAddr]struct{}{},
-	}
+	e := &Encoder{}
 	return e
 }
 
@@ -101,32 +102,41 @@ func implementsMarshalerAttr(v fakerefle
 	return true
 }
 
-var textMarshalerType = types.NewInterfaceType([]*types.Func{
-	types.NewFunc(token.NoPos, nil, "MarshalText", types.NewSignature(nil,
-		types.NewTuple(),
-		types.NewTuple(
-			types.NewVar(token.NoPos, nil, "", types.NewSlice(types.Typ[types.Byte])),
-			types.NewVar(0, nil, "", types.Universe.Lookup("error").Type())),
-		false,
-	)),
-}, nil).Complete()
+type CyclicTypeError struct {
+	Type types.Type
+	Path string
+}
 
-var N = 0
+func (err *CyclicTypeError) Error() string {
+	return "cyclic type"
+}
 
 // marshalValue writes one or more XML elements representing val.
 // If val was obtained from a struct field, finfo must have its details.
 func (e *Encoder) marshalValue(val fakereflect.TypeAndCanAddr, finfo *fieldInfo, startTemplate *StartElement, stack string) error {
-	if _, ok := e.seen[val]; ok {
+	var m *typeutil.Map
+	if val.CanAddr() {
+		m = &e.seenCanAddr
+	} else {
+		m = &e.seenCantAddr
+	}
+	if ok := m.At(val.Type); ok != nil {
 		return nil
 	}
-	e.seen[val] = struct{}{}
+	m.Set(val.Type, struct{}{})
 
 	// Drill into interfaces and pointers.
+	seen := map[fakereflect.TypeAndCanAddr]struct{}{}
 	for val.IsInterface() || val.IsPtr() {
 		if val.IsInterface() {
 			return nil
 		}
 		val = val.Elem()
+		if _, ok := seen[val]; ok {
+			// Loop in type graph, e.g. 'type P *P'
+			return &CyclicTypeError{val.Type, stack}
+		}
+		seen[val] = struct{}{}
 	}
 
 	// Check for marshaler.
@@ -141,12 +151,12 @@ func (e *Encoder) marshalValue(val faker
 	}
 
 	// Check for text marshaler.
-	if val.Implements(textMarshalerType) {
+	if val.Implements(knowledge.Interfaces["encoding.TextMarshaler"]) {
 		return nil
 	}
 	if val.CanAddr() {
 		pv := fakereflect.PtrTo(val)
-		if pv.Implements(textMarshalerType) {
+		if pv.Implements(knowledge.Interfaces["encoding.TextMarshaler"]) {
 			return nil
 		}
 	}
@@ -245,13 +255,13 @@ func (e *Encoder) marshalAttr(start *Sta
 		}
 	}
 
-	if val.Implements(textMarshalerType) {
+	if val.Implements(knowledge.Interfaces["encoding.TextMarshaler"]) {
 		return nil
 	}
 
 	if val.CanAddr() {
 		pv := fakereflect.PtrTo(val)
-		if pv.Implements(textMarshalerType) {
+		if pv.Implements(knowledge.Interfaces["encoding.TextMarshaler"]) {
 			return nil
 		}
 	}
@@ -320,17 +330,15 @@ func (e *Encoder) marshalStruct(tinfo *t
 
 		switch finfo.flags & fMode {
 		case fCDATA, fCharData:
-			if vf.Implements(textMarshalerType) {
+			if vf.Implements(knowledge.Interfaces["encoding.TextMarshaler"]) {
 				continue
 			}
 			if vf.CanAddr() {
 				pv := fakereflect.PtrTo(vf)
-				if pv.Implements(textMarshalerType) {
+				if pv.Implements(knowledge.Interfaces["encoding.TextMarshaler"]) {
 					continue
 				}
 			}
-
-			vf = indirect(vf)
 			continue
 
 		case fComment:
diff -pruN 2022.1-1/staticcheck/fakexml/typeinfo.go 2022.1.3-1/staticcheck/fakexml/typeinfo.go
--- 2022.1-1/staticcheck/fakexml/typeinfo.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/fakexml/typeinfo.go	2022-07-31 15:38:22.000000000 +0000
@@ -249,8 +249,14 @@ func StructFieldInfo(f fakereflect.Struc
 // in case it exists and has a valid xml field tag, otherwise
 // it returns nil.
 func lookupXMLName(typ fakereflect.TypeAndCanAddr) (xmlname *fieldInfo) {
+	seen := map[fakereflect.TypeAndCanAddr]struct{}{}
 	for typ.IsPtr() {
 		typ = typ.Elem()
+		if _, ok := seen[typ]; ok {
+			// Loop in type graph, e.g. 'type P *P'
+			return nil
+		}
+		seen[typ] = struct{}{}
 	}
 	if !typ.IsStruct() {
 		return nil
diff -pruN 2022.1-1/staticcheck/lint.go 2022.1.3-1/staticcheck/lint.go
--- 2022.1-1/staticcheck/lint.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/lint.go	2022-07-31 15:38:22.000000000 +0000
@@ -20,8 +20,10 @@ import (
 
 	"honnef.co/go/tools/analysis/code"
 	"honnef.co/go/tools/analysis/edit"
-	"honnef.co/go/tools/analysis/facts"
+	"honnef.co/go/tools/analysis/facts/deprecated"
+	"honnef.co/go/tools/analysis/facts/generated"
 	"honnef.co/go/tools/analysis/facts/nilness"
+	"honnef.co/go/tools/analysis/facts/purity"
 	"honnef.co/go/tools/analysis/facts/typedness"
 	"honnef.co/go/tools/analysis/lint"
 	"honnef.co/go/tools/analysis/report"
@@ -500,51 +502,6 @@ func checkPrintfCallImpl(carg *Argument,
 		return ok && basic.Info()&info != 0
 	}
 
-	isStringer := func(T types.Type, ms *types.MethodSet) bool {
-		sel := ms.Lookup(nil, "String")
-		if sel == nil {
-			return false
-		}
-		fn, ok := sel.Obj().(*types.Func)
-		if !ok {
-			// should be unreachable
-			return false
-		}
-		sig := fn.Type().(*types.Signature)
-		if sig.Params().Len() != 0 {
-			return false
-		}
-		if sig.Results().Len() != 1 {
-			return false
-		}
-		if !typeutil.IsType(sig.Results().At(0).Type(), "string") {
-			return false
-		}
-		return true
-	}
-	isError := func(T types.Type, ms *types.MethodSet) bool {
-		sel := ms.Lookup(nil, "Error")
-		if sel == nil {
-			return false
-		}
-		fn, ok := sel.Obj().(*types.Func)
-		if !ok {
-			// should be unreachable
-			return false
-		}
-		sig := fn.Type().(*types.Signature)
-		if sig.Params().Len() != 0 {
-			return false
-		}
-		if sig.Results().Len() != 1 {
-			return false
-		}
-		if !typeutil.IsType(sig.Results().At(0).Type(), "string") {
-			return false
-		}
-		return true
-	}
-
 	isFormatter := func(T types.Type, ms *types.MethodSet) bool {
 		sel := ms.Lookup(nil, "Format")
 		if sel == nil {
@@ -567,18 +524,16 @@ func checkPrintfCallImpl(carg *Argument,
 		return true
 	}
 
-	seen := map[types.Type]bool{}
+	var seen typeutil.Map
 	var checkType func(verb rune, T types.Type, top bool) bool
 	checkType = func(verb rune, T types.Type, top bool) bool {
 		if top {
-			for k := range seen {
-				delete(seen, k)
-			}
+			seen = typeutil.Map{}
 		}
-		if seen[T] {
+		if ok := seen.At(T); ok != nil {
 			return true
 		}
-		seen[T] = true
+		seen.Set(T, struct{}{})
 		if int(verb) >= len(verbs) {
 			// Unknown verb
 			return true
@@ -596,7 +551,7 @@ func checkPrintfCallImpl(carg *Argument,
 			return true
 		}
 
-		if flags&isString != 0 && (isStringer(T, ms) || isError(T, ms)) {
+		if flags&isString != 0 && (types.Implements(T, knowledge.Interfaces["fmt.Stringer"]) || types.Implements(T, knowledge.Interfaces["error"])) {
 			// Check for stringer early because we're about to dereference
 			return true
 		}
@@ -652,7 +607,7 @@ func checkPrintfCallImpl(carg *Argument,
 					return true
 				}
 			}
-			if isStringer(T, ms) || isError(T, ms) {
+			if types.Implements(T, knowledge.Interfaces["fmt.Stringer"]) || types.Implements(T, knowledge.Interfaces["error"]) {
 				return true
 			}
 		}
@@ -897,6 +852,13 @@ func checkUnsupportedMarshalXML(call *Ca
 			} else {
 				arg.Invalid(fmt.Sprintf("trying to marshal unsupported type %s, via %s", typ, err.Path))
 			}
+		case *fakexml.CyclicTypeError:
+			typ := types.TypeString(err.Type, types.RelativeTo(arg.Value.Value.Parent().Pkg.Pkg))
+			if err.Path == "x" {
+				arg.Invalid(fmt.Sprintf("trying to marshal cyclic type %s", typ))
+			} else {
+				arg.Invalid(fmt.Sprintf("trying to marshal cyclic type %s, via %s", typ, err.Path))
+			}
 		case *fakexml.TagPathError:
 			// Vet does a better job at reporting this error, because it can flag the actual struct tags, not just the call to Marshal
 		default:
@@ -1027,7 +989,8 @@ func CheckTemplate(pass *analysis.Pass)
 		}
 		if err != nil {
 			// TODO(dominikh): whitelist other parse errors, if any
-			if strings.Contains(err.Error(), "unexpected") {
+			if strings.Contains(err.Error(), "unexpected") ||
+				strings.Contains(err.Error(), "bad character") {
 				report.Report(pass, call.Args[knowledge.Arg("(*text/template.Template).Parse.text")], err.Error())
 			}
 		}
@@ -1037,7 +1000,7 @@ func CheckTemplate(pass *analysis.Pass)
 }
 
 var (
-	checkTimeSleepConstantPatternQ   = pattern.MustParse(`(CallExpr (Function "time.Sleep") lit@(IntegerLiteral value))`)
+	checkTimeSleepConstantPatternQ   = pattern.MustParse(`(CallExpr (Symbol "time.Sleep") lit@(IntegerLiteral value))`)
 	checkTimeSleepConstantPatternRns = pattern.MustParse(`(BinaryExpr duration "*" (SelectorExpr (Ident "time") (Ident "Nanosecond")))`)
 	checkTimeSleepConstantPatternRs  = pattern.MustParse(`(BinaryExpr duration "*" (SelectorExpr (Ident "time") (Ident "Second")))`)
 )
@@ -1074,7 +1037,7 @@ var checkWaitgroupAddQ = pattern.MustPar
 		(CallExpr
 			(FuncLit
 				_
-				call@(CallExpr (Function "(*sync.WaitGroup).Add") _):_) _))`)
+				call@(CallExpr (Symbol "(*sync.WaitGroup).Add") _):_) _))`)
 
 func CheckWaitgroupAdd(pass *analysis.Pass) (interface{}, error) {
 	fn := func(node ast.Node) {
@@ -1789,7 +1752,7 @@ func CheckUnreadVariableValues(pass *ana
 		if node == nil {
 			continue
 		}
-		if gen, ok := code.Generator(pass, node.Pos()); ok && gen == facts.Goyacc {
+		if gen, ok := code.Generator(pass, node.Pos()); ok && gen == generated.Goyacc {
 			// Don't flag unused values in code generated by goyacc.
 			// There may be hundreds of those due to the way the state
 			// machine is constructed.
@@ -2365,7 +2328,7 @@ func CheckIneffectiveLoop(pass *analysis
 	return nil, nil
 }
 
-var checkNilContextQ = pattern.MustParse(`(CallExpr fun@(Function _) (Builtin "nil"):_)`)
+var checkNilContextQ = pattern.MustParse(`(CallExpr fun@(Symbol _) (Builtin "nil"):_)`)
 
 func CheckNilContext(pass *analysis.Pass) (interface{}, error) {
 	todo := &ast.CallExpr{
@@ -2406,13 +2369,16 @@ func CheckNilContext(pass *analysis.Pass
 }
 
 var (
-	checkSeekerQ = pattern.MustParse(`(CallExpr fun@(SelectorExpr _ (Ident "Seek")) [arg1@(SelectorExpr (Ident "io") (Ident (Or "SeekStart" "SeekCurrent" "SeekEnd"))) arg2])`)
+	checkSeekerQ = pattern.MustParse(`(CallExpr fun@(SelectorExpr _ (Ident "Seek")) [arg1@(SelectorExpr _ (Symbol (Or "io.SeekStart" "io.SeekCurrent" "io.SeekEnd"))) arg2])`)
 	checkSeekerR = pattern.MustParse(`(CallExpr fun [arg2 arg1])`)
 )
 
 func CheckSeeker(pass *analysis.Pass) (interface{}, error) {
 	fn := func(node ast.Node) {
-		if _, edits, ok := code.MatchAndEdit(pass, checkSeekerQ, checkSeekerR, node); ok {
+		if m, edits, ok := code.MatchAndEdit(pass, checkSeekerQ, checkSeekerR, node); ok {
+			if !code.IsMethod(pass, m.State["fun"].(*ast.SelectorExpr), "Seek", knowledge.Signatures["(io.Seeker).Seek"]) {
+				return
+			}
 			report.Report(pass, node, "the first argument of io.Seeker is the offset, but an io.Seek* constant is being used instead",
 				report.Fixes(edit.Fix("swap arguments", edits...)))
 		}
@@ -2845,21 +2811,6 @@ func CheckInfiniteRecursion(pass *analys
 	return nil, nil
 }
 
-func objectName(obj types.Object) string {
-	if obj == nil {
-		return "<nil>"
-	}
-	var name string
-	if obj.Pkg() != nil && obj.Pkg().Scope().Lookup(obj.Name()) == obj {
-		s := obj.Pkg().Path()
-		if s != "" {
-			name += s + "."
-		}
-	}
-	name += obj.Name()
-	return name
-}
-
 func CheckLeakyTimeTick(pass *analysis.Pass) (interface{}, error) {
 	for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
 		if code.IsMainLike(pass) || code.IsInTest(pass, fn) {
@@ -3059,7 +3010,7 @@ func CheckNonOctalFileMode(pass *analysi
 }
 
 func CheckPureFunctions(pass *analysis.Pass) (interface{}, error) {
-	pure := pass.ResultOf[facts.Purity].(facts.PurityResult)
+	pure := pass.ResultOf[purity.Analyzer].(purity.Result)
 
 fnLoop:
 	for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
@@ -3113,19 +3064,92 @@ fnLoop:
 }
 
 func CheckDeprecated(pass *analysis.Pass) (interface{}, error) {
-	deprs := pass.ResultOf[facts.Deprecated].(facts.DeprecatedResult)
+	deprs := pass.ResultOf[deprecated.Analyzer].(deprecated.Result)
 
 	// Selectors can appear outside of function literals, e.g. when
 	// declaring package level variables.
 
-	isStdlib := func(obj types.Object) bool {
+	isStdlibPath := func(path string) bool {
 		// Modules with no dot in the first path element are reserved for the standard library and tooling.
 		// This is the best we can currently do.
 		// Nobody tells us which import paths are part of the standard library.
 		//
 		// We check the entire path instead of just the first path element, because the standard library doesn't contain paths with any dots, anyway.
 
-		return !strings.Contains(obj.Pkg().Path(), ".")
+		return !strings.Contains(path, ".")
+	}
+
+	handleDeprecation := func(depr *deprecated.IsDeprecated, node ast.Node, deprecatedObjName string, pkgPath string, tfn types.Object) {
+		// Note: gopls doesn't correctly run analyzers on
+		// dependencies, so we'll never be able to find deprecated
+		// objects in imported code. We've experimented with
+		// lifting the stdlib handling out of the general check,
+		// to at least work for deprecated objects in the stdlib,
+		// but we gave up on that, because we wouldn't have access
+		// to the deprecation message.
+		std, ok := knowledge.StdlibDeprecations[deprecatedObjName]
+		if !ok && isStdlibPath(pkgPath) {
+			// Deprecated object in the standard library, but we don't know the details of the deprecation.
+			// Don't flag it at all, to avoid flagging an object that was deprecated in 1.N when targeting 1.N-1.
+			// See https://staticcheck.io/issues/1108 for the background on this.
+			return
+		}
+		if ok {
+			switch std.AlternativeAvailableSince {
+			case knowledge.DeprecatedNeverUse:
+				// This should never be used, regardless of the
+				// targeted Go version. Examples include insecure
+				// cryptography or inherently broken APIs.
+				//
+				// We always want to flag these.
+			case knowledge.DeprecatedUseNoLonger:
+				// This should no longer be used. Using it with
+				// older Go versions might still make sense.
+				if !code.IsGoVersion(pass, std.DeprecatedSince) {
+					return
+				}
+			default:
+				if std.AlternativeAvailableSince < 0 {
+					panic(fmt.Sprintf("unhandled case %d", std.AlternativeAvailableSince))
+				}
+				// Look for the first available alternative, not the first
+				// version something was deprecated in. If a function was
+				// deprecated in Go 1.6, an alternative has been available
+				// already in 1.0, and we're targeting 1.2, it still
+				// makes sense to use the alternative from 1.0, to be
+				// future-proof.
+				if !code.IsGoVersion(pass, std.AlternativeAvailableSince) {
+					return
+				}
+			}
+		}
+
+		if tfn != nil {
+			if _, ok := deprs.Objects[tfn]; ok {
+				// functions that are deprecated may use deprecated
+				// symbols
+				return
+			}
+		}
+
+		if ok {
+			switch std.AlternativeAvailableSince {
+			case knowledge.DeprecatedNeverUse:
+				report.Report(pass, node,
+					fmt.Sprintf("%s has been deprecated since Go 1.%d because it shouldn't be used: %s",
+						report.Render(pass, node), std.DeprecatedSince, depr.Msg))
+			case std.DeprecatedSince, knowledge.DeprecatedUseNoLonger:
+				report.Report(pass, node,
+					fmt.Sprintf("%s has been deprecated since Go 1.%d: %s",
+						report.Render(pass, node), std.DeprecatedSince, depr.Msg))
+			default:
+				report.Report(pass, node,
+					fmt.Sprintf("%s has been deprecated since Go 1.%d and an alternative has been available since Go 1.%d: %s",
+						report.Render(pass, node), std.DeprecatedSince, std.AlternativeAvailableSince, depr.Msg))
+			}
+		} else {
+			report.Report(pass, node, fmt.Sprintf("%s is deprecated: %s", report.Render(pass, node), depr.Msg))
+		}
 	}
 
 	var tfn types.Object
@@ -3160,70 +3184,7 @@ func CheckDeprecated(pass *analysis.Pass
 		}
 
 		if depr, ok := deprs.Objects[obj]; ok {
-			// Note: gopls doesn't correctly run analyzers on
-			// dependencies, so we'll never be able to find deprecated
-			// objects in imported code. We've experimented with
-			// lifting the stdlib handling out of the general check,
-			// to at least work for deprecated objects in the stdlib,
-			// but we gave up on that, because we wouldn't have access
-			// to the deprecation message.
-			std, ok := knowledge.StdlibDeprecations[code.SelectorName(pass, sel)]
-			if !ok && isStdlib(obj) {
-				// Deprecated object in the standard library, but we don't know the details of the deprecation.
-				// Don't flag it at all, to avoid flagging an object that was deprecated in 1.N when targeting 1.N-1.
-				// See https://staticcheck.io/issues/1108 for the background on this.
-				return true
-			}
-			if ok {
-				switch std.AlternativeAvailableSince {
-				case knowledge.DeprecatedNeverUse:
-					// This should never be used, regardless of the
-					// targeted Go version. Examples include insecure
-					// cryptography or inherently broken APIs.
-					//
-					// We always want to flag these.
-				case knowledge.DeprecatedUseNoLonger:
-					// This should no longer be used. Using it with
-					// older Go versions might still make sense.
-					if !code.IsGoVersion(pass, std.DeprecatedSince) {
-						return true
-					}
-				default:
-					if std.AlternativeAvailableSince < 0 {
-						panic(fmt.Sprintf("unhandled case %d", std.AlternativeAvailableSince))
-					}
-					// Look for the first available alternative, not the first
-					// version something was deprecated in. If a function was
-					// deprecated in Go 1.6, an alternative has been available
-					// already in 1.0, and we're targeting 1.2, it still
-					// makes sense to use the alternative from 1.0, to be
-					// future-proof.
-					if !code.IsGoVersion(pass, std.AlternativeAvailableSince) {
-						return true
-					}
-				}
-			}
-
-			if tfn != nil {
-				if _, ok := deprs.Objects[tfn]; ok {
-					// functions that are deprecated may use deprecated
-					// symbols
-					return true
-				}
-			}
-
-			if ok {
-				if std.AlternativeAvailableSince == knowledge.DeprecatedNeverUse {
-					report.Report(pass, sel, fmt.Sprintf("%s has been deprecated since Go 1.%d because it shouldn't be used: %s", report.Render(pass, sel), std.DeprecatedSince, depr.Msg))
-				} else if std.AlternativeAvailableSince == std.DeprecatedSince || std.AlternativeAvailableSince == knowledge.DeprecatedUseNoLonger {
-					report.Report(pass, sel, fmt.Sprintf("%s has been deprecated since Go 1.%d: %s", report.Render(pass, sel), std.DeprecatedSince, depr.Msg))
-				} else {
-					report.Report(pass, sel, fmt.Sprintf("%s has been deprecated since Go 1.%d and an alternative has been available since Go 1.%d: %s", report.Render(pass, sel), std.DeprecatedSince, std.AlternativeAvailableSince, depr.Msg))
-				}
-			} else {
-				report.Report(pass, sel, fmt.Sprintf("%s is deprecated: %s", report.Render(pass, sel), depr.Msg))
-			}
-			return true
+			handleDeprecation(depr, sel, code.SelectorName(pass, sel), obj.Pkg().Path(), tfn)
 		}
 		return true
 	}
@@ -3242,11 +3203,12 @@ func CheckDeprecated(pass *analysis.Pass
 		if depr, ok := deprs.Packages[imp]; ok {
 			if path == "github.com/golang/protobuf/proto" {
 				gen, ok := code.Generator(pass, spec.Path.Pos())
-				if ok && gen == facts.ProtocGenGo {
+				if ok && gen == generated.ProtocGenGo {
 					return
 				}
 			}
-			report.Report(pass, spec, fmt.Sprintf("package %s is deprecated: %s", path, depr.Msg))
+
+			handleDeprecation(depr, spec.Path, path, path, nil)
 		}
 	}
 	pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Nodes(nil, fn)
@@ -3509,7 +3471,7 @@ func CheckRangeStringRunes(pass *analysi
 }
 
 func CheckSelfAssignment(pass *analysis.Pass) (interface{}, error) {
-	pure := pass.ResultOf[facts.Purity].(facts.PurityResult)
+	pure := pass.ResultOf[purity.Analyzer].(purity.Result)
 
 	fn := func(node ast.Node) {
 		assign := node.(*ast.AssignStmt)
@@ -3748,7 +3710,7 @@ func CheckTimerResetReturnValue(pass *an
 var (
 	checkToLowerToUpperComparisonQ = pattern.MustParse(`
 	(BinaryExpr
-		(CallExpr fun@(Function (Or "strings.ToLower" "strings.ToUpper")) [a])
+		(CallExpr fun@(Symbol (Or "strings.ToLower" "strings.ToUpper")) [a])
  		tok@(Or "==" "!=")
  		(CallExpr fun [b]))`)
 	checkToLowerToUpperComparisonR = pattern.MustParse(`(CallExpr (SelectorExpr (Ident "strings") (Ident "EqualFold")) [a b])`)
@@ -3930,22 +3892,23 @@ func checkJSONTag(pass *analysis.Pass, f
 	//lint:ignore SA9003 TODO(dh): should we flag empty tags?
 	if len(tag) == 0 {
 	}
+	if i := strings.Index(tag, ",format:"); i >= 0 {
+		tag = tag[:i]
+	}
 	fields := strings.Split(tag, ",")
 	for _, r := range fields[0] {
 		if !unicode.IsLetter(r) && !unicode.IsDigit(r) && !strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", r) {
 			report.Report(pass, field.Tag, fmt.Sprintf("invalid JSON field name %q", fields[0]))
 		}
 	}
-	var co, cs, ci int
+	options := make(map[string]int)
 	for _, s := range fields[1:] {
 		switch s {
-		case "omitempty":
-			co++
 		case "":
 			// allow stuff like "-,"
 		case "string":
-			cs++
 			// only for string, floating point, integer and bool
+			options[s]++
 			tset := typeutil.NewTypeSet(pass.TypesInfo.TypeOf(field.Type))
 			if len(tset.Terms) == 0 {
 				// TODO(dh): improve message, call out the use of type parameters
@@ -3962,20 +3925,23 @@ func checkJSONTag(pass *analysis.Pass, f
 					}
 				}
 			}
-		case "inline":
-			ci++
+		case "omitzero", "omitempty", "nocase", "inline", "unknown":
+			options[s]++
 		default:
 			report.Report(pass, field.Tag, fmt.Sprintf("unknown JSON option %q", s))
 		}
 	}
-	if co > 1 {
-		report.Report(pass, field.Tag, `duplicate JSON option "omitempty"`)
-	}
-	if cs > 1 {
-		report.Report(pass, field.Tag, `duplicate JSON option "string"`)
+	var duplicates []string
+	for option, n := range options {
+		if n > 1 {
+			duplicates = append(duplicates, option)
+		}
 	}
-	if ci > 1 {
-		report.Report(pass, field.Tag, `duplicate JSON option "inline"`)
+	if len(duplicates) > 0 {
+		sort.Strings(duplicates)
+		for _, option := range duplicates {
+			report.Report(pass, field.Tag, fmt.Sprintf("duplicate JSON option %q", option))
+		}
 	}
 }
 
@@ -4585,6 +4551,14 @@ func CheckTypedNilInterface(pass *analys
 					default:
 						panic("unreachable")
 					}
+
+					terms, err := typeparams.NormalTerms(x.X.Type())
+					if len(terms) == 0 || err != nil {
+						// Type is a type parameter with no type terms (or we couldn't determine the terms). Such a type
+						// _can_ be nil when put in an interface value.
+						continue
+					}
+
 					if report.HasRange(x.X) {
 						report.Report(pass, binop, fmt.Sprintf("this comparison is %s true", qualifier),
 							report.Related(x.X, "the lhs of the comparison gets its value from here and has a concrete type"))
@@ -4965,6 +4939,10 @@ func CheckTypeAssertionShadowingElse(pas
 			return
 		}
 		irfn := ir.EnclosingFunction(irpkg, path)
+		if irfn == nil {
+			// For example for functions named "_", because we don't generate IR for them.
+			return
+		}
 
 		shadoweeIR, isAddr := irfn.ValueForExpr(m.State["obj"].(*ast.Ident))
 		if shadoweeIR == nil || isAddr {
@@ -5017,7 +4995,7 @@ func CheckTypeAssertionShadowingElse(pas
 	return nil, nil
 }
 
-var ineffectiveSortQ = pattern.MustParse(`(AssignStmt target@(Ident _) "=" (CallExpr typ@(Function (Or "sort.Float64Slice" "sort.IntSlice" "sort.StringSlice")) [target]))`)
+var ineffectiveSortQ = pattern.MustParse(`(AssignStmt target@(Ident _) "=" (CallExpr typ@(Symbol (Or "sort.Float64Slice" "sort.IntSlice" "sort.StringSlice")) [target]))`)
 
 func CheckIneffectiveSort(pass *analysis.Pass) (interface{}, error) {
 	fn := func(node ast.Node) {
@@ -5066,7 +5044,7 @@ func CheckIneffectiveSort(pass *analysis
 
 var ineffectiveRandIntQ = pattern.MustParse(`
 	(CallExpr
-		(Function
+		(Symbol
 			name@(Or
 				"math/rand.Int31n"
 				"math/rand.Int63n"
@@ -5096,7 +5074,9 @@ var allocationNilCheckQ = pattern.MustPa
 
 func CheckAllocationNilCheck(pass *analysis.Pass) (interface{}, error) {
 	irpkg := pass.ResultOf[buildir.Analyzer].(*buildir.IR).Pkg
-	fn := func(node ast.Node) {
+
+	var path []ast.Node
+	fn := func(node ast.Node, stack []ast.Node) {
 		m, ok := code.Match(pass, allocationNilCheckQ, node)
 		if !ok {
 			return
@@ -5107,12 +5087,15 @@ func CheckAllocationNilCheck(pass *analy
 			return
 		}
 		lhs := m.State["lhs"].(ast.Expr)
-		path, exact := astutil.PathEnclosingInterval(code.File(pass, lhs), lhs.Pos(), lhs.Pos())
-		if !exact {
-			// TODO(dh): when can this happen?
-			return
+		path = path[:0]
+		for i := len(stack) - 1; i >= 0; i-- {
+			path = append(path, stack[i])
 		}
 		irfn := ir.EnclosingFunction(irpkg, path)
+		if irfn == nil {
+			// For example for functions named "_", because we don't generate IR for them.
+			return
+		}
 		v, isAddr := irfn.ValueForExpr(lhs)
 		if isAddr {
 			return
@@ -5208,8 +5191,7 @@ func CheckAllocationNilCheck(pass *analy
 				report.Report(pass, cond, fallback)
 			}
 		}
-
 	}
-	code.Preorder(pass, fn, (*ast.IfStmt)(nil))
+	code.PreorderStack(pass, fn, (*ast.IfStmt)(nil))
 	return nil, nil
 }
diff -pruN 2022.1-1/staticcheck/lint_test.go 2022.1.3-1/staticcheck/lint_test.go
--- 2022.1-1/staticcheck/lint_test.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/lint_test.go	2022-07-31 15:38:22.000000000 +0000
@@ -31,6 +31,7 @@ func TestAll(t *testing.T) {
 			{Dir: "CheckDeprecated_go13", Version: "1.3"},
 			{Dir: "CheckDeprecated_go14", Version: "1.4"},
 			{Dir: "CheckDeprecated_go18", Version: "1.8"},
+			{Dir: "CheckDeprecated_go119", Version: "1.19"},
 		},
 		"SA1020": {{Dir: "CheckListenAddress"}},
 		"SA1021": {{Dir: "CheckBytesEqualIP"}},
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckAddressIsNil/CheckAddressIsNil.go 2022.1.3-1/staticcheck/testdata/src/CheckAddressIsNil/CheckAddressIsNil.go
--- 2022.1-1/staticcheck/testdata/src/CheckAddressIsNil/CheckAddressIsNil.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckAddressIsNil/CheckAddressIsNil.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,10 +1,10 @@
 package pkg
 
 func fn(x int, y *int) {
-	_ = &x == nil // want `the address of a variable cannot be nil`
-	_ = &y != nil // want `the address of a variable cannot be nil`
+	_ = &x == nil //@ diag(`the address of a variable cannot be nil`)
+	_ = &y != nil //@ diag(`the address of a variable cannot be nil`)
 
-	if &x != nil { // want `the address of a variable cannot be nil`
+	if &x != nil { //@ diag(`the address of a variable cannot be nil`)
 		println("obviously.")
 	}
 
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckAllocationNilCheck/CheckAllocationNilCheck.go 2022.1.3-1/staticcheck/testdata/src/CheckAllocationNilCheck/CheckAllocationNilCheck.go
--- 2022.1-1/staticcheck/testdata/src/CheckAllocationNilCheck/CheckAllocationNilCheck.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckAllocationNilCheck/CheckAllocationNilCheck.go	2022-07-31 15:38:22.000000000 +0000
@@ -35,41 +35,41 @@ func fn1() {
 
 	if a != nil {
 	}
-	if b != nil { // want `always true`
+	if b != nil { //@ diag(`always true`)
 	}
-	if b == nil { // want `never true`
+	if b == nil { //@ diag(`never true`)
 	}
-	if c != nil { // want `always true`
+	if c != nil { //@ diag(`always true`)
 	}
 	if d != nil { // field value could be anything
 	}
-	if e != nil { // want `contains a function`
+	if e != nil { //@ diag(`contains a function`)
 	}
-	if f != nil { // want `always true`
+	if f != nil { //@ diag(`always true`)
 	}
-	if g != nil { // want `contains a function`
+	if g != nil { //@ diag(`contains a function`)
 	}
-	if h != nil { // want `always true`
+	if h != nil { //@ diag(`always true`)
 	}
 	if &a != nil { // already flagged by SA4022
 	}
-	if (&T{}).Method != nil { // want `always true`
+	if (&T{}).Method != nil { //@ diag(`always true`)
 	}
 	if (&T{}) != nil { // already flagged by SA4022
 	}
 	if i != nil { // just a function return value
 	}
-	if fn1 != nil { // want `functions are never nil`
+	if fn1 != nil { //@ diag(`functions are never nil`)
 	}
-	if j != nil { // want `contains a function`
+	if j != nil { //@ diag(`contains a function`)
 	}
-	if k != nil { // want `always true`
+	if k != nil { //@ diag(`always true`)
 	}
 	if l != nil { // slicing a nil slice yields nil
 	}
-	if m != nil { // want `always true`
+	if m != nil { //@ diag(`always true`)
 	}
-	if n != nil { // want `always true`
+	if n != nil { //@ diag(`always true`)
 	}
 	if o != nil { // in &pt.Field, pt might be nil
 	}
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckArgOverwritten/CheckArgOverwritten.go 2022.1.3-1/staticcheck/testdata/src/CheckArgOverwritten/CheckArgOverwritten.go
--- 2022.1-1/staticcheck/testdata/src/CheckArgOverwritten/CheckArgOverwritten.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckArgOverwritten/CheckArgOverwritten.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,6 +1,6 @@
 package pkg
 
-var x = func(arg int) { // want `overwritten`
+var x = func(arg int) { //@ diag(`overwritten`)
 	arg = 1
 	println(arg)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckAtomicAlignment/atomic32.go 2022.1.3-1/staticcheck/testdata/src/CheckAtomicAlignment/atomic32.go
--- 2022.1-1/staticcheck/testdata/src/CheckAtomicAlignment/atomic32.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckAtomicAlignment/atomic32.go	2022-07-31 15:38:22.000000000 +0000
@@ -13,14 +13,14 @@ type T struct {
 func fn() {
 	var v T
 	atomic.AddInt64(&v.A, 0)
-	atomic.AddInt64(&v.C, 0) // want `address of non 64-bit aligned field C passed to sync/atomic.AddInt64`
-	atomic.LoadInt64(&v.C)   // want `address of non 64-bit aligned field C passed to sync/atomic.LoadInt64`
+	atomic.AddInt64(&v.C, 0) //@ diag(`address of non 64-bit aligned field C passed to sync/atomic.AddInt64`)
+	atomic.LoadInt64(&v.C)   //@ diag(`address of non 64-bit aligned field C passed to sync/atomic.LoadInt64`)
 }
 
 func fn2(t *T) {
 	addr := &t.C
 	if true {
-		atomic.LoadInt64(addr) // want `address of non 64-bit`
+		atomic.LoadInt64(addr) //@ diag(`address of non 64-bit`)
 	} else {
 		_ = addr
 	}
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckBadRemoveAll/CheckBadRemoveAll.go 2022.1.3-1/staticcheck/testdata/src/CheckBadRemoveAll/CheckBadRemoveAll.go
--- 2022.1-1/staticcheck/testdata/src/CheckBadRemoveAll/CheckBadRemoveAll.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckBadRemoveAll/CheckBadRemoveAll.go	2022-07-31 15:38:22.000000000 +0000
@@ -7,7 +7,7 @@ import (
 
 func fn1() {
 	x := os.TempDir()
-	defer os.RemoveAll(x) // want `deletes the user's entire temporary directory`
+	defer os.RemoveAll(x) //@ diag(`deletes the user's entire temporary directory`)
 
 	x = ""
 }
@@ -15,7 +15,7 @@ func fn1() {
 func fn2() {
 	x := os.TempDir()
 	if true {
-		os.RemoveAll(x) // want `deletes the user's entire temporary directory`
+		os.RemoveAll(x) //@ diag(`deletes the user's entire temporary directory`)
 	}
 }
 
@@ -30,11 +30,11 @@ func fn3() {
 
 func fn4() {
 	x, _ := os.UserCacheDir()
-	os.RemoveAll(x) // want `deletes the user's entire cache directory`
+	os.RemoveAll(x) //@ diag(`deletes the user's entire cache directory`)
 
 	x, _ = os.UserConfigDir()
-	os.RemoveAll(x) // want `deletes the user's entire config directory`
+	os.RemoveAll(x) //@ diag(`deletes the user's entire config directory`)
 
 	x, _ = os.UserHomeDir()
-	os.RemoveAll(x) // want `deletes the user's entire home directory`
+	os.RemoveAll(x) //@ diag(`deletes the user's entire home directory`)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckBenchmarkN/CheckBenchmarkN.go 2022.1.3-1/staticcheck/testdata/src/CheckBenchmarkN/CheckBenchmarkN.go
--- 2022.1-1/staticcheck/testdata/src/CheckBenchmarkN/CheckBenchmarkN.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckBenchmarkN/CheckBenchmarkN.go	2022-07-31 15:38:22.000000000 +0000
@@ -4,6 +4,6 @@ import "testing"
 
 func foo() {
 	var b *testing.B
-	b.N = 1 // want `should not assign to b\.N`
+	b.N = 1 //@ diag(`should not assign to b.N`)
 	_ = b
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckBuiltinZeroComparison/CheckBuiltinZeroComparison.go 2022.1.3-1/staticcheck/testdata/src/CheckBuiltinZeroComparison/CheckBuiltinZeroComparison.go
--- 2022.1-1/staticcheck/testdata/src/CheckBuiltinZeroComparison/CheckBuiltinZeroComparison.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckBuiltinZeroComparison/CheckBuiltinZeroComparison.go	2022-07-31 15:38:22.000000000 +0000
@@ -3,35 +3,35 @@ package pkg
 func fn1() {
 	var foo []int
 
-	if len(foo) < 0 { // want `len does not return negative values`
+	if len(foo) < 0 { //@ diag(`len does not return negative values`)
 		println("test")
 	}
 
 	switch {
-	case len(foo) < 0: // want `negative`
+	case len(foo) < 0: //@ diag(`negative`)
 		println("test")
 	}
 
-	for len(foo) < 0 { // want `negative`
+	for len(foo) < 0 { //@ diag(`negative`)
 		println("test")
 	}
 
-	println(len(foo) < 0) // want `negative`
+	println(len(foo) < 0) //@ diag(`negative`)
 
-	if 0 > cap(foo) { // want `cap does not return negative values`
+	if 0 > cap(foo) { //@ diag(`cap does not return negative values`)
 		println("test")
 	}
 
 	switch {
-	case 0 > cap(foo): // want `negative`
+	case 0 > cap(foo): //@ diag(`negative`)
 		println("test")
 	}
 
-	for 0 > cap(foo) { // want `negative`
+	for 0 > cap(foo) { //@ diag(`negative`)
 		println("test")
 	}
 
-	println(0 > cap(foo)) // want `negative`
+	println(0 > cap(foo)) //@ diag(`negative`)
 }
 
 func fn2() {
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckBytesEqualIP/CheckBytesEqualIP.go 2022.1.3-1/staticcheck/testdata/src/CheckBytesEqualIP/CheckBytesEqualIP.go
--- 2022.1-1/staticcheck/testdata/src/CheckBytesEqualIP/CheckBytesEqualIP.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckBytesEqualIP/CheckBytesEqualIP.go	2022-07-31 15:38:22.000000000 +0000
@@ -11,7 +11,7 @@ func fn() {
 	var b1, b2 []byte
 	var t1, t2 T
 
-	bytes.Equal(i1, i2) // want `use net\.IP\.Equal to compare net\.IPs, not bytes\.Equal`
+	bytes.Equal(i1, i2) //@ diag(`use net.IP.Equal to compare net.IPs, not bytes.Equal`)
 	bytes.Equal(b1, b2)
 	bytes.Equal(t1, t2)
 
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckCanonicalHeaderKey/CheckCanonicalHeaderKey.go 2022.1.3-1/staticcheck/testdata/src/CheckCanonicalHeaderKey/CheckCanonicalHeaderKey.go
--- 2022.1-1/staticcheck/testdata/src/CheckCanonicalHeaderKey/CheckCanonicalHeaderKey.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckCanonicalHeaderKey/CheckCanonicalHeaderKey.go	2022-07-31 15:38:22.000000000 +0000
@@ -7,10 +7,10 @@ func fn() {
 	var r http.Request
 	h := http.Header{}
 	var m map[string][]string
-	_ = h["foo"] // want `keys in http\.Header are canonicalized`
-	_ = h[hdr]   //  want `keys in http\.Header are canonicalized`
+	_ = h["foo"] //@ diag(`keys in http.Header are canonicalized`)
+	_ = h[hdr]   //@ diag(`keys in http.Header are canonicalized`)
 	h["foo"] = nil
-	_ = r.Header["foo"] // want `keys in http\.Header are canonicalized`
+	_ = r.Header["foo"] //@ diag(`keys in http.Header are canonicalized`)
 	r.Header["foo"] = nil
 	_ = m["foo"]
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckCanonicalHeaderKey/CheckCanonicalHeaderKey.go.golden 2022.1.3-1/staticcheck/testdata/src/CheckCanonicalHeaderKey/CheckCanonicalHeaderKey.go.golden
--- 2022.1-1/staticcheck/testdata/src/CheckCanonicalHeaderKey/CheckCanonicalHeaderKey.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckCanonicalHeaderKey/CheckCanonicalHeaderKey.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -7,10 +7,10 @@ func fn() {
 	var r http.Request
 	h := http.Header{}
 	var m map[string][]string
-	_ = h["Foo"]                        // want `keys in http\.Header are canonicalized`
-	_ = h[http.CanonicalHeaderKey(hdr)] //  want `keys in http\.Header are canonicalized`
+	_ = h["Foo"]                        //@ diag(`keys in http.Header are canonicalized`)
+	_ = h[http.CanonicalHeaderKey(hdr)] //@ diag(`keys in http.Header are canonicalized`)
 	h["foo"] = nil
-	_ = r.Header["Foo"] // want `keys in http\.Header are canonicalized`
+	_ = r.Header["Foo"] //@ diag(`keys in http.Header are canonicalized`)
 	r.Header["foo"] = nil
 	_ = m["foo"]
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckConcurrentTesting/CheckConcurrentTesting.go 2022.1.3-1/staticcheck/testdata/src/CheckConcurrentTesting/CheckConcurrentTesting.go
--- 2022.1-1/staticcheck/testdata/src/CheckConcurrentTesting/CheckConcurrentTesting.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckConcurrentTesting/CheckConcurrentTesting.go	2022-07-31 15:38:22.000000000 +0000
@@ -4,15 +4,15 @@ import "testing"
 
 func fn1() {
 	var t *testing.T
-	go func() { // want `the goroutine calls T\.Fatal, which must be called in the same goroutine as the test`
+	go func() { //@ diag(`the goroutine calls T.Fatal, which must be called in the same goroutine as the test`)
 		t.Fatal()
 	}()
-	go fn2(t) // want `the goroutine calls T\.Fatal, which must be called in the same goroutine as the test`
+	go fn2(t) //@ diag(`the goroutine calls T.Fatal, which must be called in the same goroutine as the test`)
 
 	fn := func() {
 		t.Fatal()
 	}
-	go fn() // want `the goroutine calls T\.Fatal, which must be called in the same goroutine as the test`
+	go fn() //@ diag(`the goroutine calls T.Fatal, which must be called in the same goroutine as the test`)
 }
 
 func fn2(t *testing.T) {
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckCyclicFinalizer/CheckCyclicFinalizer.go 2022.1.3-1/staticcheck/testdata/src/CheckCyclicFinalizer/CheckCyclicFinalizer.go
--- 2022.1-1/staticcheck/testdata/src/CheckCyclicFinalizer/CheckCyclicFinalizer.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckCyclicFinalizer/CheckCyclicFinalizer.go	2022-07-31 15:38:22.000000000 +0000
@@ -8,9 +8,9 @@ import (
 func fn() {
 	var x *int
 	foo := func(y *int) { fmt.Println(x) }
-	runtime.SetFinalizer(x, foo) // want `the finalizer closes over the object, preventing the finalizer from ever running \(at .+:10:9`
+	runtime.SetFinalizer(x, foo) //@ diag(re`the finalizer closes over the object, preventing the finalizer from ever running \(at .+:10:9`)
 	runtime.SetFinalizer(x, nil)
-	runtime.SetFinalizer(x, func(_ *int) { // want `the finalizer closes over the object, preventing the finalizer from ever running \(at .+:13:26`
+	runtime.SetFinalizer(x, func(_ *int) { //@ diag(re`the finalizer closes over the object, preventing the finalizer from ever running \(at .+:13:26`)
 		fmt.Println(x)
 	})
 
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckDeferInInfiniteLoop/CheckDeferInInfiniteLoop.go 2022.1.3-1/staticcheck/testdata/src/CheckDeferInInfiniteLoop/CheckDeferInInfiniteLoop.go
--- 2022.1-1/staticcheck/testdata/src/CheckDeferInInfiniteLoop/CheckDeferInInfiniteLoop.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckDeferInInfiniteLoop/CheckDeferInInfiniteLoop.go	2022-07-31 15:38:22.000000000 +0000
@@ -2,10 +2,10 @@ package pkg
 
 func fn() {
 	for {
-		defer println() // want `will never run`
+		defer println() //@ diag(`will never run`)
 	}
 	for {
-		defer println() // want `will never run`
+		defer println() //@ diag(`will never run`)
 		go func() {
 			return
 		}()
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckDeferLock/CheckDeferLock.go 2022.1.3-1/staticcheck/testdata/src/CheckDeferLock/CheckDeferLock.go
--- 2022.1-1/staticcheck/testdata/src/CheckDeferLock/CheckDeferLock.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckDeferLock/CheckDeferLock.go	2022-07-31 15:38:22.000000000 +0000
@@ -7,7 +7,7 @@ var rw sync.RWMutex
 
 func fn1() {
 	r.Lock()
-	defer r.Lock() // want `deferring Lock right after having locked already; did you mean to defer Unlock`
+	defer r.Lock() //@ diag(`deferring Lock right after having locked already; did you mean to defer Unlock`)
 }
 
 func fn2() {
@@ -22,7 +22,7 @@ func fn3() {
 
 func fn4() {
 	rw.RLock()
-	defer rw.RLock() // want `deferring RLock right after having locked already; did you mean to defer RUnlock`
+	defer rw.RLock() //@ diag(`deferring RLock right after having locked already; did you mean to defer RUnlock`)
 }
 
 func fn5() {
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckDeprecated/CheckDeprecated_generics.go 2022.1.3-1/staticcheck/testdata/src/CheckDeprecated/CheckDeprecated_generics.go
--- 2022.1-1/staticcheck/testdata/src/CheckDeprecated/CheckDeprecated_generics.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckDeprecated/CheckDeprecated_generics.go	2022-07-31 15:38:22.000000000 +0000
@@ -7,8 +7,8 @@ import pkg "CheckDeprecatedassist.notstd
 func tpFn() {
 	var x pkg.S[int]
 	x.Foo()
-	x.Bar() // want `deprecated`
-	x.Baz() // want `deprecated`
+	x.Bar() //@ diag(`deprecated`)
+	x.Baz() //@ diag(`deprecated`)
 	x.Qux()
 	_ = x.Field1
 	_ = x.Field2 // This should be flagged, but see issue 1215
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckDeprecated/CheckDeprecated.go 2022.1.3-1/staticcheck/testdata/src/CheckDeprecated/CheckDeprecated.go
--- 2022.1-1/staticcheck/testdata/src/CheckDeprecated/CheckDeprecated.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckDeprecated/CheckDeprecated.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,9 +1,9 @@
 package pkg
 
-import _ "CheckDeprecatedassist"          // want `Alas, it is deprecated\.`
-import _ "AnotherCheckDeprecatedassist"   // want `Alas, it is deprecated\.`
-import foo "AnotherCheckDeprecatedassist" // want `Alas, it is deprecated\.`
-import "AnotherCheckDeprecatedassist"     // want `Alas, it is deprecated\.`
+import _ "CheckDeprecated.assist"          //@ diag(`Alas, it is deprecated.`)
+import _ "AnotherCheckDeprecated.assist"   //@ diag(`Alas, it is deprecated.`)
+import foo "AnotherCheckDeprecated.assist" //@ diag(`Alas, it is deprecated.`)
+import "AnotherCheckDeprecated.assist"     //@ diag(`Alas, it is deprecated.`)
 
 func init() {
 	foo.Fn()
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckDeprecated/not-protobuf.go 2022.1.3-1/staticcheck/testdata/src/CheckDeprecated/not-protobuf.go
--- 2022.1-1/staticcheck/testdata/src/CheckDeprecated/not-protobuf.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckDeprecated/not-protobuf.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,3 +1,3 @@
 package pkg
 
-import _ "github.com/golang/protobuf/proto" // want `Alas, it is deprecated\.`
+import _ "github.com/golang/protobuf/proto" //@ diag(`Alas, it is deprecated.`)
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckDeprecated/vendor/AnotherCheckDeprecatedassist/CheckDeprecatedassist.go 2022.1.3-1/staticcheck/testdata/src/CheckDeprecated/vendor/AnotherCheckDeprecatedassist/CheckDeprecatedassist.go
--- 2022.1-1/staticcheck/testdata/src/CheckDeprecated/vendor/AnotherCheckDeprecatedassist/CheckDeprecatedassist.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckDeprecated/vendor/AnotherCheckDeprecatedassist/CheckDeprecatedassist.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,6 +0,0 @@
-// Package pkg is a nice package.
-//
-// Deprecated: Alas, it is deprecated.
-package AnotherCheckDeprecatedassist
-
-func Fn() {}
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckDeprecated/vendor/AnotherCheckDeprecated.assist/CheckDeprecatedassist.go 2022.1.3-1/staticcheck/testdata/src/CheckDeprecated/vendor/AnotherCheckDeprecated.assist/CheckDeprecatedassist.go
--- 2022.1-1/staticcheck/testdata/src/CheckDeprecated/vendor/AnotherCheckDeprecated.assist/CheckDeprecatedassist.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckDeprecated/vendor/AnotherCheckDeprecated.assist/CheckDeprecatedassist.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,6 @@
+// Package pkg is a nice package.
+//
+// Deprecated: Alas, it is deprecated.
+package AnotherCheckDeprecatedassist
+
+func Fn() {}
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckDeprecatedassist/CheckDeprecatedassist.go 2022.1.3-1/staticcheck/testdata/src/CheckDeprecatedassist/CheckDeprecatedassist.go
--- 2022.1-1/staticcheck/testdata/src/CheckDeprecatedassist/CheckDeprecatedassist.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckDeprecatedassist/CheckDeprecatedassist.go	1970-01-01 00:00:00.000000000 +0000
@@ -1,4 +0,0 @@
-// Package pkg is a nice package.
-//
-// Deprecated: Alas, it is deprecated.
-package pkg
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckDeprecated.assist/CheckDeprecatedassist.go 2022.1.3-1/staticcheck/testdata/src/CheckDeprecated.assist/CheckDeprecatedassist.go
--- 2022.1-1/staticcheck/testdata/src/CheckDeprecated.assist/CheckDeprecatedassist.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckDeprecated.assist/CheckDeprecatedassist.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,4 @@
+// Package pkg is a nice package.
+//
+// Deprecated: Alas, it is deprecated.
+package pkg
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckDeprecated_go119/CheckDeprecated.go 2022.1.3-1/staticcheck/testdata/src/CheckDeprecated_go119/CheckDeprecated.go
--- 2022.1-1/staticcheck/testdata/src/CheckDeprecated_go119/CheckDeprecated.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckDeprecated_go119/CheckDeprecated.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,8 @@
+//go:build go1.19
+
+package pkg
+
+import _ "io/ioutil" //@ diag("has been deprecated")
+
+// We test this in Go 1.19 even though io/ioutil has technically been deprecated since Go 1.16, because only in Go 1.19
+// was the proper deprecation marker added.
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckDeprecated_go119/stub.go 2022.1.3-1/staticcheck/testdata/src/CheckDeprecated_go119/stub.go
--- 2022.1-1/staticcheck/testdata/src/CheckDeprecated_go119/stub.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckDeprecated_go119/stub.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1 @@
+package pkg
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckDeprecated_go13/CheckDeprecated.go 2022.1.3-1/staticcheck/testdata/src/CheckDeprecated_go13/CheckDeprecated.go
--- 2022.1-1/staticcheck/testdata/src/CheckDeprecated_go13/CheckDeprecated.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckDeprecated_go13/CheckDeprecated.go	2022-07-31 15:38:22.000000000 +0000
@@ -7,8 +7,8 @@ import (
 )
 
 func fn() {
-	filepath.HasPrefix("", "")               // want `filepath.HasPrefix has been deprecated since Go 1.0 because it shouldn't be used:`
-	_ = httputil.ErrPersistEOF               // want `httputil.ErrPersistEOF has been deprecated since Go 1.0:`
-	_ = httputil.ServerConn{}                // want `httputil.ServerConn has been deprecated since Go 1.0:`
-	_ = x509.CertificateRequest{}.Attributes // want `x509.CertificateRequest{}.Attributes has been deprecated since Go 1.5 and an alternative has been available since Go 1.3:`
+	filepath.HasPrefix("", "")               //@ diag(`filepath.HasPrefix has been deprecated since Go 1.0 because it shouldn't be used:`)
+	_ = httputil.ErrPersistEOF               //@ diag(`httputil.ErrPersistEOF has been deprecated since Go 1.0:`)
+	_ = httputil.ServerConn{}                //@ diag(`httputil.ServerConn has been deprecated since Go 1.0:`)
+	_ = x509.CertificateRequest{}.Attributes //@ diag(`x509.CertificateRequest{}.Attributes has been deprecated since Go 1.5 and an alternative has been available since Go 1.3:`)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckDeprecated_go14/CheckDeprecated.go 2022.1.3-1/staticcheck/testdata/src/CheckDeprecated_go14/CheckDeprecated.go
--- 2022.1-1/staticcheck/testdata/src/CheckDeprecated_go14/CheckDeprecated.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckDeprecated_go14/CheckDeprecated.go	2022-07-31 15:38:22.000000000 +0000
@@ -8,12 +8,12 @@ import (
 	"syscall"
 )
 
-var _ = syscall.StringByteSlice("") // want `Use ByteSliceFromString instead`
+var _ = syscall.StringByteSlice("") //@ diag(`Use ByteSliceFromString instead`)
 
 func fn1(err error) {
 	var r *http.Request
 	_ = r.Cancel
-	_ = syscall.StringByteSlice("") // want `Use ByteSliceFromString instead`
+	_ = syscall.StringByteSlice("") //@ diag(`Use ByteSliceFromString instead`)
 	_ = os.SEEK_SET
 	var _ flate.ReadError
 
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckDeprecated_go18/CheckDeprecated.go 2022.1.3-1/staticcheck/testdata/src/CheckDeprecated_go18/CheckDeprecated.go
--- 2022.1-1/staticcheck/testdata/src/CheckDeprecated_go18/CheckDeprecated.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckDeprecated_go18/CheckDeprecated.go	2022-07-31 15:38:22.000000000 +0000
@@ -8,25 +8,25 @@ import (
 	"syscall"
 )
 
-var _ = syscall.StringByteSlice("") // want `Use ByteSliceFromString instead`
+var _ = syscall.StringByteSlice("") //@ diag(`Use ByteSliceFromString instead`)
 
 func fn1(err error) {
 	var r http.Request
 	var rp *http.Request
-	_ = r.Cancel                        // want `deprecated since Go 1\.7:.+If a Request's Cancel field and context are both`
-	_ = rp.Cancel                       // want `deprecated since Go 1\.7:.+If a Request's Cancel field and context are both`
-	_ = syscall.StringByteSlice("")     // want `Use ByteSliceFromString instead`
-	_ = os.SEEK_SET                     // want `Use io\.SeekStart, io\.SeekCurrent, and io\.SeekEnd`
-	if err == http.ErrWriteAfterFlush { // want `ErrWriteAfterFlush is no longer`
+	_ = r.Cancel                        //@ diag(re`deprecated since Go 1\.7:.+If a Request's Cancel field and context are both`)
+	_ = rp.Cancel                       //@ diag(re`deprecated since Go 1\.7:.+If a Request's Cancel field and context are both`)
+	_ = syscall.StringByteSlice("")     //@ diag(`Use ByteSliceFromString instead`)
+	_ = os.SEEK_SET                     //@ diag(`Use io.SeekStart, io.SeekCurrent, and io.SeekEnd`)
+	if err == http.ErrWriteAfterFlush { //@ diag(`ErrWriteAfterFlush is no longer`)
 		println()
 	}
-	var _ flate.ReadError // want `No longer returned`
+	var _ flate.ReadError //@ diag(`No longer returned`)
 
 	var tr *http.Transport
-	tr.CancelRequest(nil) // want `CancelRequest has been deprecated`
+	tr.CancelRequest(nil) //@ diag(`CancelRequest has been deprecated`)
 
 	var conn driver.Conn
-	conn.Begin() // want `Begin has been deprecated`
+	conn.Begin() //@ diag(`Begin has been deprecated`)
 }
 
 // Deprecated: Don't use this.
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckDoubleNegation/CheckDoubleNegation.go 2022.1.3-1/staticcheck/testdata/src/CheckDoubleNegation/CheckDoubleNegation.go
--- 2022.1-1/staticcheck/testdata/src/CheckDoubleNegation/CheckDoubleNegation.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckDoubleNegation/CheckDoubleNegation.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,15 +1,15 @@
 package pkg
 
 func fn(b1, b2 bool) {
-	if !!b1 { // want `negating a boolean twice`
+	if !!b1 { //@ diag(`negating a boolean twice`)
 		println()
 	}
 
-	if b1 && !!b2 { // want `negating a boolean twice`
+	if b1 && !!b2 { //@ diag(`negating a boolean twice`)
 		println()
 	}
 
-	if !(!b1) { // want `negating a boolean twice`
+	if !(!b1) { //@ diag(`negating a boolean twice`)
 		println()
 	}
 
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckDoubleNegation/CheckDoubleNegation.go.golden 2022.1.3-1/staticcheck/testdata/src/CheckDoubleNegation/CheckDoubleNegation.go.golden
--- 2022.1-1/staticcheck/testdata/src/CheckDoubleNegation/CheckDoubleNegation.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckDoubleNegation/CheckDoubleNegation.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -2,15 +2,15 @@
 package pkg
 
 func fn(b1, b2 bool) {
-	if !b1 { // want `negating a boolean twice`
+	if !b1 { //@ diag(`negating a boolean twice`)
 		println()
 	}
 
-	if b1 && !b2 { // want `negating a boolean twice`
+	if b1 && !b2 { //@ diag(`negating a boolean twice`)
 		println()
 	}
 
-	if !b1 { // want `negating a boolean twice`
+	if !b1 { //@ diag(`negating a boolean twice`)
 		println()
 	}
 
@@ -27,15 +27,15 @@ func fn(b1, b2 bool) {
 package pkg
 
 func fn(b1, b2 bool) {
-	if b1 { // want `negating a boolean twice`
+	if b1 { //@ diag(`negating a boolean twice`)
 		println()
 	}
 
-	if b1 && b2 { // want `negating a boolean twice`
+	if b1 && b2 { //@ diag(`negating a boolean twice`)
 		println()
 	}
 
-	if b1 { // want `negating a boolean twice`
+	if b1 { //@ diag(`negating a boolean twice`)
 		println()
 	}
 
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckDubiousDeferInChannelRangeLoop/CheckDubiousDeferInChannelRangeLoop.go 2022.1.3-1/staticcheck/testdata/src/CheckDubiousDeferInChannelRangeLoop/CheckDubiousDeferInChannelRangeLoop.go
--- 2022.1-1/staticcheck/testdata/src/CheckDubiousDeferInChannelRangeLoop/CheckDubiousDeferInChannelRangeLoop.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckDubiousDeferInChannelRangeLoop/CheckDubiousDeferInChannelRangeLoop.go	2022-07-31 15:38:22.000000000 +0000
@@ -3,6 +3,6 @@ package pkg
 func fn() {
 	var ch chan int
 	for range ch {
-		defer println() // want `defers in this range loop`
+		defer println() //@ diag(`defers in this range loop`)
 	}
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckDubiousDeferInChannelRangeLoop/generics.go 2022.1.3-1/staticcheck/testdata/src/CheckDubiousDeferInChannelRangeLoop/generics.go
--- 2022.1-1/staticcheck/testdata/src/CheckDubiousDeferInChannelRangeLoop/generics.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckDubiousDeferInChannelRangeLoop/generics.go	2022-07-31 15:38:22.000000000 +0000
@@ -5,6 +5,6 @@ package pkg
 func tpfn[T chan int]() {
 	var ch T
 	for range ch {
-		defer println() // want `defers in this range loop`
+		defer println() //@ diag(`defers in this range loop`)
 	}
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckDuplicateBuildConstraints/CheckDuplicateBuildConstraints.go 2022.1.3-1/staticcheck/testdata/src/CheckDuplicateBuildConstraints/CheckDuplicateBuildConstraints.go
--- 2022.1-1/staticcheck/testdata/src/CheckDuplicateBuildConstraints/CheckDuplicateBuildConstraints.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckDuplicateBuildConstraints/CheckDuplicateBuildConstraints.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,4 +1,5 @@
+//go:build (one || two || three || go1.1) && (three || one || two || go1.1)
 // +build one two three go1.1
 // +build three one two go1.1
 
-package pkg // want `identical build constraints`
+package pkg //@ diag(`identical build constraints`)
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckEarlyDefer/CheckEarlyDefer.go 2022.1.3-1/staticcheck/testdata/src/CheckEarlyDefer/CheckEarlyDefer.go
--- 2022.1-1/staticcheck/testdata/src/CheckEarlyDefer/CheckEarlyDefer.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckEarlyDefer/CheckEarlyDefer.go	2022-07-31 15:38:22.000000000 +0000
@@ -16,7 +16,7 @@ func fn3() (T, error) {
 
 func fn2() {
 	rc, err := fn1()
-	defer rc.Close() // want `should check returned error before deferring rc\.Close`
+	defer rc.Close() //@ diag(`should check returned error before deferring rc.Close`)
 	if err != nil {
 		println()
 	}
@@ -31,7 +31,7 @@ func fn2() {
 	defer rc.Close()
 
 	t, err := fn3()
-	defer t.rc.Close() // want `should check returned error before deferring t\.rc\.Close`
+	defer t.rc.Close() //@ diag(`should check returned error before deferring t.rc.Close`)
 	if err != nil {
 		println()
 	}
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckEmptyBranch/CheckEmptyBranch.go 2022.1.3-1/staticcheck/testdata/src/CheckEmptyBranch/CheckEmptyBranch.go
--- 2022.1-1/staticcheck/testdata/src/CheckEmptyBranch/CheckEmptyBranch.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckEmptyBranch/CheckEmptyBranch.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,10 +1,10 @@
 package pkg
 
 func fn1() {
-	if true { // want `empty branch`
+	if true { //@ diag(`empty branch`)
 	}
-	if true { // want `empty branch`
-	} else { // want `empty branch`
+	if true { //@ diag(`empty branch`)
+	} else { //@ diag(`empty branch`)
 	}
 	if true {
 		println()
@@ -12,10 +12,10 @@ func fn1() {
 
 	if true {
 		println()
-	} else { // want `empty branch`
+	} else { //@ diag(`empty branch`)
 	}
 
-	if true { // want `empty branch`
+	if true { //@ diag(`empty branch`)
 		// TODO handle error
 	}
 
@@ -25,6 +25,6 @@ func fn1() {
 	}
 
 	if true {
-	} else if false { // want `empty branch`
+	} else if false { //@ diag(`empty branch`)
 	}
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckEmptyBranch/CheckEmptyBranch_test.go 2022.1.3-1/staticcheck/testdata/src/CheckEmptyBranch/CheckEmptyBranch_test.go
--- 2022.1-1/staticcheck/testdata/src/CheckEmptyBranch/CheckEmptyBranch_test.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckEmptyBranch/CheckEmptyBranch_test.go	2022-07-31 15:38:22.000000000 +0000
@@ -3,7 +3,7 @@ package pkg
 import "testing"
 
 func TestFoo(t *testing.T) {
-	if true { // want `empty branch`
+	if true { //@ diag(`empty branch`)
 		// TODO
 	}
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckEmptyCriticalSection/CheckEmptyCriticalSection.go 2022.1.3-1/staticcheck/testdata/src/CheckEmptyCriticalSection/CheckEmptyCriticalSection.go
--- 2022.1-1/staticcheck/testdata/src/CheckEmptyCriticalSection/CheckEmptyCriticalSection.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckEmptyCriticalSection/CheckEmptyCriticalSection.go	2022-07-31 15:38:22.000000000 +0000
@@ -5,7 +5,7 @@ import "sync"
 func fn1() {
 	var x sync.Mutex
 	x.Lock()
-	x.Unlock() // want `empty critical section`
+	x.Unlock() //@ diag(`empty critical section`)
 }
 
 func fn2() {
@@ -16,16 +16,16 @@ func fn2() {
 	}{}
 
 	x.m1.m2.Lock()
-	x.m1.m2.Unlock() // want `empty critical section`
+	x.m1.m2.Unlock() //@ diag(`empty critical section`)
 }
 
 func fn3() {
 	var x sync.RWMutex
 	x.Lock()
-	x.Unlock() // want `empty critical section`
+	x.Unlock() //@ diag(`empty critical section`)
 
 	x.RLock()
-	x.RUnlock() // want `empty critical section`
+	x.RUnlock() //@ diag(`empty critical section`)
 
 	x.Lock()
 	defer x.Unlock()
@@ -41,7 +41,7 @@ func fn4() {
 	}
 
 	x.m().Lock()
-	x.m().Unlock() // want `empty critical section`
+	x.m().Unlock() //@ diag(`empty critical section`)
 }
 
 func fn5() {
@@ -55,7 +55,7 @@ func fn5() {
 func fn6() {
 	x := &sync.Mutex{}
 	x.Lock()
-	x.Unlock() // want `empty critical section`
+	x.Unlock() //@ diag(`empty critical section`)
 }
 
 func fn7() {
@@ -64,7 +64,7 @@ func fn7() {
 	}{}
 
 	x.Lock()
-	x.Unlock() // want `empty critical section`
+	x.Unlock() //@ diag(`empty critical section`)
 }
 
 func fn8() {
@@ -72,7 +72,7 @@ func fn8() {
 	x = new(sync.Mutex)
 
 	x.Lock()
-	x.Unlock() // want `empty critical section`
+	x.Unlock() //@ diag(`empty critical section`)
 }
 
 func fn9() {
@@ -80,7 +80,7 @@ func fn9() {
 		sync.Locker
 	}{&sync.Mutex{}}
 	x.Lock()
-	x.Unlock() // want `empty critical section`
+	x.Unlock() //@ diag(`empty critical section`)
 }
 
 type T struct{}
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckEncodingBinary/CheckEncodingBinary.go 2022.1.3-1/staticcheck/testdata/src/CheckEncodingBinary/CheckEncodingBinary.go
--- 2022.1-1/staticcheck/testdata/src/CheckEncodingBinary/CheckEncodingBinary.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckEncodingBinary/CheckEncodingBinary.go	2022-07-31 15:38:22.000000000 +0000
@@ -40,22 +40,22 @@ func fn() {
 	var x13 []byte
 	var x14 *[]byte
 	var x15 T6
-	log.Println(binary.Write(ioutil.Discard, binary.LittleEndian, x1)) // want `cannot be used with binary\.Write`
+	log.Println(binary.Write(ioutil.Discard, binary.LittleEndian, x1)) //@ diag(`cannot be used with binary.Write`)
 	log.Println(binary.Write(ioutil.Discard, binary.LittleEndian, x2))
-	log.Println(binary.Write(ioutil.Discard, binary.LittleEndian, x3)) // want `cannot be used with binary\.Write`
+	log.Println(binary.Write(ioutil.Discard, binary.LittleEndian, x3)) //@ diag(`cannot be used with binary.Write`)
 	log.Println(binary.Write(ioutil.Discard, binary.LittleEndian, x4))
-	log.Println(binary.Write(ioutil.Discard, binary.LittleEndian, x5)) // want `cannot be used with binary\.Write`
+	log.Println(binary.Write(ioutil.Discard, binary.LittleEndian, x5)) //@ diag(`cannot be used with binary.Write`)
 	log.Println(binary.Write(ioutil.Discard, binary.LittleEndian, x6))
 	log.Println(binary.Write(ioutil.Discard, binary.LittleEndian, x7))
-	log.Println(binary.Write(ioutil.Discard, binary.LittleEndian, x8))  // want `cannot be used with binary\.Write`
-	log.Println(binary.Write(ioutil.Discard, binary.LittleEndian, x9))  // want `cannot be used with binary\.Write`
-	log.Println(binary.Write(ioutil.Discard, binary.LittleEndian, x10)) // want `cannot be used with binary\.Write`
+	log.Println(binary.Write(ioutil.Discard, binary.LittleEndian, x8))  //@ diag(`cannot be used with binary.Write`)
+	log.Println(binary.Write(ioutil.Discard, binary.LittleEndian, x9))  //@ diag(`cannot be used with binary.Write`)
+	log.Println(binary.Write(ioutil.Discard, binary.LittleEndian, x10)) //@ diag(`cannot be used with binary.Write`)
 	log.Println(binary.Write(ioutil.Discard, binary.LittleEndian, x11))
 	log.Println(binary.Write(ioutil.Discard, binary.LittleEndian, &x13))
-	log.Println(binary.Write(ioutil.Discard, binary.LittleEndian, &x14)) // want `cannot be used with binary\.Write`
+	log.Println(binary.Write(ioutil.Discard, binary.LittleEndian, &x14)) //@ diag(`cannot be used with binary.Write`)
 	log.Println(binary.Write(ioutil.Discard, binary.LittleEndian, x15))
 	log.Println(binary.Write(ioutil.Discard, binary.LittleEndian, &x15))
-	log.Println(binary.Write(fn2())) // want `cannot be used with binary\.Write`
+	log.Println(binary.Write(fn2())) //@ diag(`cannot be used with binary.Write`)
 	log.Println(binary.Write(fn3()))
 }
 
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckEncodingBinary_go17/CheckEncodingBinary.go 2022.1.3-1/staticcheck/testdata/src/CheckEncodingBinary_go17/CheckEncodingBinary.go
--- 2022.1-1/staticcheck/testdata/src/CheckEncodingBinary_go17/CheckEncodingBinary.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckEncodingBinary_go17/CheckEncodingBinary.go	2022-07-31 15:38:22.000000000 +0000
@@ -8,5 +8,5 @@ import (
 
 func fn() {
 	var x bool
-	log.Println(binary.Write(ioutil.Discard, binary.LittleEndian, x)) // want `cannot be used with binary\.Write`
+	log.Println(binary.Write(ioutil.Discard, binary.LittleEndian, x)) //@ diag(`cannot be used with binary.Write`)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckEvenSliceLength/CheckEvenSliceLength.go 2022.1.3-1/staticcheck/testdata/src/CheckEvenSliceLength/CheckEvenSliceLength.go
--- 2022.1-1/staticcheck/testdata/src/CheckEvenSliceLength/CheckEvenSliceLength.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckEvenSliceLength/CheckEvenSliceLength.go	2022-07-31 15:38:22.000000000 +0000
@@ -2,56 +2,56 @@ package pkg
 
 import "strings"
 
-func fnVariadic(s string, args ...interface{}) { // want args:"needs even elements"
+func fnVariadic(s string, args ...interface{}) { //@ fact(args, "needs even elements")
 	if len(args)%2 != 0 {
 		panic("I'm one of those annoying logging APIs")
 	}
 }
 
-func fnSlice(s string, args []interface{}) { // want args:"needs even elements"
+func fnSlice(s string, args []interface{}) { //@ fact(args, "needs even elements")
 	if len(args)%2 != 0 {
 		panic("I'm one of those annoying logging APIs")
 	}
 }
 
-func fnIndirect(s string, args ...interface{}) { // want args:"needs even elements"
+func fnIndirect(s string, args ...interface{}) { //@ fact(args, "needs even elements")
 	fnSlice(s, args)
 }
 
-func fn2(bleh []interface{}, arr1 [3]interface{}) { // want bleh:"needs even elements"
-	fnVariadic("%s", 1, 2, 3) // want `variadic argument "args".+ but has 3 elements`
+func fn2(bleh []interface{}, arr1 [3]interface{}) { //@ fact(bleh, "needs even elements")
+	fnVariadic("%s", 1, 2, 3) //@ diag(re`variadic argument "args".+ but has 3 elements`)
 	args := []interface{}{1, 2, 3}
-	fnVariadic("", args...)     // want `variadic argument "args".+ but has 3 elements`
-	fnVariadic("", args[:1]...) // want `variadic argument "args".+ but has 1 elements`
+	fnVariadic("", args...)     //@ diag(re`variadic argument "args".+ but has 3 elements`)
+	fnVariadic("", args[:1]...) //@ diag(re`variadic argument "args".+ but has 1 elements`)
 	fnVariadic("", args[:2]...)
-	fnVariadic("", args[0:1]...) // want `variadic argument "args".+ but has 1 elements`
-	fnVariadic("", args[0:]...)  // want `variadic argument "args".+ but has 3 elements`
-	fnVariadic("", args[:]...)   // want `variadic argument "args".+ but has 3 elements`
+	fnVariadic("", args[0:1]...) //@ diag(re`variadic argument "args".+ but has 1 elements`)
+	fnVariadic("", args[0:]...)  //@ diag(re`variadic argument "args".+ but has 3 elements`)
+	fnVariadic("", args[:]...)   //@ diag(re`variadic argument "args".+ but has 3 elements`)
 	fnVariadic("", bleh...)
-	fnVariadic("", bleh[:1]...)  // want `variadic argument "args".+ but has 1 elements`
-	fnVariadic("", bleh[0:1]...) // want `variadic argument "args".+ but has 1 elements`
+	fnVariadic("", bleh[:1]...)  //@ diag(re`variadic argument "args".+ but has 1 elements`)
+	fnVariadic("", bleh[0:1]...) //@ diag(re`variadic argument "args".+ but has 1 elements`)
 	fnVariadic("", bleh[0:]...)
 	fnVariadic("", bleh[:]...)
-	fnVariadic("", bleh)                      // want `variadic argument "args".+ but has 1 elements`
-	fnVariadic("", make([]interface{}, 3)...) // want `variadic argument "args".+ but has 3 elements`
+	fnVariadic("", bleh)                      //@ diag(re`variadic argument "args".+ but has 1 elements`)
+	fnVariadic("", make([]interface{}, 3)...) //@ diag(re`variadic argument "args".+ but has 3 elements`)
 	fnVariadic("", make([]interface{}, 4)...)
 	var arr2 [3]interface{}
-	fnVariadic("", arr1[:]...) // want `variadic argument "args".+ but has 3 elements`
-	fnVariadic("", arr2[:]...) // want `variadic argument "args".+ but has 3 elements`
+	fnVariadic("", arr1[:]...) //@ diag(re`variadic argument "args".+ but has 3 elements`)
+	fnVariadic("", arr2[:]...) //@ diag(re`variadic argument "args".+ but has 3 elements`)
 
-	fnSlice("", []interface{}{1, 2, 3}) // want `argument "args".+ but has 3 elements`
+	fnSlice("", []interface{}{1, 2, 3}) //@ diag(re`argument "args".+ but has 3 elements`)
 	fnSlice("", []interface{}{1, 2, 3, 4})
 
-	fnIndirect("%s", 1, 2, 3) // want `argument "args".+ but has 3 elements`
+	fnIndirect("%s", 1, 2, 3) //@ diag(re`argument "args".+ but has 3 elements`)
 	fnIndirect("%s", 1, 2)
 
-	strings.NewReplacer("one") // want `variadic argument "oldnew".+ but has 1 elements`
+	strings.NewReplacer("one") //@ diag(re`variadic argument "oldnew".+ but has 1 elements`)
 	strings.NewReplacer("one", "two")
 }
 
 func fn3() {
 	args := []interface{}{""}
 	if true {
-		fnSlice("", args) // want `but has 1 element`
+		fnSlice("", args) //@ diag(`but has 1 element`)
 	}
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckExec/CheckExec.go 2022.1.3-1/staticcheck/testdata/src/CheckExec/CheckExec.go
--- 2022.1-1/staticcheck/testdata/src/CheckExec/CheckExec.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckExec/CheckExec.go	2022-07-31 15:38:22.000000000 +0000
@@ -4,7 +4,7 @@ import "os/exec"
 
 func fn() {
 	exec.Command("ls")
-	exec.Command("ls arg1") // want `first argument to exec`
+	exec.Command("ls arg1") //@ diag(`first argument to exec`)
 	exec.Command(`C:\Program Files\this\is\insane.exe`)
 	exec.Command("/Library/Application Support/VMware Tools/vmware-tools-daemon")
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckExtremeComparison/CheckExtremeComparison64.go 2022.1.3-1/staticcheck/testdata/src/CheckExtremeComparison/CheckExtremeComparison64.go
--- 2022.1-1/staticcheck/testdata/src/CheckExtremeComparison/CheckExtremeComparison64.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckExtremeComparison/CheckExtremeComparison64.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,3 +1,4 @@
+//go:build amd64 || arm64 || ppc64 || ppc64le || mips64 || mips64le || mips64p32 || mips64p32le || sparc64
 // +build amd64 arm64 ppc64 ppc64le mips64 mips64le mips64p32 mips64p32le sparc64
 
 package pkg
@@ -9,7 +10,7 @@ func fn2() {
 		u uint
 		i int
 	)
-	_ = u > math.MaxUint64 // want `no value of type uint is greater than math\.MaxUint64`
-	_ = i > math.MaxInt64  // want `no value of type int is greater than math\.MaxInt64`
+	_ = u > math.MaxUint64 //@ diag(`no value of type uint is greater than math.MaxUint64`)
+	_ = i > math.MaxInt64  //@ diag(`no value of type int is greater than math.MaxInt64`)
 
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckExtremeComparison/CheckExtremeComparison.go 2022.1.3-1/staticcheck/testdata/src/CheckExtremeComparison/CheckExtremeComparison.go
--- 2022.1-1/staticcheck/testdata/src/CheckExtremeComparison/CheckExtremeComparison.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckExtremeComparison/CheckExtremeComparison.go	2022-07-31 15:38:22.000000000 +0000
@@ -13,31 +13,31 @@ func fn1() {
 		i   int
 	)
 
-	_ = u8 > math.MaxUint8  // want `no value of type uint8 is greater than math\.MaxUint8`
-	_ = u8 >= math.MaxUint8 // want `no value of type uint8 is greater than math\.MaxUint8`
-	_ = u8 >= 0             // want `every value of type uint8 is >= 0`
-	_ = u8 <= math.MaxUint8 // want `every value of type uint8 is <= math\.MaxUint8`
+	_ = u8 > math.MaxUint8  //@ diag(`no value of type uint8 is greater than math.MaxUint8`)
+	_ = u8 >= math.MaxUint8 //@ diag(`no value of type uint8 is greater than math.MaxUint8`)
+	_ = u8 >= 0             //@ diag(`every value of type uint8 is >= 0`)
+	_ = u8 <= math.MaxUint8 //@ diag(`every value of type uint8 is <= math.MaxUint8`)
 	_ = u8 > 0
 	_ = u8 >= 1
 	_ = u8 < math.MaxUint8
-	_ = u8 < 0 // want `no value of type uint8 is less than 0`
+	_ = u8 < 0 //@ diag(`no value of type uint8 is less than 0`)
 	_ = u8 <= 0
-	_ = 0 > u8 // want `no value of type uint8 is less than 0`
+	_ = 0 > u8 //@ diag(`no value of type uint8 is less than 0`)
 	_ = 0 >= u8
 
 	_ = u16 > math.MaxUint8
-	_ = u16 > math.MaxUint16 // want `no value of type uint16 is greater than math\.MaxUint16`
+	_ = u16 > math.MaxUint16 //@ diag(`no value of type uint16 is greater than math.MaxUint16`)
 	_ = u16 <= math.MaxUint8
-	_ = u16 <= math.MaxUint16 // want `every value of type uint16 is <= math\.MaxUint16`
+	_ = u16 <= math.MaxUint16 //@ diag(`every value of type uint16 is <= math.MaxUint16`)
 
 	_ = u > math.MaxUint32
 
-	_ = i8 > math.MaxInt8 // want `no value of type int8 is greater than math\.MaxInt8`
+	_ = i8 > math.MaxInt8 //@ diag(`no value of type int8 is greater than math.MaxInt8`)
 	_ = i16 > math.MaxInt8
-	_ = i16 > math.MaxInt16 // want `no value of type int16 is greater than math\.MaxInt16`
+	_ = i16 > math.MaxInt16 //@ diag(`no value of type int16 is greater than math.MaxInt16`)
 	_ = i > math.MaxInt32
 	_ = i8 < 0
-	_ = i8 <= math.MinInt8 // want `no value of type int8 is less than math\.MinInt8`
-	_ = i8 < math.MinInt8  // want `no value of type int8 is less than math\.MinInt8`
-	_ = i8 >= math.MinInt8 // want `every value of type int8 is >= math.MinInt8`
+	_ = i8 <= math.MinInt8 //@ diag(`no value of type int8 is less than math.MinInt8`)
+	_ = i8 < math.MinInt8  //@ diag(`no value of type int8 is less than math.MinInt8`)
+	_ = i8 >= math.MinInt8 //@ diag(`every value of type int8 is >= math.MinInt8`)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckImpossibleTypeAssertion/CheckImpossibleTypeAssertion.go 2022.1.3-1/staticcheck/testdata/src/CheckImpossibleTypeAssertion/CheckImpossibleTypeAssertion.go
--- 2022.1-1/staticcheck/testdata/src/CheckImpossibleTypeAssertion/CheckImpossibleTypeAssertion.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckImpossibleTypeAssertion/CheckImpossibleTypeAssertion.go	2022-07-31 15:38:22.000000000 +0000
@@ -21,11 +21,11 @@ type i4 interface {
 
 func fn() {
 	var v1 i1
-	_ = v1.(i2) // want `impossible type assertion; i1 and i2 contradict each other`
+	_ = v1.(i2) //@ diag(`impossible type assertion; i1 and i2 contradict each other`)
 	_ = v1.(i3)
 	_ = v1.(i4)
-	_ = v1.(fmt.Stringer) // want `impossible type assertion; i1 and fmt.Stringer contradict each other`
-	_ = v1.(interface {   // want `i1 and.+String.+contradict each other`
+	_ = v1.(fmt.Stringer) //@ diag(`impossible type assertion; i1 and fmt.Stringer contradict each other`)
+	_ = v1.(interface {   //@ diag(re`i1 and.+String.+contradict each other`)
 		String() string
 	})
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckIneffectiveAppend/CheckIneffectiveAppend.go 2022.1.3-1/staticcheck/testdata/src/CheckIneffectiveAppend/CheckIneffectiveAppend.go
--- 2022.1-1/staticcheck/testdata/src/CheckIneffectiveAppend/CheckIneffectiveAppend.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckIneffectiveAppend/CheckIneffectiveAppend.go	2022-07-31 15:38:22.000000000 +0000
@@ -4,8 +4,8 @@ import "fmt"
 
 func fn1() {
 	var s []int
-	s = append(s, 1) // want `this result of append is never used`
-	s = append(s, 1) // want `this result of append is never used`
+	s = append(s, 1) //@ diag(`this result of append is never used`)
+	s = append(s, 1) //@ diag(`this result of append is never used`)
 }
 
 func fn2() (named []int) {
@@ -15,12 +15,12 @@ func fn2() (named []int) {
 
 func fn3() {
 	s := make([]int, 0)
-	s = append(s, 1) // want `this result of append is never used`
+	s = append(s, 1) //@ diag(`this result of append is never used`)
 }
 
 func fn3_1(n int) {
 	s := make([]int, n)
-	s = append(s, 1) // want `this result of append is never used`
+	s = append(s, 1) //@ diag(`this result of append is never used`)
 }
 
 func fn4() []int {
@@ -61,7 +61,7 @@ func fn10() {
 func fn11() {
 	var s []int
 	for x := 0; x < 10; x++ {
-		s = append(s, 1) // want `this result of append is never used`
+		s = append(s, 1) //@ diag(`this result of append is never used`)
 	}
 }
 
@@ -130,7 +130,7 @@ func fn19() [4]int {
 func fn20() {
 	var x [4]int
 	s := x[:]
-	s = append(s, 1) // want `this result of append is never used`
+	s = append(s, 1) //@ diag(`this result of append is never used`)
 }
 
 func fn21() {
@@ -171,7 +171,7 @@ func fn25() {
 	if true {
 		s = append(s, 1)
 	}
-	s = append(s, 2) // want `this result of append is never used`
+	s = append(s, 2) //@ diag(`this result of append is never used`)
 }
 
 func fn26() {
@@ -190,7 +190,7 @@ func fn27() {
 	} else {
 		s = make([]byte, 0, 2)
 	}
-	s = append(s, 1) // want `this result of append is never used`
+	s = append(s, 1) //@ diag(`this result of append is never used`)
 }
 
 func fn28() {
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckIneffectiveCopy/CheckIneffectiveCopy.go 2022.1.3-1/staticcheck/testdata/src/CheckIneffectiveCopy/CheckIneffectiveCopy.go
--- 2022.1-1/staticcheck/testdata/src/CheckIneffectiveCopy/CheckIneffectiveCopy.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckIneffectiveCopy/CheckIneffectiveCopy.go	2022-07-31 15:38:22.000000000 +0000
@@ -6,8 +6,8 @@ func fn1(_ *T) {}
 
 func fn2() {
 	t1 := &T{}
-	fn1(&*t1) // want `will not copy`
-	fn1(*&t1) // want `will not copy`
+	fn1(&*t1) //@ diag(`will not copy`)
+	fn1(*&t1) //@ diag(`will not copy`)
 
 	_Cvar_something := &T{}
 	fn1(&*_Cvar_something)
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckIneffectiveFieldAssignments/CheckIneffectiveFieldAssignments.go 2022.1.3-1/staticcheck/testdata/src/CheckIneffectiveFieldAssignments/CheckIneffectiveFieldAssignments.go
--- 2022.1-1/staticcheck/testdata/src/CheckIneffectiveFieldAssignments/CheckIneffectiveFieldAssignments.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckIneffectiveFieldAssignments/CheckIneffectiveFieldAssignments.go	2022-07-31 15:38:22.000000000 +0000
@@ -19,20 +19,20 @@ type T3 struct {
 
 func (v T1) fn1() {
 	v.x = 1
-	v.y = 1 // want `ineffective assignment to field T1.y`
+	v.y = 1 //@ diag(`ineffective assignment to field T1.y`)
 	println(v.x)
 }
 
 func (v T1) fn2() {
 	println(v.x)
-	v.x = 1 // want `ineffective assignment to field T1.x`
+	v.x = 1 //@ diag(`ineffective assignment to field T1.x`)
 }
 
 func (v T1) fn3() {
 	if true {
 		println(v.x)
 	}
-	v.x = 1 // want `ineffective assignment to field T1.x`
+	v.x = 1 //@ diag(`ineffective assignment to field T1.x`)
 }
 
 func (v T1) fn10() {
@@ -49,7 +49,7 @@ func (v T1) fn4() {
 
 func (v T1) fn5() {
 	v.dump()
-	v.x = 1 // want `ineffective assignment to field T1.x`
+	v.x = 1 //@ diag(`ineffective assignment to field T1.x`)
 }
 
 func (v T1) fn6() {
@@ -65,7 +65,7 @@ func (v T1) fn7() {
 }
 
 func (v T1) fn8() {
-	v.x++ // want `ineffective assignment to field T1.x`
+	v.x++ //@ diag(`ineffective assignment to field T1.x`)
 }
 
 func (v T1) fn9() {
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckIneffectiveLoop/CheckIneffectiveLoop_generics.go 2022.1.3-1/staticcheck/testdata/src/CheckIneffectiveLoop/CheckIneffectiveLoop_generics.go
--- 2022.1-1/staticcheck/testdata/src/CheckIneffectiveLoop/CheckIneffectiveLoop_generics.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckIneffectiveLoop/CheckIneffectiveLoop_generics.go	2022-07-31 15:38:22.000000000 +0000
@@ -25,7 +25,7 @@ func _[T []int]() {
 		if true {
 			println()
 		}
-		break // want `the surrounding loop is unconditionally terminated`
+		break //@ diag(`the surrounding loop is unconditionally terminated`)
 	}
 }
 
@@ -34,6 +34,6 @@ func _[T any, S ~[]T](x S) {
 		if true {
 			println()
 		}
-		break // want `the surrounding loop is unconditionally terminated`
+		break //@ diag(`the surrounding loop is unconditionally terminated`)
 	}
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckIneffectiveLoop/CheckIneffectiveLoop.go 2022.1.3-1/staticcheck/testdata/src/CheckIneffectiveLoop/CheckIneffectiveLoop.go
--- 2022.1-1/staticcheck/testdata/src/CheckIneffectiveLoop/CheckIneffectiveLoop.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckIneffectiveLoop/CheckIneffectiveLoop.go	2022-07-31 15:38:22.000000000 +0000
@@ -5,7 +5,7 @@ func fn() {
 		if true {
 			println()
 		}
-		break // want `the surrounding loop is unconditionally terminated`
+		break //@ diag(`the surrounding loop is unconditionally terminated`)
 	}
 	for {
 		if true {
@@ -18,7 +18,7 @@ func fn() {
 		if true {
 			println()
 		}
-		break // want `the surrounding loop is unconditionally terminated`
+		break //@ diag(`the surrounding loop is unconditionally terminated`)
 	}
 	for range (map[int]int)(nil) {
 		if true {
@@ -52,6 +52,6 @@ var z = func() {
 		if true {
 			println()
 		}
-		break // want `the surrounding loop is unconditionally terminated`
+		break //@ diag(`the surrounding loop is unconditionally terminated`)
 	}
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckIneffectiveRandInt/CheckIneffectiveRandInt.go 2022.1.3-1/staticcheck/testdata/src/CheckIneffectiveRandInt/CheckIneffectiveRandInt.go
--- 2022.1-1/staticcheck/testdata/src/CheckIneffectiveRandInt/CheckIneffectiveRandInt.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckIneffectiveRandInt/CheckIneffectiveRandInt.go	2022-07-31 15:38:22.000000000 +0000
@@ -7,10 +7,10 @@ func fn() {
 		rng rand.Rand
 	}
 
-	_ = rand.Intn(1)   // want `rand\.Intn\(n\) generates.+rand\.Intn\(1\) therefore`
-	_ = rand.Int63n(1) // want `rand\.Int63n\(n\) generates.+rand\.Int63n\(1\) therefore`
+	_ = rand.Intn(1)   //@ diag(re`rand\.Intn\(n\) generates.+rand\.Intn\(1\) therefore`)
+	_ = rand.Int63n(1) //@ diag(re`rand\.Int63n\(n\) generates.+rand\.Int63n\(1\) therefore`)
 	var t T
-	_ = t.rng.Intn(1) // want `\(\*math/rand\.Rand\)\.Intn\(n\) generates.+t\.rng\.Intn\(1\) therefore`
+	_ = t.rng.Intn(1) //@ diag(re`\(\*math/rand\.Rand\)\.Intn\(n\) generates.+t\.rng\.Intn\(1\) therefore`)
 
 	_ = rand.Intn(2)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckIneffectiveSort/CheckIneffectiveSort.go 2022.1.3-1/staticcheck/testdata/src/CheckIneffectiveSort/CheckIneffectiveSort.go
--- 2022.1-1/staticcheck/testdata/src/CheckIneffectiveSort/CheckIneffectiveSort.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckIneffectiveSort/CheckIneffectiveSort.go	2022-07-31 15:38:22.000000000 +0000
@@ -7,7 +7,7 @@ func fn() {
 	var b []float64
 	var c sort.StringSlice
 
-	a = sort.StringSlice(a)  // want `sort\.StringSlice is a type.+consider using sort\.Strings instead`
-	b = sort.Float64Slice(b) // want `sort\.Float64Slice is a type.+consider using sort\.Float64s instead`
+	a = sort.StringSlice(a)  //@ diag(re`sort\.StringSlice is a type.+consider using sort\.Strings instead`)
+	b = sort.Float64Slice(b) //@ diag(re`sort\.Float64Slice is a type.+consider using sort\.Float64s instead`)
 	c = sort.StringSlice(c)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckIneffectiveSort/CheckIneffectiveSort.go.golden 2022.1.3-1/staticcheck/testdata/src/CheckIneffectiveSort/CheckIneffectiveSort.go.golden
--- 2022.1-1/staticcheck/testdata/src/CheckIneffectiveSort/CheckIneffectiveSort.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckIneffectiveSort/CheckIneffectiveSort.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -7,7 +7,7 @@ func fn() {
 	var b []float64
 	var c sort.StringSlice
 
-	sort.Strings(a)  // want `sort\.StringSlice is a type.+consider using sort\.Strings instead`
-	sort.Float64s(b) // want `sort\.Float64Slice is a type.+consider using sort\.Float64s instead`
+	sort.Strings(a)  //@ diag(re`sort\.StringSlice is a type.+consider using sort\.Strings instead`)
+	sort.Float64s(b) //@ diag(re`sort\.Float64Slice is a type.+consider using sort\.Float64s instead`)
 	c = sort.StringSlice(c)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckIneffectiveURLQueryModification/CheckIneffectiveURLQueryModification.go 2022.1.3-1/staticcheck/testdata/src/CheckIneffectiveURLQueryModification/CheckIneffectiveURLQueryModification.go
--- 2022.1-1/staticcheck/testdata/src/CheckIneffectiveURLQueryModification/CheckIneffectiveURLQueryModification.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckIneffectiveURLQueryModification/CheckIneffectiveURLQueryModification.go	2022-07-31 15:38:22.000000000 +0000
@@ -3,9 +3,9 @@ package pkg
 import "net/url"
 
 func fn(u *url.URL) {
-	u.Query().Add("", "") // want `returns a copy`
-	u.Query().Set("", "") // want `returns a copy`
-	u.Query().Del("")     // want `returns a copy`
+	u.Query().Add("", "") //@ diag(`returns a copy`)
+	u.Query().Set("", "") //@ diag(`returns a copy`)
+	u.Query().Del("")     //@ diag(`returns a copy`)
 	u.Query().Encode()
 
 	var t T
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckInfiniteEmptyLoop/CheckInfiniteEmptyLoop.go 2022.1.3-1/staticcheck/testdata/src/CheckInfiniteEmptyLoop/CheckInfiniteEmptyLoop.go
--- 2022.1-1/staticcheck/testdata/src/CheckInfiniteEmptyLoop/CheckInfiniteEmptyLoop.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckInfiniteEmptyLoop/CheckInfiniteEmptyLoop.go	2022-07-31 15:38:22.000000000 +0000
@@ -3,7 +3,7 @@ package pkg
 func fn2() bool { return true }
 
 func fn() {
-	for { // want `this loop will spin`
+	for { //@ diag(`this loop will spin`)
 	}
 
 	for fn2() {
@@ -13,21 +13,21 @@ func fn() {
 		break
 	}
 
-	for true { // want `loop condition never changes` `this loop will spin`
+	for true { //@ diag(`loop condition never changes`), diag(`this loop will spin`)
 	}
 
 	x := true
-	for x { // want `loop condition never changes` `this loop will spin`
+	for x { //@ diag(`loop condition never changes`), diag(`this loop will spin`)
 	}
 
 	x = false
-	for x { // want `loop condition never changes` `this loop will spin`
+	for x { //@ diag(`loop condition never changes`), diag(`this loop will spin`)
 	}
 
 	for false {
 	}
 
 	false := true
-	for false { // want `loop condition never changes` `this loop will spin`
+	for false { //@ diag(`loop condition never changes`), diag(`this loop will spin`)
 	}
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckInfiniteRecursion/CheckInfiniteRecursion.go 2022.1.3-1/staticcheck/testdata/src/CheckInfiniteRecursion/CheckInfiniteRecursion.go
--- 2022.1-1/staticcheck/testdata/src/CheckInfiniteRecursion/CheckInfiniteRecursion.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckInfiniteRecursion/CheckInfiniteRecursion.go	2022-07-31 15:38:22.000000000 +0000
@@ -2,7 +2,7 @@ package pkg
 
 func fn1(x int) bool {
 	println(x)
-	return fn1(x + 1) // want `infinite recursive call`
+	return fn1(x + 1) //@ diag(`infinite recursive call`)
 	return true
 }
 
@@ -38,7 +38,7 @@ func fn4(p *int, n int) {
 
 func fn5(p *int, n int) {
 	x := 0
-	fn5(&x, n-1) // want `infinite recursive call`
+	fn5(&x, n-1) //@ diag(`infinite recursive call`)
 	if x != n {
 		panic("stack is corrupted")
 	}
@@ -53,12 +53,12 @@ type T struct {
 }
 
 func (t T) Fn1() {
-	t.Fn1() // want `infinite recursive call`
+	t.Fn1() //@ diag(`infinite recursive call`)
 }
 
 func (t T) Fn2() {
 	x := T{}
-	x.Fn2() // want `infinite recursive call`
+	x.Fn2() //@ diag(`infinite recursive call`)
 }
 
 func (t T) Fn3() {
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckIntegerDivisionEqualsZero/CheckIntegerDivisionEqualsZero.go 2022.1.3-1/staticcheck/testdata/src/CheckIntegerDivisionEqualsZero/CheckIntegerDivisionEqualsZero.go
--- 2022.1-1/staticcheck/testdata/src/CheckIntegerDivisionEqualsZero/CheckIntegerDivisionEqualsZero.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckIntegerDivisionEqualsZero/CheckIntegerDivisionEqualsZero.go	2022-07-31 15:38:22.000000000 +0000
@@ -3,16 +3,16 @@ package pkg
 func foo(x float64) {}
 
 func fn() {
-	_ = 2 / 3 // want `results in zero`
+	_ = 2 / 3 //@ diag(`results in zero`)
 	_ = 4 / 2
 	_ = 4 / 3
-	_ = 0 / 2 // want `results in zero`
+	_ = 0 / 2 //@ diag(`results in zero`)
 	_ = 2 / 3.
 	_ = 2 / 3.0
 	_ = 2.0 / 3
-	const _ = 2 / 3         // want `results in zero`
-	const _ float64 = 2 / 3 // want `results in zero`
-	_ = float64(2 / 3)      // want `results in zero`
+	const _ = 2 / 3         //@ diag(`results in zero`)
+	const _ float64 = 2 / 3 //@ diag(`results in zero`)
+	_ = float64(2 / 3)      //@ diag(`results in zero`)
 
-	foo(1 / 2) // want `results in zero`
+	foo(1 / 2) //@ diag(`results in zero`)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckLeakyTimeTick/CheckLeakyTimeTick.go 2022.1.3-1/staticcheck/testdata/src/CheckLeakyTimeTick/CheckLeakyTimeTick.go
--- 2022.1-1/staticcheck/testdata/src/CheckLeakyTimeTick/CheckLeakyTimeTick.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckLeakyTimeTick/CheckLeakyTimeTick.go	2022-07-31 15:38:22.000000000 +0000
@@ -9,7 +9,7 @@ func fn1() {
 }
 
 func fn2() {
-	for range time.Tick(0) { // want `leaks the underlying ticker`
+	for range time.Tick(0) { //@ diag(`leaks the underlying ticker`)
 		println("")
 		if true {
 			break
@@ -18,7 +18,7 @@ func fn2() {
 }
 
 func fn3() {
-	for range time.Tick(0) { // want `leaks the underlying ticker`
+	for range time.Tick(0) { //@ diag(`leaks the underlying ticker`)
 		println("")
 		if true {
 			return
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckLhsRhsIdentical/CheckLhsRhsIdentical.go 2022.1.3-1/staticcheck/testdata/src/CheckLhsRhsIdentical/CheckLhsRhsIdentical.go
--- 2022.1-1/staticcheck/testdata/src/CheckLhsRhsIdentical/CheckLhsRhsIdentical.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckLhsRhsIdentical/CheckLhsRhsIdentical.go	2022-07-31 15:38:22.000000000 +0000
@@ -18,25 +18,25 @@ type T2 struct {
 }
 
 func fn(a int, s []int, f1 float64, f2 Float, fs Floats, is Ints, t1 T1, t2 T2) {
-	if 0 == 0 { // want `identical expressions`
+	if 0 == 0 { //@ diag(`identical expressions`)
 		println()
 	}
-	if 1 == 1 { // want `identical expressions`
+	if 1 == 1 { //@ diag(`identical expressions`)
 		println()
 	}
-	if a == a { // want `identical expressions`
+	if a == a { //@ diag(`identical expressions`)
 		println()
 	}
-	if a != a { // want `identical expressions`
+	if a != a { //@ diag(`identical expressions`)
 		println()
 	}
-	if s[0] == s[0] { // want `identical expressions`
+	if s[0] == s[0] { //@ diag(`identical expressions`)
 		println()
 	}
-	if 1&1 == 1 { // want `identical expressions`
+	if 1&1 == 1 { //@ diag(`identical expressions`)
 		println()
 	}
-	if (1 + 2 + 3) == (1 + 2 + 3) { // want `identical expressions`
+	if (1 + 2 + 3) == (1 + 2 + 3) { //@ diag(`identical expressions`)
 		println()
 	}
 	if f1 == f1 {
@@ -57,13 +57,13 @@ func fn(a int, s []int, f1 float64, f2 F
 	if fs == fs {
 		println()
 	}
-	if is == is { // want `identical expressions`
+	if is == is { //@ diag(`identical expressions`)
 		println()
 	}
 	if t1 == t1 {
 		println()
 	}
-	if t2 == t2 { // want `identical expressions`
+	if t2 == t2 { //@ diag(`identical expressions`)
 		println()
 	}
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckLhsRhsIdentical/generics.go 2022.1.3-1/staticcheck/testdata/src/CheckLhsRhsIdentical/generics.go
--- 2022.1-1/staticcheck/testdata/src/CheckLhsRhsIdentical/generics.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckLhsRhsIdentical/generics.go	2022-07-31 15:38:22.000000000 +0000
@@ -8,7 +8,7 @@ func tpfn1[T comparable](x T) {
 }
 
 func tpfn2[T int | string](x T) {
-	if x != x { // want `identical expressions`
+	if x != x { //@ diag(`identical expressions`)
 	}
 }
 
@@ -18,7 +18,7 @@ func tpfn3[T int | float64](x T) {
 }
 
 func tpfn4[E int | int64, T [4]E](x T) {
-	if x != x { // want `identical expressions`
+	if x != x { //@ diag(`identical expressions`)
 	}
 }
 
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckListenAddress/CheckListenAddress.go 2022.1.3-1/staticcheck/testdata/src/CheckListenAddress/CheckListenAddress.go
--- 2022.1-1/staticcheck/testdata/src/CheckListenAddress/CheckListenAddress.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckListenAddress/CheckListenAddress.go	2022-07-31 15:38:22.000000000 +0000
@@ -4,8 +4,8 @@ import "net/http"
 
 func fn() {
 	// Seen in actual code
-	http.ListenAndServe("localhost:8080/", nil) // want `invalid port or service name in host:port pair`
-	http.ListenAndServe("localhost", nil)       // want `invalid port or service name in host:port pair`
+	http.ListenAndServe("localhost:8080/", nil) //@ diag(`invalid port or service name in host:port pair`)
+	http.ListenAndServe("localhost", nil)       //@ diag(`invalid port or service name in host:port pair`)
 	http.ListenAndServe("localhost:8080", nil)
 	http.ListenAndServe(":8080", nil)
 	http.ListenAndServe(":http", nil)
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckLoopCondition/CheckLoopCondition.go 2022.1.3-1/staticcheck/testdata/src/CheckLoopCondition/CheckLoopCondition.go
--- 2022.1-1/staticcheck/testdata/src/CheckLoopCondition/CheckLoopCondition.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckLoopCondition/CheckLoopCondition.go	2022-07-31 15:38:22.000000000 +0000
@@ -2,7 +2,7 @@ package pkg
 
 func fn() {
 	for i := 0; i < 10; i++ {
-		for j := 0; j < 10; i++ { // want `variable in loop condition never changes`
+		for j := 0; j < 10; i++ { //@ diag(`variable in loop condition never changes`)
 		}
 	}
 
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckLoopEmptyDefault/CheckLoopEmptyDefault.go 2022.1.3-1/staticcheck/testdata/src/CheckLoopEmptyDefault/CheckLoopEmptyDefault.go
--- 2022.1-1/staticcheck/testdata/src/CheckLoopEmptyDefault/CheckLoopEmptyDefault.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckLoopEmptyDefault/CheckLoopEmptyDefault.go	2022-07-31 15:38:22.000000000 +0000
@@ -10,7 +10,7 @@ func fn() {
 	for {
 		select {
 		case <-ch:
-		default: // want `should not have an empty default case`
+		default: //@ diag(`should not have an empty default case`)
 		}
 	}
 
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckLoopEmptyDefault/CheckLoopEmptyDefault.go.golden 2022.1.3-1/staticcheck/testdata/src/CheckLoopEmptyDefault/CheckLoopEmptyDefault.go.golden
--- 2022.1-1/staticcheck/testdata/src/CheckLoopEmptyDefault/CheckLoopEmptyDefault.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckLoopEmptyDefault/CheckLoopEmptyDefault.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -10,7 +10,7 @@ func fn() {
 	for {
 		select {
 		case <-ch:
-			// want `should not have an empty default case`
+			//@ diag(`should not have an empty default case`)
 		}
 	}
 
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckMapBytesKey/key_generics.go 2022.1.3-1/staticcheck/testdata/src/CheckMapBytesKey/key_generics.go
--- 2022.1-1/staticcheck/testdata/src/CheckMapBytesKey/key_generics.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckMapBytesKey/key_generics.go	2022-07-31 15:38:22.000000000 +0000
@@ -4,6 +4,6 @@ package pkg
 
 func tpfn[T ~string | []byte | int](b T) {
 	var m map[string]int
-	k := string(b) // want `would be more efficient`
+	k := string(b) //@ diag(`would be more efficient`)
 	_ = m[k]
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckMapBytesKey/key.go 2022.1.3-1/staticcheck/testdata/src/CheckMapBytesKey/key.go
--- 2022.1-1/staticcheck/testdata/src/CheckMapBytesKey/key.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckMapBytesKey/key.go	2022-07-31 15:38:22.000000000 +0000
@@ -5,7 +5,7 @@ func fn() {
 	var b []byte
 	_ = m[string(b)]
 	_ = m[string(b)]
-	s1 := string(b) // want `m\[string\(key\)\] would be more efficient than k := string\(key\); m\[k\]`
+	s1 := string(b) //@ diag(`m[string(key)] would be more efficient than k := string(key); m[k]`)
 	_ = m[s1]
 	_ = m[s1]
 
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckMathInt/CheckMathInt.go 2022.1.3-1/staticcheck/testdata/src/CheckMathInt/CheckMathInt.go
--- 2022.1-1/staticcheck/testdata/src/CheckMathInt/CheckMathInt.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckMathInt/CheckMathInt.go	2022-07-31 15:38:22.000000000 +0000
@@ -3,6 +3,6 @@ package pkg
 import "math"
 
 func fn(x int) {
-	math.Ceil(float64(x))      // want `on a converted integer is pointless`
-	math.Floor(float64(x * 2)) // want `on a converted integer is pointless`
+	math.Ceil(float64(x))      //@ diag(`on a converted integer is pointless`)
+	math.Floor(float64(x * 2)) //@ diag(`on a converted integer is pointless`)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckMaybeNil/CheckMaybeNil.go 2022.1.3-1/staticcheck/testdata/src/CheckMaybeNil/CheckMaybeNil.go
--- 2022.1-1/staticcheck/testdata/src/CheckMaybeNil/CheckMaybeNil.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckMaybeNil/CheckMaybeNil.go	2022-07-31 15:38:22.000000000 +0000
@@ -6,7 +6,7 @@ import (
 )
 
 func fn1(x *int) {
-	_ = *x // want `possible nil pointer dereference`
+	_ = *x //@ diag(`possible nil pointer dereference`)
 	if x != nil {
 		return
 	}
@@ -25,7 +25,7 @@ func fn2(x *int) {
 	if x == nil {
 		println("we should return")
 	}
-	_ = *x // want `possible nil pointer dereference`
+	_ = *x //@ diag(`possible nil pointer dereference`)
 }
 
 func fn3(x *int) {
@@ -45,7 +45,7 @@ func fn5(x *int) {
 	if x == nil {
 		x = gen()
 	}
-	_ = *x // want `possible nil pointer dereference`
+	_ = *x //@ diag(`possible nil pointer dereference`)
 	if x == nil {
 		println("we should return")
 	}
@@ -116,7 +116,7 @@ func fn11(x *int) {
 	if x == nil {
 		die2(true)
 	}
-	_ = *x // want `possible nil pointer dereference`
+	_ = *x //@ diag(`possible nil pointer dereference`)
 }
 
 func doPanic() { panic("") }
@@ -175,7 +175,7 @@ func fn16() {
 	if xs3 == nil {
 		println()
 	}
-	for _, x := range *xs3 { // want `possible nil pointer dereference`
+	for _, x := range *xs3 { //@ diag(`possible nil pointer dereference`)
 		_ = x
 	}
 
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckMaybeNil/generics.go 2022.1.3-1/staticcheck/testdata/src/CheckMaybeNil/generics.go
--- 2022.1-1/staticcheck/testdata/src/CheckMaybeNil/generics.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckMaybeNil/generics.go	2022-07-31 15:38:22.000000000 +0000
@@ -12,7 +12,7 @@ func tpfn1[T []int](x T) {
 }
 
 func tpfn2[T *int,](x T) {
-	_ = *x // want `possible nil pointer dereference`
+	_ = *x //@ diag(`possible nil pointer dereference`)
 	if x == nil {
 		return
 	}
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckMissingEnumTypesInDeclaration/CheckMissingEnumTypesInDeclaration.go 2022.1.3-1/staticcheck/testdata/src/CheckMissingEnumTypesInDeclaration/CheckMissingEnumTypesInDeclaration.go
--- 2022.1-1/staticcheck/testdata/src/CheckMissingEnumTypesInDeclaration/CheckMissingEnumTypesInDeclaration.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckMissingEnumTypesInDeclaration/CheckMissingEnumTypesInDeclaration.go	2022-07-31 15:38:22.000000000 +0000
@@ -10,7 +10,7 @@ const (
 )
 
 const (
-	c6 int = 1 // want `only the first constant in this group has an explicit type`
+	c6 int = 1 //@ diag(`only the first constant in this group has an explicit type`)
 	c7     = 2 // comment for testing https://github.com/dominikh/go-tools/issues/866
 	c8     = 3
 )
@@ -46,7 +46,7 @@ const (
 	c23 int = 1
 	c24 int = 2
 
-	c25 string = "" // want `only the first constant in this group has an explicit type`
+	c25 string = "" //@ diag(`only the first constant in this group has an explicit type`)
 	c26        = ""
 
 	c27     = 1
@@ -56,12 +56,12 @@ const (
 	c30     = 2
 	c31 int = 2
 
-	c32 string = "" // want `only the first constant in this group has an explicit type`
+	c32 string = "" //@ diag(`only the first constant in this group has an explicit type`)
 	c33        = ""
 )
 
 const (
-	c34 int = 1 // want `only the first constant in this group has an explicit type`
+	c34 int = 1 //@ diag(`only the first constant in this group has an explicit type`)
 	c35     = 2
 
 	c36 int = 2
@@ -73,7 +73,7 @@ const (
 )
 
 const (
-	c39 int8 = 1.0 // want `only the first constant in this group has an explicit type`
+	c39 int8 = 1.0 //@ diag(`only the first constant in this group has an explicit type`)
 	c40      = 'a'
 	c41      = 3
 )
@@ -81,6 +81,6 @@ const (
 type String string
 
 const (
-	c42 String = "" // want `only the first constant in this group has an explicit type`
+	c42 String = "" //@ diag(`only the first constant in this group has an explicit type`)
 	c43        = ""
 )
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckMissingEnumTypesInDeclaration/CheckMissingEnumTypesInDeclaration.go.golden 2022.1.3-1/staticcheck/testdata/src/CheckMissingEnumTypesInDeclaration/CheckMissingEnumTypesInDeclaration.go.golden
--- 2022.1-1/staticcheck/testdata/src/CheckMissingEnumTypesInDeclaration/CheckMissingEnumTypesInDeclaration.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckMissingEnumTypesInDeclaration/CheckMissingEnumTypesInDeclaration.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -10,7 +10,7 @@ const (
 )
 
 const (
-	c6 int = 1 // want `only the first constant in this group has an explicit type`
+	c6 int = 1 //@ diag(`only the first constant in this group has an explicit type`)
 	c7 int = 2 // comment for testing https://github.com/dominikh/go-tools/issues/866
 	c8 int = 3
 )
@@ -46,7 +46,7 @@ const (
 	c23 int = 1
 	c24 int = 2
 
-	c25 string = "" // want `only the first constant in this group has an explicit type`
+	c25 string = "" //@ diag(`only the first constant in this group has an explicit type`)
 	c26 string = ""
 
 	c27     = 1
@@ -56,12 +56,12 @@ const (
 	c30     = 2
 	c31 int = 2
 
-	c32 string = "" // want `only the first constant in this group has an explicit type`
+	c32 string = "" //@ diag(`only the first constant in this group has an explicit type`)
 	c33 string = ""
 )
 
 const (
-	c34 int = 1 // want `only the first constant in this group has an explicit type`
+	c34 int = 1 //@ diag(`only the first constant in this group has an explicit type`)
 	c35 int = 2
 
 	c36 int = 2
@@ -73,7 +73,7 @@ const (
 )
 
 const (
-	c39 int8 = 1.0 // want `only the first constant in this group has an explicit type`
+	c39 int8 = 1.0 //@ diag(`only the first constant in this group has an explicit type`)
 	c40 int8 = 'a'
 	c41 int8 = 3
 )
@@ -81,6 +81,6 @@ const (
 type String string
 
 const (
-	c42 String = "" // want `only the first constant in this group has an explicit type`
+	c42 String = "" //@ diag(`only the first constant in this group has an explicit type`)
 	c43 String = ""
 )
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckModuloOne/CheckModuloOne.go 2022.1.3-1/staticcheck/testdata/src/CheckModuloOne/CheckModuloOne.go
--- 2022.1-1/staticcheck/testdata/src/CheckModuloOne/CheckModuloOne.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckModuloOne/CheckModuloOne.go	2022-07-31 15:38:22.000000000 +0000
@@ -3,7 +3,7 @@ package pkg
 func fn() {
 	var a int
 	var b uint
-	_ = a % 1 // want `x % 1 is always zero`
+	_ = a % 1 //@ diag(`x % 1 is always zero`)
 	_ = a % 2
-	_ = b % 1 // want `x % 1 is always zero`
+	_ = b % 1 //@ diag(`x % 1 is always zero`)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckNaNComparison/CheckNaNComparison.go 2022.1.3-1/staticcheck/testdata/src/CheckNaNComparison/CheckNaNComparison.go
--- 2022.1-1/staticcheck/testdata/src/CheckNaNComparison/CheckNaNComparison.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckNaNComparison/CheckNaNComparison.go	2022-07-31 15:38:22.000000000 +0000
@@ -3,15 +3,15 @@ package pkg
 import "math"
 
 func fn(f float64) {
-	_ = f == math.NaN() // want `no value is equal to NaN`
-	_ = f > math.NaN()  // want `no value is equal to NaN`
-	_ = f != math.NaN() // want `no value is equal to NaN`
+	_ = f == math.NaN() //@ diag(`no value is equal to NaN`)
+	_ = f > math.NaN()  //@ diag(`no value is equal to NaN`)
+	_ = f != math.NaN() //@ diag(`no value is equal to NaN`)
 }
 
 func fn2(f float64) {
 	x := math.NaN()
 	if true {
-		if f == x { // want `no value is equal to NaN`
+		if f == x { //@ diag(`no value is equal to NaN`)
 		}
 	}
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckNegativeZeroFloat/CheckNegativeZeroFloat.go 2022.1.3-1/staticcheck/testdata/src/CheckNegativeZeroFloat/CheckNegativeZeroFloat.go
--- 2022.1-1/staticcheck/testdata/src/CheckNegativeZeroFloat/CheckNegativeZeroFloat.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckNegativeZeroFloat/CheckNegativeZeroFloat.go	2022-07-31 15:38:22.000000000 +0000
@@ -3,13 +3,13 @@ package pkg
 const x = 0.0
 
 func fn() {
-	_ = -0.0          // want `in Go, the floating-point literal '-0\.0' is the same as '0\.0', it does not produce a negative zero`
-	_ = float32(-0.0) // want `in Go, the floating-point literal '-0\.0' is the same as '0\.0', it does not produce a negative zero`
-	_ = float64(-0.0) // want `in Go, the floating-point literal '-0\.0' is the same as '0\.0', it does not produce a negative zero`
-	_ = -float32(0)   // want `in Go, the floating-point expression '-float32\(0\)' is the same as 'float32\(0\)', it does not produce a negative zero`
-	_ = -float64(0)   // want `in Go, the floating-point expression '-float64\(0\)' is the same as 'float64\(0\)', it does not produce a negative zero`
-	_ = -float32(0.0) // want `in Go, the floating-point expression '-float32\(0\.0\)' is the same as 'float32\(0\.0\)', it does not produce a negative zero`
-	_ = -float64(0.0) // want `in Go, the floating-point expression '-float64\(0\.0\)' is the same as 'float64\(0\.0\)', it does not produce a negative zero`
+	_ = -0.0          //@ diag(`in Go, the floating-point literal '-0.0' is the same as '0.0', it does not produce a negative zero`)
+	_ = float32(-0.0) //@ diag(`in Go, the floating-point literal '-0.0' is the same as '0.0', it does not produce a negative zero`)
+	_ = float64(-0.0) //@ diag(`in Go, the floating-point literal '-0.0' is the same as '0.0', it does not produce a negative zero`)
+	_ = -float32(0)   //@ diag(`in Go, the floating-point expression '-float32(0)' is the same as 'float32(0)', it does not produce a negative zero`)
+	_ = -float64(0)   //@ diag(`in Go, the floating-point expression '-float64(0)' is the same as 'float64(0)', it does not produce a negative zero`)
+	_ = -float32(0.0) //@ diag(`in Go, the floating-point expression '-float32(0.0)' is the same as 'float32(0.0)', it does not produce a negative zero`)
+	_ = -float64(0.0) //@ diag(`in Go, the floating-point expression '-float64(0.0)' is the same as 'float64(0.0)', it does not produce a negative zero`)
 
 	// intentionally not flagged
 	_ = -x
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckNegativeZeroFloat/CheckNegativeZeroFloat.go.golden 2022.1.3-1/staticcheck/testdata/src/CheckNegativeZeroFloat/CheckNegativeZeroFloat.go.golden
--- 2022.1-1/staticcheck/testdata/src/CheckNegativeZeroFloat/CheckNegativeZeroFloat.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckNegativeZeroFloat/CheckNegativeZeroFloat.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -3,13 +3,13 @@ package pkg
 const x = 0.0
 
 func fn() {
-	_ = math.Copysign(0, -1)          // want `in Go, the floating-point literal '-0\.0' is the same as '0\.0', it does not produce a negative zero`
-	_ = float32(math.Copysign(0, -1)) // want `in Go, the floating-point literal '-0\.0' is the same as '0\.0', it does not produce a negative zero`
-	_ = float64(math.Copysign(0, -1)) // want `in Go, the floating-point literal '-0\.0' is the same as '0\.0', it does not produce a negative zero`
-	_ = float32(math.Copysign(0, -1)) // want `in Go, the floating-point expression '-float32\(0\)' is the same as 'float32\(0\)', it does not produce a negative zero`
-	_ = math.Copysign(0, -1)          // want `in Go, the floating-point expression '-float64\(0\)' is the same as 'float64\(0\)', it does not produce a negative zero`
-	_ = float32(math.Copysign(0, -1)) // want `in Go, the floating-point expression '-float32\(0\.0\)' is the same as 'float32\(0\.0\)', it does not produce a negative zero`
-	_ = math.Copysign(0, -1)          // want `in Go, the floating-point expression '-float64\(0\.0\)' is the same as 'float64\(0\.0\)', it does not produce a negative zero`
+	_ = math.Copysign(0, -1)          //@ diag(`in Go, the floating-point literal '-0.0' is the same as '0.0', it does not produce a negative zero`)
+	_ = float32(math.Copysign(0, -1)) //@ diag(`in Go, the floating-point literal '-0.0' is the same as '0.0', it does not produce a negative zero`)
+	_ = float64(math.Copysign(0, -1)) //@ diag(`in Go, the floating-point literal '-0.0' is the same as '0.0', it does not produce a negative zero`)
+	_ = float32(math.Copysign(0, -1)) //@ diag(`in Go, the floating-point expression '-float32(0)' is the same as 'float32(0)', it does not produce a negative zero`)
+	_ = math.Copysign(0, -1)          //@ diag(`in Go, the floating-point expression '-float64(0)' is the same as 'float64(0)', it does not produce a negative zero`)
+	_ = float32(math.Copysign(0, -1)) //@ diag(`in Go, the floating-point expression '-float32(0.0)' is the same as 'float32(0.0)', it does not produce a negative zero`)
+	_ = math.Copysign(0, -1)          //@ diag(`in Go, the floating-point expression '-float64(0.0)' is the same as 'float64(0.0)', it does not produce a negative zero`)
 
 	// intentionally not flagged
 	_ = -x
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckNilMaps/CheckNilMaps.go 2022.1.3-1/staticcheck/testdata/src/CheckNilMaps/CheckNilMaps.go
--- 2022.1-1/staticcheck/testdata/src/CheckNilMaps/CheckNilMaps.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckNilMaps/CheckNilMaps.go	2022-07-31 15:38:22.000000000 +0000
@@ -4,7 +4,7 @@ import "fmt"
 
 func fn1() {
 	var m map[int]int
-	m[1] = 1 // want `assignment to nil map`
+	m[1] = 1 //@ diag(`assignment to nil map`)
 }
 
 func fn2(m map[int]int) {
@@ -15,7 +15,7 @@ func fn3() {
 	v := []int{1, 2, 3}
 	var m map[string]int
 	for i := range v {
-		m["a"] = i // want `assignment to nil map`
+		m["a"] = i //@ diag(`assignment to nil map`)
 	}
 	fmt.Println(m["a"])
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckNonOctalFileMode/CheckNonOctalFileMode.go 2022.1.3-1/staticcheck/testdata/src/CheckNonOctalFileMode/CheckNonOctalFileMode.go
--- 2022.1-1/staticcheck/testdata/src/CheckNonOctalFileMode/CheckNonOctalFileMode.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckNonOctalFileMode/CheckNonOctalFileMode.go	2022-07-31 15:38:22.000000000 +0000
@@ -3,7 +3,7 @@ package pkg
 import "os"
 
 func fn() {
-	os.OpenFile("", 0, 644) // want `file mode.+`
+	os.OpenFile("", 0, 644) //@ diag(`file mode`)
 }
 
 func fn2() (string, int, os.FileMode) {
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckNonOctalFileMode/CheckNonOctalFileMode.go.golden 2022.1.3-1/staticcheck/testdata/src/CheckNonOctalFileMode/CheckNonOctalFileMode.go.golden
--- 2022.1-1/staticcheck/testdata/src/CheckNonOctalFileMode/CheckNonOctalFileMode.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckNonOctalFileMode/CheckNonOctalFileMode.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -3,7 +3,7 @@ package pkg
 import "os"
 
 func fn() {
-	os.OpenFile("", 0, 0644) // want `file mode.+`
+	os.OpenFile("", 0, 0644) //@ diag(`file mode`)
 }
 
 func fn2() (string, int, os.FileMode) {
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckNonUniqueCutset/CheckNonUniqueCutset.go 2022.1.3-1/staticcheck/testdata/src/CheckNonUniqueCutset/CheckNonUniqueCutset.go
--- 2022.1-1/staticcheck/testdata/src/CheckNonUniqueCutset/CheckNonUniqueCutset.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckNonUniqueCutset/CheckNonUniqueCutset.go	2022-07-31 15:38:22.000000000 +0000
@@ -7,5 +7,5 @@ func fn(s string) {
 	_ = strings.TrimLeft(s, "a")
 	_ = strings.TrimLeft(s, "µ")
 	_ = strings.TrimLeft(s, "abc")
-	_ = strings.TrimLeft(s, "http://") // want `duplicate characters`
+	_ = strings.TrimLeft(s, "http://") //@ diag(`duplicate characters`)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckNoopMarshal/CheckNoopMarshal.go 2022.1.3-1/staticcheck/testdata/src/CheckNoopMarshal/CheckNoopMarshal.go
--- 2022.1-1/staticcheck/testdata/src/CheckNoopMarshal/CheckNoopMarshal.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckNoopMarshal/CheckNoopMarshal.go	2022-07-31 15:38:22.000000000 +0000
@@ -46,9 +46,9 @@ func fn() {
 	// don't flag structs with no fields
 	json.Marshal(T1{})
 	// no exported fields
-	json.Marshal(T2{}) // want `struct type 'CheckNoopMarshal.T2' doesn't have any exported fields, nor custom marshaling`
+	json.Marshal(T2{}) //@ diag(`struct type 'CheckNoopMarshal.T2' doesn't have any exported fields, nor custom marshaling`)
 	// pointer vs non-pointer makes no difference
-	json.Marshal(&T2{}) // want `struct type 'CheckNoopMarshal.T2' doesn't have any exported fields, nor custom marshaling`
+	json.Marshal(&T2{}) //@ diag(`struct type 'CheckNoopMarshal.T2' doesn't have any exported fields, nor custom marshaling`)
 	// exported field
 	json.Marshal(T3{})
 	// exported field, pointer makes no difference
@@ -62,11 +62,11 @@ func fn() {
 	// MarshalJSON
 	json.Marshal(T7{})
 	// MarshalXML does not apply to JSON
-	json.Marshal(T8{}) // want `struct type 'CheckNoopMarshal.T8' doesn't have any exported fields, nor custom marshaling`
+	json.Marshal(T8{}) //@ diag(`struct type 'CheckNoopMarshal.T8' doesn't have any exported fields, nor custom marshaling`)
 	// MarshalText
 	json.Marshal(T9{})
 	// embeds exported struct, but it has no fields
-	json.Marshal(T11{}) // want `struct type 'CheckNoopMarshal.T11' doesn't have any exported fields, nor custom marshaling`
+	json.Marshal(T11{}) //@ diag(`struct type 'CheckNoopMarshal.T11' doesn't have any exported fields, nor custom marshaling`)
 	// embeds type with MarshalJSON
 	json.Marshal(T12{})
 	// embeds type with MarshalJSON and type isn't exported
@@ -76,11 +76,11 @@ func fn() {
 	// embedded pointer to struct with exported fields
 	json.Marshal(T16{})
 	// don't recurse forever on recursive data structure
-	json.Marshal(T17{}) // want `struct type 'CheckNoopMarshal.T17' doesn't have any exported fields, nor custom marshaling`
+	json.Marshal(T17{}) //@ diag(`struct type 'CheckNoopMarshal.T17' doesn't have any exported fields, nor custom marshaling`)
 	json.Marshal(T18{})
 
 	// MarshalJSON does not apply to JSON
-	xml.Marshal(T7{}) // want `struct type 'CheckNoopMarshal.T7' doesn't have any exported fields, nor custom marshaling`
+	xml.Marshal(T7{}) //@ diag(`struct type 'CheckNoopMarshal.T7' doesn't have any exported fields, nor custom marshaling`)
 	// MarshalXML
 	xml.Marshal(T8{})
 
@@ -90,32 +90,32 @@ func fn() {
 	var t8 T8
 	var t9 T9
 	// check that all other variations of methods also work
-	json.Unmarshal(nil, &t2) // want `struct type 'CheckNoopMarshal.T2' doesn't have any exported fields, nor custom marshaling`
+	json.Unmarshal(nil, &t2) //@ diag(`struct type 'CheckNoopMarshal.T2' doesn't have any exported fields, nor custom marshaling`)
 	json.Unmarshal(nil, &t3)
 	json.Unmarshal(nil, &t9)
-	xml.Unmarshal(nil, &t2) // want `struct type 'CheckNoopMarshal.T2' doesn't have any exported fields, nor custom marshaling`
+	xml.Unmarshal(nil, &t2) //@ diag(`struct type 'CheckNoopMarshal.T2' doesn't have any exported fields, nor custom marshaling`)
 	xml.Unmarshal(nil, &t3)
 	xml.Unmarshal(nil, &t9)
-	(*json.Decoder)(nil).Decode(&t2) // want `struct type 'CheckNoopMarshal.T2' doesn't have any exported fields, nor custom marshaling`
+	(*json.Decoder)(nil).Decode(&t2) //@ diag(`struct type 'CheckNoopMarshal.T2' doesn't have any exported fields, nor custom marshaling`)
 	(*json.Decoder)(nil).Decode(&t3)
 	(*json.Decoder)(nil).Decode(&t9)
-	(*json.Encoder)(nil).Encode(t2) // want `struct type 'CheckNoopMarshal.T2' doesn't have any exported fields, nor custom marshaling`
+	(*json.Encoder)(nil).Encode(t2) //@ diag(`struct type 'CheckNoopMarshal.T2' doesn't have any exported fields, nor custom marshaling`)
 	(*json.Encoder)(nil).Encode(t3)
 	(*json.Encoder)(nil).Encode(t9)
-	(*xml.Decoder)(nil).Decode(&t2) // want `struct type 'CheckNoopMarshal.T2' doesn't have any exported fields, nor custom marshaling`
+	(*xml.Decoder)(nil).Decode(&t2) //@ diag(`struct type 'CheckNoopMarshal.T2' doesn't have any exported fields, nor custom marshaling`)
 	(*xml.Decoder)(nil).Decode(&t3)
 	(*xml.Decoder)(nil).Decode(&t9)
-	(*xml.Encoder)(nil).Encode(t2) // want `struct type 'CheckNoopMarshal.T2' doesn't have any exported fields, nor custom marshaling`
+	(*xml.Encoder)(nil).Encode(t2) //@ diag(`struct type 'CheckNoopMarshal.T2' doesn't have any exported fields, nor custom marshaling`)
 	(*xml.Encoder)(nil).Encode(t3)
 	(*xml.Encoder)(nil).Encode(t9)
 
 	(*json.Decoder)(nil).Decode(&t7)
-	(*json.Decoder)(nil).Decode(&t8) // want `struct type 'CheckNoopMarshal.T8' doesn't have any exported fields, nor custom marshaling`
+	(*json.Decoder)(nil).Decode(&t8) //@ diag(`struct type 'CheckNoopMarshal.T8' doesn't have any exported fields, nor custom marshaling`)
 	(*json.Encoder)(nil).Encode(t7)
-	(*json.Encoder)(nil).Encode(t8) // want `struct type 'CheckNoopMarshal.T8' doesn't have any exported fields, nor custom marshaling`
-	(*xml.Decoder)(nil).Decode(&t7) // want `struct type 'CheckNoopMarshal.T7' doesn't have any exported fields, nor custom marshaling`
+	(*json.Encoder)(nil).Encode(t8) //@ diag(`struct type 'CheckNoopMarshal.T8' doesn't have any exported fields, nor custom marshaling`)
+	(*xml.Decoder)(nil).Decode(&t7) //@ diag(`struct type 'CheckNoopMarshal.T7' doesn't have any exported fields, nor custom marshaling`)
 	(*xml.Decoder)(nil).Decode(&t8)
-	(*xml.Encoder)(nil).Encode(t7) // want `struct type 'CheckNoopMarshal.T7' doesn't have any exported fields, nor custom marshaling`
+	(*xml.Encoder)(nil).Encode(t7) //@ diag(`struct type 'CheckNoopMarshal.T7' doesn't have any exported fields, nor custom marshaling`)
 	(*xml.Encoder)(nil).Encode(t8)
 
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckPrintf/CheckPrintf.go 2022.1.3-1/staticcheck/testdata/src/CheckPrintf/CheckPrintf.go
--- 2022.1-1/staticcheck/testdata/src/CheckPrintf/CheckPrintf.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckPrintf/CheckPrintf.go	2022-07-31 15:38:22.000000000 +0000
@@ -66,69 +66,69 @@ func fn() {
 	fmt.Printf("%g", 1+2i)
 	fmt.Printf("%#e %#E %#f %#F %#g %#G", 1.2, 1.2, 1.2, 1.2, 1.2, 1.2) // OK since Go 1.9
 	// Some bad format/argTypes
-	fmt.Printf("%b", "hi")             // want `Printf format %b has arg #1 of wrong type string`
-	_ = fmt.Sprintf("%b", "hi")        // want `Printf format %b has arg #1 of wrong type string`
-	fmt.Fprintf(os.Stdout, "%b", "hi") // want `Printf format %b has arg #1 of wrong type string`
-	fmt.Printf("%t", c)                // want `Printf format %t has arg #1 of wrong type complex64`
-	fmt.Printf("%t", 1+2i)             // want `Printf format %t has arg #1 of wrong type complex128`
-	fmt.Printf("%c", 2.3)              // want `Printf format %c has arg #1 of wrong type float64`
-	fmt.Printf("%d", 2.3)              // want `Printf format %d has arg #1 of wrong type float64`
-	fmt.Printf("%e", "hi")             // want `Printf format %e has arg #1 of wrong type string`
-	fmt.Printf("%E", true)             // want `Printf format %E has arg #1 of wrong type bool`
-	fmt.Printf("%f", "hi")             // want `Printf format %f has arg #1 of wrong type string`
-	fmt.Printf("%F", 'x')              // want `Printf format %F has arg #1 of wrong type rune`
-	fmt.Printf("%g", "hi")             // want `Printf format %g has arg #1 of wrong type string`
-	fmt.Printf("%g", imap)             // want `Printf format %g has arg #1 of wrong type map\[int\]int`
-	fmt.Printf("%G", i)                // want `Printf format %G has arg #1 of wrong type int`
-	fmt.Printf("%o", x)                // want `Printf format %o has arg #1 of wrong type float64`
-	fmt.Printf("%p", 23)               // want `Printf format %p has arg #1 of wrong type int`
-	fmt.Printf("%q", x)                // want `Printf format %q has arg #1 of wrong type float64`
-	fmt.Printf("%s", b)                // want `Printf format %s has arg #1 of wrong type bool`
-	fmt.Printf("%s", byte(65))         // want `Printf format %s has arg #1 of wrong type byte`
-	fmt.Printf("%t", 23)               // want `Printf format %t has arg #1 of wrong type int`
-	fmt.Printf("%U", x)                // want `Printf format %U has arg #1 of wrong type float64`
+	fmt.Printf("%b", "hi")             //@ diag(`Printf format %b has arg #1 of wrong type string`)
+	_ = fmt.Sprintf("%b", "hi")        //@ diag(`Printf format %b has arg #1 of wrong type string`)
+	fmt.Fprintf(os.Stdout, "%b", "hi") //@ diag(`Printf format %b has arg #1 of wrong type string`)
+	fmt.Printf("%t", c)                //@ diag(`Printf format %t has arg #1 of wrong type complex64`)
+	fmt.Printf("%t", 1+2i)             //@ diag(`Printf format %t has arg #1 of wrong type complex128`)
+	fmt.Printf("%c", 2.3)              //@ diag(`Printf format %c has arg #1 of wrong type float64`)
+	fmt.Printf("%d", 2.3)              //@ diag(`Printf format %d has arg #1 of wrong type float64`)
+	fmt.Printf("%e", "hi")             //@ diag(`Printf format %e has arg #1 of wrong type string`)
+	fmt.Printf("%E", true)             //@ diag(`Printf format %E has arg #1 of wrong type bool`)
+	fmt.Printf("%f", "hi")             //@ diag(`Printf format %f has arg #1 of wrong type string`)
+	fmt.Printf("%F", 'x')              //@ diag(`Printf format %F has arg #1 of wrong type rune`)
+	fmt.Printf("%g", "hi")             //@ diag(`Printf format %g has arg #1 of wrong type string`)
+	fmt.Printf("%g", imap)             //@ diag(`Printf format %g has arg #1 of wrong type map[int]int`)
+	fmt.Printf("%G", i)                //@ diag(`Printf format %G has arg #1 of wrong type int`)
+	fmt.Printf("%o", x)                //@ diag(`Printf format %o has arg #1 of wrong type float64`)
+	fmt.Printf("%p", 23)               //@ diag(`Printf format %p has arg #1 of wrong type int`)
+	fmt.Printf("%q", x)                //@ diag(`Printf format %q has arg #1 of wrong type float64`)
+	fmt.Printf("%s", b)                //@ diag(`Printf format %s has arg #1 of wrong type bool`)
+	fmt.Printf("%s", byte(65))         //@ diag(`Printf format %s has arg #1 of wrong type byte`)
+	fmt.Printf("%t", 23)               //@ diag(`Printf format %t has arg #1 of wrong type int`)
+	fmt.Printf("%U", x)                //@ diag(`Printf format %U has arg #1 of wrong type float64`)
 	fmt.Printf("%X", 2.3)
 	fmt.Printf("%X", 2+3i)
-	fmt.Printf("%s", stringerv)                 // want `Printf format %s has arg #1 of wrong type CheckPrintf\.ptrStringer`
-	fmt.Printf("%t", stringerv)                 // want `Printf format %t has arg #1 of wrong type CheckPrintf\.ptrStringer`
-	fmt.Printf("%s", embeddedStringerv)         // want `Printf format %s has arg #1 of wrong type CheckPrintf\.embeddedStringer`
-	fmt.Printf("%t", embeddedStringerv)         // want `Printf format %t has arg #1 of wrong type CheckPrintf\.embeddedStringer`
-	fmt.Printf("%q", notstringerv)              // want `Printf format %q has arg #1 of wrong type CheckPrintf\.notstringer`
-	fmt.Printf("%t", notstringerv)              // want `Printf format %t has arg #1 of wrong type CheckPrintf\.notstringer`
-	fmt.Printf("%t", stringerarrayv)            // want `Printf format %t has arg #1 of wrong type CheckPrintf\.stringerarray`
-	fmt.Printf("%t", notstringerarrayv)         // want `Printf format %t has arg #1 of wrong type CheckPrintf\.notstringerarray`
-	fmt.Printf("%q", notstringerarrayv)         // want `Printf format %q has arg #1 of wrong type CheckPrintf\.notstringerarray`
-	fmt.Printf("%d", BoolFormatter(true))       // want `Printf format %d has arg #1 of wrong type CheckPrintf\.BoolFormatter`
+	fmt.Printf("%s", stringerv)                 //@ diag(`Printf format %s has arg #1 of wrong type CheckPrintf.ptrStringer`)
+	fmt.Printf("%t", stringerv)                 //@ diag(`Printf format %t has arg #1 of wrong type CheckPrintf.ptrStringer`)
+	fmt.Printf("%s", embeddedStringerv)         //@ diag(`Printf format %s has arg #1 of wrong type CheckPrintf.embeddedStringer`)
+	fmt.Printf("%t", embeddedStringerv)         //@ diag(`Printf format %t has arg #1 of wrong type CheckPrintf.embeddedStringer`)
+	fmt.Printf("%q", notstringerv)              //@ diag(`Printf format %q has arg #1 of wrong type CheckPrintf.notstringer`)
+	fmt.Printf("%t", notstringerv)              //@ diag(`Printf format %t has arg #1 of wrong type CheckPrintf.notstringer`)
+	fmt.Printf("%t", stringerarrayv)            //@ diag(`Printf format %t has arg #1 of wrong type CheckPrintf.stringerarray`)
+	fmt.Printf("%t", notstringerarrayv)         //@ diag(`Printf format %t has arg #1 of wrong type CheckPrintf.notstringerarray`)
+	fmt.Printf("%q", notstringerarrayv)         //@ diag(`Printf format %q has arg #1 of wrong type CheckPrintf.notstringerarray`)
+	fmt.Printf("%d", BoolFormatter(true))       //@ diag(`Printf format %d has arg #1 of wrong type CheckPrintf.BoolFormatter`)
 	fmt.Printf("%z", FormatterVal(true))        // correct (the type is responsible for formatting)
 	fmt.Printf("%d", FormatterVal(true))        // correct (the type is responsible for formatting)
 	fmt.Printf("%s", nonemptyinterface)         // correct (the type is responsible for formatting)
-	fmt.Printf("%.*s %d %6g", 3, "hi", 23, 'x') // want `Printf format %6g has arg #4 of wrong type rune`
-	fmt.Printf("%s", "hi", 3)                   // want `Printf call needs 1 args but has 2 args`
-	fmt.Printf("%"+("s"), "hi", 3)              // want `Printf call needs 1 args but has 2 args`
+	fmt.Printf("%.*s %d %6g", 3, "hi", 23, 'x') //@ diag(`Printf format %6g has arg #4 of wrong type rune`)
+	fmt.Printf("%s", "hi", 3)                   //@ diag(`Printf call needs 1 args but has 2 args`)
+	fmt.Printf("%"+("s"), "hi", 3)              //@ diag(`Printf call needs 1 args but has 2 args`)
 	fmt.Printf("%s%%%d", "hi", 3)               // correct
 	fmt.Printf("%08s", "woo")                   // correct
 	fmt.Printf("% 8s", "woo")                   // correct
 	fmt.Printf("%.*d", 3, 3)                    // correct
-	fmt.Printf("%.*d x", 3, 3, 3, 3)            // want `Printf call needs 2 args but has 4 args`
-	fmt.Printf("%.*d x", "hi", 3)               // want `Printf format %\.\*d reads non-int arg #1 as argument of \*`
+	fmt.Printf("%.*d x", 3, 3, 3, 3)            //@ diag(`Printf call needs 2 args but has 4 args`)
+	fmt.Printf("%.*d x", "hi", 3)               //@ diag(`Printf format %.*d reads non-int arg #1 as argument of *`)
 	fmt.Printf("%.*d x", i, 3)                  // correct
-	fmt.Printf("%.*d x", s, 3)                  // want `Printf format %\.\*d reads non-int arg #1 as argument of \*`
-	fmt.Printf("%*% x", 0.22)                   // want `Printf format %\*% reads non-int arg #1 as argument of \*`
+	fmt.Printf("%.*d x", s, 3)                  //@ diag(`Printf format %.*d reads non-int arg #1 as argument of *`)
+	fmt.Printf("%*% x", 0.22)                   //@ diag(`Printf format %*% reads non-int arg #1 as argument of *`)
 	fmt.Printf("%q %q", multi()...)             // ok
 	fmt.Printf("%#q", `blah`)                   // ok
 	const format = "%s %s\n"
 	fmt.Printf(format, "hi", "there")
-	fmt.Printf(format, "hi")              // want `Printf format %s reads arg #2, but call has only 1 args`
-	fmt.Printf("%s %d %.3v %q", "str", 4) // want `Printf format %\.3v reads arg #3, but call has only 2 args`
+	fmt.Printf(format, "hi")              //@ diag(`Printf format %s reads arg #2, but call has only 1 args`)
+	fmt.Printf("%s %d %.3v %q", "str", 4) //@ diag(`Printf format %.3v reads arg #3, but call has only 2 args`)
 
 	fmt.Printf("%#s", FormatterVal(true)) // correct (the type is responsible for formatting)
-	fmt.Printf("d%", 2)                   // want `couldn't parse format string`
+	fmt.Printf("d%", 2)                   //@ diag(`couldn't parse format string`)
 	fmt.Printf("%d", percentDV)
 	fmt.Printf("%d", &percentDV)
-	fmt.Printf("%d", notPercentDV)  // want `Printf format %d has arg #1 of wrong type CheckPrintf\.notPercentDStruct`
-	fmt.Printf("%d", &notPercentDV) // want `Printf format %d has arg #1 of wrong type \*CheckPrintf\.notPercentDStruct`
+	fmt.Printf("%d", notPercentDV)  //@ diag(`Printf format %d has arg #1 of wrong type CheckPrintf.notPercentDStruct`)
+	fmt.Printf("%d", &notPercentDV) //@ diag(`Printf format %d has arg #1 of wrong type *CheckPrintf.notPercentDStruct`)
 	fmt.Printf("%p", &notPercentDV) // Works regardless: we print it as a pointer.
-	fmt.Printf("%q", &percentDV)    // want `Printf format %q has arg #1 of wrong type \*CheckPrintf\.percentDStruct`
+	fmt.Printf("%q", &percentDV)    //@ diag(`Printf format %q has arg #1 of wrong type *CheckPrintf.percentDStruct`)
 	fmt.Printf("%s", percentSV)
 	fmt.Printf("%s", &percentSV)
 	// Good argument reorderings.
@@ -138,13 +138,13 @@ func fn() {
 	fmt.Printf("%[2]*.[1]*[3]d", 2, 3, 4)
 	fmt.Fprintf(os.Stderr, "%[2]*.[1]*[3]d", 2, 3, 4) // Use Fprintf to make sure we count arguments correctly.
 	// Bad argument reorderings.
-	fmt.Printf("%[xd", 3)                      // want `couldn't parse format string`
-	fmt.Printf("%[x]d x", 3)                   // want `couldn't parse format string`
-	fmt.Printf("%[3]*s x", "hi", 2)            // want `Printf format %\[3\]\*s reads arg #3, but call has only 2 args`
-	fmt.Printf("%[3]d x", 2)                   // want `Printf format %\[3\]d reads arg #3, but call has only 1 args`
-	fmt.Printf("%[2]*.[1]*[3]d x", 2, "hi", 4) // want `Printf format %\[2\]\*\.\[1\]\*\[3\]d reads non-int arg #2 as argument of \*`
-	fmt.Printf("%[0]s x", "arg1")              // want `Printf format %\[0\]s reads invalid arg 0; indices are 1-based`
-	fmt.Printf("%[0]d x", 1)                   // want `Printf format %\[0\]d reads invalid arg 0; indices are 1-based`
+	fmt.Printf("%[xd", 3)                      //@ diag(`couldn't parse format string`)
+	fmt.Printf("%[x]d x", 3)                   //@ diag(`couldn't parse format string`)
+	fmt.Printf("%[3]*s x", "hi", 2)            //@ diag(`Printf format %[3]*s reads arg #3, but call has only 2 args`)
+	fmt.Printf("%[3]d x", 2)                   //@ diag(`Printf format %[3]d reads arg #3, but call has only 1 args`)
+	fmt.Printf("%[2]*.[1]*[3]d x", 2, "hi", 4) //@ diag(`Printf format %[2]*.[1]*[3]d reads non-int arg #2 as argument of *`)
+	fmt.Printf("%[0]s x", "arg1")              //@ diag(`Printf format %[0]s reads invalid arg 0; indices are 1-based`)
+	fmt.Printf("%[0]d x", 1)                   //@ diag(`Printf format %[0]d reads invalid arg 0; indices are 1-based`)
 
 	// Interfaces can be used with any verb.
 	var iface interface {
@@ -152,7 +152,7 @@ func fn() {
 	}
 	fmt.Printf("%f", iface) // ok: fmt treats interfaces as transparent and iface may well have a float concrete type
 	// Can print functions in many ways
-	fmt.Printf("%s", someFunction) // want `Printf format %s has arg #1 of wrong type func\(\)`
+	fmt.Printf("%s", someFunction) //@ diag(`Printf format %s has arg #1 of wrong type func()`)
 	fmt.Printf("%d", someFunction) // ok: maybe someone wants to see the pointer
 	fmt.Printf("%v", someFunction) // ok: maybe someone wants to see the pointer in decimal
 	fmt.Printf("%p", someFunction) // ok: maybe someone wants to see the pointer
@@ -165,11 +165,11 @@ func fn() {
 
 	// indexed arguments
 	fmt.Printf("%d %[3]d %d %[2]d x", 1, 2, 3, 4)    // OK
-	fmt.Printf("%d %[0]d %d %[2]d x", 1, 2, 3, 4)    // want `Printf format %\[0\]d reads invalid arg 0; indices are 1-based`
-	fmt.Printf("%d %[3]d %d %[-2]d x", 1, 2, 3, 4)   // want `couldn't parse format string`
-	fmt.Printf("%d %[3]d %d %[5]d x", 1, 2, 3, 4)    // want `Printf format %\[5\]d reads arg #5, but call has only 4 args`
-	fmt.Printf("%d %[3]d %-10d %[2]d x", 1, 2, 3)    // want `Printf format %-10d reads arg #4, but call has only 3 args`
-	fmt.Printf("%[1][3]d x", 1, 2)                   // want `couldn't parse format string`
+	fmt.Printf("%d %[0]d %d %[2]d x", 1, 2, 3, 4)    //@ diag(`Printf format %[0]d reads invalid arg 0; indices are 1-based`)
+	fmt.Printf("%d %[3]d %d %[-2]d x", 1, 2, 3, 4)   //@ diag(`couldn't parse format string`)
+	fmt.Printf("%d %[3]d %d %[5]d x", 1, 2, 3, 4)    //@ diag(`Printf format %[5]d reads arg #5, but call has only 4 args`)
+	fmt.Printf("%d %[3]d %-10d %[2]d x", 1, 2, 3)    //@ diag(`Printf format %-10d reads arg #4, but call has only 3 args`)
+	fmt.Printf("%[1][3]d x", 1, 2)                   //@ diag(`couldn't parse format string`)
 	fmt.Printf("%[1]d x", 1, 2)                      // OK
 	fmt.Printf("%d %[3]d %d %[2]d x", 1, 2, 3, 4, 5) // OK
 
@@ -193,11 +193,11 @@ func fn() {
 		t1 := T1{&T2{"hi"}}
 
 		fmt.Printf("%s\n", &x1)
-		fmt.Printf("%s\n", t1) // want `Printf format %s has arg #1 of wrong type CheckPrintf\.T1`
+		fmt.Printf("%s\n", t1) //@ diag(`Printf format %s has arg #1 of wrong type CheckPrintf.T1`)
 		var x2 struct{ A *int }
-		fmt.Printf("%p\n", x2) // want `Printf format %p has arg #1 of wrong type struct\{A \*int\}`
+		fmt.Printf("%p\n", x2) //@ diag(`Printf format %p has arg #1 of wrong type struct{A *int}`)
 		var x3 [2]int
-		fmt.Printf("%p", x3) // want `Printf format %p has arg #1 of wrong type \[2\]int`
+		fmt.Printf("%p", x3) //@ diag(`Printf format %p has arg #1 of wrong type [2]int`)
 
 		ue := unexportedError{nil}
 		fmt.Printf("%s", ue)
@@ -368,20 +368,20 @@ func UnexportedStringerOrError() {
 	fmt.Printf("%s", unexportedInterface{3})     // ok; we can't see the problem
 
 	us := unexportedStringer{}
-	fmt.Printf("%s", us)  // want `Printf format %s has arg #1 of wrong type CheckPrintf\.unexportedStringer`
-	fmt.Printf("%s", &us) // want `Printf format %s has arg #1 of wrong type \*CheckPrintf\.unexportedStringer`
+	fmt.Printf("%s", us)  //@ diag(`Printf format %s has arg #1 of wrong type CheckPrintf.unexportedStringer`)
+	fmt.Printf("%s", &us) //@ diag(`Printf format %s has arg #1 of wrong type *CheckPrintf.unexportedStringer`)
 
 	usf := unexportedStringerOtherFields{
 		s: "foo",
 		S: "bar",
 	}
-	fmt.Printf("%s", usf)  // want `Printf format %s has arg #1 of wrong type CheckPrintf\.unexportedStringerOtherFields`
-	fmt.Printf("%s", &usf) // want `Printf format %s has arg #1 of wrong type \*CheckPrintf\.unexportedStringerOtherFields`
+	fmt.Printf("%s", usf)  //@ diag(`Printf format %s has arg #1 of wrong type CheckPrintf.unexportedStringerOtherFields`)
+	fmt.Printf("%s", &usf) //@ diag(`Printf format %s has arg #1 of wrong type *CheckPrintf.unexportedStringerOtherFields`)
 
 	intSlice := []int{3, 4}
-	fmt.Printf("%s", intSlice) // want `Printf format %s has arg #1 of wrong type \[\]int`
+	fmt.Printf("%s", intSlice) //@ diag(`Printf format %s has arg #1 of wrong type []int`)
 	nonStringerArray := [1]unexportedStringer{{}}
-	fmt.Printf("%s", nonStringerArray)  // want `Printf format %s has arg #1 of wrong type \[1\]CheckPrintf\.unexportedStringer`
+	fmt.Printf("%s", nonStringerArray)  //@ diag(`Printf format %s has arg #1 of wrong type [1]CheckPrintf.unexportedStringer`)
 	fmt.Printf("%s", []stringer{3, 4})  // not an error
 	fmt.Printf("%s", [2]stringer{3, 4}) // not an error
 }
@@ -417,7 +417,7 @@ func fn2() {
 func fn3() {
 	s := "%d"
 	if true {
-		fmt.Printf(s, "") // want `Printf format`
+		fmt.Printf(s, "") //@ diag(`Printf format`)
 	} else {
 		_ = s
 	}
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckPureFunctions/CheckPureFunctions.go 2022.1.3-1/staticcheck/testdata/src/CheckPureFunctions/CheckPureFunctions.go
--- 2022.1-1/staticcheck/testdata/src/CheckPureFunctions/CheckPureFunctions.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckPureFunctions/CheckPureFunctions.go	2022-07-31 15:38:22.000000000 +0000
@@ -8,9 +8,9 @@ import (
 )
 
 func fn1() {
-	strings.Replace("", "", "", 1) // want `is a pure function but its return value is ignored`
-	foo(1, 2)                      // want `is a pure function but its return value is ignored`
-	baz(1, 2)                      // want `is a pure function but its return value is ignored`
+	strings.Replace("", "", "", 1) //@ diag(`is a pure function but its return value is ignored`)
+	foo(1, 2)                      //@ diag(`is a pure function but its return value is ignored`)
+	baz(1, 2)                      //@ diag(`is a pure function but its return value is ignored`)
 	_, x := baz(1, 2)
 	_ = x
 	bar(1, 2)
@@ -18,7 +18,7 @@ func fn1() {
 
 func fn2() {
 	r, _ := http.NewRequest("GET", "/", nil)
-	r.WithContext(context.Background()) // want `is a pure function but its return value is ignored`
+	r.WithContext(context.Background()) //@ diag(`is a pure function but its return value is ignored`)
 }
 
 func foo(a, b int) int        { return a + b }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckPureFunctions/CheckPureFunctions_test.go 2022.1.3-1/staticcheck/testdata/src/CheckPureFunctions/CheckPureFunctions_test.go
--- 2022.1-1/staticcheck/testdata/src/CheckPureFunctions/CheckPureFunctions_test.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckPureFunctions/CheckPureFunctions_test.go	2022-07-31 15:38:22.000000000 +0000
@@ -6,7 +6,7 @@ import (
 )
 
 func TestFoo(t *testing.T) {
-	strings.Replace("", "", "", 1) // want `is a pure function but its return value is ignored`
+	strings.Replace("", "", "", 1) //@ diag(`is a pure function but its return value is ignored`)
 }
 
 func BenchmarkFoo(b *testing.B) {
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckRangeStringRunes/CheckRangeStringRunes.go 2022.1.3-1/staticcheck/testdata/src/CheckRangeStringRunes/CheckRangeStringRunes.go
--- 2022.1-1/staticcheck/testdata/src/CheckRangeStringRunes/CheckRangeStringRunes.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckRangeStringRunes/CheckRangeStringRunes.go	2022-07-31 15:38:22.000000000 +0000
@@ -7,7 +7,7 @@ func fn(s string, s2 String) {
 		println(r)
 	}
 
-	for _, r := range []rune(s) { // want `should range over string`
+	for _, r := range []rune(s) { //@ diag(`should range over string`)
 		println(r)
 	}
 
@@ -17,7 +17,7 @@ func fn(s string, s2 String) {
 	}
 
 	x := []rune(s)
-	for _, r := range x { // want `should range over string`
+	for _, r := range x { //@ diag(`should range over string`)
 		println(r)
 	}
 
@@ -27,7 +27,7 @@ func fn(s string, s2 String) {
 	}
 	println(y[0])
 
-	for _, r := range []rune(s2) { // want `should range over string`
+	for _, r := range []rune(s2) { //@ diag(`should range over string`)
 		println(r)
 	}
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckRangeStringRunes/generics.go 2022.1.3-1/staticcheck/testdata/src/CheckRangeStringRunes/generics.go
--- 2022.1-1/staticcheck/testdata/src/CheckRangeStringRunes/generics.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckRangeStringRunes/generics.go	2022-07-31 15:38:22.000000000 +0000
@@ -3,13 +3,13 @@
 package pkg
 
 func tpfn1[T string](x T) {
-	for _, c := range []rune(x) { // want `should range over string`
+	for _, c := range []rune(x) { //@ diag(`should range over string`)
 		println(c)
 	}
 }
 
 func tpfn2[T1 string, T2 []rune](x T1) {
-	for _, c := range T2(x) { // want `should range over string`
+	for _, c := range T2(x) { //@ diag(`should range over string`)
 		println(c)
 	}
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckRegexpMatchLoop/CheckRegexpMatchLoop.go 2022.1.3-1/staticcheck/testdata/src/CheckRegexpMatchLoop/CheckRegexpMatchLoop.go
--- 2022.1-1/staticcheck/testdata/src/CheckRegexpMatchLoop/CheckRegexpMatchLoop.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckRegexpMatchLoop/CheckRegexpMatchLoop.go	2022-07-31 15:38:22.000000000 +0000
@@ -8,8 +8,8 @@ func fn() {
 	regexp.MatchReader(".", nil)
 
 	for {
-		regexp.Match(".", nil)       // want `calling regexp\.Match in a loop has poor performance`
-		regexp.MatchString(".", "")  // want `calling regexp\.MatchString in a loop has poor performance`
-		regexp.MatchReader(".", nil) // want `calling regexp\.MatchReader in a loop has poor performance`
+		regexp.Match(".", nil)       //@ diag(`calling regexp.Match in a loop has poor performance`)
+		regexp.MatchString(".", "")  //@ diag(`calling regexp.MatchString in a loop has poor performance`)
+		regexp.MatchReader(".", nil) //@ diag(`calling regexp.MatchReader in a loop has poor performance`)
 	}
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckRegexps/CheckRegexps.go 2022.1.3-1/staticcheck/testdata/src/CheckRegexps/CheckRegexps.go
--- 2022.1-1/staticcheck/testdata/src/CheckRegexps/CheckRegexps.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckRegexps/CheckRegexps.go	2022-07-31 15:38:22.000000000 +0000
@@ -8,15 +8,15 @@ import (
 const c1 = `[`
 const c2 = `(abc)`
 
-var re1 = regexp.MustCompile(`ab\yef`) // want `error parsing regexp`
-var re2 = regexp.MustCompile(c1)       // want `error parsing regexp`
+var re1 = regexp.MustCompile(`ab\yef`) //@ diag(`error parsing regexp`)
+var re2 = regexp.MustCompile(c1)       //@ diag(`error parsing regexp`)
 var re3 = regexp.MustCompile(c2)
 var re4 = regexp.MustCompile(
-	c1, // want `error parsing regexp`
+	c1, //@ diag(`error parsing regexp`)
 )
 
 func fn() {
-	_, err := regexp.Compile(`foo(`) // want `error parsing regexp`
+	_, err := regexp.Compile(`foo(`) //@ diag(`error parsing regexp`)
 	if err != nil {
 		panic(err)
 	}
@@ -24,9 +24,9 @@ func fn() {
 		log.Println("of course 'foo(' matches 'foo('")
 	}
 
-	regexp.Match("foo(", nil)       // want `error parsing regexp`
-	regexp.MatchReader("foo(", nil) // want `error parsing regexp`
-	regexp.MatchString("foo(", "")  // want `error parsing regexp`
+	regexp.Match("foo(", nil)       //@ diag(`error parsing regexp`)
+	regexp.MatchReader("foo(", nil) //@ diag(`error parsing regexp`)
+	regexp.MatchString("foo(", "")  //@ diag(`error parsing regexp`)
 }
 
 // must be a basic type to trigger SA4017 (in case of a test failure)
@@ -39,8 +39,8 @@ func (T) init() {}
 
 // this will become a synthetic init function, that we don't want to
 // ignore
-var _ = regexp.MustCompile("(") // want `error parsing regexp`
+var _ = regexp.MustCompile("(") //@ diag(`error parsing regexp`)
 
 func fn2() {
-	regexp.MustCompile("foo(").FindAll(nil, 0) // want `error parsing regexp`
+	regexp.MustCompile("foo(").FindAll(nil, 0) //@ diag(`error parsing regexp`)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckRepeatedIfElse/CheckRepeatedIfElse.go 2022.1.3-1/staticcheck/testdata/src/CheckRepeatedIfElse/CheckRepeatedIfElse.go
--- 2022.1-1/staticcheck/testdata/src/CheckRepeatedIfElse/CheckRepeatedIfElse.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckRepeatedIfElse/CheckRepeatedIfElse.go	2022-07-31 15:38:22.000000000 +0000
@@ -3,8 +3,8 @@ package pkg
 func fn1(b1, b2 bool) {
 	if b1 && !b2 {
 	} else if b1 {
-	} else if b1 && !b2 { // want `condition occurs multiple times`
-	} else if b1 { // want `condition occurs multiple times`
+	} else if b1 && !b2 { //@ diag(`condition occurs multiple times`)
+	} else if b1 { //@ diag(`condition occurs multiple times`)
 	} else {
 		println()
 	}
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckScopedBreak/CheckScopedBreak.go 2022.1.3-1/staticcheck/testdata/src/CheckScopedBreak/CheckScopedBreak.go
--- 2022.1-1/staticcheck/testdata/src/CheckScopedBreak/CheckScopedBreak.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckScopedBreak/CheckScopedBreak.go	2022-07-31 15:38:22.000000000 +0000
@@ -5,16 +5,16 @@ func fn() {
 	for {
 		switch {
 		case true:
-			break // want `ineffective break statement`
+			break //@ diag(`ineffective break statement`)
 		default:
-			break // want `ineffective break statement`
+			break //@ diag(`ineffective break statement`)
 		}
 	}
 
 	for {
 		select {
 		case <-ch:
-			break // want `ineffective break statement`
+			break //@ diag(`ineffective break statement`)
 		}
 	}
 
@@ -25,7 +25,7 @@ func fn() {
 
 		switch {
 		case true:
-			break // want `ineffective break statement`
+			break //@ diag(`ineffective break statement`)
 		}
 
 		switch {
@@ -37,9 +37,9 @@ func fn() {
 		switch {
 		case true:
 			if true {
-				break // want `ineffective break statement`
+				break //@ diag(`ineffective break statement`)
 			} else {
-				break // want `ineffective break statement`
+				break //@ diag(`ineffective break statement`)
 			}
 		}
 	}
@@ -66,7 +66,7 @@ label:
 	for range ([]int)(nil) {
 		switch {
 		default:
-			break // want `ineffective break statement`
+			break //@ diag(`ineffective break statement`)
 		}
 	}
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckSelfAssignment/CheckSelfAssignment.go 2022.1.3-1/staticcheck/testdata/src/CheckSelfAssignment/CheckSelfAssignment.go
--- 2022.1-1/staticcheck/testdata/src/CheckSelfAssignment/CheckSelfAssignment.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckSelfAssignment/CheckSelfAssignment.go	2022-07-31 15:38:22.000000000 +0000
@@ -3,9 +3,9 @@ package pkg
 func fn(x int) {
 	var z int
 	var y int
-	x = x             // want `self-assignment`
-	y = y             // want `self-assignment`
-	y, x, z = y, x, 1 // want `self-assignment of y to y` `self-assignment of x to x`
+	x = x             //@ diag(`self-assignment`)
+	y = y             //@ diag(`self-assignment`)
+	y, x, z = y, x, 1 //@ diag(`self-assignment of y to y`), diag(`self-assignment of x to x`)
 	y = x
 	_ = y
 	_ = x
@@ -21,9 +21,9 @@ func fn1() {
 		x  []byte
 		ch chan int
 	)
-	x[42] = x[42]                         // want `self-assignment`
-	x[pure(42)] = x[pure(42)]             // want `self-assignment`
-	x[pure(pure(42))] = x[pure(pure(42))] // want `self-assignment`
+	x[42] = x[42]                         //@ diag(`self-assignment`)
+	x[pure(42)] = x[pure(42)]             //@ diag(`self-assignment`)
+	x[pure(pure(42))] = x[pure(pure(42))] //@ diag(`self-assignment`)
 	x[impure(42)] = x[impure(42)]
 	x[impure(pure(42))] = x[impure(pure(42))]
 	x[pure(impure(42))] = x[pure(impure(42))]
@@ -42,10 +42,10 @@ func fn1() {
 	m[new(int)] = m[new(int)]
 
 	m2 := map[int]int{}
-	m2[len(x)] = m2[len(x)] // want `self-assignment`
+	m2[len(x)] = m2[len(x)] //@ diag(`self-assignment`)
 
 	gen1()[0] = gen1()[0]
-	gen2(0)[0] = gen2(0)[0] // want `self-assignment`
+	gen2(0)[0] = gen2(0)[0] //@ diag(`self-assignment`)
 	gen3(0)[0] = gen3(0)[0]
 }
 
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckSillyBitwiseOps/CheckSillyBitwiseOps.go 2022.1.3-1/staticcheck/testdata/src/CheckSillyBitwiseOps/CheckSillyBitwiseOps.go
--- 2022.1-1/staticcheck/testdata/src/CheckSillyBitwiseOps/CheckSillyBitwiseOps.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckSillyBitwiseOps/CheckSillyBitwiseOps.go	2022-07-31 15:38:22.000000000 +0000
@@ -14,16 +14,16 @@ const (
 )
 
 func fn(x int) {
-	println(x | 0)        // want `x \| 0 always equals x`
-	println(x & 0)        // want `x & 0 always equals 0`
-	println(x ^ 0)        // want `x \^ 0 always equals x`
-	println((x << 5) | 0) // want `\(x << 5\) \| 0 always equals \(x << 5\)`
+	println(x | 0)        //@ diag(`x | 0 always equals x`)
+	println(x & 0)        //@ diag(`x & 0 always equals 0`)
+	println(x ^ 0)        //@ diag(`x ^ 0 always equals x`)
+	println((x << 5) | 0) //@ diag(`(x << 5) | 0 always equals (x << 5)`)
 	println(x | 1)
 	println(x << 0)
 
 	println(x | a)
-	println(x | b) // want `x \| b always equals x; b is defined as iota`
-	println(x & b) // want `x & b always equals 0; b is defined as iota`
+	println(x | b) //@ diag(`x | b always equals x; b is defined as iota`)
+	println(x & b) //@ diag(`x & b always equals 0; b is defined as iota`)
 	println(x | c)
 
 	// d is iota, but its value is 1
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckSillyBitwiseOps/generics.go 2022.1.3-1/staticcheck/testdata/src/CheckSillyBitwiseOps/generics.go
--- 2022.1-1/staticcheck/testdata/src/CheckSillyBitwiseOps/generics.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckSillyBitwiseOps/generics.go	2022-07-31 15:38:22.000000000 +0000
@@ -3,5 +3,5 @@
 package pkg
 
 func tpfn[T int](x T) {
-	_ = x & 0 // want `always equals 0`
+	_ = x & 0 //@ diag(`always equals 0`)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckSingleArgAppend/CheckSingleArgAppend.go 2022.1.3-1/staticcheck/testdata/src/CheckSingleArgAppend/CheckSingleArgAppend.go
--- 2022.1-1/staticcheck/testdata/src/CheckSingleArgAppend/CheckSingleArgAppend.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckSingleArgAppend/CheckSingleArgAppend.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,11 +1,11 @@
 package pkg
 
 func fn(arg []int) {
-	x := append(arg) // want `x = append\(y\) is equivalent to x = y`
+	x := append(arg) //@ diag(`x = append(y) is equivalent to x = y`)
 	_ = x
 	y := append(arg, 1)
 	_ = y
-	arg = append(arg) // want `x = append\(y\) is equivalent to x = y`
+	arg = append(arg) //@ diag(`x = append(y) is equivalent to x = y`)
 	arg = append(arg, 1, 2, 3)
 	var nilly []int
 	arg = append(arg, nilly...)
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckSortSlice/slice.go 2022.1.3-1/staticcheck/testdata/src/CheckSortSlice/slice.go
--- 2022.1-1/staticcheck/testdata/src/CheckSortSlice/slice.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckSortSlice/slice.go	2022-07-31 15:38:22.000000000 +0000
@@ -25,15 +25,15 @@ func fn(arg1 interface{}, arg2 []int) {
 	sort.Slice(arg2, nil)
 	sort.Slice(v1, nil)
 	sort.Slice(v2, nil)
-	sort.Slice(v3, nil) // want `sort\.Slice must only be called on slices, was called on \[1\]int`
-	sort.Slice(v4, nil) // want `sort\.Slice must only be called on slices, was called on string`
+	sort.Slice(v3, nil) //@ diag(`sort.Slice must only be called on slices, was called on [1]int`)
+	sort.Slice(v4, nil) //@ diag(`sort.Slice must only be called on slices, was called on string`)
 	sort.Slice(v5, nil)
 	sort.Slice(v6, nil)
 	sort.Slice(v7, nil)
-	sort.Slice(v8, nil) // want `sort\.Slice must only be called on slices, was called on int`
+	sort.Slice(v8, nil) //@ diag(`sort.Slice must only be called on slices, was called on int`)
 	sort.Slice([]int{}, nil)
-	sort.Slice(0, nil)         // want `sort\.Slice must only be called on slices, was called on int`
-	sort.Slice(nil, nil)       // want `cannot call sort\.Slice on nil literal`
-	sort.SliceIsSorted(0, nil) // want `sort\.SliceIsSorted must only be called on slices, was called on int`
-	sort.SliceStable(0, nil)   // want `sort\.SliceStable must only be called on slices, was called on int`
+	sort.Slice(0, nil)         //@ diag(`sort.Slice must only be called on slices, was called on int`)
+	sort.Slice(nil, nil)       //@ diag(`cannot call sort.Slice on nil literal`)
+	sort.SliceIsSorted(0, nil) //@ diag(`sort.SliceIsSorted must only be called on slices, was called on int`)
+	sort.SliceStable(0, nil)   //@ diag(`sort.SliceStable must only be called on slices, was called on int`)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckStaticBitShift/CheckStaticBitShift.go 2022.1.3-1/staticcheck/testdata/src/CheckStaticBitShift/CheckStaticBitShift.go
--- 2022.1-1/staticcheck/testdata/src/CheckStaticBitShift/CheckStaticBitShift.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckStaticBitShift/CheckStaticBitShift.go	2022-07-31 15:38:22.000000000 +0000
@@ -10,72 +10,72 @@ type Number int8
 
 func fn() {
 	var n8 Number
-	n8 <<= 8 // want `will always clear it`
+	n8 <<= 8 //@ diag(`will always clear it`)
 
 	var i8 int8
 	_ = i8 << 7
-	_ = (i8 + 1) << 8 // want `will always clear it`
-	_ = i8 << (7 + 1) // want `will always clear it`
-	_ = i8 >> 8       // want `will always clear it`
-	i8 <<= 8          // want `will always clear it`
-	i8 >>= 8          // want `will always clear it`
-	i8 <<= 12         // want `will always clear it`
+	_ = (i8 + 1) << 8 //@ diag(`will always clear it`)
+	_ = i8 << (7 + 1) //@ diag(`will always clear it`)
+	_ = i8 >> 8       //@ diag(`will always clear it`)
+	i8 <<= 8          //@ diag(`will always clear it`)
+	i8 >>= 8          //@ diag(`will always clear it`)
+	i8 <<= 12         //@ diag(`will always clear it`)
 
 	var i16 int16
 	_ = i16 << 15
-	_ = i16 << 16 // want `will always clear it`
-	_ = i16 >> 16 // want `will always clear it`
-	i16 <<= 16    // want `will always clear it`
-	i16 >>= 16    // want `will always clear it`
-	i16 <<= 18    // want `will always clear it`
+	_ = i16 << 16 //@ diag(`will always clear it`)
+	_ = i16 >> 16 //@ diag(`will always clear it`)
+	i16 <<= 16    //@ diag(`will always clear it`)
+	i16 >>= 16    //@ diag(`will always clear it`)
+	i16 <<= 18    //@ diag(`will always clear it`)
 
 	var i32 int32
 	_ = i32 << 31
-	_ = i32 << 32 // want `will always clear it`
-	_ = i32 >> 32 // want `will always clear it`
-	i32 <<= 32    // want `will always clear it`
-	i32 >>= 32    // want `will always clear it`
-	i32 <<= 40    // want `will always clear it`
+	_ = i32 << 32 //@ diag(`will always clear it`)
+	_ = i32 >> 32 //@ diag(`will always clear it`)
+	i32 <<= 32    //@ diag(`will always clear it`)
+	i32 >>= 32    //@ diag(`will always clear it`)
+	i32 <<= 40    //@ diag(`will always clear it`)
 
 	var i64 int64
 	_ = i64 << 63
-	_ = i64 << 64 // want `will always clear it`
-	_ = i64 >> 64 // want `will always clear it`
-	i64 <<= 64    // want `will always clear it`
-	i64 >>= 64    // want `will always clear it`
-	i64 <<= 70    // want `will always clear it`
+	_ = i64 << 64 //@ diag(`will always clear it`)
+	_ = i64 >> 64 //@ diag(`will always clear it`)
+	i64 <<= 64    //@ diag(`will always clear it`)
+	i64 >>= 64    //@ diag(`will always clear it`)
+	i64 <<= 70    //@ diag(`will always clear it`)
 
 	var u8 uint8
 	_ = u8 << 7
-	_ = u8 << 8 // want `will always clear it`
-	_ = u8 >> 8 // want `will always clear it`
-	u8 <<= 8    // want `will always clear it`
-	u8 >>= 8    // want `will always clear it`
-	u8 <<= 12   // want `will always clear it`
+	_ = u8 << 8 //@ diag(`will always clear it`)
+	_ = u8 >> 8 //@ diag(`will always clear it`)
+	u8 <<= 8    //@ diag(`will always clear it`)
+	u8 >>= 8    //@ diag(`will always clear it`)
+	u8 <<= 12   //@ diag(`will always clear it`)
 
 	var u16 uint16
 	_ = u16 << 15
-	_ = u16 << 16 // want `will always clear it`
-	_ = u16 >> 16 // want `will always clear it`
-	u16 <<= 16    // want `will always clear it`
-	u16 >>= 16    // want `will always clear it`
-	u16 <<= 18    // want `will always clear it`
+	_ = u16 << 16 //@ diag(`will always clear it`)
+	_ = u16 >> 16 //@ diag(`will always clear it`)
+	u16 <<= 16    //@ diag(`will always clear it`)
+	u16 >>= 16    //@ diag(`will always clear it`)
+	u16 <<= 18    //@ diag(`will always clear it`)
 
 	var u32 uint32
 	_ = u32 << 31
-	_ = u32 << 32 // want `will always clear it`
-	_ = u32 >> 32 // want `will always clear it`
-	u32 <<= 32    // want `will always clear it`
-	u32 >>= 32    // want `will always clear it`
-	u32 <<= 40    // want `will always clear it`
+	_ = u32 << 32 //@ diag(`will always clear it`)
+	_ = u32 >> 32 //@ diag(`will always clear it`)
+	u32 <<= 32    //@ diag(`will always clear it`)
+	u32 >>= 32    //@ diag(`will always clear it`)
+	u32 <<= 40    //@ diag(`will always clear it`)
 
 	var u64 uint64
 	_ = u64 << 63
-	_ = u64 << 64 // want `will always clear it`
-	_ = u64 >> 64 // want `will always clear it`
-	u64 <<= 64    // want `will always clear it`
-	u64 >>= 64    // want `will always clear it`
-	u64 <<= 70    // want `will always clear it`
+	_ = u64 << 64 //@ diag(`will always clear it`)
+	_ = u64 >> 64 //@ diag(`will always clear it`)
+	u64 <<= 64    //@ diag(`will always clear it`)
+	u64 >>= 64    //@ diag(`will always clear it`)
+	u64 <<= 70    //@ diag(`will always clear it`)
 	_ = u64 << u64
 }
 
diff -pruN 2022.1-1/staticcheck/testdata/src/checkStdlibUsageNilContext/checkStdlibUsageNilContext_generics.go 2022.1.3-1/staticcheck/testdata/src/checkStdlibUsageNilContext/checkStdlibUsageNilContext_generics.go
--- 2022.1-1/staticcheck/testdata/src/checkStdlibUsageNilContext/checkStdlibUsageNilContext_generics.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/checkStdlibUsageNilContext/checkStdlibUsageNilContext_generics.go	2022-07-31 15:38:22.000000000 +0000
@@ -8,9 +8,9 @@ func tpfn1[T any](ctx context.Context, x
 func tpfn2[T1, T2 any](ctx context.Context, x T1, y T2) {}
 
 func tpbar() {
-	tpfn1[int](nil, 0) // want `do not pass a nil Context`
-	tpfn1(nil, 0)      // want `do not pass a nil Context`
+	tpfn1[int](nil, 0) //@ diag(`do not pass a nil Context`)
+	tpfn1(nil, 0)      //@ diag(`do not pass a nil Context`)
 
-	tpfn2[int, int](nil, 0, 0) // want `do not pass a nil Context`
-	tpfn2(nil, 0, 0)           // want `do not pass a nil Context`
+	tpfn2[int, int](nil, 0, 0) //@ diag(`do not pass a nil Context`)
+	tpfn2(nil, 0, 0)           //@ diag(`do not pass a nil Context`)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/checkStdlibUsageNilContext/checkStdlibUsageNilContext_generics.go.golden 2022.1.3-1/staticcheck/testdata/src/checkStdlibUsageNilContext/checkStdlibUsageNilContext_generics.go.golden
--- 2022.1-1/staticcheck/testdata/src/checkStdlibUsageNilContext/checkStdlibUsageNilContext_generics.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/checkStdlibUsageNilContext/checkStdlibUsageNilContext_generics.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -9,11 +9,11 @@ func tpfn1[T any](ctx context.Context, x
 func tpfn2[T1, T2 any](ctx context.Context, x T1, y T2) {}
 
 func tpbar() {
-	tpfn1[int](context.Background(), 0) // want `do not pass a nil Context`
-	tpfn1(context.Background(), 0)      // want `do not pass a nil Context`
+	tpfn1[int](context.Background(), 0) //@ diag(`do not pass a nil Context`)
+	tpfn1(context.Background(), 0)      //@ diag(`do not pass a nil Context`)
 
-	tpfn2[int, int](context.Background(), 0, 0) // want `do not pass a nil Context`
-	tpfn2(context.Background(), 0, 0)           // want `do not pass a nil Context`
+	tpfn2[int, int](context.Background(), 0, 0) //@ diag(`do not pass a nil Context`)
+	tpfn2(context.Background(), 0, 0)           //@ diag(`do not pass a nil Context`)
 }
 -- use context.TODO --
 //go:build go1.18
@@ -26,9 +26,9 @@ func tpfn1[T any](ctx context.Context, x
 func tpfn2[T1, T2 any](ctx context.Context, x T1, y T2) {}
 
 func tpbar() {
-	tpfn1[int](context.TODO(), 0) // want `do not pass a nil Context`
-	tpfn1(context.TODO(), 0)      // want `do not pass a nil Context`
+	tpfn1[int](context.TODO(), 0) //@ diag(`do not pass a nil Context`)
+	tpfn1(context.TODO(), 0)      //@ diag(`do not pass a nil Context`)
 
-	tpfn2[int, int](context.TODO(), 0, 0) // want `do not pass a nil Context`
-	tpfn2(context.TODO(), 0, 0)           // want `do not pass a nil Context`
+	tpfn2[int, int](context.TODO(), 0, 0) //@ diag(`do not pass a nil Context`)
+	tpfn2(context.TODO(), 0, 0)           //@ diag(`do not pass a nil Context`)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/checkStdlibUsageNilContext/checkStdlibUsageNilContext.go 2022.1.3-1/staticcheck/testdata/src/checkStdlibUsageNilContext/checkStdlibUsageNilContext.go
--- 2022.1-1/staticcheck/testdata/src/checkStdlibUsageNilContext/checkStdlibUsageNilContext.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/checkStdlibUsageNilContext/checkStdlibUsageNilContext.go	2022-07-31 15:38:22.000000000 +0000
@@ -11,7 +11,7 @@ type T struct{}
 func (*T) Foo() {}
 
 func fn3() {
-	fn1(nil) // want `do not pass a nil Context`
+	fn1(nil) //@ diag(`do not pass a nil Context`)
 	fn1(context.TODO())
 	fn2("", nil)
 	fn4()
diff -pruN 2022.1-1/staticcheck/testdata/src/checkStdlibUsageNilContext/checkStdlibUsageNilContext.go.golden 2022.1.3-1/staticcheck/testdata/src/checkStdlibUsageNilContext/checkStdlibUsageNilContext.go.golden
--- 2022.1-1/staticcheck/testdata/src/checkStdlibUsageNilContext/checkStdlibUsageNilContext.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/checkStdlibUsageNilContext/checkStdlibUsageNilContext.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -12,7 +12,7 @@ type T struct{}
 func (*T) Foo() {}
 
 func fn3() {
-	fn1(context.Background()) // want `do not pass a nil Context`
+	fn1(context.Background()) //@ diag(`do not pass a nil Context`)
 	fn1(context.TODO())
 	fn2("", nil)
 	fn4()
@@ -37,7 +37,7 @@ type T struct{}
 func (*T) Foo() {}
 
 func fn3() {
-	fn1(context.TODO()) // want `do not pass a nil Context`
+	fn1(context.TODO()) //@ diag(`do not pass a nil Context`)
 	fn1(context.TODO())
 	fn2("", nil)
 	fn4()
diff -pruN 2022.1-1/staticcheck/testdata/src/checkStdlibUsageRegexpFindAll/checkStdlibUsageRegexpFindAll.go 2022.1.3-1/staticcheck/testdata/src/checkStdlibUsageRegexpFindAll/checkStdlibUsageRegexpFindAll.go
--- 2022.1-1/staticcheck/testdata/src/checkStdlibUsageRegexpFindAll/checkStdlibUsageRegexpFindAll.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/checkStdlibUsageRegexpFindAll/checkStdlibUsageRegexpFindAll.go	2022-07-31 15:38:22.000000000 +0000
@@ -4,9 +4,9 @@ import "regexp"
 
 func fn() {
 	var r *regexp.Regexp
-	_ = r.FindAll(nil, 0) //want `calling a FindAll method with n == 0 will return no results`
+	_ = r.FindAll(nil, 0) //@ diag(`calling a FindAll method with n == 0 will return no results`)
 }
 
 func fn2() {
-	regexp.MustCompile("foo(").FindAll(nil, 0) // want `calling a FindAll`
+	regexp.MustCompile("foo(").FindAll(nil, 0) //@ diag(`calling a FindAll`)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/checkStdlibUsageSeeker/checkStdlibUsageSeeker.go 2022.1.3-1/staticcheck/testdata/src/checkStdlibUsageSeeker/checkStdlibUsageSeeker.go
--- 2022.1-1/staticcheck/testdata/src/checkStdlibUsageSeeker/checkStdlibUsageSeeker.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/checkStdlibUsageSeeker/checkStdlibUsageSeeker.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,12 +1,30 @@
 package pkg
 
-import "io"
+import (
+	"io"
+	myio "io"
+	"os"
+)
+
+type T struct{}
+
+func (T) Seek(whence int, offset int64) (int64, error) {
+	// This method does NOT implement io.Seeker
+	return 0, nil
+}
 
 func fn() {
 	const SeekStart = 0
 	var s io.Seeker
 	s.Seek(0, 0)
 	s.Seek(0, io.SeekStart)
-	s.Seek(io.SeekStart, 0) // want `the first argument of io\.Seeker is the offset`
+	s.Seek(io.SeekStart, 0)   //@ diag(`the first argument of io.Seeker is the offset`)
+	s.Seek(myio.SeekStart, 0) //@ diag(`the first argument of io.Seeker is the offset`)
 	s.Seek(SeekStart, 0)
+
+	var f *os.File
+	f.Seek(io.SeekStart, 0) //@ diag(`the first argument of io.Seeker is the offset`)
+
+	var t T
+	t.Seek(io.SeekStart, 0) // not flagged, T is not an io.Seeker
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/checkStdlibUsageSeeker/checkStdlibUsageSeeker.go.golden 2022.1.3-1/staticcheck/testdata/src/checkStdlibUsageSeeker/checkStdlibUsageSeeker.go.golden
--- 2022.1-1/staticcheck/testdata/src/checkStdlibUsageSeeker/checkStdlibUsageSeeker.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/checkStdlibUsageSeeker/checkStdlibUsageSeeker.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -1,12 +1,30 @@
 package pkg
 
-import "io"
+import (
+	"io"
+	myio "io"
+	"os"
+)
+
+type T struct{}
+
+func (T) Seek(whence int, offset int64) (int64, error) {
+	// This method does NOT implement io.Seeker
+	return 0, nil
+}
 
 func fn() {
 	const SeekStart = 0
 	var s io.Seeker
 	s.Seek(0, 0)
 	s.Seek(0, io.SeekStart)
-	s.Seek(0, io.SeekStart) // want `the first argument of io\.Seeker is the offset`
+	s.Seek(0, io.SeekStart)   //@ diag(`the first argument of io.Seeker is the offset`)
+	s.Seek(0, myio.SeekStart) //@ diag(`the first argument of io.Seeker is the offset`)
 	s.Seek(SeekStart, 0)
+
+	var f *os.File
+	f.Seek(0, io.SeekStart) //@ diag(`the first argument of io.Seeker is the offset`)
+
+	var t T
+	t.Seek(io.SeekStart, 0) // not flagged, T is not an io.Seeker
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/checkStdlibUsageUTF8Cutset/checkStdlibUsageUTF8Cutset.go 2022.1.3-1/staticcheck/testdata/src/checkStdlibUsageUTF8Cutset/checkStdlibUsageUTF8Cutset.go
--- 2022.1-1/staticcheck/testdata/src/checkStdlibUsageUTF8Cutset/checkStdlibUsageUTF8Cutset.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/checkStdlibUsageUTF8Cutset/checkStdlibUsageUTF8Cutset.go	2022-07-31 15:38:22.000000000 +0000
@@ -3,7 +3,7 @@ package pkg
 import "strings"
 
 func fn() {
-	println(strings.Trim("\x80test\xff", "\xff")) // want `is not a valid UTF-8 encoded string`
+	println(strings.Trim("\x80test\xff", "\xff")) //@ diag(`is not a valid UTF-8 encoded string`)
 	println(strings.Trim("foo", "bar"))
 
 	s := "\xff"
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckStrconv/CheckStrconv.go 2022.1.3-1/staticcheck/testdata/src/CheckStrconv/CheckStrconv.go
--- 2022.1-1/staticcheck/testdata/src/CheckStrconv/CheckStrconv.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckStrconv/CheckStrconv.go	2022-07-31 15:38:22.000000000 +0000
@@ -3,72 +3,72 @@ package pkg
 import "strconv"
 
 func fn() {
-	strconv.ParseFloat("", 16) // want `'bitSize' argument is invalid, must be either 32 or 64`
+	strconv.ParseFloat("", 16) //@ diag(`'bitSize' argument is invalid, must be either 32 or 64`)
 	strconv.ParseFloat("", 32)
 	strconv.ParseFloat("", 64)
-	strconv.ParseFloat("", 128) // want `'bitSize' argument is invalid, must be either 32 or 64`
+	strconv.ParseFloat("", 128) //@ diag(`'bitSize' argument is invalid, must be either 32 or 64`)
 
-	strconv.ParseInt("", 0, -1) // want `'bitSize' argument is invalid, must be within 0 and 64`
+	strconv.ParseInt("", 0, -1) //@ diag(`'bitSize' argument is invalid, must be within 0 and 64`)
 	strconv.ParseInt("", 0, 0)
 	strconv.ParseInt("", 0, 1)
 	strconv.ParseInt("", 0, 64)
-	strconv.ParseInt("", 0, 65) // want `'bitSize' argument is invalid, must be within 0 and 64`
-	strconv.ParseInt("", -1, 0) // want `'base' must not be smaller than 2, unless it is 0`
-	strconv.ParseInt("", 1, 0)  // want `'base' must not be smaller than 2, unless it is 0`
+	strconv.ParseInt("", 0, 65) //@ diag(`'bitSize' argument is invalid, must be within 0 and 64`)
+	strconv.ParseInt("", -1, 0) //@ diag(`'base' must not be smaller than 2, unless it is 0`)
+	strconv.ParseInt("", 1, 0)  //@ diag(`'base' must not be smaller than 2, unless it is 0`)
 	strconv.ParseInt("", 2, 0)
 	strconv.ParseInt("", 10, 0)
 	strconv.ParseInt("", 36, 0)
-	strconv.ParseInt("", 37, 0) // want `'base' must not be larger than 36`
+	strconv.ParseInt("", 37, 0) //@ diag(`'base' must not be larger than 36`)
 
-	strconv.ParseUint("", 0, -1) // want `'bitSize' argument is invalid, must be within 0 and 64`
+	strconv.ParseUint("", 0, -1) //@ diag(`'bitSize' argument is invalid, must be within 0 and 64`)
 	strconv.ParseUint("", 0, 0)
 	strconv.ParseUint("", 0, 1)
 	strconv.ParseUint("", 0, 64)
-	strconv.ParseUint("", 0, 65) // want `'bitSize' argument is invalid, must be within 0 and 64`
-	strconv.ParseUint("", -1, 0) // want `'base' must not be smaller than 2, unless it is 0`
-	strconv.ParseUint("", 1, 0)  // want `'base' must not be smaller than 2, unless it is 0`
+	strconv.ParseUint("", 0, 65) //@ diag(`'bitSize' argument is invalid, must be within 0 and 64`)
+	strconv.ParseUint("", -1, 0) //@ diag(`'base' must not be smaller than 2, unless it is 0`)
+	strconv.ParseUint("", 1, 0)  //@ diag(`'base' must not be smaller than 2, unless it is 0`)
 	strconv.ParseUint("", 2, 0)
 	strconv.ParseUint("", 10, 0)
 	strconv.ParseUint("", 36, 0)
-	strconv.ParseUint("", 37, 0) // want `'base' must not be larger than 36`
+	strconv.ParseUint("", 37, 0) //@ diag(`'base' must not be larger than 36`)
 
-	strconv.FormatFloat(0, 'e', 0, 18) // want `'bitSize' argument is invalid, must be either 32 or 64`
+	strconv.FormatFloat(0, 'e', 0, 18) //@ diag(`'bitSize' argument is invalid, must be either 32 or 64`)
 	strconv.FormatFloat(0, 'e', 0, 32)
 	strconv.FormatFloat(0, 'e', 0, 64)
-	strconv.FormatFloat(0, 'e', 0, 128) // want `'bitSize' argument is invalid, must be either 32 or 64`
-	strconv.FormatFloat(0, 'j', 0, 32)  // want `'fmt' argument is invalid: unknown format 'j'`
+	strconv.FormatFloat(0, 'e', 0, 128) //@ diag(`'bitSize' argument is invalid, must be either 32 or 64`)
+	strconv.FormatFloat(0, 'j', 0, 32)  //@ diag(`'fmt' argument is invalid: unknown format 'j'`)
 
-	strconv.FormatInt(0, 0) // want `'base' must not be smaller than 2`
-	strconv.FormatInt(0, 1) // want `'base' must not be smaller than 2`
+	strconv.FormatInt(0, 0) //@ diag(`'base' must not be smaller than 2`)
+	strconv.FormatInt(0, 1) //@ diag(`'base' must not be smaller than 2`)
 	strconv.FormatInt(0, 2)
 	strconv.FormatInt(0, 3)
 	strconv.FormatInt(0, 36)
-	strconv.FormatInt(0, 37) // want `'base' must not be larger than 36`
+	strconv.FormatInt(0, 37) //@ diag(`'base' must not be larger than 36`)
 
-	strconv.FormatUint(0, 0) // want `'base' must not be smaller than 2`
-	strconv.FormatUint(0, 1) // want `'base' must not be smaller than 2`
+	strconv.FormatUint(0, 0) //@ diag(`'base' must not be smaller than 2`)
+	strconv.FormatUint(0, 1) //@ diag(`'base' must not be smaller than 2`)
 	strconv.FormatUint(0, 2)
 	strconv.FormatUint(0, 3)
 	strconv.FormatUint(0, 36)
-	strconv.FormatUint(0, 37) // want `'base' must not be larger than 36`
+	strconv.FormatUint(0, 37) //@ diag(`'base' must not be larger than 36`)
 
-	strconv.AppendFloat(nil, 0, 'e', 0, 18) // want `'bitSize' argument is invalid, must be either 32 or 64`
+	strconv.AppendFloat(nil, 0, 'e', 0, 18) //@ diag(`'bitSize' argument is invalid, must be either 32 or 64`)
 	strconv.AppendFloat(nil, 0, 'e', 0, 32)
 	strconv.AppendFloat(nil, 0, 'e', 0, 64)
-	strconv.AppendFloat(nil, 0, 'e', 0, 128) // want `'bitSize' argument is invalid, must be either 32 or 64`
-	strconv.AppendFloat(nil, 0, 'j', 0, 32)  // want `'fmt' argument is invalid: unknown format 'j'`
+	strconv.AppendFloat(nil, 0, 'e', 0, 128) //@ diag(`'bitSize' argument is invalid, must be either 32 or 64`)
+	strconv.AppendFloat(nil, 0, 'j', 0, 32)  //@ diag(`'fmt' argument is invalid: unknown format 'j'`)
 
-	strconv.AppendInt(nil, 0, 0) // want `'base' must not be smaller than 2`
-	strconv.AppendInt(nil, 0, 1) // want `'base' must not be smaller than 2`
+	strconv.AppendInt(nil, 0, 0) //@ diag(`'base' must not be smaller than 2`)
+	strconv.AppendInt(nil, 0, 1) //@ diag(`'base' must not be smaller than 2`)
 	strconv.AppendInt(nil, 0, 2)
 	strconv.AppendInt(nil, 0, 3)
 	strconv.AppendInt(nil, 0, 36)
-	strconv.AppendInt(nil, 0, 37) // want `'base' must not be larger than 36`
+	strconv.AppendInt(nil, 0, 37) //@ diag(`'base' must not be larger than 36`)
 
-	strconv.AppendUint(nil, 0, 0) // want `'base' must not be smaller than 2`
-	strconv.AppendUint(nil, 0, 1) // want `'base' must not be smaller than 2`
+	strconv.AppendUint(nil, 0, 0) //@ diag(`'base' must not be smaller than 2`)
+	strconv.AppendUint(nil, 0, 1) //@ diag(`'base' must not be smaller than 2`)
 	strconv.AppendUint(nil, 0, 2)
 	strconv.AppendUint(nil, 0, 3)
 	strconv.AppendUint(nil, 0, 36)
-	strconv.AppendUint(nil, 0, 37) // want `'base' must not be larger than 36`
+	strconv.AppendUint(nil, 0, 37) //@ diag(`'base' must not be larger than 36`)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckStrconv_go115/CheckStrconv.go 2022.1.3-1/staticcheck/testdata/src/CheckStrconv_go115/CheckStrconv.go
--- 2022.1-1/staticcheck/testdata/src/CheckStrconv_go115/CheckStrconv.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckStrconv_go115/CheckStrconv.go	2022-07-31 15:38:22.000000000 +0000
@@ -5,14 +5,14 @@ package pkg
 import "strconv"
 
 func fn() {
-	strconv.ParseComplex("", 32) // want `'bitSize' argument is invalid, must be either 64 or 128`
+	strconv.ParseComplex("", 32) //@ diag(`'bitSize' argument is invalid, must be either 64 or 128`)
 	strconv.ParseComplex("", 64)
 	strconv.ParseComplex("", 128)
-	strconv.ParseComplex("", 256) // want `'bitSize' argument is invalid, must be either 64 or 128`
+	strconv.ParseComplex("", 256) //@ diag(`'bitSize' argument is invalid, must be either 64 or 128`)
 
-	strconv.FormatComplex(0, 'e', 0, 32) // want `'bitSize' argument is invalid, must be either 64 or 128`
+	strconv.FormatComplex(0, 'e', 0, 32) //@ diag(`'bitSize' argument is invalid, must be either 64 or 128`)
 	strconv.FormatComplex(0, 'e', 0, 64)
 	strconv.FormatComplex(0, 'e', 0, 128)
-	strconv.FormatComplex(0, 'e', 0, 256) // want `'bitSize' argument is invalid, must be either 64 or 128`
-	strconv.FormatComplex(0, 'j', 0, 64)  // want `'fmt' argument is invalid: unknown format 'j'`
+	strconv.FormatComplex(0, 'e', 0, 256) //@ diag(`'bitSize' argument is invalid, must be either 64 or 128`)
+	strconv.FormatComplex(0, 'j', 0, 64)  //@ diag(`'fmt' argument is invalid: unknown format 'j'`)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckStringsReplaceZero/CheckStringsReplaceZero.go 2022.1.3-1/staticcheck/testdata/src/CheckStringsReplaceZero/CheckStringsReplaceZero.go
--- 2022.1-1/staticcheck/testdata/src/CheckStringsReplaceZero/CheckStringsReplaceZero.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckStringsReplaceZero/CheckStringsReplaceZero.go	2022-07-31 15:38:22.000000000 +0000
@@ -3,7 +3,7 @@ package pkg
 import "strings"
 
 func fn() {
-	_ = strings.Replace("", "", "", 0) // want `calling strings\.Replace with n == 0`
+	_ = strings.Replace("", "", "", 0) //@ diag(`calling strings.Replace with n == 0`)
 	_ = strings.Replace("", "", "", -1)
 	_ = strings.Replace("", "", "", 1)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckStructTags/CheckStructTags.go 2022.1.3-1/staticcheck/testdata/src/CheckStructTags/CheckStructTags.go
--- 2022.1-1/staticcheck/testdata/src/CheckStructTags/CheckStructTags.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckStructTags/CheckStructTags.go	2022-07-31 15:38:22.000000000 +0000
@@ -7,20 +7,20 @@ import (
 )
 
 type T1 struct {
-	B int        `foo:"" foo:""` // want `duplicate struct tag`
+	B int        `foo:"" foo:""` //@ diag(`duplicate struct tag`)
 	C int        `foo:"" bar:""`
 	D int        `json:"-"`
-	E int        `json:"\\"`                   // want `invalid JSON field name`
-	F int        `json:",omitempty,omitempty"` // want `duplicate JSON option "omitempty"`
+	E int        `json:"\\"`                   //@ diag(`invalid JSON field name`)
+	F int        `json:",omitempty,omitempty"` //@ diag(`duplicate JSON option "omitempty"`)
 	G int        `json:",omitempty,string"`
-	H int        `json:",string,omitempty,string"` // want `duplicate JSON option "string"`
-	I int        `json:",unknown"`                 // want `unknown JSON option "unknown"`
+	H int        `json:",string,omitempty,string"` //@ diag(`duplicate JSON option "string"`)
+	I int        `json:",foreign"`                 //@ diag(`unknown JSON option "foreign"`)
 	J int        `json:",string"`
 	K *int       `json:",string"`
-	L **int      `json:",string"` // want `the JSON string option`
-	M complex128 `json:",string"` // want `the JSON string option`
+	L **int      `json:",string"` //@ diag(`the JSON string option`)
+	M complex128 `json:",string"` //@ diag(`the JSON string option`)
 	N int        `json:"some-name"`
-	O int        `json:"some-name,inline"`
+	O int        `json:"some-name,omitzero,omitempty,nocase,inline,unknown,format:'something,with,commas'"`
 }
 
 type T2 struct {
@@ -31,34 +31,34 @@ type T2 struct {
 	E int `xml:",comment"`
 	F int `xml:",omitempty"`
 	G int `xml:",any"`
-	H int `xml:",unknown"` // want `unknown option`
-	I int `xml:",any,any"` // want `duplicate option`
+	H int `xml:",unknown"` //@ diag(`unknown option`)
+	I int `xml:",any,any"` //@ diag(`duplicate option`)
 	J int `xml:"a>b>c,"`
 }
 
 type T3 struct {
 	A int `json:",omitempty" xml:",attr"`
-	B int `json:",unknown" xml:",attr"` // want `unknown JSON option`
+	B int `json:",foreign" xml:",attr"` //@ diag(`unknown JSON option "foreign"`)
 }
 
 type T4 struct {
 	A int   `choice:"foo" choice:"bar"`
 	B []int `optional-value:"foo" optional-value:"bar"`
 	C []int `default:"foo" default:"bar"`
-	D int   `json:"foo" json:"bar"` // want `duplicate struct tag`
+	D int   `json:"foo" json:"bar"` //@ diag(`duplicate struct tag`)
 }
 
 func xmlTags() {
 	type T1 struct {
-		A       int      `xml:",attr,innerxml"` // want `invalid combination of options: ",attr,innerxml"`
-		XMLName xml.Name `xml:"ns "`            // want `namespace without name: "ns "`
-		B       int      `xml:"a>"`             // want `trailing '>'`
-		C       int      `xml:"a>b,attr"`       // want `a>b chain not valid with attr flag`
+		A       int      `xml:",attr,innerxml"` //@ diag(`invalid combination of options: ",attr,innerxml"`)
+		XMLName xml.Name `xml:"ns "`            //@ diag(`namespace without name: "ns "`)
+		B       int      `xml:"a>"`             //@ diag(`trailing '>'`)
+		C       int      `xml:"a>b,attr"`       //@ diag(`a>b chain not valid with attr flag`)
 	}
 	type T6 struct {
 		XMLName xml.Name `xml:"foo"`
 	}
 	type T5 struct {
-		F T6 `xml:"f"` // want `name "f" conflicts with name "foo" in CheckStructTags\.T6\.XMLName`
+		F T6 `xml:"f"` //@ diag(`name "f" conflicts with name "foo" in CheckStructTags.T6.XMLName`)
 	}
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckStructTags/generics.go 2022.1.3-1/staticcheck/testdata/src/CheckStructTags/generics.go
--- 2022.1-1/staticcheck/testdata/src/CheckStructTags/generics.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckStructTags/generics.go	2022-07-31 15:38:22.000000000 +0000
@@ -4,7 +4,7 @@ package pkg
 
 type S1[T any] struct {
 	// flag, 'any' is too permissive
-	F T `json:",string"` // want `the JSON string option`
+	F T `json:",string"` //@ diag(`the JSON string option`)
 }
 
 type S2[T int | string] struct {
@@ -14,7 +14,7 @@ type S2[T int | string] struct {
 
 type S3[T int | complex128] struct {
 	// flag, can't use ,string on complex128
-	F T `json:",string"` // want `the JSON string option`
+	F T `json:",string"` //@ diag(`the JSON string option`)
 }
 
 type S4[T int | string] struct {
@@ -29,29 +29,29 @@ type S5[T ~int | ~string, PT ~int | ~str
 
 type S6[T int | complex128] struct {
 	// flag, pointers to non-stringable types aren't stringable, either
-	F *T `json:",string"` // want `the JSON string option`
+	F *T `json:",string"` //@ diag(`the JSON string option`)
 }
 
 type S7[T int | complex128, PT *T] struct {
 	// flag, pointers to non-stringable types aren't stringable, either
-	F PT `json:",string"` // want `the JSON string option`
+	F PT `json:",string"` //@ diag(`the JSON string option`)
 }
 
 type S8[T int, PT *T | complex128] struct {
 	// do flag, variation of S7
-	F PT `json:",string"` // want `the JSON string option`
+	F PT `json:",string"` //@ diag(`the JSON string option`)
 }
 
 type S9[T int | *bool, PT *T | float64, PPT *PT | string] struct {
 	// do flag, multiple levels of pointers aren't allowed
-	F PPT `json:",string"` // want `the JSON string option`
+	F PPT `json:",string"` //@ diag(`the JSON string option`)
 }
 
 type S10[T1 *T2, T2 *T1] struct {
 	// do flag, don't get stuck in an infinite loop
-	F T1 `json:",string"` // want `the JSON string option`
+	F T1 `json:",string"` //@ diag(`the JSON string option`)
 }
 
 type S11[E ~int | ~complex128, T ~*E] struct {
-	F T `json:",string"` // want `the JSON string option`
+	F T `json:",string"` //@ diag(`the JSON string option`)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckStructTags2/CheckStructTags2.go 2022.1.3-1/staticcheck/testdata/src/CheckStructTags2/CheckStructTags2.go
--- 2022.1-1/staticcheck/testdata/src/CheckStructTags2/CheckStructTags2.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckStructTags2/CheckStructTags2.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,7 +1,7 @@
 package pkg
 
 type T5 struct {
-	A int   `choice:"foo" choice:"bar"`                 // want `duplicate struct tag`
-	B []int `optional-value:"foo" optional-value:"bar"` // want `duplicate struct tag`
-	C []int `default:"foo" default:"bar"`               // want `duplicate struct tag`
+	A int   `choice:"foo" choice:"bar"`                 //@ diag(`duplicate struct tag`)
+	B []int `optional-value:"foo" optional-value:"bar"` //@ diag(`duplicate struct tag`)
+	C []int `default:"foo" default:"bar"`               //@ diag(`duplicate struct tag`)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckStructTags3/CheckStructTags.go 2022.1.3-1/staticcheck/testdata/src/CheckStructTags3/CheckStructTags.go
--- 2022.1-1/staticcheck/testdata/src/CheckStructTags3/CheckStructTags.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckStructTags3/CheckStructTags.go	2022-07-31 15:38:22.000000000 +0000
@@ -3,18 +3,18 @@ package pkg
 import _ "github.com/jessevdk/go-flags"
 
 type T1 struct {
-	B int        `foo:"" foo:""` // want `duplicate struct tag`
+	B int        `foo:"" foo:""` //@ diag(`duplicate struct tag`)
 	C int        `foo:"" bar:""`
 	D int        `json:"-"`
-	E int        `json:"\\"`                   // want `invalid JSON field name`
-	F int        `json:",omitempty,omitempty"` // want `duplicate JSON option "omitempty"`
+	E int        `json:"\\"`                   //@ diag(`invalid JSON field name`)
+	F int        `json:",omitempty,omitempty"` //@ diag(`duplicate JSON option "omitempty"`)
 	G int        `json:",omitempty,string"`
-	H int        `json:",string,omitempty,string"` // want `duplicate JSON option "string"`
-	I int        `json:",unknown"`                 // want `unknown JSON option "unknown"`
+	H int        `json:",string,omitempty,string"` //@ diag(`duplicate JSON option "string"`)
+	I int        `json:",foreign"`                 //@ diag(`unknown JSON option "foreign"`)
 	J int        `json:",string"`
 	K *int       `json:",string"`
-	L **int      `json:",string"` // want `the JSON string option`
-	M complex128 `json:",string"` // want `the JSON string option`
+	L **int      `json:",string"` //@ diag(`the JSON string option`)
+	M complex128 `json:",string"` //@ diag(`the JSON string option`)
 	N int        `json:"some-name"`
 	O int        `json:"some-name,inline"`
 }
@@ -27,19 +27,19 @@ type T2 struct {
 	E int `xml:",comment"`
 	F int `xml:",omitempty"`
 	G int `xml:",any"`
-	H int `xml:",unknown"` // want `unknown option`
-	I int `xml:",any,any"` // want `duplicate option`
+	H int `xml:",unknown"` //@ diag(`unknown option`)
+	I int `xml:",any,any"` //@ diag(`duplicate option`)
 	J int `xml:"a>b>c,"`
 }
 
 type T3 struct {
 	A int `json:",omitempty" xml:",attr"`
-	B int `json:",unknown" xml:",attr"` // want `unknown JSON option`
+	B int `json:",foreign" xml:",attr"` //@ diag(`unknown JSON option "foreign"`)
 }
 
 type T4 struct {
 	A int   `choice:"foo" choice:"bar"`
 	B []int `optional-value:"foo" optional-value:"bar"`
 	C []int `default:"foo" default:"bar"`
-	D int   `json:"foo" json:"bar"` // want `duplicate struct tag`
+	D int   `json:"foo" json:"bar"` //@ diag(`duplicate struct tag`)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckSyncPoolValue/CheckSyncPoolValue.go 2022.1.3-1/staticcheck/testdata/src/CheckSyncPoolValue/CheckSyncPoolValue.go
--- 2022.1-1/staticcheck/testdata/src/CheckSyncPoolValue/CheckSyncPoolValue.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckSyncPoolValue/CheckSyncPoolValue.go	2022-07-31 15:38:22.000000000 +0000
@@ -18,13 +18,13 @@ func fn() {
 	s := []int{}
 
 	v := sync.Pool{}
-	v.Put(s) // want `argument should be pointer-like`
+	v.Put(s) //@ diag(`argument should be pointer-like`)
 	v.Put(&s)
-	v.Put(T1{}) // want `argument should be pointer-like`
-	v.Put(T2{}) // want `argument should be pointer-like`
+	v.Put(T1{}) //@ diag(`argument should be pointer-like`)
+	v.Put(T2{}) //@ diag(`argument should be pointer-like`)
 
 	p := &sync.Pool{}
-	p.Put(s) // want `argument should be pointer-like`
+	p.Put(s) //@ diag(`argument should be pointer-like`)
 	p.Put(&s)
 
 	var i interface{}
@@ -34,19 +34,19 @@ func fn() {
 	p.Put(up)
 
 	var basic int
-	p.Put(basic) // want `argument should be pointer-like`
+	p.Put(basic) //@ diag(`argument should be pointer-like`)
 }
 
 func fn2() {
 	// https://github.com/dominikh/go-tools/issues/873
 	var pool sync.Pool
 	func() {
-		defer pool.Put([]byte{}) // want `argument should be pointer-like`
+		defer pool.Put([]byte{}) //@ diag(`argument should be pointer-like`)
 	}()
 }
 
 func fn3() {
 	var pool sync.Pool
-	defer pool.Put([]byte{}) // want `argument should be pointer-like`
-	go pool.Put([]byte{})    // want `argument should be pointer-like`
+	defer pool.Put([]byte{}) //@ diag(`argument should be pointer-like`)
+	go pool.Put([]byte{})    //@ diag(`argument should be pointer-like`)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckTemplate/CheckTemplate.go 2022.1.3-1/staticcheck/testdata/src/CheckTemplate/CheckTemplate.go
--- 2022.1-1/staticcheck/testdata/src/CheckTemplate/CheckTemplate.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckTemplate/CheckTemplate.go	2022-07-31 15:38:22.000000000 +0000
@@ -9,11 +9,11 @@ const tmpl1 = `{{.Name}} {{.LastName}`
 const tmpl2 = `{{fn}}`
 
 func fn() {
-	tt.New("").Parse(tmpl1) // want `template`
+	tt.New("").Parse(tmpl1) //@ diag(`template`)
 	tt.New("").Parse(tmpl2)
 	t1 := tt.New("")
 	t1.Parse(tmpl1)
-	th.New("").Parse(tmpl1) // want `template`
+	th.New("").Parse(tmpl1) //@ diag(`template`)
 	th.New("").Parse(tmpl2)
 	t2 := th.New("")
 	t2.Parse(tmpl1)
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckTestMainExit-1_go14/CheckTestMainExit-1.go 2022.1.3-1/staticcheck/testdata/src/CheckTestMainExit-1_go14/CheckTestMainExit-1.go
--- 2022.1-1/staticcheck/testdata/src/CheckTestMainExit-1_go14/CheckTestMainExit-1.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckTestMainExit-1_go14/CheckTestMainExit-1.go	2022-07-31 15:38:22.000000000 +0000
@@ -2,6 +2,6 @@ package pkg
 
 import "testing"
 
-func TestMain(m *testing.M) { // want `should call os\.Exit`
+func TestMain(m *testing.M) { //@ diag(`should call os.Exit`)
 	m.Run()
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckTestMainExit-4_go14/CheckTestMainExit-4.go 2022.1.3-1/staticcheck/testdata/src/CheckTestMainExit-4_go14/CheckTestMainExit-4.go
--- 2022.1-1/staticcheck/testdata/src/CheckTestMainExit-4_go14/CheckTestMainExit-4.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckTestMainExit-4_go14/CheckTestMainExit-4.go	2022-07-31 15:38:22.000000000 +0000
@@ -7,7 +7,7 @@ import (
 
 func helper() { os.Exit(1) }
 
-func TestMain(m *testing.M) { // want `should call os\.Exit`
+func TestMain(m *testing.M) { //@ diag(`should call os.Exit`)
 	// FIXME(dominikh): this is a false positive
 	m.Run()
 	helper()
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckTimeParse/CheckTimeParse.go 2022.1.3-1/staticcheck/testdata/src/CheckTimeParse/CheckTimeParse.go
--- 2022.1-1/staticcheck/testdata/src/CheckTimeParse/CheckTimeParse.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckTimeParse/CheckTimeParse.go	2022-07-31 15:38:22.000000000 +0000
@@ -6,8 +6,8 @@ const c1 = "12345"
 const c2 = "2006"
 
 func fn() {
-	time.Parse("12345", "") // want `parsing time`
-	time.Parse(c1, "")      // want `parsing time`
+	time.Parse("12345", "") //@ diag(`parsing time`)
+	time.Parse(c1, "")      //@ diag(`parsing time`)
 	time.Parse(c2, "")
 	time.Parse(time.RFC3339Nano, "")
 	time.Parse(time.Kitchen, "")
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckTimerResetReturnValue/CheckTimerResetReturnValue.go 2022.1.3-1/staticcheck/testdata/src/CheckTimerResetReturnValue/CheckTimerResetReturnValue.go
--- 2022.1-1/staticcheck/testdata/src/CheckTimerResetReturnValue/CheckTimerResetReturnValue.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckTimerResetReturnValue/CheckTimerResetReturnValue.go	2022-07-31 15:38:22.000000000 +0000
@@ -26,7 +26,7 @@ func fn4() {
 
 func fn5() {
 	t := time.NewTimer(time.Second)
-	if t.Reset(time.Second) { // want `it is not possible to use Reset's return value correctly`
+	if t.Reset(time.Second) { //@ diag(`it is not possible to use Reset's return value correctly`)
 		<-t.C
 	}
 }
@@ -53,7 +53,7 @@ func fn7(x bool) {
 
 func fn8() {
 	t := time.NewTimer(time.Second)
-	abc := t.Reset(time.Second) // want `it is not possible to use Reset's return value correctly`
+	abc := t.Reset(time.Second) //@ diag(`it is not possible to use Reset's return value correctly`)
 	if abc {
 		<-t.C
 	}
@@ -69,7 +69,7 @@ func fn9() {
 
 func fn10() {
 	t := time.NewTimer(time.Second)
-	if !t.Reset(time.Second) { // want `it is not possible to use Reset's return value correctly`
+	if !t.Reset(time.Second) { //@ diag(`it is not possible to use Reset's return value correctly`)
 		<-t.C
 	}
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckTimeSleepConstant/CheckTimeSleepConstant.go 2022.1.3-1/staticcheck/testdata/src/CheckTimeSleepConstant/CheckTimeSleepConstant.go
--- 2022.1-1/staticcheck/testdata/src/CheckTimeSleepConstant/CheckTimeSleepConstant.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckTimeSleepConstant/CheckTimeSleepConstant.go	2022-07-31 15:38:22.000000000 +0000
@@ -6,8 +6,8 @@ const c1 = 1
 const c2 = 200
 
 func fn() {
-	time.Sleep(1)  // want `sleeping for 1`
-	time.Sleep(42) // want `sleeping for 42`
+	time.Sleep(1)  //@ diag(`sleeping for 1`)
+	time.Sleep(42) //@ diag(`sleeping for 42`)
 	time.Sleep(201)
 	time.Sleep(c1)
 	time.Sleep(c2)
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckTimeSleepConstant/CheckTimeSleepConstant.go.golden 2022.1.3-1/staticcheck/testdata/src/CheckTimeSleepConstant/CheckTimeSleepConstant.go.golden
--- 2022.1-1/staticcheck/testdata/src/CheckTimeSleepConstant/CheckTimeSleepConstant.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckTimeSleepConstant/CheckTimeSleepConstant.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -7,8 +7,8 @@ const c1 = 1
 const c2 = 200
 
 func fn() {
-	time.Sleep(1 * time.Nanosecond)  // want `sleeping for 1`
-	time.Sleep(42 * time.Nanosecond) // want `sleeping for 42`
+	time.Sleep(1 * time.Nanosecond)  //@ diag(`sleeping for 1`)
+	time.Sleep(42 * time.Nanosecond) //@ diag(`sleeping for 42`)
 	time.Sleep(201)
 	time.Sleep(c1)
 	time.Sleep(c2)
@@ -25,8 +25,8 @@ const c1 = 1
 const c2 = 200
 
 func fn() {
-	time.Sleep(1 * time.Second)  // want `sleeping for 1`
-	time.Sleep(42 * time.Second) // want `sleeping for 42`
+	time.Sleep(1 * time.Second)  //@ diag(`sleeping for 1`)
+	time.Sleep(42 * time.Second) //@ diag(`sleeping for 42`)
 	time.Sleep(201)
 	time.Sleep(c1)
 	time.Sleep(c2)
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckToLowerToUpperComparison/CheckToLowerToUpperComparison.go 2022.1.3-1/staticcheck/testdata/src/CheckToLowerToUpperComparison/CheckToLowerToUpperComparison.go
--- 2022.1-1/staticcheck/testdata/src/CheckToLowerToUpperComparison/CheckToLowerToUpperComparison.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckToLowerToUpperComparison/CheckToLowerToUpperComparison.go	2022-07-31 15:38:22.000000000 +0000
@@ -8,24 +8,24 @@ func fn() {
 		s2 = "bar"
 	)
 
-	if strings.ToLower(s1) == strings.ToLower(s2) { // want `should use strings\.EqualFold instead`
+	if strings.ToLower(s1) == strings.ToLower(s2) { //@ diag(`should use strings.EqualFold instead`)
 		panic("")
 	}
 
-	if strings.ToUpper(s1) == strings.ToUpper(s2) { // want `should use strings\.EqualFold instead`
+	if strings.ToUpper(s1) == strings.ToUpper(s2) { //@ diag(`should use strings.EqualFold instead`)
 		panic("")
 	}
 
-	if strings.ToLower(s1) != strings.ToLower(s2) { // want `should use strings\.EqualFold instead`
+	if strings.ToLower(s1) != strings.ToLower(s2) { //@ diag(`should use strings.EqualFold instead`)
 		panic("")
 	}
 
-	switch strings.ToLower(s1) == strings.ToLower(s2) { // want `should use strings\.EqualFold instead`
+	switch strings.ToLower(s1) == strings.ToLower(s2) { //@ diag(`should use strings.EqualFold instead`)
 	case true, false:
 		panic("")
 	}
 
-	if strings.ToLower(s1) == strings.ToLower(s2) || s1+s2 == s2+s1 { // want `should use strings\.EqualFold instead`
+	if strings.ToLower(s1) == strings.ToLower(s2) || s1+s2 == s2+s1 { //@ diag(`should use strings.EqualFold instead`)
 		panic("")
 	}
 
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckToLowerToUpperComparison/CheckToLowerToUpperComparison.go.golden 2022.1.3-1/staticcheck/testdata/src/CheckToLowerToUpperComparison/CheckToLowerToUpperComparison.go.golden
--- 2022.1-1/staticcheck/testdata/src/CheckToLowerToUpperComparison/CheckToLowerToUpperComparison.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckToLowerToUpperComparison/CheckToLowerToUpperComparison.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -8,24 +8,24 @@ func fn() {
 		s2 = "bar"
 	)
 
-	if strings.EqualFold(s1, s2) { // want `should use strings\.EqualFold instead`
+	if strings.EqualFold(s1, s2) { //@ diag(`should use strings.EqualFold instead`)
 		panic("")
 	}
 
-	if strings.EqualFold(s1, s2) { // want `should use strings\.EqualFold instead`
+	if strings.EqualFold(s1, s2) { //@ diag(`should use strings.EqualFold instead`)
 		panic("")
 	}
 
-	if !strings.EqualFold(s1, s2) { // want `should use strings\.EqualFold instead`
+	if !strings.EqualFold(s1, s2) { //@ diag(`should use strings.EqualFold instead`)
 		panic("")
 	}
 
-	switch strings.EqualFold(s1, s2) { // want `should use strings\.EqualFold instead`
+	switch strings.EqualFold(s1, s2) { //@ diag(`should use strings.EqualFold instead`)
 	case true, false:
 		panic("")
 	}
 
-	if strings.EqualFold(s1, s2) || s1+s2 == s2+s1 { // want `should use strings\.EqualFold instead`
+	if strings.EqualFold(s1, s2) || s1+s2 == s2+s1 { //@ diag(`should use strings.EqualFold instead`)
 		panic("")
 	}
 
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckTypeAssertionShadowingElse/CheckTypeAssertionShadowingElse.go 2022.1.3-1/staticcheck/testdata/src/CheckTypeAssertionShadowingElse/CheckTypeAssertionShadowingElse.go
--- 2022.1-1/staticcheck/testdata/src/CheckTypeAssertionShadowingElse/CheckTypeAssertionShadowingElse.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckTypeAssertionShadowingElse/CheckTypeAssertionShadowingElse.go	2022-07-31 15:38:22.000000000 +0000
@@ -4,7 +4,7 @@ func fn1(x interface{}) {
 	if x, ok := x.(int); ok {
 		_ = x
 	} else {
-		_ = x // want `x refers to the result of a failed type assertion`
+		_ = x //@ diag(`x refers to the result of a failed type assertion`)
 		x = 1
 		// No diagnostic, x is no longer the zero value
 		_ = x
@@ -40,7 +40,7 @@ func fn1(x interface{}) {
 
 	if x, ok := x.(*int); ok {
 		_ = x
-	} else if x != nil { // want `x refers to`
-	} else if x == nil { // want `x refers to`
+	} else if x != nil { //@ diag(`x refers to`)
+	} else if x == nil { //@ diag(`x refers to`)
 	}
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckTypedNilInterface/CheckTypedNilInterface.go 2022.1.3-1/staticcheck/testdata/src/CheckTypedNilInterface/CheckTypedNilInterface.go
--- 2022.1-1/staticcheck/testdata/src/CheckTypedNilInterface/CheckTypedNilInterface.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckTypedNilInterface/CheckTypedNilInterface.go	2022-07-31 15:38:22.000000000 +0000
@@ -177,23 +177,23 @@ func gen22() interface{} {
 func test() {
 	_ = gen1() == nil
 	_ = gen2() == nil
-	_ = gen3() == nil // want `never true`
+	_ = gen3() == nil //@ diag(`never true`)
 	{
 		_, r2, r3 := gen4()
-		_ = r2 == nil // want `never true`
+		_ = r2 == nil //@ diag(`never true`)
 		_ = r3 == nil
 	}
-	_ = gen5() == nil // want `never true`
+	_ = gen5() == nil //@ diag(`never true`)
 	_ = gen6(false) == nil
-	_ = gen7() == nil    // want `never true`
-	_ = gen8(nil) == nil // want `never true`
-	_ = gen9() == nil    // want `never true`
-	_ = gen10() == nil   // want `never true`
+	_ = gen7() == nil    //@ diag(`never true`)
+	_ = gen8(nil) == nil //@ diag(`never true`)
+	_ = gen9() == nil    //@ diag(`never true`)
+	_ = gen10() == nil   //@ diag(`never true`)
 	_ = gen11() == nil
-	_ = gen12(true) == nil // want `never true`
-	_ = gen13() == nil     // want `never true`
-	_ = gen14(nil) == nil  // want `never true`
-	_ = gen15() == nil     // want `never true`
+	_ = gen12(true) == nil //@ diag(`never true`)
+	_ = gen13() == nil     //@ diag(`never true`)
+	_ = gen14(nil) == nil  //@ diag(`never true`)
+	_ = gen15() == nil     //@ diag(`never true`)
 	_ = gen16() == nil
 	_ = gen17(nil) == nil
 	{
@@ -203,8 +203,13 @@ func test() {
 	_ = gen19() == nil
 	_ = gen20() == nil
 	_ = gen21() == nil
-	_ = gen22() == nil // want `never true`
+	_ = gen22() == nil //@ diag(`never true`)
 
 	var v1 interface{} = 0
-	_ = v1 == nil // want `never true; the lhs`
+	_ = v1 == nil //@ diag(`never true; the lhs`)
+
+	_ = any((*int)(nil)) == nil //@ diag(`never true`)
+	_ = any((error)(nil)) == nil
 }
+
+type any = interface{}
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckTypedNilInterface/generics.go 2022.1.3-1/staticcheck/testdata/src/CheckTypedNilInterface/generics.go
--- 2022.1-1/staticcheck/testdata/src/CheckTypedNilInterface/generics.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckTypedNilInterface/generics.go	2022-07-31 15:38:22.000000000 +0000
@@ -2,11 +2,42 @@
 
 package pkg
 
-func foo[T *int,]() T {
+func tpgen1[T *int,]() T {
 	return (T)(nil)
 }
 
 func bar() {
-	if foo() == nil {
+	if tpgen1() == nil {
 	}
 }
+
+func tpfn1[T any](x T) {
+	if any(x) == nil {
+		// this is entirely possible if baz is instantiated with an interface type for T. For example: baz[error](nil)
+	}
+}
+
+func tpfn2[T ~int](x T) {
+	if any(x) == nil { //@ diag(`this comparison is never true`)
+		// this is not possible, because T only accepts concrete types
+	}
+}
+
+func tpgen3[T any](x T) any {
+	return any(x)
+}
+
+func tpgen4[T ~*int](x T) any {
+	return any(x)
+}
+
+func tptest() {
+	_ = tpgen1() == nil
+
+	_ = tpgen3[error](nil) == nil
+
+	// ideally we'd flag this, but the analysis is generic-insensitive at the moment.
+	_ = tpgen3[*int](nil) == nil
+
+	_ = tpgen4[*int](nil) == nil //@ diag(`never true`)
+}
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckTypedNilInterface/i26000/26000.go 2022.1.3-1/staticcheck/testdata/src/CheckTypedNilInterface/i26000/26000.go
--- 2022.1-1/staticcheck/testdata/src/CheckTypedNilInterface/i26000/26000.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckTypedNilInterface/i26000/26000.go	2022-07-31 15:38:22.000000000 +0000
@@ -26,7 +26,7 @@ func main() {
 
 	// Then replace the err type with *CustomError
 	val, err := SomeFunc()
-	if err != nil { // want `this comparison is always true`
+	if err != nil { //@ diag(`this comparison is always true`)
 		panic(err)
 	}
 
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckTypedNilInterface/i27815/27815.go 2022.1.3-1/staticcheck/testdata/src/CheckTypedNilInterface/i27815/27815.go
--- 2022.1-1/staticcheck/testdata/src/CheckTypedNilInterface/i27815/27815.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckTypedNilInterface/i27815/27815.go	2022-07-31 15:38:22.000000000 +0000
@@ -20,7 +20,7 @@ func main() {
 	var e error
 	e = f()
 	// e should be nil ?
-	if e != nil { // want `this comparison is always true`
+	if e != nil { //@ diag(`this comparison is always true`)
 		fmt.Println("NOT NIL")
 	} else {
 		fmt.Println("NIL")
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckTypedNilInterface/i28241/28241.go 2022.1.3-1/staticcheck/testdata/src/CheckTypedNilInterface/i28241/28241.go
--- 2022.1-1/staticcheck/testdata/src/CheckTypedNilInterface/i28241/28241.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckTypedNilInterface/i28241/28241.go	2022-07-31 15:38:22.000000000 +0000
@@ -31,7 +31,7 @@ func main() {
 		reflect.ValueOf(n).IsNil())
 	n2 := MakeNil()
 	fmt.Printf("%t %#v %s %t\n",
-		n2 == nil, // want `this comparison is never true`
+		n2 == nil, //@ diag(`this comparison is never true`)
 		n2,
 		reflect.ValueOf(n2).Kind(),
 		reflect.ValueOf(n2).IsNil())
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckTypedNilInterface/i31873/31873.go 2022.1.3-1/staticcheck/testdata/src/CheckTypedNilInterface/i31873/31873.go
--- 2022.1-1/staticcheck/testdata/src/CheckTypedNilInterface/i31873/31873.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckTypedNilInterface/i31873/31873.go	2022-07-31 15:38:22.000000000 +0000
@@ -20,7 +20,7 @@ func main() {
 	err := errorNil()
 	fmt.Println(err != nil)
 	err = structNil()
-	fmt.Println(err != nil) // want `this comparison is always true`
+	fmt.Println(err != nil) //@ diag(`this comparison is always true`)
 	err = errorNil()
 	fmt.Println(err != nil)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckTypedNilInterface/i33965/33965.go 2022.1.3-1/staticcheck/testdata/src/CheckTypedNilInterface/i33965/33965.go
--- 2022.1-1/staticcheck/testdata/src/CheckTypedNilInterface/i33965/33965.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckTypedNilInterface/i33965/33965.go	2022-07-31 15:38:22.000000000 +0000
@@ -22,5 +22,5 @@ func TestWebSocketClient_basic(t *testin
 
 	err2 := error(nil)
 	err2 = getNilCustomError()
-	fmt.Println(err2 == nil) // want `this comparison is never true`
+	fmt.Println(err2 == nil) //@ diag(`this comparison is never true`)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckTypedNilInterface/i33994/33994.go 2022.1.3-1/staticcheck/testdata/src/CheckTypedNilInterface/i33994/33994.go
--- 2022.1-1/staticcheck/testdata/src/CheckTypedNilInterface/i33994/33994.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckTypedNilInterface/i33994/33994.go	2022-07-31 15:38:22.000000000 +0000
@@ -8,7 +8,7 @@ import (
 func main() {
 	var err = errors.New("errors msg")
 	name, err := GetName()
-	if err != nil { // want `this comparison is always true`
+	if err != nil { //@ diag(`this comparison is always true`)
 		fmt.Println(err)
 	} else {
 		fmt.Println(name)
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckTypedNilInterface/i35217/35217.go 2022.1.3-1/staticcheck/testdata/src/CheckTypedNilInterface/i35217/35217.go
--- 2022.1-1/staticcheck/testdata/src/CheckTypedNilInterface/i35217/35217.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckTypedNilInterface/i35217/35217.go	2022-07-31 15:38:22.000000000 +0000
@@ -20,5 +20,5 @@ func calculate() (int, *someError) {
 func main() {
 	err := errors.New("ERROR")
 	num, err := calculate()
-	fmt.Println(num, err, err == nil) // want `this comparison is never true`
+	fmt.Println(num, err, err == nil) //@ diag(`this comparison is never true`)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckTypedNilInterface/real.go 2022.1.3-1/staticcheck/testdata/src/CheckTypedNilInterface/real.go
--- 2022.1-1/staticcheck/testdata/src/CheckTypedNilInterface/real.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckTypedNilInterface/real.go	2022-07-31 15:38:22.000000000 +0000
@@ -31,7 +31,7 @@ func SyncPublicMethod(input int) iface {
 func main() {
 	for i := 0; i < 10; i++ {
 		k := SyncPublicMethod(i)
-		if k == nil { // want `this comparison is never true`
+		if k == nil { //@ diag(`this comparison is never true`)
 			log.Println("never printed")
 			return
 		}
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckUnbufferedSignalChan/CheckUnbufferedSignalChan.go 2022.1.3-1/staticcheck/testdata/src/CheckUnbufferedSignalChan/CheckUnbufferedSignalChan.go
--- 2022.1-1/staticcheck/testdata/src/CheckUnbufferedSignalChan/CheckUnbufferedSignalChan.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckUnbufferedSignalChan/CheckUnbufferedSignalChan.go	2022-07-31 15:38:22.000000000 +0000
@@ -8,7 +8,7 @@ import (
 
 func fn(b bool) {
 	c0 := make(chan os.Signal)
-	signal.Notify(c0, os.Interrupt) // want `the channel used with signal\.Notify should be buffered`
+	signal.Notify(c0, os.Interrupt) //@ diag(`the channel used with signal.Notify should be buffered`)
 
 	c1 := make(chan os.Signal, 1)
 	signal.Notify(c1, os.Interrupt, syscall.SIGHUP)
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckUnmarshalPointer/CheckUnmarshalPointer.go 2022.1.3-1/staticcheck/testdata/src/CheckUnmarshalPointer/CheckUnmarshalPointer.go
--- 2022.1-1/staticcheck/testdata/src/CheckUnmarshalPointer/CheckUnmarshalPointer.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckUnmarshalPointer/CheckUnmarshalPointer.go	2022-07-31 15:38:22.000000000 +0000
@@ -7,12 +7,12 @@ func fn1(i3 interface{}) {
 	var i1 interface{} = v
 	var i2 interface{} = &v
 	p := &v
-	json.Unmarshal([]byte(`{}`), v) // want `Unmarshal expects to unmarshal into a pointer`
+	json.Unmarshal([]byte(`{}`), v) //@ diag(`Unmarshal expects to unmarshal into a pointer`)
 	json.Unmarshal([]byte(`{}`), &v)
-	json.Unmarshal([]byte(`{}`), i1) // want `Unmarshal expects to unmarshal into a pointer`
+	json.Unmarshal([]byte(`{}`), i1) //@ diag(`Unmarshal expects to unmarshal into a pointer`)
 	json.Unmarshal([]byte(`{}`), i2)
 	json.Unmarshal([]byte(`{}`), i3)
 	json.Unmarshal([]byte(`{}`), p)
 
-	json.NewDecoder(nil).Decode(v) // want `Decode expects to unmarshal into a pointer`
+	json.NewDecoder(nil).Decode(v) //@ diag(`Decode expects to unmarshal into a pointer`)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckUnreachableTypeCases/CheckUnreachableTypeCases.go 2022.1.3-1/staticcheck/testdata/src/CheckUnreachableTypeCases/CheckUnreachableTypeCases.go
--- 2022.1-1/staticcheck/testdata/src/CheckUnreachableTypeCases/CheckUnreachableTypeCases.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckUnreachableTypeCases/CheckUnreachableTypeCases.go	2022-07-31 15:38:22.000000000 +0000
@@ -19,37 +19,37 @@ func fn1() {
 	switch v.(type) {
 	case io.Reader:
 		println("io.Reader")
-	case io.ReadCloser: // want `unreachable case clause: io\.Reader will always match before io\.ReadCloser`
+	case io.ReadCloser: //@ diag(`unreachable case clause: io.Reader will always match before io.ReadCloser`)
 		println("io.ReadCloser")
 	}
 
 	switch v.(type) {
 	case io.Reader:
 		println("io.Reader")
-	case T: // want `unreachable case clause: io\.Reader will always match before CheckUnreachableTypeCases\.T`
+	case T: //@ diag(`unreachable case clause: io.Reader will always match before CheckUnreachableTypeCases.T`)
 		println("T")
 	}
 
 	switch v.(type) {
 	case io.Reader:
 		println("io.Reader")
-	case io.ReadCloser: // want `unreachable case clause: io\.Reader will always match before io\.ReadCloser`
+	case io.ReadCloser: //@ diag(`unreachable case clause: io.Reader will always match before io.ReadCloser`)
 		println("io.ReadCloser")
-	case T: // want `unreachable case clause: io\.Reader will always match before CheckUnreachableTypeCases\.T`
+	case T: //@ diag(`unreachable case clause: io.Reader will always match before CheckUnreachableTypeCases.T`)
 		println("T")
 	}
 
 	switch v.(type) {
 	case io.Reader:
 		println("io.Reader")
-	case io.ReadCloser, T: // want `unreachable case clause: io\.Reader will always match before io\.ReadCloser`
+	case io.ReadCloser, T: //@ diag(`unreachable case clause: io.Reader will always match before io.ReadCloser`)
 		println("io.ReadCloser or T")
 	}
 
 	switch v.(type) {
 	case io.ReadCloser, io.Reader:
 		println("io.ReadCloser or io.Reader")
-	case T: // want `unreachable case clause: io\.Reader will always match before CheckUnreachableTypeCases\.T`
+	case T: //@ diag(`unreachable case clause: io.Reader will always match before CheckUnreachableTypeCases.T`)
 		println("T")
 	}
 
@@ -58,28 +58,28 @@ func fn1() {
 		println("something else")
 	case io.Reader:
 		println("io.Reader")
-	case T: // want `unreachable case clause: io\.Reader will always match before CheckUnreachableTypeCases\.T`
+	case T: //@ diag(`unreachable case clause: io.Reader will always match before CheckUnreachableTypeCases.T`)
 		println("T")
 	}
 
 	switch v.(type) {
 	case interface{}:
 		println("interface{}")
-	case nil, T: // want `unreachable case clause: interface{} will always match before CheckUnreachableTypeCases\.T`
+	case nil, T: //@ diag(`unreachable case clause: interface{} will always match before CheckUnreachableTypeCases.T`)
 		println("nil or T")
 	}
 
 	switch err.(type) {
 	case V:
 		println("V")
-	case U: // want `unreachable case clause: CheckUnreachableTypeCases\.V will always match before CheckUnreachableTypeCases\.U`
+	case U: //@ diag(`unreachable case clause: CheckUnreachableTypeCases.V will always match before CheckUnreachableTypeCases.U`)
 		println("U")
 	}
 
 	switch err.(type) {
 	case U:
 		println("U")
-	case V: // want `unreachable case clause: CheckUnreachableTypeCases\.U will always match before CheckUnreachableTypeCases\.V`
+	case V: //@ diag(`unreachable case clause: CheckUnreachableTypeCases.U will always match before CheckUnreachableTypeCases.V`)
 		println("V")
 	}
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckUnreadVariableValues/CheckUnreadVariableValues.go 2022.1.3-1/staticcheck/testdata/src/CheckUnreadVariableValues/CheckUnreadVariableValues.go
--- 2022.1-1/staticcheck/testdata/src/CheckUnreadVariableValues/CheckUnreadVariableValues.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckUnreadVariableValues/CheckUnreadVariableValues.go	2022-07-31 15:38:22.000000000 +0000
@@ -4,13 +4,13 @@ import "fmt"
 
 func fn1() {
 	var x int
-	x = gen() // want `this value of x is never used`
+	x = gen() //@ diag(`this value of x is never used`)
 	x = gen()
 	println(x)
 
 	var y int
 	if true {
-		y = gen() // want `this value of y is never used`
+		y = gen() //@ diag(`this value of y is never used`)
 	}
 	y = gen()
 	println(y)
@@ -22,7 +22,7 @@ func gen() int {
 }
 
 func fn2() {
-	x, y := gen(), gen() // want `this value of x is never used` `this value of y is never used`
+	x, y := gen(), gen() //@ diag(`this value of x is never used`), diag(`this value of y is never used`)
 	x, y = gen(), gen()
 	println(x, y)
 }
@@ -43,16 +43,16 @@ func gen2() (int, int) {
 }
 
 func fn4() {
-	x, y := gen2() // want `this value of x is never used`
+	x, y := gen2() //@ diag(`this value of x is never used`)
 	println(y)
-	x, y = gen2() // want `this value of x is never used` `this value of y is never used`
-	x, _ = gen2() // want `this value of x is never used`
+	x, y = gen2() //@ diag(`this value of x is never used`), diag(`this value of y is never used`)
+	x, _ = gen2() //@ diag(`this value of x is never used`)
 	x, y = gen2()
 	println(x, y)
 }
 
 func fn5(m map[string]string) {
-	v, ok := m[""] // want `this value of v is never used` `this value of ok is never used`
+	v, ok := m[""] //@ diag(`this value of v is never used`), diag(`this value of ok is never used`)
 	v, ok = m[""]
 	println(v, ok)
 }
@@ -66,7 +66,7 @@ func fn6() {
 func fn7() {
 	func() {
 		var x int
-		x = gen() // want `this value of x is never used`
+		x = gen() //@ diag(`this value of x is never used`)
 		x = gen()
 		println(x)
 	}()
@@ -75,7 +75,7 @@ func fn7() {
 func fn() int { println(); return 0 }
 
 var y = func() {
-	v := fn() // want `never used`
+	v := fn() //@ diag(`never used`)
 	v = fn()
 	println(v)
 }
@@ -85,7 +85,7 @@ func fn8() {
 	switch x {
 	}
 
-	y := gen() // want `this value of y is never used`
+	y := gen() //@ diag(`this value of y is never used`)
 	y = gen()
 	switch y {
 	}
@@ -98,9 +98,9 @@ func fn8() {
 	switch a {
 	}
 
-	b, c := gen2() // want `this value of b is never used`
+	b, c := gen2() //@ diag(`this value of b is never used`)
 	println(c)
-	b, c = gen2() // want `this value of c is never used`
+	b, c = gen2() //@ diag(`this value of c is never used`)
 	switch b {
 	}
 }
@@ -108,7 +108,7 @@ func fn8() {
 func fn9() {
 	xs := []int{}
 	for _, x := range xs {
-		foo, err := work(x) // want `this value of foo is never used`
+		foo, err := work(x) //@ diag(`this value of foo is never used`)
 		if err != nil {
 			return
 		}
@@ -127,7 +127,7 @@ func resolveWeakTypes(types []int) {
 		if true {
 			_ = runEnd
 		}
-		i = runEnd // want `this value of i is never used`
+		i = runEnd //@ diag(`this value of i is never used`)
 	}
 }
 
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckUnreadVariableValues/CheckUnreadVariableValues_test.go 2022.1.3-1/staticcheck/testdata/src/CheckUnreadVariableValues/CheckUnreadVariableValues_test.go
--- 2022.1-1/staticcheck/testdata/src/CheckUnreadVariableValues/CheckUnreadVariableValues_test.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckUnreadVariableValues/CheckUnreadVariableValues_test.go	2022-07-31 15:38:22.000000000 +0000
@@ -3,7 +3,7 @@ package pkg
 import "testing"
 
 func TestFoo(t *testing.T) {
-	x := fn() // want `never used`
+	x := fn() //@ diag(`never used`)
 	x = fn()
 	println(x)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckUnsafePrintf/CheckUnsafePrintf.go 2022.1.3-1/staticcheck/testdata/src/CheckUnsafePrintf/CheckUnsafePrintf.go
--- 2022.1-1/staticcheck/testdata/src/CheckUnsafePrintf/CheckUnsafePrintf.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckUnsafePrintf/CheckUnsafePrintf.go	2022-07-31 15:38:22.000000000 +0000
@@ -8,12 +8,12 @@ import (
 
 func fn(s string) {
 	fn2 := func() string { return "" }
-	fmt.Printf(fn2())      // want `should use print-style function`
-	_ = fmt.Sprintf(fn2()) // want `should use print-style function`
-	log.Printf(fn2())      // want `should use print-style function`
-	fmt.Printf(s)          // want `should use print-style function`
+	fmt.Printf(fn2())      //@ diag(`should use print-style function`)
+	_ = fmt.Sprintf(fn2()) //@ diag(`should use print-style function`)
+	log.Printf(fn2())      //@ diag(`should use print-style function`)
+	fmt.Printf(s)          //@ diag(`should use print-style function`)
 	fmt.Printf(s, "")
-	fmt.Fprintf(os.Stdout, s) // want `should use print-style function`
+	fmt.Fprintf(os.Stdout, s) //@ diag(`should use print-style function`)
 	fmt.Fprintf(os.Stdout, s, "")
 
 	fmt.Printf(fn2(), "")
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckUnsafePrintf/CheckUnsafePrintf.go.golden 2022.1.3-1/staticcheck/testdata/src/CheckUnsafePrintf/CheckUnsafePrintf.go.golden
--- 2022.1-1/staticcheck/testdata/src/CheckUnsafePrintf/CheckUnsafePrintf.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckUnsafePrintf/CheckUnsafePrintf.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -8,12 +8,12 @@ import (
 
 func fn(s string) {
 	fn2 := func() string { return "" }
-	fmt.Print(fn2())      // want `should use print-style function`
-	_ = fmt.Sprint(fn2()) // want `should use print-style function`
-	log.Print(fn2())      // want `should use print-style function`
-	fmt.Print(s)          // want `should use print-style function`
+	fmt.Print(fn2())      //@ diag(`should use print-style function`)
+	_ = fmt.Sprint(fn2()) //@ diag(`should use print-style function`)
+	log.Print(fn2())      //@ diag(`should use print-style function`)
+	fmt.Print(s)          //@ diag(`should use print-style function`)
 	fmt.Printf(s, "")
-	fmt.Fprint(os.Stdout, s) // want `should use print-style function`
+	fmt.Fprint(os.Stdout, s) //@ diag(`should use print-style function`)
 	fmt.Fprintf(os.Stdout, s, "")
 
 	fmt.Printf(fn2(), "")
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckUnsupportedMarshal/CheckUnsupportedMarshal.go 2022.1.3-1/staticcheck/testdata/src/CheckUnsupportedMarshal/CheckUnsupportedMarshal.go
--- 2022.1-1/staticcheck/testdata/src/CheckUnsupportedMarshal/CheckUnsupportedMarshal.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckUnsupportedMarshal/CheckUnsupportedMarshal.go	2022-07-31 15:38:22.000000000 +0000
@@ -78,37 +78,37 @@ func fn() {
 	var t11 Recursive
 	json.Marshal(t1)
 	json.Marshal(t2)
-	json.Marshal(t3) // want `unsupported type chan int, via x\.Ch`
+	json.Marshal(t3) //@ diag(`unsupported type chan int, via x.Ch`)
 	json.Marshal(t4)
-	json.Marshal(t5) // want `unsupported type func\(\), via x\.B`
+	json.Marshal(t5) //@ diag(`unsupported type func(), via x.B`)
 	json.Marshal(t6)
 	(*json.Encoder)(nil).Encode(t1)
 	(*json.Encoder)(nil).Encode(t2)
-	(*json.Encoder)(nil).Encode(t3) // want `unsupported type chan int, via x\.Ch`
+	(*json.Encoder)(nil).Encode(t3) //@ diag(`unsupported type chan int, via x.Ch`)
 	(*json.Encoder)(nil).Encode(t4)
-	(*json.Encoder)(nil).Encode(t5) // want `unsupported type func\(\), via x\.B`
+	(*json.Encoder)(nil).Encode(t5) //@ diag(`unsupported type func(), via x.B`)
 	(*json.Encoder)(nil).Encode(t6)
 
 	xml.Marshal(t1)
 	xml.Marshal(t2)
-	xml.Marshal(t3) // want `unsupported type chan int, via x\.Ch`
+	xml.Marshal(t3) //@ diag(`unsupported type chan int, via x.Ch`)
 	xml.Marshal(t4)
 	xml.Marshal(t5)
-	xml.Marshal(t6) // want `unsupported type func\(\), via x\.B`
+	xml.Marshal(t6) //@ diag(`unsupported type func(), via x.B`)
 	(*xml.Encoder)(nil).Encode(t1)
 	(*xml.Encoder)(nil).Encode(t2)
-	(*xml.Encoder)(nil).Encode(t3) // want `unsupported type chan int, via x\.C`
+	(*xml.Encoder)(nil).Encode(t3) //@ diag(`unsupported type chan int, via x.C`)
 	(*xml.Encoder)(nil).Encode(t4)
 	(*xml.Encoder)(nil).Encode(t5)
-	(*xml.Encoder)(nil).Encode(t6) // want `unsupported type func\(\), via x\.B`
+	(*xml.Encoder)(nil).Encode(t6) //@ diag(`unsupported type func(), via x.B`)
 
-	json.Marshal(t8)  // want `unsupported type chan int, via x\.T7\.T3\.Ch`
-	json.Marshal(t9)  // want `unsupported type PointerMarshaler, via x\.F`
+	json.Marshal(t8)  //@ diag(`unsupported type chan int, via x.T7.T3.Ch`)
+	json.Marshal(t9)  //@ diag(`unsupported type PointerMarshaler, via x.F`)
 	json.Marshal(&t9) // this is fine, t9 is addressable, therefore T9.D is, too
 	json.Marshal(t10) // this is fine, T10.F.D is addressable
 
-	xml.Marshal(t8)  // want `unsupported type chan int, via x\.T7\.T3\.Ch`
-	xml.Marshal(t9)  // want `unsupported type PointerMarshaler, via x\.F`
+	xml.Marshal(t8)  //@ diag(`unsupported type chan int, via x.T7.T3.Ch`)
+	xml.Marshal(t9)  //@ diag(`unsupported type PointerMarshaler, via x.F`)
 	xml.Marshal(&t9) // this is fine, t9 is addressable, therefore T9.D is, too
 	xml.Marshal(t10) // this is fine, T10.F.D is addressable
 
@@ -123,19 +123,19 @@ func addressabilityJSON() {
 		F PointerMarshaler
 	}
 	var d [4]PointerMarshaler
-	json.Marshal(a) // want `unsupported type PointerMarshaler$`
+	json.Marshal(a) //@ diag(re`unsupported type PointerMarshaler$`)
 	json.Marshal(&a)
 	json.Marshal(b)
 	json.Marshal(&b)
-	json.Marshal(c) // want `unsupported type PointerMarshaler, via x\.F`
+	json.Marshal(c) //@ diag(`unsupported type PointerMarshaler, via x.F`)
 	json.Marshal(&c)
-	json.Marshal(d) // want `unsupported type PointerMarshaler, via x\[0\]`
+	json.Marshal(d) //@ diag(`unsupported type PointerMarshaler, via x[0]`)
 	json.Marshal(&d)
 
 	var m1 map[string]PointerMarshaler
-	json.Marshal(m1)                                // want `unsupported type PointerMarshaler, via x\[k\]`
-	json.Marshal(&m1)                               // want `unsupported type PointerMarshaler, via x\[k\]`
-	json.Marshal([]map[string]PointerMarshaler{m1}) // want `unsupported type PointerMarshaler, via x\[0\]\[k\]`
+	json.Marshal(m1)                                //@ diag(`unsupported type PointerMarshaler, via x[k]`)
+	json.Marshal(&m1)                               //@ diag(`unsupported type PointerMarshaler, via x[k]`)
+	json.Marshal([]map[string]PointerMarshaler{m1}) //@ diag(`unsupported type PointerMarshaler, via x[0][k]`)
 
 	var m2 map[string]*PointerMarshaler
 	json.Marshal(m2)
@@ -151,13 +151,13 @@ func addressabilityXML() {
 		F       PointerMarshaler
 	}
 	var d [4]PointerMarshaler
-	xml.Marshal(a) // want `unsupported type PointerMarshaler$`
+	xml.Marshal(a) //@ diag(re`unsupported type PointerMarshaler$`)
 	xml.Marshal(&a)
 	xml.Marshal(b)
 	xml.Marshal(&b)
-	xml.Marshal(c) // want `unsupported type PointerMarshaler, via x\.F`
+	xml.Marshal(c) //@ diag(`unsupported type PointerMarshaler, via x.F`)
 	xml.Marshal(&c)
-	xml.Marshal(d) // want `unsupported type PointerMarshaler, via x\[0\]`
+	xml.Marshal(d) //@ diag(`unsupported type PointerMarshaler, via x[0]`)
 	xml.Marshal(&d)
 }
 
@@ -166,12 +166,12 @@ func mapsJSON() {
 	var bad map[interface{}]string
 	// the map key has to be statically known good; it must be a number or a string
 	json.Marshal(good)
-	json.Marshal(bad) // want `unsupported type map\[interface\{\}\]string$`
+	json.Marshal(bad) //@ diag(`unsupported type map[interface{}]string`)
 
 	var m1 map[string]PointerMarshaler
-	json.Marshal(m1)                                // want `unsupported type PointerMarshaler, via x\[k\]`
-	json.Marshal(&m1)                               // want `unsupported type PointerMarshaler, via x\[k\]`
-	json.Marshal([]map[string]PointerMarshaler{m1}) // want `unsupported type PointerMarshaler, via x\[0\]\[k\]`
+	json.Marshal(m1)                                //@ diag(`unsupported type PointerMarshaler, via x[k]`)
+	json.Marshal(&m1)                               //@ diag(`unsupported type PointerMarshaler, via x[k]`)
+	json.Marshal([]map[string]PointerMarshaler{m1}) //@ diag(`unsupported type PointerMarshaler, via x[0][k]`)
 
 	var m2 map[string]*PointerMarshaler
 	json.Marshal(m2)
@@ -195,14 +195,14 @@ func mapsJSON() {
 
 	json.Marshal(m5)
 	json.Marshal(m6)
-	json.Marshal(m7) // want `unsupported type map\[PointerMarshaler\]string$`
+	json.Marshal(m7) //@ diag(`unsupported type map[PointerMarshaler]string`)
 	json.Marshal(m8)
 }
 
 func mapsXML() {
 	// encoding/xml doesn't support any maps
 	var bad map[string]string
-	xml.Marshal(bad) // want `unsupported type`
+	xml.Marshal(bad) //@ diag(`unsupported type`)
 }
 
 func fieldPriorityJSON() {
@@ -224,7 +224,7 @@ func fieldPriorityJSON() {
 		F int
 		lT4
 	}
-	json.Marshal(lT3{}) // want `unsupported type chan int, via x\.lT4\.C`
+	json.Marshal(lT3{}) //@ diag(`unsupported type chan int, via x.lT4.C`)
 }
 
 func fieldPriorityXML() {
@@ -246,7 +246,7 @@ func fieldPriorityXML() {
 		F int
 		lT4
 	}
-	xml.Marshal(lT3{}) // want `unsupported type chan int, via x\.lT4\.C`
+	xml.Marshal(lT3{}) //@ diag(`unsupported type chan int, via x.lT4.C`)
 }
 
 func longPathJSON() {
@@ -257,12 +257,12 @@ func longPathJSON() {
 			}
 		}
 	}
-	json.Marshal(foo) // want `unsupported type chan int, via x\.Field\.Field2\[0\].Map\[k\]`
+	json.Marshal(foo) //@ diag(`unsupported type chan int, via x.Field.Field2[0].Map[k]`)
 }
 
 func otherPackageJSON() {
 	var x time.Ticker
-	json.Marshal(x) // want `unsupported type <-chan time\.Time, via x\.C`
+	json.Marshal(x) //@ diag(`unsupported type <-chan time.Time, via x.C`)
 }
 
 func longPathXML() {
@@ -273,12 +273,12 @@ func longPathXML() {
 			}
 		}
 	}
-	xml.Marshal(foo) // want `unsupported type map\[string\]chan int, via x\.Field\.Field2\[0\].Map`
+	xml.Marshal(foo) //@ diag(`unsupported type map[string]chan int, via x.Field.Field2[0].Map`)
 }
 
 func otherPackageXML() {
 	var x time.Ticker
-	xml.Marshal(x) // want `unsupported type <-chan time\.Time, via x\.C`
+	xml.Marshal(x) //@ diag(`unsupported type <-chan time.Time, via x.C`)
 }
 
 type ToplevelPointerMarshalerXML struct {
@@ -300,6 +300,18 @@ func (*ToplevelPointerMarshalerText) Mar
 func toplevelPointer() {
 	xml.Marshal(&ToplevelPointerMarshalerXML{})
 	xml.Marshal(&ToplevelPointerMarshalerText{})
-	xml.Marshal(ToplevelPointerMarshalerXML{})  // want `unsupported type`
-	xml.Marshal(ToplevelPointerMarshalerText{}) // want `unsupported type`
+	xml.Marshal(ToplevelPointerMarshalerXML{})  //@ diag(`unsupported type`)
+	xml.Marshal(ToplevelPointerMarshalerText{}) //@ diag(`unsupported type`)
+}
+
+func cyclicPointer() {
+	type P *P
+	type S2 struct {
+		Bar P
+	}
+	type S1 struct {
+		Foo S2
+	}
+	var s S1
+	xml.Marshal(s) //@ diag(`cyclic type P, via x.Foo.Bar`)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckUnsupportedMarshal/generics.go 2022.1.3-1/staticcheck/testdata/src/CheckUnsupportedMarshal/generics.go
--- 2022.1-1/staticcheck/testdata/src/CheckUnsupportedMarshal/generics.go	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckUnsupportedMarshal/generics.go	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1,33 @@
+//go:build go1.18
+
+package pkg
+
+import (
+	"encoding/json"
+	"encoding/xml"
+)
+
+type LMap[K comparable, V any] struct {
+	M1 map[K]V
+	M2 map[K]chan int
+}
+
+func (lm *LMap[K, V]) MarshalJSON() {
+	json.Marshal(lm.M1)
+	json.Marshal(lm.M2) //@ diag(`unsupported type`)
+}
+
+func recursiveGeneric() {
+	// don't recurse infinitely
+	var t Tree[int]
+	json.Marshal(t)
+	xml.Marshal(t)
+}
+
+type Tree[T any] struct {
+	Node *Node[T]
+}
+
+type Node[T any] struct {
+	Tree *Tree[T]
+}
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckUntrappableSignal/CheckUntrappableSignal.go 2022.1.3-1/staticcheck/testdata/src/CheckUntrappableSignal/CheckUntrappableSignal.go
--- 2022.1-1/staticcheck/testdata/src/CheckUntrappableSignal/CheckUntrappableSignal.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckUntrappableSignal/CheckUntrappableSignal.go	2022-07-31 15:38:22.000000000 +0000
@@ -9,11 +9,11 @@ import (
 func fn() {
 	c := make(chan os.Signal, 1)
 	signal.Notify(c, os.Interrupt)
-	signal.Ignore(os.Signal(syscall.SIGKILL)) // want `cannot be trapped`
-	signal.Ignore(os.Kill)                    // want `cannot be trapped`
-	signal.Notify(c, os.Kill)                 // want `cannot be trapped`
-	signal.Reset(os.Kill)                     // want `cannot be trapped`
-	signal.Ignore(syscall.SIGKILL)            // want `cannot be trapped`
-	signal.Notify(c, syscall.SIGKILL)         // want `cannot be trapped`
-	signal.Reset(syscall.SIGKILL)             // want `cannot be trapped`
+	signal.Ignore(os.Signal(syscall.SIGKILL)) //@ diag(`cannot be trapped`)
+	signal.Ignore(os.Kill)                    //@ diag(`cannot be trapped`)
+	signal.Notify(c, os.Kill)                 //@ diag(`cannot be trapped`)
+	signal.Reset(os.Kill)                     //@ diag(`cannot be trapped`)
+	signal.Ignore(syscall.SIGKILL)            //@ diag(`cannot be trapped`)
+	signal.Notify(c, syscall.SIGKILL)         //@ diag(`cannot be trapped`)
+	signal.Reset(syscall.SIGKILL)             //@ diag(`cannot be trapped`)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckUntrappableSignal/CheckUntrappableSignal.go.golden 2022.1.3-1/staticcheck/testdata/src/CheckUntrappableSignal/CheckUntrappableSignal.go.golden
--- 2022.1-1/staticcheck/testdata/src/CheckUntrappableSignal/CheckUntrappableSignal.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckUntrappableSignal/CheckUntrappableSignal.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -10,13 +10,13 @@ import (
 func fn() {
 	c := make(chan os.Signal, 1)
 	signal.Notify(c, os.Interrupt)
-	signal.Ignore()           // want `cannot be trapped`
-	signal.Ignore(os.Kill)    // want `cannot be trapped`
-	signal.Notify(c, os.Kill) // want `cannot be trapped`
-	signal.Reset(os.Kill)     // want `cannot be trapped`
-	signal.Ignore()           // want `cannot be trapped`
-	signal.Notify(c)          // want `cannot be trapped`
-	signal.Reset()            // want `cannot be trapped`
+	signal.Ignore()           //@ diag(`cannot be trapped`)
+	signal.Ignore(os.Kill)    //@ diag(`cannot be trapped`)
+	signal.Notify(c, os.Kill) //@ diag(`cannot be trapped`)
+	signal.Reset(os.Kill)     //@ diag(`cannot be trapped`)
+	signal.Ignore()           //@ diag(`cannot be trapped`)
+	signal.Notify(c)          //@ diag(`cannot be trapped`)
+	signal.Reset()            //@ diag(`cannot be trapped`)
 }
 
 -- remove os.Kill from list of arguments --
@@ -31,13 +31,13 @@ import (
 func fn() {
 	c := make(chan os.Signal, 1)
 	signal.Notify(c, os.Interrupt)
-	signal.Ignore(os.Signal(syscall.SIGKILL)) // want `cannot be trapped`
-	signal.Ignore()                           // want `cannot be trapped`
-	signal.Notify(c)                          // want `cannot be trapped`
-	signal.Reset()                            // want `cannot be trapped`
-	signal.Ignore(syscall.SIGKILL)            // want `cannot be trapped`
-	signal.Notify(c, syscall.SIGKILL)         // want `cannot be trapped`
-	signal.Reset(syscall.SIGKILL)             // want `cannot be trapped`
+	signal.Ignore(os.Signal(syscall.SIGKILL)) //@ diag(`cannot be trapped`)
+	signal.Ignore()                           //@ diag(`cannot be trapped`)
+	signal.Notify(c)                          //@ diag(`cannot be trapped`)
+	signal.Reset()                            //@ diag(`cannot be trapped`)
+	signal.Ignore(syscall.SIGKILL)            //@ diag(`cannot be trapped`)
+	signal.Notify(c, syscall.SIGKILL)         //@ diag(`cannot be trapped`)
+	signal.Reset(syscall.SIGKILL)             //@ diag(`cannot be trapped`)
 }
 
 -- use syscall.SIGTERM instead of syscall.SIGKILL --
@@ -52,13 +52,13 @@ import (
 func fn() {
 	c := make(chan os.Signal, 1)
 	signal.Notify(c, os.Interrupt)
-	signal.Ignore(syscall.SIGTERM)    // want `cannot be trapped`
-	signal.Ignore(os.Kill)            // want `cannot be trapped`
-	signal.Notify(c, os.Kill)         // want `cannot be trapped`
-	signal.Reset(os.Kill)             // want `cannot be trapped`
-	signal.Ignore(syscall.SIGTERM)    // want `cannot be trapped`
-	signal.Notify(c, syscall.SIGTERM) // want `cannot be trapped`
-	signal.Reset(syscall.SIGTERM)     // want `cannot be trapped`
+	signal.Ignore(syscall.SIGTERM)    //@ diag(`cannot be trapped`)
+	signal.Ignore(os.Kill)            //@ diag(`cannot be trapped`)
+	signal.Notify(c, os.Kill)         //@ diag(`cannot be trapped`)
+	signal.Reset(os.Kill)             //@ diag(`cannot be trapped`)
+	signal.Ignore(syscall.SIGTERM)    //@ diag(`cannot be trapped`)
+	signal.Notify(c, syscall.SIGTERM) //@ diag(`cannot be trapped`)
+	signal.Reset(syscall.SIGTERM)     //@ diag(`cannot be trapped`)
 }
 
 -- use syscall.SIGTERM instead of os.Kill --
@@ -73,11 +73,11 @@ import (
 func fn() {
 	c := make(chan os.Signal, 1)
 	signal.Notify(c, os.Interrupt)
-	signal.Ignore(os.Signal(syscall.SIGKILL)) // want `cannot be trapped`
-	signal.Ignore(syscall.SIGTERM)            // want `cannot be trapped`
-	signal.Notify(c, syscall.SIGTERM)         // want `cannot be trapped`
-	signal.Reset(syscall.SIGTERM)             // want `cannot be trapped`
-	signal.Ignore(syscall.SIGKILL)            // want `cannot be trapped`
-	signal.Notify(c, syscall.SIGKILL)         // want `cannot be trapped`
-	signal.Reset(syscall.SIGKILL)             // want `cannot be trapped`
+	signal.Ignore(os.Signal(syscall.SIGKILL)) //@ diag(`cannot be trapped`)
+	signal.Ignore(syscall.SIGTERM)            //@ diag(`cannot be trapped`)
+	signal.Notify(c, syscall.SIGTERM)         //@ diag(`cannot be trapped`)
+	signal.Reset(syscall.SIGTERM)             //@ diag(`cannot be trapped`)
+	signal.Ignore(syscall.SIGKILL)            //@ diag(`cannot be trapped`)
+	signal.Notify(c, syscall.SIGKILL)         //@ diag(`cannot be trapped`)
+	signal.Reset(syscall.SIGKILL)             //@ diag(`cannot be trapped`)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckUntrappableSignal/CheckUntrappableSignal_unix.go 2022.1.3-1/staticcheck/testdata/src/CheckUntrappableSignal/CheckUntrappableSignal_unix.go
--- 2022.1-1/staticcheck/testdata/src/CheckUntrappableSignal/CheckUntrappableSignal_unix.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckUntrappableSignal/CheckUntrappableSignal_unix.go	2022-07-31 15:38:22.000000000 +0000
@@ -11,7 +11,7 @@ import (
 
 func fn2() {
 	c := make(chan os.Signal, 1)
-	signal.Ignore(syscall.SIGSTOP)    // want `cannot be trapped`
-	signal.Notify(c, syscall.SIGSTOP) // want `cannot be trapped`
-	signal.Reset(syscall.SIGSTOP)     // want `cannot be trapped`
+	signal.Ignore(syscall.SIGSTOP)    //@ diag(`cannot be trapped`)
+	signal.Notify(c, syscall.SIGSTOP) //@ diag(`cannot be trapped`)
+	signal.Reset(syscall.SIGSTOP)     //@ diag(`cannot be trapped`)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckUntrappableSignal/CheckUntrappableSignal_unix.go.golden 2022.1.3-1/staticcheck/testdata/src/CheckUntrappableSignal/CheckUntrappableSignal_unix.go.golden
--- 2022.1-1/staticcheck/testdata/src/CheckUntrappableSignal/CheckUntrappableSignal_unix.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckUntrappableSignal/CheckUntrappableSignal_unix.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -11,7 +11,7 @@ import (
 
 func fn2() {
 	c := make(chan os.Signal, 1)
-	signal.Ignore()  // want `cannot be trapped`
-	signal.Notify(c) // want `cannot be trapped`
-	signal.Reset()   // want `cannot be trapped`
+	signal.Ignore()  //@ diag(`cannot be trapped`)
+	signal.Notify(c) //@ diag(`cannot be trapped`)
+	signal.Reset()   //@ diag(`cannot be trapped`)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckURLs/CheckURLs.go 2022.1.3-1/staticcheck/testdata/src/CheckURLs/CheckURLs.go
--- 2022.1-1/staticcheck/testdata/src/CheckURLs/CheckURLs.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckURLs/CheckURLs.go	2022-07-31 15:38:22.000000000 +0000
@@ -4,6 +4,6 @@ import "net/url"
 
 func fn() {
 	url.Parse("foobar")
-	url.Parse(":") // want `is not a valid URL`
+	url.Parse(":") //@ diag(`is not a valid URL`)
 	url.Parse("https://golang.org")
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckWaitgroupAdd/CheckWaitgroupAdd.go 2022.1.3-1/staticcheck/testdata/src/CheckWaitgroupAdd/CheckWaitgroupAdd.go
--- 2022.1-1/staticcheck/testdata/src/CheckWaitgroupAdd/CheckWaitgroupAdd.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckWaitgroupAdd/CheckWaitgroupAdd.go	2022-07-31 15:38:22.000000000 +0000
@@ -12,7 +12,7 @@ func fn() {
 	}()
 
 	go func() {
-		wg.Add(1) // want `should call wg\.Add\(1\) before starting`
+		wg.Add(1) //@ diag(`should call wg.Add(1) before starting`)
 		wg.Done()
 	}()
 
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckWithValueKey/CheckWithValueKey.go 2022.1.3-1/staticcheck/testdata/src/CheckWithValueKey/CheckWithValueKey.go
--- 2022.1-1/staticcheck/testdata/src/CheckWithValueKey/CheckWithValueKey.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckWithValueKey/CheckWithValueKey.go	2022-07-31 15:38:22.000000000 +0000
@@ -14,20 +14,20 @@ type T3 struct {
 
 func fn(arg1 interface{}, arg2 string) {
 	var ctx context.Context
-	context.WithValue(ctx, "hi", nil) // want `should not use built-in type string`
+	context.WithValue(ctx, "hi", nil) //@ diag(`should not use built-in type string`)
 	context.WithValue(ctx, arg1, nil)
-	context.WithValue(ctx, arg2, nil) // want `should not use built-in type string`
+	context.WithValue(ctx, arg2, nil) //@ diag(`should not use built-in type string`)
 	v1 := interface{}("byte")
-	context.WithValue(ctx, v1, nil) // want `should not use built-in type string`
+	context.WithValue(ctx, v1, nil) //@ diag(`should not use built-in type string`)
 
 	var key T
 	context.WithValue(ctx, key, nil)
 	v2 := interface{}(key)
 	context.WithValue(ctx, v2, nil)
 	context.WithValue(ctx, T(""), nil)
-	context.WithValue(ctx, string(key), nil) // want `should not use built-in type string`
+	context.WithValue(ctx, string(key), nil) //@ diag(`should not use built-in type string`)
 
-	context.WithValue(ctx, []byte(nil), nil) // want `must be comparable`
+	context.WithValue(ctx, []byte(nil), nil) //@ diag(`must be comparable`)
 	context.WithValue(ctx, T2{}, nil)
-	context.WithValue(ctx, T3{}, nil) // want `must be comparable`
+	context.WithValue(ctx, T3{}, nil) //@ diag(`must be comparable`)
 }
diff -pruN 2022.1-1/staticcheck/testdata/src/CheckWriterBufferModified/CheckWriterBufferModified.go 2022.1.3-1/staticcheck/testdata/src/CheckWriterBufferModified/CheckWriterBufferModified.go
--- 2022.1-1/staticcheck/testdata/src/CheckWriterBufferModified/CheckWriterBufferModified.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/staticcheck/testdata/src/CheckWriterBufferModified/CheckWriterBufferModified.go	2022-07-31 15:38:22.000000000 +0000
@@ -6,13 +6,13 @@ type T3 struct{}
 type T4 struct{}
 
 func (T1) Write(b []byte) (int, error) {
-	b = append(b, '\n') // want `io\.Writer\.Write must not modify the provided buffer`
+	b = append(b, '\n') //@ diag(`io.Writer.Write must not modify the provided buffer`)
 	_ = b
 	return 0, nil
 }
 
 func (T2) Write(b []byte) (int, error) {
-	b[0] = 0 // want `io\.Writer\.Write must not modify the provided buffer`
+	b[0] = 0 //@ diag(`io.Writer.Write must not modify the provided buffer`)
 	return 0, nil
 }
 
diff -pruN 2022.1-1/stylecheck/analysis.go 2022.1.3-1/stylecheck/analysis.go
--- 2022.1-1/stylecheck/analysis.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/stylecheck/analysis.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,7 +1,8 @@
 package stylecheck
 
 import (
-	"honnef.co/go/tools/analysis/facts"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/facts/tokenfile"
 	"honnef.co/go/tools/analysis/lint"
 	"honnef.co/go/tools/config"
 	"honnef.co/go/tools/internal/passes/buildir"
@@ -17,11 +18,11 @@ var Analyzers = lint.InitializeAnalyzers
 	},
 	"ST1001": {
 		Run:      CheckDotImports,
-		Requires: []*analysis.Analyzer{facts.Generated, config.Analyzer},
+		Requires: []*analysis.Analyzer{generated.Analyzer, config.Analyzer},
 	},
 	"ST1003": {
 		Run:      CheckNames,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated, config.Analyzer},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer, config.Analyzer},
 	},
 	"ST1005": {
 		Run:      CheckErrorStrings,
@@ -29,7 +30,7 @@ var Analyzers = lint.InitializeAnalyzers
 	},
 	"ST1006": {
 		Run:      CheckReceiverNames,
-		Requires: []*analysis.Analyzer{buildir.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{buildir.Analyzer, generated.Analyzer},
 	},
 	"ST1008": {
 		Run:      CheckErrorReturn,
@@ -44,20 +45,20 @@ var Analyzers = lint.InitializeAnalyzers
 	},
 	"ST1013": {
 		Run: CheckHTTPStatusCodes,
-		// TODO(dh): why does this depend on facts.TokenFile?
-		Requires: []*analysis.Analyzer{facts.Generated, facts.TokenFile, config.Analyzer, inspect.Analyzer},
+		// TODO(dh): why does this depend on tokenfile.TokenFile?
+		Requires: []*analysis.Analyzer{generated.Analyzer, tokenfile.Analyzer, config.Analyzer, inspect.Analyzer},
 	},
 	"ST1015": {
 		Run:      CheckDefaultCaseOrder,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated, facts.TokenFile},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer, tokenfile.Analyzer},
 	},
 	"ST1016": {
 		Run:      CheckReceiverNamesIdentical,
-		Requires: []*analysis.Analyzer{buildir.Analyzer, facts.Generated},
+		Requires: []*analysis.Analyzer{buildir.Analyzer, generated.Analyzer},
 	},
 	"ST1017": {
 		Run:      CheckYodaConditions,
-		Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated, facts.TokenFile},
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer, tokenfile.Analyzer},
 	},
 	"ST1018": {
 		Run:      CheckInvisibleCharacters,
@@ -65,19 +66,19 @@ var Analyzers = lint.InitializeAnalyzers
 	},
 	"ST1019": {
 		Run:      CheckDuplicatedImports,
-		Requires: []*analysis.Analyzer{facts.Generated},
+		Requires: []*analysis.Analyzer{generated.Analyzer},
 	},
 	"ST1020": {
 		Run:      CheckExportedFunctionDocs,
-		Requires: []*analysis.Analyzer{facts.Generated, inspect.Analyzer},
+		Requires: []*analysis.Analyzer{generated.Analyzer, inspect.Analyzer},
 	},
 	"ST1021": {
 		Run:      CheckExportedTypeDocs,
-		Requires: []*analysis.Analyzer{facts.Generated, inspect.Analyzer},
+		Requires: []*analysis.Analyzer{generated.Analyzer, inspect.Analyzer},
 	},
 	"ST1022": {
 		Run:      CheckExportedVarDocs,
-		Requires: []*analysis.Analyzer{facts.Generated, inspect.Analyzer},
+		Requires: []*analysis.Analyzer{generated.Analyzer, inspect.Analyzer},
 	},
 	"ST1023": sharedcheck.RedundantTypeInDeclarationChecker("should", false),
 })
diff -pruN 2022.1-1/stylecheck/lint.go 2022.1.3-1/stylecheck/lint.go
--- 2022.1-1/stylecheck/lint.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/stylecheck/lint.go	2022-07-31 15:38:22.000000000 +0000
@@ -649,15 +649,48 @@ func CheckHTTPStatusCodes(pass *analysis
 }
 
 func CheckDefaultCaseOrder(pass *analysis.Pass) (interface{}, error) {
+	hasFallthrough := func(clause ast.Stmt) bool {
+		// A valid fallthrough statement may be used only as the final non-empty statement in a case clause. Thus we can
+		// easily avoid falsely matching fallthroughs in nested switches by not descending into blocks.
+
+		body := clause.(*ast.CaseClause).Body
+		for i := len(body) - 1; i >= 0; i-- {
+			last := body[i]
+			switch stmt := last.(type) {
+			case *ast.EmptyStmt:
+				// Fallthrough may be followed by empty statements
+			case *ast.BranchStmt:
+				return stmt.Tok == token.FALLTHROUGH
+			default:
+				return false
+			}
+		}
+
+		return false
+	}
+
 	fn := func(node ast.Node) {
 		stmt := node.(*ast.SwitchStmt)
 		list := stmt.Body.List
+		defaultIdx := -1
 		for i, c := range list {
-			if c.(*ast.CaseClause).List == nil && i != 0 && i != len(list)-1 {
-				report.Report(pass, c, "default case should be first or last in switch statement", report.FilterGenerated())
+			if c.(*ast.CaseClause).List == nil {
+				defaultIdx = i
 				break
 			}
 		}
+
+		if defaultIdx == -1 || defaultIdx == 0 || defaultIdx == len(list)-1 {
+			// No default case, or it's the first or last case
+			return
+		}
+
+		if hasFallthrough(list[defaultIdx-1]) || hasFallthrough(list[defaultIdx]) {
+			// We either fall into or out of this case; don't mess with the order
+			return
+		}
+
+		report.Report(pass, list[defaultIdx], "default case should be first or last in switch statement", report.FilterGenerated())
 	}
 	code.Preorder(pass, fn, (*ast.SwitchStmt)(nil))
 	return nil, nil
@@ -876,6 +909,11 @@ func CheckExportedTypeDocs(pass *analysi
 				}
 			}
 
+			// Check comment before we strip articles in case the type's name is an article.
+			if strings.HasPrefix(text, node.Name.Name+" ") {
+				return false
+			}
+
 			s := text
 			articles := [...]string{"A", "An", "The"}
 			for _, a := range articles {
diff -pruN 2022.1-1/stylecheck/testdata/src/_CheckBlankImports.disabled/CheckBlankImports-2.go 2022.1.3-1/stylecheck/testdata/src/_CheckBlankImports.disabled/CheckBlankImports-2.go
--- 2022.1-1/stylecheck/testdata/src/_CheckBlankImports.disabled/CheckBlankImports-2.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/stylecheck/testdata/src/_CheckBlankImports.disabled/CheckBlankImports-2.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,15 +1,15 @@
 // Package pkg ...
 package pkg
 
-import _ "fmt" // want `blank import`
+import _ "fmt" //@ diag(`blank import`)
 
-import _ "fmt" // want `blank import`
+import _ "fmt" //@ diag(`blank import`)
 import _ "fmt"
 import _ "fmt"
 
-import _ "fmt" // want `blank import`
+import _ "fmt" //@ diag(`blank import`)
 import "strings"
-import _ "fmt" // want `blank import`
+import _ "fmt" //@ diag(`blank import`)
 
 // This is fine
 import _ "fmt"
@@ -22,17 +22,17 @@ import _ "fmt"
 // This is fine
 import _ "fmt"
 import "bytes"
-import _ "fmt" // want `blank import`
+import _ "fmt" //@ diag(`blank import`)
 
 import _ "fmt" // This is fine
 
 // This is not fine
 import (
-	_ "fmt" // want `blank import`
+	_ "fmt" //@ diag(`blank import`)
 )
 
 import (
-	_ "fmt" // want `blank import`
+	_ "fmt" //@ diag(`blank import`)
 	"strconv"
 	// This is fine
 	_ "fmt"
diff -pruN 2022.1-1/stylecheck/testdata/src/CheckContextFirstArg.disabled/CheckContextFirstArg.go 2022.1.3-1/stylecheck/testdata/src/CheckContextFirstArg.disabled/CheckContextFirstArg.go
--- 2022.1-1/stylecheck/testdata/src/CheckContextFirstArg.disabled/CheckContextFirstArg.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/stylecheck/testdata/src/CheckContextFirstArg.disabled/CheckContextFirstArg.go	2022-07-31 15:38:22.000000000 +0000
@@ -8,5 +8,5 @@ type T int
 func fn1(int)                                   {}
 func fn2(context.Context, int)                  {}
 func fn3(context.Context, int, context.Context) {}
-func fn4(int, context.Context)                  {} // want `context\.Context should be the first argument of a function`
-func (T) FN(int, context.Context)               {} // want `context\.Context should be the first argument of a function`
+func fn4(int, context.Context)                  {} //@ diag(`context\.Context should be the first argument of a function`)
+func (T) FN(int, context.Context)               {} //@ diag(`context\.Context should be the first argument of a function`)
diff -pruN 2022.1-1/stylecheck/testdata/src/CheckDefaultCaseOrder/CheckDefaultCaseOrder.go 2022.1.3-1/stylecheck/testdata/src/CheckDefaultCaseOrder/CheckDefaultCaseOrder.go
--- 2022.1-1/stylecheck/testdata/src/CheckDefaultCaseOrder/CheckDefaultCaseOrder.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/stylecheck/testdata/src/CheckDefaultCaseOrder/CheckDefaultCaseOrder.go	2022-07-31 15:38:22.000000000 +0000
@@ -30,7 +30,55 @@ func fn(x int) {
 
 	switch x {
 	case 1:
-	default: // want `default case should be first or last in switch statement`
+	default: //@ diag(`default case should be first or last in switch statement`)
 	case 2:
 	}
+
+	// Don't flag either of these two; fallthrough is sensitive to the order of cases
+	switch x {
+	case 1:
+		fallthrough
+	default:
+	case 2:
+	}
+	switch x {
+	case 1:
+	default:
+		fallthrough
+	case 2:
+	}
+
+	// Do flag these branches; don't get confused by the nested switch statements
+	switch x {
+	case 1:
+		func() {
+			switch x {
+			case 1:
+				fallthrough
+			case 2:
+			}
+		}()
+	default: //@ diag(`default case should be first or last in switch statement`)
+	case 3:
+	}
+
+	switch x {
+	case 1:
+		switch x {
+		case 1:
+			fallthrough
+		case 2:
+		}
+	default: //@ diag(`default case should be first or last in switch statement`)
+	case 3:
+	}
+
+	// Fallthrough may be followed by empty statements
+	switch x {
+	case 1:
+		fallthrough
+		;
+	default:
+	case 3:
+	}
 }
diff -pruN 2022.1-1/stylecheck/testdata/src/CheckDotImports/CheckDotImports.go 2022.1.3-1/stylecheck/testdata/src/CheckDotImports/CheckDotImports.go
--- 2022.1-1/stylecheck/testdata/src/CheckDotImports/CheckDotImports.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/stylecheck/testdata/src/CheckDotImports/CheckDotImports.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,6 +1,6 @@
 // Package pkg ...
 package pkg
 
-import . "fmt" // want `should not use dot imports`
+import . "fmt" //@ diag(`should not use dot imports`)
 
 var _ = Println
diff -pruN 2022.1-1/stylecheck/testdata/src/CheckDuplicatedImports/CheckDuplicatedImports.go 2022.1.3-1/stylecheck/testdata/src/CheckDuplicatedImports/CheckDuplicatedImports.go
--- 2022.1-1/stylecheck/testdata/src/CheckDuplicatedImports/CheckDuplicatedImports.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/stylecheck/testdata/src/CheckDuplicatedImports/CheckDuplicatedImports.go	2022-07-31 15:38:22.000000000 +0000
@@ -2,13 +2,13 @@
 package pkg
 
 import (
-	"fmt" // want `package "fmt" is being imported more than once`
+	"fmt" //@ diag(`package "fmt" is being imported more than once`)
 	fmt1 "fmt"
 	fmt2 "fmt"
 
 	fine "net/http"
 
-	"os" // want `package "os" is being imported more than once`
+	"os" //@ diag(`package "os" is being imported more than once`)
 	os1 "os"
 
 	"C"
diff -pruN 2022.1-1/stylecheck/testdata/src/CheckErrorReturn/CheckErrorReturn.go 2022.1.3-1/stylecheck/testdata/src/CheckErrorReturn/CheckErrorReturn.go
--- 2022.1-1/stylecheck/testdata/src/CheckErrorReturn/CheckErrorReturn.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/stylecheck/testdata/src/CheckErrorReturn/CheckErrorReturn.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,8 +1,8 @@
 // Package pkg ...
 package pkg
 
-func fn1() (error, int)        { return nil, 0 }      // want `error should be returned as the last argument`
-func fn2() (a, b error, c int) { return nil, nil, 0 } // want `error should be returned as the last argument`
+func fn1() (error, int)        { return nil, 0 }      //@ diag(`error should be returned as the last argument`)
+func fn2() (a, b error, c int) { return nil, nil, 0 } //@ diag(`error should be returned as the last argument`)
 func fn3() (a int, b, c error) { return 0, nil, nil }
 func fn4() (error, error)      { return nil, nil }
 func fn5() int                 { return 0 }
diff -pruN 2022.1-1/stylecheck/testdata/src/CheckErrorStrings/CheckErrorStrings.go 2022.1.3-1/stylecheck/testdata/src/CheckErrorStrings/CheckErrorStrings.go
--- 2022.1-1/stylecheck/testdata/src/CheckErrorStrings/CheckErrorStrings.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/stylecheck/testdata/src/CheckErrorStrings/CheckErrorStrings.go	2022-07-31 15:38:22.000000000 +0000
@@ -5,11 +5,11 @@ import "errors"
 
 func fn() {
 	errors.New("a perfectly fine error")
-	errors.New("Not a great error")       // want `error strings should not be capitalized`
-	errors.New("also not a great error.") // want `error strings should not end with punctuation or newlines`
+	errors.New("Not a great error")       //@ diag(`error strings should not be capitalized`)
+	errors.New("also not a great error.") //@ diag(`error strings should not end with punctuation or newlines`)
 	errors.New("URL is okay")
 	errors.New("SomeFunc is okay")
-	errors.New("URL is okay, but the period is not.") // want `error strings should not end with punctuation or newlines`
+	errors.New("URL is okay, but the period is not.") //@ diag(`error strings should not end with punctuation or newlines`)
 	errors.New("T must not be nil")
 	errors.New("Foo() failed")
 	errors.New("Foo(bar) failed")
diff -pruN 2022.1-1/stylecheck/testdata/src/CheckErrorVarNames/CheckErrorVarNames.go 2022.1.3-1/stylecheck/testdata/src/CheckErrorVarNames/CheckErrorVarNames.go
--- 2022.1-1/stylecheck/testdata/src/CheckErrorVarNames/CheckErrorVarNames.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/stylecheck/testdata/src/CheckErrorVarNames/CheckErrorVarNames.go	2022-07-31 15:38:22.000000000 +0000
@@ -7,15 +7,15 @@ import (
 )
 
 var (
-	foo                   = errors.New("") // want `error var foo should have name of the form errFoo`
+	foo                   = errors.New("") //@ diag(`error var foo should have name of the form errFoo`)
 	errBar                = errors.New("")
-	qux, fisk, errAnother = errors.New(""), errors.New(""), errors.New("") // want `error var qux should have name of the form errFoo` `error var fisk should have name of the form errFoo`
-	abc                   = fmt.Errorf("")                                 // want `error var abc should have name of the form errFoo`
+	qux, fisk, errAnother = errors.New(""), errors.New(""), errors.New("") //@ diag(`error var qux should have name of the form errFoo`), diag(`error var fisk should have name of the form errFoo`)
+	abc                   = fmt.Errorf("")                                 //@ diag(`error var abc should have name of the form errFoo`)
 
 	errAbc = fmt.Errorf("")
 )
 
-var wrong = errors.New("") // want `error var wrong should have name of the form errFoo`
+var wrong = errors.New("") //@ diag(`error var wrong should have name of the form errFoo`)
 
 var result = fn()
 
diff -pruN 2022.1-1/stylecheck/testdata/src/CheckExportedFunctionDocs/CheckExportedFunctionDocs.go 2022.1.3-1/stylecheck/testdata/src/CheckExportedFunctionDocs/CheckExportedFunctionDocs.go
--- 2022.1-1/stylecheck/testdata/src/CheckExportedFunctionDocs/CheckExportedFunctionDocs.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/stylecheck/testdata/src/CheckExportedFunctionDocs/CheckExportedFunctionDocs.go	2022-07-31 15:38:22.000000000 +0000
@@ -6,7 +6,7 @@ func foo() {}
 // Foo is amazing
 func Foo() {}
 
-// Whatever // want `comment on exported function`
+// Whatever //@ diag(`comment on exported function`)
 func Bar() {}
 
 type T struct{}
@@ -17,7 +17,7 @@ func (T) foo() {}
 // Foo is amazing
 func (T) Foo() {}
 
-// Whatever // want `comment on exported method`
+// Whatever //@ diag(`comment on exported method`)
 func (T) Bar() {}
 
 //
@@ -38,6 +38,6 @@ func F1() {} // we pretend that directiv
 // F2 is amazing
 func F2() {}
 
-//some:directive // want `comment on exported function`
+//some:directive //@ diag(`comment on exported function`)
 // Whatever
 func F3() {}
diff -pruN 2022.1-1/stylecheck/testdata/src/CheckExportedFunctionDocs/generics.go 2022.1.3-1/stylecheck/testdata/src/CheckExportedFunctionDocs/generics.go
--- 2022.1-1/stylecheck/testdata/src/CheckExportedFunctionDocs/generics.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/stylecheck/testdata/src/CheckExportedFunctionDocs/generics.go	2022-07-31 15:38:22.000000000 +0000
@@ -2,10 +2,10 @@
 
 package pkg
 
-// Whatever // want `comment on exported function`
+// Whatever //@ diag(`comment on exported function`)
 func TPFoo[T any]() {}
 
-// Whatever // want `comment on exported function`
+// Whatever //@ diag(`comment on exported function`)
 func TPBar[T1, T2 any]() {}
 
 // TPBaz is amazing
@@ -16,7 +16,7 @@ type TPT[T any] struct{}
 // Foo is amazing
 func (TPT[T]) Foo() {}
 
-// Whatever // want `comment on exported method`
+// Whatever //@ diag(`comment on exported method`)
 func (TPT[T]) Bar() {}
 
 type TPT2[T1, T2 any] struct{}
@@ -24,5 +24,5 @@ type TPT2[T1, T2 any] struct{}
 // Foo is amazing
 func (TPT2[T1, T2]) Foo() {}
 
-// Whatever // want `comment on exported method`
+// Whatever //@ diag(`comment on exported method`)
 func (*TPT2[T1, T2]) Bar() {}
diff -pruN 2022.1-1/stylecheck/testdata/src/CheckExportedTypeDocs/CheckExportedTypeDocs.go 2022.1.3-1/stylecheck/testdata/src/CheckExportedTypeDocs/CheckExportedTypeDocs.go
--- 2022.1-1/stylecheck/testdata/src/CheckExportedTypeDocs/CheckExportedTypeDocs.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/stylecheck/testdata/src/CheckExportedTypeDocs/CheckExportedTypeDocs.go	2022-07-31 15:38:22.000000000 +0000
@@ -3,14 +3,14 @@ package pkg
 // Some type
 type t1 struct{}
 
-// Some type // want `comment on exported type`
+// Some type //@ diag(`comment on exported type`)
 type T2 struct{}
 
 // T3 is amazing
 type T3 struct{}
 
 type (
-	// Some type // want `comment on exported type`
+	// Some type //@ diag(`comment on exported type`)
 	T4 struct{}
 	// The T5 type is amazing
 	T5 struct{}
@@ -52,6 +52,9 @@ type T12 struct{} // we pretend that dir
 // T13 is amazing
 type T13 struct{}
 
-//some:directive // want `comment on exported type`
+//some:directive //@ diag(`comment on exported type`)
 // Whatever
 type T14 struct{}
+
+// A does stuff.
+type A struct{}
diff -pruN 2022.1-1/stylecheck/testdata/src/CheckExportedVarDocs/CheckExportedVarDocs.go 2022.1.3-1/stylecheck/testdata/src/CheckExportedVarDocs/CheckExportedVarDocs.go
--- 2022.1-1/stylecheck/testdata/src/CheckExportedVarDocs/CheckExportedVarDocs.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/stylecheck/testdata/src/CheckExportedVarDocs/CheckExportedVarDocs.go	2022-07-31 15:38:22.000000000 +0000
@@ -3,7 +3,7 @@ package pkg
 // Whatever
 var a int
 
-// Whatever // want `should be of the form`
+// Whatever //@ diag(`should be of the form`)
 var B int
 
 // Whatever
@@ -36,6 +36,6 @@ var G int // we pretend that directives
 // H is amazing
 var H int
 
-//some:directive // want `should be of the form`
+//some:directive //@ diag(`should be of the form`)
 // Whatever
 var I int
diff -pruN 2022.1-1/stylecheck/testdata/src/CheckHTTPStatusCodes/CheckHTTPStatusCodes.go 2022.1.3-1/stylecheck/testdata/src/CheckHTTPStatusCodes/CheckHTTPStatusCodes.go
--- 2022.1-1/stylecheck/testdata/src/CheckHTTPStatusCodes/CheckHTTPStatusCodes.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/stylecheck/testdata/src/CheckHTTPStatusCodes/CheckHTTPStatusCodes.go	2022-07-31 15:38:22.000000000 +0000
@@ -5,10 +5,10 @@ import "net/http"
 
 func fn() {
 	// Check all the supported functions
-	http.Error(nil, "", 506)         // want `http\.StatusVariantAlsoNegotiates`
-	http.Redirect(nil, nil, "", 506) // want `http\.StatusVariantAlsoNegotiates`
-	http.StatusText(506)             // want `http\.StatusVariantAlsoNegotiates`
-	http.RedirectHandler("", 506)    // want `http\.StatusVariantAlsoNegotiates`
+	http.Error(nil, "", 506)         //@ diag(`http.StatusVariantAlsoNegotiates`)
+	http.Redirect(nil, nil, "", 506) //@ diag(`http.StatusVariantAlsoNegotiates`)
+	http.StatusText(506)             //@ diag(`http.StatusVariantAlsoNegotiates`)
+	http.RedirectHandler("", 506)    //@ diag(`http.StatusVariantAlsoNegotiates`)
 
 	// Don't flag literals with no known constant
 	http.StatusText(600)
diff -pruN 2022.1-1/stylecheck/testdata/src/CheckHTTPStatusCodes/CheckHTTPStatusCodes.go.golden 2022.1.3-1/stylecheck/testdata/src/CheckHTTPStatusCodes/CheckHTTPStatusCodes.go.golden
--- 2022.1-1/stylecheck/testdata/src/CheckHTTPStatusCodes/CheckHTTPStatusCodes.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/stylecheck/testdata/src/CheckHTTPStatusCodes/CheckHTTPStatusCodes.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -5,10 +5,10 @@ import "net/http"
 
 func fn() {
 	// Check all the supported functions
-	http.Error(nil, "", http.StatusVariantAlsoNegotiates)         // want `http\.StatusVariantAlsoNegotiates`
-	http.Redirect(nil, nil, "", http.StatusVariantAlsoNegotiates) // want `http\.StatusVariantAlsoNegotiates`
-	http.StatusText(http.StatusVariantAlsoNegotiates)             // want `http\.StatusVariantAlsoNegotiates`
-	http.RedirectHandler("", http.StatusVariantAlsoNegotiates)    // want `http\.StatusVariantAlsoNegotiates`
+	http.Error(nil, "", http.StatusVariantAlsoNegotiates)         //@ diag(`http.StatusVariantAlsoNegotiates`)
+	http.Redirect(nil, nil, "", http.StatusVariantAlsoNegotiates) //@ diag(`http.StatusVariantAlsoNegotiates`)
+	http.StatusText(http.StatusVariantAlsoNegotiates)             //@ diag(`http.StatusVariantAlsoNegotiates`)
+	http.RedirectHandler("", http.StatusVariantAlsoNegotiates)    //@ diag(`http.StatusVariantAlsoNegotiates`)
 
 	// Don't flag literals with no known constant
 	http.StatusText(600)
diff -pruN 2022.1-1/stylecheck/testdata/src/CheckIncDec.disabled/CheckIncDec.go 2022.1.3-1/stylecheck/testdata/src/CheckIncDec.disabled/CheckIncDec.go
--- 2022.1-1/stylecheck/testdata/src/CheckIncDec.disabled/CheckIncDec.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/stylecheck/testdata/src/CheckIncDec.disabled/CheckIncDec.go	2022-07-31 15:38:22.000000000 +0000
@@ -5,8 +5,8 @@ func fn() {
 	var x int
 	x--
 	x++
-	x += 1 // want `should replace x \+= 1 with x\+\+`
-	x -= 1 // want `should replace x -= 1 with x--`
+	x += 1 //@ diag(`should replace x \+= 1 with x\+\+`)
+	x -= 1 //@ diag(`should replace x -= 1 with x--`)
 	x /= 1
 	x += 2
 	x -= 2
diff -pruN 2022.1-1/stylecheck/testdata/src/CheckInvisibleCharacters/CheckInvisibleCharacters.go 2022.1.3-1/stylecheck/testdata/src/CheckInvisibleCharacters/CheckInvisibleCharacters.go
--- 2022.1-1/stylecheck/testdata/src/CheckInvisibleCharacters/CheckInvisibleCharacters.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/stylecheck/testdata/src/CheckInvisibleCharacters/CheckInvisibleCharacters.go	2022-07-31 15:38:22.000000000 +0000
@@ -2,13 +2,13 @@
 package pkg
 
 var (
-	a = ""  // want `Unicode control character U\+0007`
-	b = "" // want `Unicode control characters`
+	a = ""  //@ diag(`Unicode control character U+0007`)
+	b = "" //@ diag(`Unicode control characters`)
 	c = "Test	test"
 	d = `T
 est`
-	e = `Zero​Width` // want `Unicode format character U\+200B`
+	e = `Zero​Width` //@ diag(`Unicode format character U+200B`)
 	f = "\u200b"
-	g = "👩🏽‍🔬" //  want `Unicode control character U\+0007`
-	h = "👩🏽‍🔬​" // want `Unicode format and control characters`
+	g = "👩🏽‍🔬" //@ diag(`Unicode control character U+0007`)
+	h = "👩🏽‍🔬​" //@ diag(`Unicode format and control characters`)
 )
diff -pruN 2022.1-1/stylecheck/testdata/src/CheckInvisibleCharacters/CheckInvisibleCharacters.go.golden 2022.1.3-1/stylecheck/testdata/src/CheckInvisibleCharacters/CheckInvisibleCharacters.go.golden
--- 2022.1-1/stylecheck/testdata/src/CheckInvisibleCharacters/CheckInvisibleCharacters.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/stylecheck/testdata/src/CheckInvisibleCharacters/CheckInvisibleCharacters.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -3,15 +3,15 @@
 package pkg
 
 var (
-	a = "\a" // want `Unicode control character U\+0007`
-	b = "" // want `Unicode control characters`
+	a = "\a" //@ diag(`Unicode control character U+0007`)
+	b = "" //@ diag(`Unicode control characters`)
 	c = "Test	test"
 	d = `T
 est`
-	e = `Zero​Width` // want `Unicode format character U\+200B`
+	e = `Zero​Width` //@ diag(`Unicode format character U+200B`)
 	f = "\u200b"
-	g = "👩🏽‍🔬\a" //  want `Unicode control character U\+0007`
-	h = "👩🏽‍🔬​" // want `Unicode format and control characters`
+	g = "👩🏽‍🔬\a" //@ diag(`Unicode control character U+0007`)
+	h = "👩🏽‍🔬​" //@ diag(`Unicode format and control characters`)
 )
 
 -- delete control character U+0007 --
@@ -19,15 +19,15 @@ est`
 package pkg
 
 var (
-	a = ""   // want `Unicode control character U\+0007`
-	b = "" // want `Unicode control characters`
+	a = ""   //@ diag(`Unicode control character U+0007`)
+	b = "" //@ diag(`Unicode control characters`)
 	c = "Test	test"
 	d = `T
 est`
-	e = `Zero​Width` // want `Unicode format character U\+200B`
+	e = `Zero​Width` //@ diag(`Unicode format character U+200B`)
 	f = "\u200b"
-	g = "👩🏽‍🔬"   //  want `Unicode control character U\+0007`
-	h = "👩🏽‍🔬​" // want `Unicode format and control characters`
+	g = "👩🏽‍🔬"   //@ diag(`Unicode control character U+0007`)
+	h = "👩🏽‍🔬​" //@ diag(`Unicode format and control characters`)
 )
 
 -- delete format character U+200B --
@@ -35,15 +35,15 @@ est`
 package pkg
 
 var (
-	a = ""  // want `Unicode control character U\+0007`
-	b = "" // want `Unicode control characters`
+	a = ""  //@ diag(`Unicode control character U+0007`)
+	b = "" //@ diag(`Unicode control characters`)
 	c = "Test	test"
 	d = `T
 est`
-	e = `ZeroWidth` // want `Unicode format character U\+200B`
+	e = `ZeroWidth` //@ diag(`Unicode format character U+200B`)
 	f = "\u200b"
-	g = "👩🏽‍🔬"  //  want `Unicode control character U\+0007`
-	h = "👩🏽‍🔬​" // want `Unicode format and control characters`
+	g = "👩🏽‍🔬"  //@ diag(`Unicode control character U+0007`)
+	h = "👩🏽‍🔬​" //@ diag(`Unicode format and control characters`)
 )
 
 -- replace format character U+200B with '\u200b' --
@@ -51,15 +51,15 @@ est`
 package pkg
 
 var (
-	a = ""  // want `Unicode control character U\+0007`
-	b = "" // want `Unicode control characters`
+	a = ""  //@ diag(`Unicode control character U+0007`)
+	b = "" //@ diag(`Unicode control characters`)
 	c = "Test	test"
 	d = `T
 est`
-	e = `Zero\u200bWidth` // want `Unicode format character U\+200B`
+	e = `Zero\u200bWidth` //@ diag(`Unicode format character U+200B`)
 	f = "\u200b"
-	g = "👩🏽‍🔬"  //  want `Unicode control character U\+0007`
-	h = "👩🏽‍🔬​" // want `Unicode format and control characters`
+	g = "👩🏽‍🔬"  //@ diag(`Unicode control character U+0007`)
+	h = "👩🏽‍🔬​" //@ diag(`Unicode format and control characters`)
 )
 
 -- delete all control characters --
@@ -67,15 +67,15 @@ est`
 package pkg
 
 var (
-	a = "" // want `Unicode control character U\+0007`
-	b = ""  // want `Unicode control characters`
+	a = "" //@ diag(`Unicode control character U+0007`)
+	b = ""  //@ diag(`Unicode control characters`)
 	c = "Test	test"
 	d = `T
 est`
-	e = `Zero​Width` // want `Unicode format character U\+200B`
+	e = `Zero​Width` //@ diag(`Unicode format character U+200B`)
 	f = "\u200b"
-	g = "👩🏽‍🔬"  //  want `Unicode control character U\+0007`
-	h = "👩🏽‍🔬​" // want `Unicode format and control characters`
+	g = "👩🏽‍🔬"  //@ diag(`Unicode control character U+0007`)
+	h = "👩🏽‍🔬​" //@ diag(`Unicode format and control characters`)
 )
 
 -- replace all control characters with escape sequences --
@@ -83,15 +83,15 @@ est`
 package pkg
 
 var (
-	a = ""      // want `Unicode control character U\+0007`
-	b = "\a\x1a" // want `Unicode control characters`
+	a = ""      //@ diag(`Unicode control character U+0007`)
+	b = "\a\x1a" //@ diag(`Unicode control characters`)
 	c = "Test	test"
 	d = `T
 est`
-	e = `Zero​Width` // want `Unicode format character U\+200B`
+	e = `Zero​Width` //@ diag(`Unicode format character U+200B`)
 	f = "\u200b"
-	g = "👩🏽‍🔬"  //  want `Unicode control character U\+0007`
-	h = "👩🏽‍🔬​" // want `Unicode format and control characters`
+	g = "👩🏽‍🔬"  //@ diag(`Unicode control character U+0007`)
+	h = "👩🏽‍🔬​" //@ diag(`Unicode format and control characters`)
 )
 
 
@@ -100,15 +100,15 @@ est`
 package pkg
 
 var (
-	a = ""  // want `Unicode control character U\+0007`
-	b = "" // want `Unicode control characters`
+	a = ""  //@ diag(`Unicode control character U+0007`)
+	b = "" //@ diag(`Unicode control characters`)
 	c = "Test	test"
 	d = `T
 est`
-	e = `Zero​Width` // want `Unicode format character U\+200B`
+	e = `Zero​Width` //@ diag(`Unicode format character U+200B`)
 	f = "\u200b"
-	g = "👩🏽‍🔬" //  want `Unicode control character U\+0007`
-	h = "👩🏽‍🔬"  // want `Unicode format and control characters`
+	g = "👩🏽‍🔬" //@ diag(`Unicode control character U+0007`)
+	h = "👩🏽‍🔬"  //@ diag(`Unicode format and control characters`)
 )
 
 -- replace all format and control characters with escape sequences --
@@ -116,13 +116,13 @@ est`
 package pkg
 
 var (
-	a = ""  // want `Unicode control character U\+0007`
-	b = "" // want `Unicode control characters`
+	a = ""  //@ diag(`Unicode control character U+0007`)
+	b = "" //@ diag(`Unicode control characters`)
 	c = "Test	test"
 	d = `T
 est`
-	e = `Zero​Width` // want `Unicode format character U\+200B`
+	e = `Zero​Width` //@ diag(`Unicode format character U+200B`)
 	f = "\u200b"
-	g = "👩🏽‍🔬"        //  want `Unicode control character U\+0007`
-	h = "👩🏽‍🔬\a\u200b" // want `Unicode format and control characters`
+	g = "👩🏽‍🔬"        //@ diag(`Unicode control character U+0007`)
+	h = "👩🏽‍🔬\a\u200b" //@ diag(`Unicode format and control characters`)
 )
diff -pruN 2022.1-1/stylecheck/testdata/src/CheckNames/CheckNames.go 2022.1.3-1/stylecheck/testdata/src/CheckNames/CheckNames.go
--- 2022.1-1/stylecheck/testdata/src/CheckNames/CheckNames.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/stylecheck/testdata/src/CheckNames/CheckNames.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,31 +1,31 @@
 // Package pkg_foo ...
-package pkg_foo // want `should not use underscores in package names`
+package pkg_foo //@ diag(`should not use underscores in package names`)
 
 var range_ int
 var _abcdef int
 var abcdef_ int
-var abc_def int  // want `should not use underscores in Go names; var abc_def should be abcDef`
-var abc_def_ int // want `should not use underscores in Go names; var abc_def_ should be abcDef_`
+var abc_def int  //@ diag(`should not use underscores in Go names; var abc_def should be abcDef`)
+var abc_def_ int //@ diag(`should not use underscores in Go names; var abc_def_ should be abcDef_`)
 
-func fn_1()  {} // want `func fn_1 should be fn1`
+func fn_1()  {} //@ diag(`func fn_1 should be fn1`)
 func fn2()   {}
-func fn_Id() {} // want `func fn_Id should be fnID`
-func fnId()  {} // want `func fnId should be fnID`
+func fn_Id() {} //@ diag(`func fn_Id should be fnID`)
+func fnId()  {} //@ diag(`func fnId should be fnID`)
 
-var FOO_BAR int // want `should not use ALL_CAPS in Go names; use CamelCase instead`
-var Foo_BAR int // want `var Foo_BAR should be FooBAR`
-var foo_bar int // want `foo_bar should be fooBar`
+var FOO_BAR int //@ diag(`should not use ALL_CAPS in Go names; use CamelCase instead`)
+var Foo_BAR int //@ diag(`var Foo_BAR should be FooBAR`)
+var foo_bar int //@ diag(`foo_bar should be fooBar`)
 var kFoobar int // not a check we inherited from golint. more false positives than true ones.
 
 var _1000 int // issue 858
 
 func fn(x []int) {
 	var (
-		a_b = 1 // want `var a_b should be aB`
-		c_d int // want `var c_d should be cD`
+		a_b = 1 //@ diag(`var a_b should be aB`)
+		c_d int //@ diag(`var c_d should be cD`)
 	)
 	a_b += 2
-	for e_f := range x { // want `range var e_f should be eF`
+	for e_f := range x { //@ diag(`range var e_f should be eF`)
 		_ = e_f
 	}
 
@@ -37,16 +37,16 @@ func fn(x []int) {
 func fn_3() {}
 
 //export not actually the export keyword
-func fn_4() {} // want `func fn_4 should be fn4`
+func fn_4() {} //@ diag(`func fn_4 should be fn4`)
 
 //export
-func fn_5() {} // want `func fn_5 should be fn5`
+func fn_5() {} //@ diag(`func fn_5 should be fn5`)
 
 // export fn_6
-func fn_6() {} // want `func fn_6 should be fn6`
+func fn_6() {} //@ diag(`func fn_6 should be fn6`)
 
 //export fn_8
-func fn_7() {} // want `func fn_7 should be fn7`
+func fn_7() {} //@ diag(`func fn_7 should be fn7`)
 
 //go:linkname fn_8 time.Now
 func fn_8() {}
diff -pruN 2022.1-1/stylecheck/testdata/src/CheckPackageComment-1/CheckPackageComment-1.go 2022.1.3-1/stylecheck/testdata/src/CheckPackageComment-1/CheckPackageComment-1.go
--- 2022.1-1/stylecheck/testdata/src/CheckPackageComment-1/CheckPackageComment-1.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/stylecheck/testdata/src/CheckPackageComment-1/CheckPackageComment-1.go	2022-07-31 15:38:22.000000000 +0000
@@ -1 +1 @@
-package pkg // want `at least one file in a package should have a package comment`
+package pkg //@ diag(`at least one file in a package should have a package comment`)
diff -pruN 2022.1-1/stylecheck/testdata/src/CheckPackageComment-2/CheckPackageComment-2.go 2022.1.3-1/stylecheck/testdata/src/CheckPackageComment-2/CheckPackageComment-2.go
--- 2022.1-1/stylecheck/testdata/src/CheckPackageComment-2/CheckPackageComment-2.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/stylecheck/testdata/src/CheckPackageComment-2/CheckPackageComment-2.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,2 +1,2 @@
-// This package is great // want `package comment should be of the form`
+// This package is great //@ diag(`package comment should be of the form`)
 package pkg
diff -pruN 2022.1-1/stylecheck/testdata/src/CheckReceiverNames/CheckReceiverNames.go 2022.1.3-1/stylecheck/testdata/src/CheckReceiverNames/CheckReceiverNames.go
--- 2022.1-1/stylecheck/testdata/src/CheckReceiverNames/CheckReceiverNames.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/stylecheck/testdata/src/CheckReceiverNames/CheckReceiverNames.go	2022-07-31 15:38:22.000000000 +0000
@@ -7,5 +7,5 @@ func (x T1) Fn1()    {}
 func (y T1) Fn2()    {}
 func (x T1) Fn3()    {}
 func (T1) Fn4()      {}
-func (_ T1) Fn5()    {} // want `receiver name should not be an underscore, omit the name if it is unused`
-func (self T1) Fn6() {} // want `receiver name should be a reflection of its identity`
+func (_ T1) Fn5()    {} //@ diag(`receiver name should not be an underscore, omit the name if it is unused`)
+func (self T1) Fn6() {} //@ diag(`receiver name should be a reflection of its identity`)
diff -pruN 2022.1-1/stylecheck/testdata/src/CheckReceiverNamesIdentical/CheckReceiverNames.go 2022.1.3-1/stylecheck/testdata/src/CheckReceiverNamesIdentical/CheckReceiverNames.go
--- 2022.1-1/stylecheck/testdata/src/CheckReceiverNamesIdentical/CheckReceiverNames.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/stylecheck/testdata/src/CheckReceiverNamesIdentical/CheckReceiverNames.go	2022-07-31 15:38:22.000000000 +0000
@@ -3,14 +3,14 @@ package pkg
 
 type T1 int
 
-func (x T1) Fn1()    {} // want `methods on the same type should have the same receiver name`
+func (x T1) Fn1()    {} //@ diag(`methods on the same type should have the same receiver name`)
 func (y T1) Fn2()    {}
 func (x T1) Fn3()    {}
 func (T1) Fn4()      {}
 func (_ T1) Fn5()    {}
 func (self T1) Fn6() {}
 
-func (bar T3) Fn2()  {} // want `1x "bar", 1x "meow"`
+func (bar T3) Fn2()  {} //@ diag(`1x "bar", 1x "meow"`)
 func (meow T3) Fn3() {}
 
 func (bar T4) Fn2() {}
diff -pruN 2022.1-1/stylecheck/testdata/src/CheckRedundantTypeInDeclaration/CheckRedundantTypeInDeclaration.go 2022.1.3-1/stylecheck/testdata/src/CheckRedundantTypeInDeclaration/CheckRedundantTypeInDeclaration.go
--- 2022.1-1/stylecheck/testdata/src/CheckRedundantTypeInDeclaration/CheckRedundantTypeInDeclaration.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/stylecheck/testdata/src/CheckRedundantTypeInDeclaration/CheckRedundantTypeInDeclaration.go	2022-07-31 15:38:22.000000000 +0000
@@ -20,15 +20,15 @@ var a int = gen1()
 func fn() {
 	var _ int = gen1()           // don't flag blank identifier
 	var a int = Y                // don't flag named untyped constants
-	var b int = 1                // want `should omit type int`
+	var b int = 1                //@ diag(`should omit type int`)
 	var c int = 1.0              // different default type
 	var d MyInt = 1              // different default type
-	var e io.ReadCloser = gen2() // want `should omit type io.ReadCloser`
+	var e io.ReadCloser = gen2() //@ diag(`should omit type io.ReadCloser`)
 	var f io.Reader = gen2()     // different interface type
 	var g float64 = math.Pi      // don't flag named untyped constants
-	var h bool = true            // want `should omit type bool`
-	var i string = ""            // want `should omit type string`
-	var j MyInt = gen3()         // want `should omit type MyInt`
+	var h bool = true            //@ diag(`should omit type bool`)
+	var i string = ""            //@ diag(`should omit type string`)
+	var j MyInt = gen3()         //@ diag(`should omit type MyInt`)
 	var k uint8 = Y              // different default type on constant
 	var l uint8 = (Y + Y) / 2    // different default type on rhs
 	var m int = (Y + Y) / 2      // complex expression
diff -pruN 2022.1-1/stylecheck/testdata/src/CheckRedundantTypeInDeclaration/CheckRedundantTypeInDeclaration.go.golden 2022.1.3-1/stylecheck/testdata/src/CheckRedundantTypeInDeclaration/CheckRedundantTypeInDeclaration.go.golden
--- 2022.1-1/stylecheck/testdata/src/CheckRedundantTypeInDeclaration/CheckRedundantTypeInDeclaration.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/stylecheck/testdata/src/CheckRedundantTypeInDeclaration/CheckRedundantTypeInDeclaration.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -20,15 +20,15 @@ var a int = gen1()
 func fn() {
 	var _ int = gen1()        // don't flag blank identifier
 	var a int = Y             // don't flag named untyped constants
-	var b = 1                 // want `should omit type int`
+	var b = 1                 //@ diag(`should omit type int`)
 	var c int = 1.0           // different default type
 	var d MyInt = 1           // different default type
-	var e = gen2()            // want `should omit type io.ReadCloser`
+	var e = gen2()            //@ diag(`should omit type io.ReadCloser`)
 	var f io.Reader = gen2()  // different interface type
 	var g float64 = math.Pi   // don't flag named untyped constants
-	var h = true              // want `should omit type bool`
-	var i = ""                // want `should omit type string`
-	var j = gen3()            // want `should omit type MyInt`
+	var h = true              //@ diag(`should omit type bool`)
+	var i = ""                //@ diag(`should omit type string`)
+	var j = gen3()            //@ diag(`should omit type MyInt`)
 	var k uint8 = Y           // different default type on constant
 	var l uint8 = (Y + Y) / 2 // different default type on rhs
 	var m int = (Y + Y) / 2   // complex expression
diff -pruN 2022.1-1/stylecheck/testdata/src/CheckTimeNames/CheckTimeNames.go 2022.1.3-1/stylecheck/testdata/src/CheckTimeNames/CheckTimeNames.go
--- 2022.1-1/stylecheck/testdata/src/CheckTimeNames/CheckTimeNames.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/stylecheck/testdata/src/CheckTimeNames/CheckTimeNames.go	2022-07-31 15:38:22.000000000 +0000
@@ -6,17 +6,17 @@ import "time"
 type T1 struct {
 	aMS     int
 	B       time.Duration
-	BMillis time.Duration // want `don't use unit-specific suffix`
+	BMillis time.Duration //@ diag(`don't use unit-specific suffix`)
 }
 
-func fn1(a, b, cMS time.Duration) { // want `don't use unit-specific suffix`
+func fn1(a, b, cMS time.Duration) { //@ diag(`don't use unit-specific suffix`)
 	var x time.Duration
-	var xMS time.Duration    // want `don't use unit-specific suffix`
-	var y, yMS time.Duration // want `don't use unit-specific suffix`
-	var zMS = time.Second    // want `don't use unit-specific suffix`
-	aMS := time.Second       // want `don't use unit-specific suffix`
+	var xMS time.Duration    //@ diag(`don't use unit-specific suffix`)
+	var y, yMS time.Duration //@ diag(`don't use unit-specific suffix`)
+	var zMS = time.Second    //@ diag(`don't use unit-specific suffix`)
+	aMS := time.Second       //@ diag(`don't use unit-specific suffix`)
 	unrelated, aMS := 0, 0
-	aMS, bMS := 0, time.Second // want `var bMS .+ don't use unit-specific suffix`
+	aMS, bMS := 0, time.Second //@ diag(re`var bMS .+ don't use unit-specific suffix`)
 
 	_, _, _, _, _, _, _, _ = x, xMS, y, yMS, zMS, aMS, unrelated, bMS
 }
diff -pruN 2022.1-1/stylecheck/testdata/src/_CheckUnexportedReturn.disabled/CheckUnexportedReturn.go 2022.1.3-1/stylecheck/testdata/src/_CheckUnexportedReturn.disabled/CheckUnexportedReturn.go
--- 2022.1-1/stylecheck/testdata/src/_CheckUnexportedReturn.disabled/CheckUnexportedReturn.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/stylecheck/testdata/src/_CheckUnexportedReturn.disabled/CheckUnexportedReturn.go	2022-07-31 15:38:22.000000000 +0000
@@ -10,12 +10,12 @@ func fn1() string { return "" }
 func Fn2() error  { return nil }
 func fn3() error  { return nil }
 func fn5() t1     { return 0 }
-func Fn6() t1     { return 0 }   // want `should not return unexported type`
-func Fn7() *t1    { return nil } // want `should not return unexported type`
+func Fn6() t1     { return 0 }   //@ diag(`should not return unexported type`)
+func Fn7() *t1    { return nil } //@ diag(`should not return unexported type`)
 func Fn8() T2     { return 0 }
 
 func (Recv) fn9() t1  { return 0 }
-func (Recv) Fn10() t1 { return 0 } // want `should not return unexported type`
+func (Recv) Fn10() t1 { return 0 } //@ diag(`should not return unexported type`)
 func (Recv) Fn11() T2 { return 0 }
 
 func (recv) fn9() t1  { return 0 }
diff -pruN 2022.1-1/stylecheck/testdata/src/CheckYodaConditions/CheckYodaConditions.go 2022.1.3-1/stylecheck/testdata/src/CheckYodaConditions/CheckYodaConditions.go
--- 2022.1-1/stylecheck/testdata/src/CheckYodaConditions/CheckYodaConditions.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/stylecheck/testdata/src/CheckYodaConditions/CheckYodaConditions.go	2022-07-31 15:38:22.000000000 +0000
@@ -2,15 +2,15 @@
 package pkg
 
 func fn(x string, y int) {
-	if "" == x { // want `Yoda`
+	if "" == x { //@ diag(`Yoda`)
 	}
-	if 0 == y { // want `Yoda`
+	if 0 == y { //@ diag(`Yoda`)
 	}
 	if 0 > y {
 	}
 	if "" == "" {
 	}
 
-	if "" == "" || 0 == y { // want `Yoda`
+	if "" == "" || 0 == y { //@ diag(`Yoda`)
 	}
 }
diff -pruN 2022.1-1/stylecheck/testdata/src/CheckYodaConditions/CheckYodaConditions.go.golden 2022.1.3-1/stylecheck/testdata/src/CheckYodaConditions/CheckYodaConditions.go.golden
--- 2022.1-1/stylecheck/testdata/src/CheckYodaConditions/CheckYodaConditions.go.golden	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/stylecheck/testdata/src/CheckYodaConditions/CheckYodaConditions.go.golden	2022-07-31 15:38:22.000000000 +0000
@@ -2,15 +2,15 @@
 package pkg
 
 func fn(x string, y int) {
-	if x == "" { // want `Yoda`
+	if x == "" { //@ diag(`Yoda`)
 	}
-	if y == 0 { // want `Yoda`
+	if y == 0 { //@ diag(`Yoda`)
 	}
 	if 0 > y {
 	}
 	if "" == "" {
 	}
 
-	if "" == "" || y == 0 { // want `Yoda`
+	if "" == "" || y == 0 { //@ diag(`Yoda`)
 	}
 }
diff -pruN 2022.1-1/unused/testdata/src/alias/alias.go 2022.1.3-1/unused/testdata/src/alias/alias.go
--- 2022.1-1/unused/testdata/src/alias/alias.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/alias/alias.go	2022-07-31 15:38:22.000000000 +0000
@@ -2,33 +2,33 @@ package main
 
 import "net/http"
 
-type t1 struct{} // used
-type t2 struct{} // unused
-type t3 struct{} // used
-
-type alias1 = t1  // used
-type alias2 = t2  // unused
-type alias3 = t3  // used
-type alias4 = int // used
+type t1 struct{} //@ used(true)
+type t2 struct{} //@ used(false)
+type t3 struct{} //@ used(true)
+
+type alias1 = t1  //@ used(true)
+type alias2 = t2  //@ used(false)
+type alias3 = t3  //@ used(true)
+type alias4 = int //@ used(true)
 
-func main() { // used
+func main() { //@ used(true)
 	var _ alias1
 	var _ t3
 }
 
-type t4 struct { // used
-	x int // used
+type t4 struct { //@ used(true)
+	x int //@ used(true)
 }
 
-func (t4) foo() {} // used
+func (t4) foo() {} //@ used(true)
 
 //lint:ignore U1000 alias5 is ignored, which also ignores t4
-type alias5 = t4 // used
+type alias5 = t4 //@ used(true)
 
 //lint:ignore U1000 alias6 is ignored, and we don't incorrectly try to include http.Server's fields and methods in the graph
-type alias6 = http.Server // used
+type alias6 = http.Server //@ used(true)
 
 //lint:ignore U1000 aliases don't have to be to named types
-type alias7 = struct { // used
-	x int // used
+type alias7 = struct { //@ used(true)
+	x int //@ used(true)
 }
diff -pruN 2022.1-1/unused/testdata/src/anonymous/anonymous.go 2022.1.3-1/unused/testdata/src/anonymous/anonymous.go
--- 2022.1-1/unused/testdata/src/anonymous/anonymous.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/anonymous/anonymous.go	2022-07-31 15:38:22.000000000 +0000
@@ -2,17 +2,17 @@ package pkg
 
 import "fmt"
 
-type Node interface { // used
-	position() int // used
+type Node interface { //@ used(true)
+	position() int //@ used(true)
 }
 
-type noder struct{} // used
+type noder struct{} //@ used(true)
 
-func (noder) position() int { panic("unreachable") } // used
+func (noder) position() int { panic("unreachable") } //@ used(true)
 
-func Fn() { // used
+func Fn() { //@ used(true)
 	nodes := []Node{struct {
-		noder // used
+		noder //@ used(true)
 	}{}}
 	fmt.Println(nodes)
 }
diff -pruN 2022.1-1/unused/testdata/src/blank/blank.go 2022.1.3-1/unused/testdata/src/blank/blank.go
--- 2022.1-1/unused/testdata/src/blank/blank.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/blank/blank.go	2022-07-31 15:38:22.000000000 +0000
@@ -2,28 +2,28 @@ package pkg
 
 import _ "fmt"
 
-type t1 struct{} // unused
-type t2 struct { // used
-	_ int // used
+type t1 struct{} //@ used(false)
+type t2 struct { //@ used(true)
+	_ int //@ used(true)
 }
-type t3 struct{} // used
-type t4 struct{} // used
-type t5 struct{} // used
+type t3 struct{} //@ used(true)
+type t4 struct{} //@ used(true)
+type t5 struct{} //@ used(true)
 
 var _ = t2{}
 
-func fn1() { // unused
+func fn1() { //@ used(false)
 	_ = t1{}
 	var _ = t1{}
 }
 
-func fn2() { // used
+func fn2() { //@ used(true)
 	_ = t3{}
 	var _ t4
 	var _ *t5 = nil
 }
 
-func init() { // used
+func init() { //@ used(true)
 	fn2()
 }
 
diff -pruN 2022.1-1/unused/testdata/src/cgo/cgo.go 2022.1.3-1/unused/testdata/src/cgo/cgo.go
--- 2022.1-1/unused/testdata/src/cgo/cgo.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/cgo/cgo.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,6 +1,6 @@
 package pkg
 
 //go:cgo_export_dynamic
-func foo() {} // used
+func foo() {} //@ used(true)
 
-func bar() {} // unused
+func bar() {} //@ used(false)
diff -pruN 2022.1-1/unused/testdata/src/consts/consts.go 2022.1.3-1/unused/testdata/src/consts/consts.go
--- 2022.1-1/unused/testdata/src/consts/consts.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/consts/consts.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,35 +1,35 @@
 package pkg
 
-const c1 = 1 // used
+const c1 = 1 //@ used(true)
 
-const c2 = 1 // used
-const c3 = 1 // used
-const c4 = 1 // used
-const C5 = 1 // used
+const c2 = 1 //@ used(true)
+const c3 = 1 //@ used(true)
+const c4 = 1 //@ used(true)
+const C5 = 1 //@ used(true)
 
 const (
-	c6 = 0 // used
-	c7     // used
-	c8     // used
-
-	c9  // unused
-	c10 // unused
-	c11 // unused
+	c6 = 0 //@ used(true)
+	c7     //@ used(true)
+	c8     //@ used(true)
+
+	c9  //@ used(false)
+	c10 //@ used(false)
+	c11 //@ used(false)
 )
 
 var _ = []int{c3: 1}
 
-type T1 struct { // used
-	F1 [c1]int // used
+type T1 struct { //@ used(true)
+	F1 [c1]int //@ used(true)
 }
 
-func init() { // used
+func init() { //@ used(true)
 	_ = []int{c2: 1}
 	var _ [c4]int
 
 	_ = c7
 }
 
-func Fn() { // used
-	const X = 1 // unused
+func Fn() { //@ used(true)
+	const X = 1 //@ used(false)
 }
diff -pruN 2022.1-1/unused/testdata/src/conversion/conversion.go 2022.1.3-1/unused/testdata/src/conversion/conversion.go
--- 2022.1-1/unused/testdata/src/conversion/conversion.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/conversion/conversion.go	2022-07-31 15:38:22.000000000 +0000
@@ -5,57 +5,57 @@ import (
 	"unsafe"
 )
 
-type t1 struct { // used
-	a int // used
-	b int // used
+type t1 struct { //@ used(true)
+	a int //@ used(true)
+	b int //@ used(true)
 }
 
-type t2 struct { // used
-	a int // used
-	b int // used
+type t2 struct { //@ used(true)
+	a int //@ used(true)
+	b int //@ used(true)
 }
 
-type t3 struct { // used
-	a int // used
-	b int // unused
+type t3 struct { //@ used(true)
+	a int //@ used(true)
+	b int //@ used(false)
 }
 
-type t4 struct { // used
-	a int // used
-	b int // unused
+type t4 struct { //@ used(true)
+	a int //@ used(true)
+	b int //@ used(false)
 }
 
-type t5 struct { // used
-	a int // used
-	b int // used
+type t5 struct { //@ used(true)
+	a int //@ used(true)
+	b int //@ used(true)
 }
 
-type t6 struct { // used
-	a int // used
-	b int // used
+type t6 struct { //@ used(true)
+	a int //@ used(true)
+	b int //@ used(true)
 }
 
-type t7 struct { // used
-	a int // used
-	b int // used
+type t7 struct { //@ used(true)
+	a int //@ used(true)
+	b int //@ used(true)
 }
 
-type t8 struct { // used
-	a int // used
-	b int // used
+type t8 struct { //@ used(true)
+	a int //@ used(true)
+	b int //@ used(true)
 }
 
-type t9 struct { // used
-	Offset int64 // used
-	Err    error // used
+type t9 struct { //@ used(true)
+	Offset int64 //@ used(true)
+	Err    error //@ used(true)
 }
 
-type t10 struct { // used
-	a int // used
-	b int // used
+type t10 struct { //@ used(true)
+	a int //@ used(true)
+	b int //@ used(true)
 }
 
-func fn() { // used
+func fn() { //@ used(true)
 	// All fields in t2 used because they're initialised in t1
 	v1 := t1{0, 1}
 	v2 := t2(v1)
@@ -89,4 +89,4 @@ func fn() { // used
 	_ = v10
 }
 
-func init() { fn() } // used
+func init() { fn() } //@ used(true)
diff -pruN 2022.1-1/unused/testdata/src/cyclic/cyclic.go 2022.1.3-1/unused/testdata/src/cyclic/cyclic.go
--- 2022.1-1/unused/testdata/src/cyclic/cyclic.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/cyclic/cyclic.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,9 +1,9 @@
 package pkg
 
-func a() { // unused
+func a() { //@ used(false)
 	b()
 }
 
-func b() { // unused
+func b() { //@ used(false)
 	a()
 }
diff -pruN 2022.1-1/unused/testdata/src/defer/defer.go 2022.1.3-1/unused/testdata/src/defer/defer.go
--- 2022.1-1/unused/testdata/src/defer/defer.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/defer/defer.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,13 +1,13 @@
 package pkg
 
-type t struct{} // used
+type t struct{} //@ used(true)
 
-func (t) fn1() {} // used
-func (t) fn2() {} // used
-func fn1()     {} // used
-func fn2()     {} // used
+func (t) fn1() {} //@ used(true)
+func (t) fn2() {} //@ used(true)
+func fn1()     {} //@ used(true)
+func fn2()     {} //@ used(true)
 
-func Fn() { // used
+func Fn() { //@ used(true)
 	var v t
 	defer fn1()
 	defer v.fn1()
diff -pruN 2022.1-1/unused/testdata/src/elem/elem.go 2022.1.3-1/unused/testdata/src/elem/elem.go
--- 2022.1-1/unused/testdata/src/elem/elem.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/elem/elem.go	2022-07-31 15:38:22.000000000 +0000
@@ -2,17 +2,17 @@
 
 package pkg
 
-type t15 struct { // used
-	f151 int // used
+type t15 struct { //@ used(true)
+	f151 int //@ used(true)
 }
-type a2 [1]t15 // used
+type a2 [1]t15 //@ used(true)
 
-type t16 struct{} // used
-type a3 [1][1]t16 // used
+type t16 struct{} //@ used(true)
+type a3 [1][1]t16 //@ used(true)
 
-func foo() { // used
+func foo() { //@ used(true)
 	_ = a2{0: {1}}
 	_ = a3{{{}}}
 }
 
-func init() { foo() } // used
+func init() { foo() } //@ used(true)
diff -pruN 2022.1-1/unused/testdata/src/embedded_call/embedded_call.go 2022.1.3-1/unused/testdata/src/embedded_call/embedded_call.go
--- 2022.1-1/unused/testdata/src/embedded_call/embedded_call.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/embedded_call/embedded_call.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,22 +1,22 @@
 package pkg
 
-var t1 struct { // used
-	t2 // used
-	t3 // used
-	t4 // used
+var t1 struct { //@ used(true)
+	t2 //@ used(true)
+	t3 //@ used(true)
+	t4 //@ used(true)
 }
 
-type t2 struct{} // used
-type t3 struct{} // used
-type t4 struct { // used
-	t5 // used
+type t2 struct{} //@ used(true)
+type t3 struct{} //@ used(true)
+type t4 struct { //@ used(true)
+	t5 //@ used(true)
 }
-type t5 struct{} // used
+type t5 struct{} //@ used(true)
 
-func (t2) foo() {} // used
-func (t3) bar() {} // used
-func (t5) baz() {} // used
-func init() { // used
+func (t2) foo() {} //@ used(true)
+func (t3) bar() {} //@ used(true)
+func (t5) baz() {} //@ used(true)
+func init() { //@ used(true)
 	t1.foo()
 	_ = t1.bar
 	t1.baz()
diff -pruN 2022.1-1/unused/testdata/src/embedding/embedding.go 2022.1.3-1/unused/testdata/src/embedding/embedding.go
--- 2022.1-1/unused/testdata/src/embedding/embedding.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/embedding/embedding.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,87 +1,87 @@
 package pkg
 
-type I interface { // used
-	f1() // used
-	f2() // used
+type I interface { //@ used(true)
+	f1() //@ used(true)
+	f2() //@ used(true)
 }
 
-func init() { // used
+func init() { //@ used(true)
 	var _ I
 }
 
-type t1 struct{} // used
-type T2 struct { // used
-	t1 // used
+type t1 struct{} //@ used(true)
+type T2 struct { //@ used(true)
+	t1 //@ used(true)
 }
 
-func (t1) f1() {} // used
-func (T2) f2() {} // used
+func (t1) f1() {} //@ used(true)
+func (T2) f2() {} //@ used(true)
 
-func Fn() { // used
+func Fn() { //@ used(true)
 	var v T2
 	_ = v.t1
 }
 
-type I2 interface { // used
-	f3() // used
-	f4() // used
+type I2 interface { //@ used(true)
+	f3() //@ used(true)
+	f4() //@ used(true)
 }
 
-type t3 struct{} // used
-type t4 struct { // used
-	x  int // unused
-	y  int // unused
-	t3     // used
+type t3 struct{} //@ used(true)
+type t4 struct { //@ used(true)
+	x  int //@ used(false)
+	y  int //@ used(false)
+	t3     //@ used(true)
 }
 
-func (*t3) f3() {} // used
-func (*t4) f4() {} // used
+func (*t3) f3() {} //@ used(true)
+func (*t4) f4() {} //@ used(true)
 
-func init() { // used
+func init() { //@ used(true)
 	var i I2 = &t4{}
 	i.f3()
 	i.f4()
 }
 
-type i3 interface { // used
-	F() // used
+type i3 interface { //@ used(true)
+	F() //@ used(true)
 }
 
-type I4 interface { // used
+type I4 interface { //@ used(true)
 	i3
 }
 
-type T5 struct { // used
-	t6 // used
+type T5 struct { //@ used(true)
+	t6 //@ used(true)
 }
 
-type t6 struct { // used
-	F int // used
+type t6 struct { //@ used(true)
+	F int //@ used(true)
 }
 
-type t7 struct { // used
-	X int // used
+type t7 struct { //@ used(true)
+	X int //@ used(true)
 }
-type t8 struct { // used
-	t7 // used
+type t8 struct { //@ used(true)
+	t7 //@ used(true)
 }
-type t9 struct { // used
-	t8 // used
+type t9 struct { //@ used(true)
+	t8 //@ used(true)
 }
 
 var _ = t9{}
 
-type t10 struct{} // used
+type t10 struct{} //@ used(true)
 
-func (*t10) Foo() {} // used
+func (*t10) Foo() {} //@ used(true)
 
-type t11 struct { // used
-	t10 // used
+type t11 struct { //@ used(true)
+	t10 //@ used(true)
 }
 
 var _ = t11{}
 
-type i5 interface{} // used
-type I6 interface { // used
+type i5 interface{} //@ used(true)
+type I6 interface { //@ used(true)
 	i5
 }
diff -pruN 2022.1-1/unused/testdata/src/embedding2/embedding2.go 2022.1.3-1/unused/testdata/src/embedding2/embedding2.go
--- 2022.1-1/unused/testdata/src/embedding2/embedding2.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/embedding2/embedding2.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,28 +1,28 @@
 package main
 
-type AA interface { // used
-	A() // used
+type AA interface { //@ used(true)
+	A() //@ used(true)
 }
 
-type BB interface { // used
+type BB interface { //@ used(true)
 	AA
 }
 
-type CC interface { // used
+type CC interface { //@ used(true)
 	BB
-	C() // used
+	C() //@ used(true)
 }
 
-func c(cc CC) { // used
+func c(cc CC) { //@ used(true)
 	cc.A()
 }
 
-type z struct{} // used
+type z struct{} //@ used(true)
 
-func (z) A() {} // used
-func (z) B() {} // used
-func (z) C() {} // used
+func (z) A() {} //@ used(true)
+func (z) B() {} //@ used(true)
+func (z) C() {} //@ used(true)
 
-func main() { // used
+func main() { //@ used(true)
 	c(z{})
 }
diff -pruN 2022.1-1/unused/testdata/src/exported_fields/exported_fields.go 2022.1.3-1/unused/testdata/src/exported_fields/exported_fields.go
--- 2022.1-1/unused/testdata/src/exported_fields/exported_fields.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/exported_fields/exported_fields.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,36 +1,36 @@
 package pkg
 
-type t1 struct { // used
-	F1 int // used
+type t1 struct { //@ used(true)
+	F1 int //@ used(true)
 }
 
-type T2 struct { // used
-	F2 int // used
+type T2 struct { //@ used(true)
+	F2 int //@ used(true)
 }
 
-var v struct { // used
-	T3 // used
+var v struct { //@ used(true)
+	T3 //@ used(true)
 }
 
-type T3 struct{} // used
+type T3 struct{} //@ used(true)
 
-func (T3) Foo() {} // used
+func (T3) Foo() {} //@ used(true)
 
-func init() { // used
+func init() { //@ used(true)
 	v.Foo()
 }
 
-func init() { // used
+func init() { //@ used(true)
 	_ = t1{}
 }
 
-type codeResponse struct { // used
-	Tree *codeNode `json:"tree"` // used
+type codeResponse struct { //@ used(true)
+	Tree *codeNode `json:"tree"` //@ used(true)
 }
 
-type codeNode struct { // used
+type codeNode struct { //@ used(true)
 }
 
-func init() { // used
+func init() { //@ used(true)
 	_ = codeResponse{}
 }
diff -pruN 2022.1-1/unused/testdata/src/exported_fields_main/exported_fields_main.go 2022.1.3-1/unused/testdata/src/exported_fields_main/exported_fields_main.go
--- 2022.1-1/unused/testdata/src/exported_fields_main/exported_fields_main.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/exported_fields_main/exported_fields_main.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,14 +1,14 @@
 package main
 
-type t1 struct { // used
-	F1 int // used
+type t1 struct { //@ used(true)
+	F1 int //@ used(true)
 }
 
-type T2 struct { // used
-	F2 int // used
+type T2 struct { //@ used(true)
+	F2 int //@ used(true)
 }
 
-func init() { // used
+func init() { //@ used(true)
 	_ = t1{}
 	_ = T2{}
 }
diff -pruN 2022.1-1/unused/testdata/src/exported_method_test/exported_method_test.go 2022.1.3-1/unused/testdata/src/exported_method_test/exported_method_test.go
--- 2022.1-1/unused/testdata/src/exported_method_test/exported_method_test.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/exported_method_test/exported_method_test.go	2022-07-31 15:38:22.000000000 +0000
@@ -7,18 +7,18 @@ import (
 	"testing"
 )
 
-type countReadSeeker struct { // used_test
-	io.ReadSeeker       // used_test
-	N             int64 // used_test
+type countReadSeeker struct { //@ used_test(true)
+	io.ReadSeeker       //@ used_test(true)
+	N             int64 //@ used_test(true)
 }
 
-func (rs *countReadSeeker) Read(buf []byte) (int, error) { // used_test
+func (rs *countReadSeeker) Read(buf []byte) (int, error) { //@ used_test(true)
 	n, err := rs.ReadSeeker.Read(buf)
 	rs.N += int64(n)
 	return n, err
 }
 
-func TestFoo(t *testing.T) { // used_test
+func TestFoo(t *testing.T) { //@ used_test(true)
 	r := bytes.NewReader([]byte("Hello, world!"))
 	cr := &countReadSeeker{ReadSeeker: r}
 	ioutil.ReadAll(cr)
@@ -27,12 +27,12 @@ func TestFoo(t *testing.T) { // used_tes
 	}
 }
 
-var sink int // used_test
+var sink int //@ used_test(true)
 
-func BenchmarkFoo(b *testing.B) { // used_test
+func BenchmarkFoo(b *testing.B) { //@ used_test(true)
 	for i := 0; i < b.N; i++ {
 		sink = fn()
 	}
 }
 
-func fn() int { return 0 } // used_test
+func fn() int { return 0 } //@ used_test(true)
diff -pruN 2022.1-1/unused/testdata/src/fields/fields.go 2022.1.3-1/unused/testdata/src/fields/fields.go
--- 2022.1-1/unused/testdata/src/fields/fields.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/fields/fields.go	2022-07-31 15:38:22.000000000 +0000
@@ -2,97 +2,97 @@
 
 package pkg
 
-type t1 struct { // used
-	f11 int // used
-	f12 int // used
+type t1 struct { //@ used(true)
+	f11 int //@ used(true)
+	f12 int //@ used(true)
 }
-type t2 struct { // used
-	f21 int // used
-	f22 int // used
+type t2 struct { //@ used(true)
+	f21 int //@ used(true)
+	f22 int //@ used(true)
 }
-type t3 struct { // used
-	f31 t4 // used
+type t3 struct { //@ used(true)
+	f31 t4 //@ used(true)
 }
-type t4 struct { // used
-	f41 int // used
+type t4 struct { //@ used(true)
+	f41 int //@ used(true)
 }
-type t5 struct { // used
-	f51 int // used
+type t5 struct { //@ used(true)
+	f51 int //@ used(true)
 }
-type t6 struct { // used
-	f61 int // used
+type t6 struct { //@ used(true)
+	f61 int //@ used(true)
 }
-type t7 struct { // used
-	f71 int // used
+type t7 struct { //@ used(true)
+	f71 int //@ used(true)
 }
-type m1 map[string]t7 // used
-type t8 struct {      // used
-	f81 int // used
+type m1 map[string]t7 //@ used(true)
+type t8 struct {      //@ used(true)
+	f81 int //@ used(true)
 }
-type t9 struct { // used
-	f91 int // used
+type t9 struct { //@ used(true)
+	f91 int //@ used(true)
 }
-type t10 struct { // used
-	f101 int // used
+type t10 struct { //@ used(true)
+	f101 int //@ used(true)
 }
-type t11 struct { // used
-	f111 int // used
+type t11 struct { //@ used(true)
+	f111 int //@ used(true)
 }
-type s1 []t11     // used
-type t12 struct { // used
-	f121 int // used
+type s1 []t11     //@ used(true)
+type t12 struct { //@ used(true)
+	f121 int //@ used(true)
 }
-type s2 []t12     // used
-type t13 struct { // used
-	f131 int // used
+type s2 []t12     //@ used(true)
+type t13 struct { //@ used(true)
+	f131 int //@ used(true)
 }
-type t14 struct { // used
-	f141 int // used
+type t14 struct { //@ used(true)
+	f141 int //@ used(true)
 }
-type a1 [1]t14    // used
-type t15 struct { // used
-	f151 int // used
+type a1 [1]t14    //@ used(true)
+type t15 struct { //@ used(true)
+	f151 int //@ used(true)
 }
-type a2 [1]t15    // used
-type t16 struct { // used
-	f161 int // used
+type a2 [1]t15    //@ used(true)
+type t16 struct { //@ used(true)
+	f161 int //@ used(true)
 }
-type t17 struct { // unused
+type t17 struct { //@ used(false)
 	f171 int
 	f172 int
 }
-type t18 struct { // used
-	f181 int // used
-	f182 int // unused
-	f183 int // unused
+type t18 struct { //@ used(true)
+	f181 int //@ used(true)
+	f182 int //@ used(false)
+	f183 int //@ used(false)
 }
 
-type t19 struct { // used
-	f191 int // used
+type t19 struct { //@ used(true)
+	f191 int //@ used(true)
 }
-type m2 map[string]t19 // used
+type m2 map[string]t19 //@ used(true)
 
-type t20 struct { // used
-	f201 int // used
+type t20 struct { //@ used(true)
+	f201 int //@ used(true)
 }
-type m3 map[string]t20 // used
+type m3 map[string]t20 //@ used(true)
 
-type t21 struct { // used
-	f211 int // unused
-	f212 int // used
+type t21 struct { //@ used(true)
+	f211 int //@ used(false)
+	f212 int //@ used(true)
 }
-type t22 struct { // unused
+type t22 struct { //@ used(false)
 	f221 int
 	f222 int
 }
 
-func foo() { // used
+func foo() { //@ used(true)
 	_ = t10{1}
 	_ = t21{f212: 1}
 	_ = []t1{{1, 2}}
 	_ = t2{1, 2}
 	_ = []struct {
-		a int // used
+		a int //@ used(true)
 	}{{1}}
 
 	// XXX
@@ -112,7 +112,7 @@ func foo() { // used
 	_ = a2{0: {1}}
 	_ = map[[1]t16]int{{{1}}: 1}
 	y := struct {
-		x int // used
+		x int //@ used(true)
 	}{}
 	_ = y
 	_ = t18{f181: 1}
@@ -120,9 +120,9 @@ func foo() { // used
 	_ = [][]m3{{{"a": {1}}}}
 }
 
-func init() { foo() } // used
+func init() { foo() } //@ used(true)
 
-func superUnused() { // unused
+func superUnused() { //@ used(false)
 	var _ struct {
 		x int
 	}
diff -pruN 2022.1-1/unused/testdata/src/functions/functions.go 2022.1.3-1/unused/testdata/src/functions/functions.go
--- 2022.1-1/unused/testdata/src/functions/functions.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/functions/functions.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,35 +1,35 @@
 package main
 
-type state func() state // used
+type state func() state //@ used(true)
 
-func a() state { // used
+func a() state { //@ used(true)
 	return a
 }
 
-func main() { // used
+func main() { //@ used(true)
 	st := a
 	_ = st()
 }
 
-type t1 struct{} // unused
-type t2 struct{} // used
-type t3 struct{} // used
-
-func fn1() t1     { return t1{} } // unused
-func fn2() (x t2) { return }      // used
-func fn3() *t3    { return nil }  // used
-
-func fn4() { // used
-	const x = 1  // used
-	const y = 2  // unused
-	type foo int // unused
-	type bar int // used
+type t1 struct{} //@ used(false)
+type t2 struct{} //@ used(true)
+type t3 struct{} //@ used(true)
+
+func fn1() t1     { return t1{} } //@ used(false)
+func fn2() (x t2) { return }      //@ used(true)
+func fn3() *t3    { return nil }  //@ used(true)
+
+func fn4() { //@ used(true)
+	const x = 1  //@ used(true)
+	const y = 2  //@ used(false)
+	type foo int //@ used(false)
+	type bar int //@ used(true)
 
 	_ = x
 	_ = bar(0)
 }
 
-func init() { // used
+func init() { //@ used(true)
 	fn2()
 	fn3()
 	fn4()
diff -pruN 2022.1-1/unused/testdata/src/ignored/ignored2.go 2022.1.3-1/unused/testdata/src/ignored/ignored2.go
--- 2022.1-1/unused/testdata/src/ignored/ignored2.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/ignored/ignored2.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,3 +1,3 @@
 package pkg
 
-func (t1) fn4() {} // used
+func (t1) fn4() {} //@ used(true)
diff -pruN 2022.1-1/unused/testdata/src/ignored/ignored3.go 2022.1.3-1/unused/testdata/src/ignored/ignored3.go
--- 2022.1-1/unused/testdata/src/ignored/ignored3.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/ignored/ignored3.go	2022-07-31 15:38:22.000000000 +0000
@@ -2,6 +2,6 @@
 
 package pkg
 
-type t9 struct{} // used
+type t9 struct{} //@ used(true)
 
-func (t9) fn1() {} // used
+func (t9) fn1() {} //@ used(true)
diff -pruN 2022.1-1/unused/testdata/src/ignored/ignored4.go 2022.1.3-1/unused/testdata/src/ignored/ignored4.go
--- 2022.1-1/unused/testdata/src/ignored/ignored4.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/ignored/ignored4.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,3 +1,3 @@
 package pkg
 
-func (t9) fn2() {} // used
+func (t9) fn2() {} //@ used(true)
diff -pruN 2022.1-1/unused/testdata/src/ignored/ignored.go 2022.1.3-1/unused/testdata/src/ignored/ignored.go
--- 2022.1-1/unused/testdata/src/ignored/ignored.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/ignored/ignored.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,56 +1,56 @@
 package pkg
 
 //lint:ignore U1000 consider yourself used
-type t1 struct{} // used
-type t2 struct{} // used
-type t3 struct{} // used
-
-func (t1) fn1() {} // used
-func (t1) fn2() {} // used
-func (t1) fn3() {} // used
+type t1 struct{} //@ used(true)
+type t2 struct{} //@ used(true)
+type t3 struct{} //@ used(true)
+
+func (t1) fn1() {} //@ used(true)
+func (t1) fn2() {} //@ used(true)
+func (t1) fn3() {} //@ used(true)
 
 //lint:ignore U1000 be gone
-func (t2) fn1() {} // used
-func (t2) fn2() {} // unused
-func (t2) fn3() {} // unused
+func (t2) fn1() {} //@ used(true)
+func (t2) fn2() {} //@ used(false)
+func (t2) fn3() {} //@ used(false)
 
-func (t3) fn1() {} // unused
-func (t3) fn2() {} // unused
-func (t3) fn3() {} // unused
+func (t3) fn1() {} //@ used(false)
+func (t3) fn2() {} //@ used(false)
+func (t3) fn3() {} //@ used(false)
 
 //lint:ignore U1000 consider yourself used
-func fn() { // used
+func fn() { //@ used(true)
 	var _ t2
 	var _ t3
 }
 
 //lint:ignore U1000 bye
-type t4 struct { // used
-	x int // used
+type t4 struct { //@ used(true)
+	x int //@ used(true)
 }
 
-func (t4) bar() {} // used
+func (t4) bar() {} //@ used(true)
 
 //lint:ignore U1000 consider yourself used
-type t5 map[int]struct { // used
-	y int // used
+type t5 map[int]struct { //@ used(true)
+	y int //@ used(true)
 }
 
 //lint:ignore U1000 consider yourself used
-type t6 interface { // used
-	foo() // used
+type t6 interface { //@ used(true)
+	foo() //@ used(true)
 }
 
 //lint:ignore U1000 consider yourself used
-type t7 = struct { // used
-	z int // used
+type t7 = struct { //@ used(true)
+	z int //@ used(true)
 }
 
 //lint:ignore U1000 consider yourself used
-type t8 struct{} // used
+type t8 struct{} //@ used(true)
 
-func (t8) fn() { // used
+func (t8) fn() { //@ used(true)
 	otherFn()
 }
 
-func otherFn() {} // used
+func otherFn() {} //@ used(true)
diff -pruN 2022.1-1/unused/testdata/src/interfaces/interfaces.go 2022.1.3-1/unused/testdata/src/interfaces/interfaces.go
--- 2022.1-1/unused/testdata/src/interfaces/interfaces.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/interfaces/interfaces.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,46 +1,46 @@
 package pkg
 
-type I interface { // used
-	fn1() // used
+type I interface { //@ used(true)
+	fn1() //@ used(true)
 }
 
-type t struct{} // used
+type t struct{} //@ used(true)
 
-func (t) fn1() {} // used
-func (t) fn2() {} // unused
+func (t) fn1() {} //@ used(true)
+func (t) fn2() {} //@ used(false)
 
-func init() { // used
+func init() { //@ used(true)
 	_ = t{}
 }
 
-type I1 interface { // used
-	Foo() // used
+type I1 interface { //@ used(true)
+	Foo() //@ used(true)
 }
 
-type I2 interface { // used
-	Foo() // used
-	bar() // used
+type I2 interface { //@ used(true)
+	Foo() //@ used(true)
+	bar() //@ used(true)
 }
 
-type i3 interface { // unused
+type i3 interface { //@ used(false)
 	foo()
 	bar()
 }
 
-type t1 struct{} // used
-type t2 struct{} // used
-type t3 struct{} // used
-type t4 struct { // used
-	t3 // used
+type t1 struct{} //@ used(true)
+type t2 struct{} //@ used(true)
+type t3 struct{} //@ used(true)
+type t4 struct { //@ used(true)
+	t3 //@ used(true)
 }
 
-func (t1) Foo() {} // used
-func (t2) Foo() {} // used
-func (t2) bar() {} // used
-func (t3) Foo() {} // used
-func (t3) bar() {} // used
+func (t1) Foo() {} //@ used(true)
+func (t2) Foo() {} //@ used(true)
+func (t2) bar() {} //@ used(true)
+func (t3) Foo() {} //@ used(true)
+func (t3) bar() {} //@ used(true)
 
-func Fn() { // used
+func Fn() { //@ used(true)
 	var v1 t1
 	var v2 t2
 	var v3 t3
diff -pruN 2022.1-1/unused/testdata/src/interfaces2/interfaces.go 2022.1.3-1/unused/testdata/src/interfaces2/interfaces.go
--- 2022.1-1/unused/testdata/src/interfaces2/interfaces.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/interfaces2/interfaces.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,14 +1,14 @@
 package pkg
 
-type I interface { // used
-	foo() // used
+type I interface { //@ used(true)
+	foo() //@ used(true)
 }
 
-type T struct{} // used
+type T struct{} //@ used(true)
 
-func (T) foo() {} // used
-func (T) bar() {} // unused
+func (T) foo() {} //@ used(true)
+func (T) bar() {} //@ used(false)
 
 var _ struct {
-	T // used
+	T //@ used(true)
 }
diff -pruN 2022.1-1/unused/testdata/src/linkname/linkname.go 2022.1.3-1/unused/testdata/src/linkname/linkname.go
--- 2022.1-1/unused/testdata/src/linkname/linkname.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/linkname/linkname.go	2022-07-31 15:38:22.000000000 +0000
@@ -6,22 +6,22 @@ import _ "unsafe"
 //go:linkname ol other4
 
 //go:linkname foo other1
-func foo() {} // used
+func foo() {} //@ used(true)
 
 //go:linkname bar other2
-var bar int // used
+var bar int //@ used(true)
 
 var (
-	baz int // unused
+	baz int //@ used(false)
 	//go:linkname qux other3
-	qux int // used
+	qux int //@ used(true)
 )
 
 //go:linkname fisk other3
 var (
-	fisk int // used
+	fisk int //@ used(true)
 )
 
-var ol int // used
+var ol int //@ used(true)
 
 //go:linkname doesnotexist other5
diff -pruN 2022.1-1/unused/testdata/src/main/main.go 2022.1.3-1/unused/testdata/src/main/main.go
--- 2022.1-1/unused/testdata/src/main/main.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/main/main.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,15 +1,15 @@
 package main
 
-func Fn1() {} // used
-func Fn2() {} // used
-func fn3() {} // unused
+func Fn1() {} //@ used(true)
+func Fn2() {} //@ used(true)
+func fn3() {} //@ used(false)
 
-const X = 1 // used
+const X = 1 //@ used(true)
 
-var Y = 2 // used
+var Y = 2 //@ used(true)
 
-type Z struct{} // used
+type Z struct{} //@ used(true)
 
-func main() { // used
+func main() { //@ used(true)
 	Fn1()
 }
diff -pruN 2022.1-1/unused/testdata/src/mapslice/mapslice.go 2022.1.3-1/unused/testdata/src/mapslice/mapslice.go
--- 2022.1-1/unused/testdata/src/mapslice/mapslice.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/mapslice/mapslice.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,8 +1,8 @@
 package pkg
 
-type M map[int]int // used
+type M map[int]int //@ used(true)
 
-func Fn() { // used
+func Fn() { //@ used(true)
 	var n M
 	_ = []M{n}
 }
diff -pruN 2022.1-1/unused/testdata/src/methods/methods.go 2022.1.3-1/unused/testdata/src/methods/methods.go
--- 2022.1-1/unused/testdata/src/methods/methods.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/methods/methods.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,16 +1,16 @@
 package pkg
 
-type t1 struct{} // used
-type t2 struct { // used
-	t3 // used
+type t1 struct{} //@ used(true)
+type t2 struct { //@ used(true)
+	t3 //@ used(true)
 }
-type t3 struct{} // used
+type t3 struct{} //@ used(true)
 
-func (t1) Foo() {} // used
-func (t3) Foo() {} // used
-func (t3) foo() {} // unused
+func (t1) Foo() {} //@ used(true)
+func (t3) Foo() {} //@ used(true)
+func (t3) foo() {} //@ used(false)
 
-func init() { // used
+func init() { //@ used(true)
 	_ = t1{}
 	_ = t2{}
 }
diff -pruN 2022.1-1/unused/testdata/src/named/named.go 2022.1.3-1/unused/testdata/src/named/named.go
--- 2022.1-1/unused/testdata/src/named/named.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/named/named.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,4 +1,4 @@
 package pkg
 
-type t1 struct{} // used
-type T2 t1       // used
+type t1 struct{} //@ used(true)
+type T2 t1       //@ used(true)
diff -pruN 2022.1-1/unused/testdata/src/nested/nested.go 2022.1.3-1/unused/testdata/src/nested/nested.go
--- 2022.1-1/unused/testdata/src/nested/nested.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/nested/nested.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,10 +1,10 @@
 package pkg
 
-type t1 struct{} // unused
+type t1 struct{} //@ used(false)
 
-func (t1) fragment() {} // unused
+func (t1) fragment() {} //@ used(false)
 
-func fn1() bool { // unused
+func fn1() bool { //@ used(false)
 	var v interface{} = t1{}
 	switch obj := v.(type) {
 	case interface {
@@ -15,15 +15,15 @@ func fn1() bool { // unused
 	return false
 }
 
-type t2 struct{} // used
+type t2 struct{} //@ used(true)
 
-func (t2) fragment() {} // used
+func (t2) fragment() {} //@ used(true)
 
-func Fn() bool { // used
+func Fn() bool { //@ used(true)
 	var v interface{} = t2{}
 	switch obj := v.(type) {
 	case interface {
-		fragment() // used
+		fragment() //@ used(true)
 	}:
 		obj.fragment()
 	}
diff -pruN 2022.1-1/unused/testdata/src/nocopy/nocopy.go 2022.1.3-1/unused/testdata/src/nocopy/nocopy.go
--- 2022.1-1/unused/testdata/src/nocopy/nocopy.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/nocopy/nocopy.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,22 +1,22 @@
 package bar
 
-type myNoCopy1 struct{}  // used
-type myNoCopy2 struct{}  // used
-type locker struct{}     // unused
-type someStruct struct { // unused
+type myNoCopy1 struct{}  //@ used(true)
+type myNoCopy2 struct{}  //@ used(true)
+type locker struct{}     //@ used(false)
+type someStruct struct { //@ used(false)
 	x int
 }
 
-func (myNoCopy1) Lock()      {} // used
-func (recv myNoCopy2) Lock() {} // used
-func (locker) Lock()         {} // unused
-func (locker) Unlock()       {} // unused
-func (someStruct) Lock()     {} // unused
+func (myNoCopy1) Lock()      {} //@ used(true)
+func (recv myNoCopy2) Lock() {} //@ used(true)
+func (locker) Lock()         {} //@ used(false)
+func (locker) Unlock()       {} //@ used(false)
+func (someStruct) Lock()     {} //@ used(false)
 
-type T struct { // used
-	noCopy1 myNoCopy1  // used
-	noCopy2 myNoCopy2  // used
-	field1  someStruct // unused
-	field2  locker     // unused
-	field3  int        // unused
+type T struct { //@ used(true)
+	noCopy1 myNoCopy1  //@ used(true)
+	noCopy2 myNoCopy2  //@ used(true)
+	field1  someStruct //@ used(false)
+	field2  locker     //@ used(false)
+	field3  int        //@ used(false)
 }
diff -pruN 2022.1-1/unused/testdata/src/nocopy-main/nocopy-main.go 2022.1.3-1/unused/testdata/src/nocopy-main/nocopy-main.go
--- 2022.1-1/unused/testdata/src/nocopy-main/nocopy-main.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/nocopy-main/nocopy-main.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,26 +1,26 @@
 package main
 
-type myNoCopy1 struct{}  // used
-type myNoCopy2 struct{}  // used
-type locker struct{}     // unused
-type someStruct struct { // unused
+type myNoCopy1 struct{}  //@ used(true)
+type myNoCopy2 struct{}  //@ used(true)
+type locker struct{}     //@ used(false)
+type someStruct struct { //@ used(false)
 	x int
 }
 
-func (myNoCopy1) Lock()      {} // used
-func (recv myNoCopy2) Lock() {} // used
-func (locker) Lock()         {} // unused
-func (locker) Unlock()       {} // unused
-func (someStruct) Lock()     {} // unused
+func (myNoCopy1) Lock()      {} //@ used(true)
+func (recv myNoCopy2) Lock() {} //@ used(true)
+func (locker) Lock()         {} //@ used(false)
+func (locker) Unlock()       {} //@ used(false)
+func (someStruct) Lock()     {} //@ used(false)
 
-type T struct { // used
-	noCopy1 myNoCopy1  // used
-	noCopy2 myNoCopy2  // used
-	field1  someStruct // unused
-	field2  locker     // unused
-	field3  int        // unused
+type T struct { //@ used(true)
+	noCopy1 myNoCopy1  //@ used(true)
+	noCopy2 myNoCopy2  //@ used(true)
+	field1  someStruct //@ used(false)
+	field2  locker     //@ used(false)
+	field3  int        //@ used(false)
 }
 
-func main() { // used
+func main() { //@ used(true)
 	_ = T{}
 }
diff -pruN 2022.1-1/unused/testdata/src/pointers/pointers.go 2022.1.3-1/unused/testdata/src/pointers/pointers.go
--- 2022.1-1/unused/testdata/src/pointers/pointers.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/pointers/pointers.go	2022-07-31 15:38:22.000000000 +0000
@@ -2,16 +2,16 @@ package baz
 
 import "fmt"
 
-type Foo interface { // used
-	bar() // used
+type Foo interface { //@ used(true)
+	bar() //@ used(true)
 }
 
-func Bar(f Foo) { // used
+func Bar(f Foo) { //@ used(true)
 	f.bar()
 }
 
-type Buzz struct{} // used
+type Buzz struct{} //@ used(true)
 
-func (b *Buzz) bar() { // used
+func (b *Buzz) bar() { //@ used(true)
 	fmt.Println("foo bar buzz")
 }
diff -pruN 2022.1-1/unused/testdata/src/pointer-type-embedding/pointer-type-embedding.go 2022.1.3-1/unused/testdata/src/pointer-type-embedding/pointer-type-embedding.go
--- 2022.1-1/unused/testdata/src/pointer-type-embedding/pointer-type-embedding.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/pointer-type-embedding/pointer-type-embedding.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,17 +1,17 @@
 package pkg
 
-func init() { // used
+func init() { //@ used(true)
 	var p P
 	_ = p.n
 }
 
-type T0 struct { // used
-	m int // unused
-	n int // used
+type T0 struct { //@ used(true)
+	m int //@ used(false)
+	n int //@ used(true)
 }
 
-type T1 struct { // used
-	T0 // used
+type T1 struct { //@ used(true)
+	T0 //@ used(true)
 }
 
-type P *T1 // used
+type P *T1 //@ used(true)
diff -pruN 2022.1-1/unused/testdata/src/quiet/quiet.go 2022.1.3-1/unused/testdata/src/quiet/quiet.go
--- 2022.1-1/unused/testdata/src/quiet/quiet.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/quiet/quiet.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,34 +1,34 @@
 package pkg
 
-type iface interface { // unused
+type iface interface { //@ used(false)
 	foo()
 }
 
-type t1 struct{} // unused
-func (t1) foo()  {} // unused
+type t1 struct{} //@ used(false)
+func (t1) foo()  {} //@ used(false)
 
-type t2 struct{} // used
+type t2 struct{} //@ used(true)
 
-func (t t2) bar(arg int) (ret int) { return 0 } // unused
+func (t t2) bar(arg int) (ret int) { return 0 } //@ used(false)
 
-func init() { // used
+func init() { //@ used(true)
 	_ = t2{}
 }
 
-type t3 struct { // unused
+type t3 struct { //@ used(false)
 	a int
 	b int
 }
 
-type T struct{} // used
+type T struct{} //@ used(true)
 
-func fn1() { // unused
+func fn1() { //@ used(false)
 	meh := func(arg T) {
 	}
 	meh(T{})
 }
 
-type localityList []int // unused
+type localityList []int //@ used(false)
 
-func (l *localityList) Fn1() {} // unused
-func (l *localityList) Fn2() {} // unused
+func (l *localityList) Fn1() {} //@ used(false)
+func (l *localityList) Fn2() {} //@ used(false)
diff -pruN 2022.1-1/unused/testdata/src/selectors/selectors.go 2022.1.3-1/unused/testdata/src/selectors/selectors.go
--- 2022.1-1/unused/testdata/src/selectors/selectors.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/selectors/selectors.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,14 +1,14 @@
 package pkg
 
-type t struct { // used
-	f int // used
+type t struct { //@ used(true)
+	f int //@ used(true)
 }
 
-func fn(v *t) { // used
+func fn(v *t) { //@ used(true)
 	println(v.f)
 }
 
-func init() { // used
+func init() { //@ used(true)
 	var v t
 	fn(&v)
 }
diff -pruN 2022.1-1/unused/testdata/src/switch_interface/switch_interface.go 2022.1.3-1/unused/testdata/src/switch_interface/switch_interface.go
--- 2022.1-1/unused/testdata/src/switch_interface/switch_interface.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/switch_interface/switch_interface.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,19 +1,19 @@
 package pkg
 
-type t struct{} // used
+type t struct{} //@ used(true)
 
-func (t) fragment() {} // used
+func (t) fragment() {} //@ used(true)
 
-func fn() bool { // used
+func fn() bool { //@ used(true)
 	var v interface{} = t{}
 	switch obj := v.(type) {
 	case interface {
-		fragment() // used
+		fragment() //@ used(true)
 	}:
 		obj.fragment()
 	}
 	return false
 }
 
-var x = fn() // used
+var x = fn() //@ used(true)
 var _ = x
diff -pruN 2022.1-1/unused/testdata/src/tests/tests.go 2022.1.3-1/unused/testdata/src/tests/tests.go
--- 2022.1-1/unused/testdata/src/tests/tests.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/tests/tests.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,3 +1,3 @@
 package pkg
 
-func fn() {} // unused used_test
+func fn() {} //@ used(false), used_test(true)
diff -pruN 2022.1-1/unused/testdata/src/tests/tests_test.go 2022.1.3-1/unused/testdata/src/tests/tests_test.go
--- 2022.1-1/unused/testdata/src/tests/tests_test.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/tests/tests_test.go	2022-07-31 15:38:22.000000000 +0000
@@ -2,6 +2,6 @@ package pkg
 
 import "testing"
 
-func TestFn(t *testing.T) { // used_test
+func TestFn(t *testing.T) { //@ used_test(true)
 	fn()
 }
diff -pruN 2022.1-1/unused/testdata/src/tests-main/main_test.go 2022.1.3-1/unused/testdata/src/tests-main/main_test.go
--- 2022.1-1/unused/testdata/src/tests-main/main_test.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/tests-main/main_test.go	2022-07-31 15:38:22.000000000 +0000
@@ -4,8 +4,8 @@ import (
 	"testing"
 )
 
-type t1 struct{} // used_test
+type t1 struct{} //@ used_test(true)
 
-func TestFoo(t *testing.T) { // used_test
+func TestFoo(t *testing.T) { //@ used_test(true)
 	_ = t1{}
 }
diff -pruN 2022.1-1/unused/testdata/src/type-dedup/dedup.go 2022.1.3-1/unused/testdata/src/type-dedup/dedup.go
--- 2022.1-1/unused/testdata/src/type-dedup/dedup.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/type-dedup/dedup.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,16 +1,16 @@
 package pkg
 
-type t1 struct { // used
-	a int // used
-	b int // unused
+type t1 struct { //@ used(true)
+	a int //@ used(true)
+	b int //@ used(false)
 }
 
-type t2 struct { // used
-	a int // unused
-	b int // used
+type t2 struct { //@ used(true)
+	a int //@ used(false)
+	b int //@ used(true)
 }
 
-func Fn() { // used
+func Fn() { //@ used(true)
 	x := t1{}
 	y := t2{}
 	println(x.a)
diff -pruN 2022.1-1/unused/testdata/src/type-dedup2/dedup.go 2022.1.3-1/unused/testdata/src/type-dedup2/dedup.go
--- 2022.1-1/unused/testdata/src/type-dedup2/dedup.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/type-dedup2/dedup.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,23 +1,23 @@
 package pkg
 
-func fn1(t struct { // used
-	a int // used
-	b int // used
+func fn1(t struct { //@ used(true)
+	a int //@ used(true)
+	b int //@ used(true)
 }) {
 	println(t.a)
 	fn2(t)
 }
 
-func fn2(t struct { // used
-	a int // used
-	b int // used
+func fn2(t struct { //@ used(true)
+	a int //@ used(true)
+	b int //@ used(true)
 }) {
 	println(t.b)
 }
 
-func Fn() { // used
+func Fn() { //@ used(true)
 	fn1(struct {
-		a int // used
-		b int // used
+		a int //@ used(true)
+		b int //@ used(true)
 	}{})
 }
diff -pruN 2022.1-1/unused/testdata/src/type-dedup3/dedup.go 2022.1.3-1/unused/testdata/src/type-dedup3/dedup.go
--- 2022.1-1/unused/testdata/src/type-dedup3/dedup.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/type-dedup3/dedup.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,23 +1,23 @@
 package pkg
 
-func fn1(t struct { // used
-	a int // used
-	b int // used
+func fn1(t struct { //@ used(true)
+	a int //@ used(true)
+	b int //@ used(true)
 }) {
 	fn2(t)
 }
 
-func fn2(t struct { // used
-	a int // used
-	b int // used
+func fn2(t struct { //@ used(true)
+	a int //@ used(true)
+	b int //@ used(true)
 }) {
 	println(t.a)
 	println(t.b)
 }
 
-func Fn() { // used
+func Fn() { //@ used(true)
 	fn1(struct {
-		a int // used
-		b int // used
+		a int //@ used(true)
+		b int //@ used(true)
 	}{1, 2})
 }
diff -pruN 2022.1-1/unused/testdata/src/typeparams/typeparams.go 2022.1.3-1/unused/testdata/src/typeparams/typeparams.go
--- 2022.1-1/unused/testdata/src/typeparams/typeparams.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/typeparams/typeparams.go	2022-07-31 15:38:22.000000000 +0000
@@ -2,71 +2,104 @@
 
 package pkg
 
-type c1 struct{} // used
-type c2 struct{} // used
-type c3 struct{} // used
-type c4 struct{} // used
-type c5 struct{} // used
-type c6 struct{} // used
-type c7 struct{} // used
+type c1 struct{} //@ used(true)
+type c2 struct{} //@ used(true)
+type c3 struct{} //@ used(true)
+type c4 struct{} //@ used(true)
+type c5 struct{} //@ used(true)
+type c6 struct{} //@ used(true)
+type c7 struct{} //@ used(true)
 // c8 should be unused, but see https://staticcheck.io/issues/1199
-type c8 struct{} // used
-type c9 struct{} // used
+type c8 struct{} //@ used(true)
+type c9 struct{} //@ used(true)
 
-type S1[T c1] struct{}  // used
-type S2[T any] struct{} // used
-type S3 S2[c2]          // used
+type S1[T c1] struct{}  //@ used(true)
+type S2[T any] struct{} //@ used(true)
+type S3 S2[c2]          //@ used(true)
 
-type I interface { // used
+type I interface { //@ used(true)
 	c3 | c9
 }
 
-func Fn1[T c4]()  {} // used
-func fn2[T any]() {} // used
-func Fn5[T any]() {} // used
-func Fn6[T any]() {} // used
+func Fn1[T c4]()  {} //@ used(true)
+func fn2[T any]() {} //@ used(true)
+func Fn5[T any]() {} //@ used(true)
+func Fn6[T any]() {} //@ used(true)
 
 var _ = fn2[c5]
 
-func Fn3() { // used
+func Fn3() { //@ used(true)
 	Fn5[c6]()
 	_ = S2[c7]{}
 }
 
-func uncalled() { // unused
+func uncalled() { //@ used(false)
 	_ = Fn6[c8]
 }
 
-type S4[T any] struct{} // used
+type S4[T any] struct{} //@ used(true)
 
-func (S4[T]) usedGenerically()  {} // used
-func (S4[T]) usedInstantiated() {} // used
-func (recv S4[T]) Exported() { // used
+func (S4[T]) usedGenerically()  {} //@ used(true)
+func (S4[T]) usedInstantiated() {} //@ used(true)
+func (recv S4[T]) Exported() { //@ used(true)
 	recv.usedGenerically()
 }
-func (S4[T]) unused() {} // unused
+func (S4[T]) unused() {} //@ used(false)
 
-func Fn4() { // used
+func Fn4() { //@ used(true)
 	var x S4[int]
 	x.usedInstantiated()
 }
 
-type s1[T any] struct{} // unused
+type s1[T any] struct{} //@ used(false)
 
-func (recv s1[a]) foo() { recv.foo(); recv.bar(); recv.baz() } // unused
-func (recv s1[b]) bar() { recv.foo(); recv.bar(); recv.baz() } // unused
-func (recv s1[c]) baz() { recv.foo(); recv.bar(); recv.baz() } // unused
+func (recv s1[a]) foo() { recv.foo(); recv.bar(); recv.baz() } //@ used(false)
+func (recv s1[b]) bar() { recv.foo(); recv.bar(); recv.baz() } //@ used(false)
+func (recv s1[c]) baz() { recv.foo(); recv.bar(); recv.baz() } //@ used(false)
 
-func fn7[T interface{ foo() }]() {} // unused
-func fn8[T struct { // unused
+func fn7[T interface{ foo() }]() {} //@ used(false)
+func fn8[T struct { //@ used(false)
 	x int
 }]() {
 }
-func Fn9[T struct { // used
-	X *s2 // used
+func Fn9[T struct { //@ used(true)
+	X *s2 //@ used(true)
 }]() {
 }
 
-type s2 struct{} // used
+type s2 struct{} //@ used(true)
 
-func fn10[E any](x []E) {} // unused
+func fn10[E any](x []E) {} //@ used(false)
+
+type Tree[T any] struct { //@ used(true)
+	Root *Node[T] //@ used(true)
+}
+
+type Node[T any] struct { //@ used(true)
+	Tree *Tree[T] //@ used(true)
+}
+
+type foo struct{} //@ used(true)
+
+type Bar *Node[foo] //@ used(true)
+
+func (n Node[T]) anyMethod() {} //@ used(false)
+
+func fn11[T ~struct{ Field int }]() { //@ used(false)
+	// don't crash because of the composite literal
+	_ = T{Field: 42}
+}
+
+type convertGeneric1 struct { //@ used(true)
+	field int //@ used(true)
+}
+
+type convertGeneric2 struct { //@ used(true)
+	field int //@ used(true)
+}
+
+var _ = convertGeneric1{}.field // mark field as used
+
+func Fn12[T1 convertGeneric1, T2 convertGeneric2](a T1) { //@ used(true)
+	_ = T2(a) // conversion marks T2.field as used
+}
diff -pruN 2022.1-1/unused/testdata/src/types/types.go 2022.1.3-1/unused/testdata/src/types/types.go
--- 2022.1-1/unused/testdata/src/types/types.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/types/types.go	2022-07-31 15:38:22.000000000 +0000
@@ -2,16 +2,16 @@ package pkg
 
 import "reflect"
 
-type wkt interface { // used
-	XXX_WellKnownType() string // used
+type wkt interface { //@ used(true)
+	XXX_WellKnownType() string //@ used(true)
 }
 
-var typeOfWkt = reflect.TypeOf((*wkt)(nil)).Elem() // used
+var typeOfWkt = reflect.TypeOf((*wkt)(nil)).Elem() //@ used(true)
 
-func Fn() { // used
+func Fn() { //@ used(true)
 	_ = typeOfWkt
 }
 
-type t *int // used
+type t *int //@ used(true)
 
 var _ t
diff -pruN 2022.1-1/unused/testdata/src/unused-argument/unused-argument.go 2022.1.3-1/unused/testdata/src/unused-argument/unused-argument.go
--- 2022.1-1/unused/testdata/src/unused-argument/unused-argument.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/unused-argument/unused-argument.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,10 +1,10 @@
 package main
 
-type t1 struct{} // used
-type t2 struct{} // used
+type t1 struct{} //@ used(true)
+type t2 struct{} //@ used(true)
 
-func (t1) foo(arg *t2) {} // used
+func (t1) foo(arg *t2) {} //@ used(true)
 
-func init() { // used
+func init() { //@ used(true)
 	t1{}.foo(nil)
 }
diff -pruN 2022.1-1/unused/testdata/src/unused_type/unused_type.go 2022.1.3-1/unused/testdata/src/unused_type/unused_type.go
--- 2022.1-1/unused/testdata/src/unused_type/unused_type.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/unused_type/unused_type.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,17 +1,17 @@
 package pkg
 
-type t1 struct{} // unused
+type t1 struct{} //@ used(false)
 
-func (t1) Fn() {} // unused
+func (t1) Fn() {} //@ used(false)
 
-type t2 struct{} // used
+type t2 struct{} //@ used(true)
 
-func (*t2) Fn() {} // used
+func (*t2) Fn() {} //@ used(true)
 
-func init() { // used
+func init() { //@ used(true)
 	(*t2).Fn(nil)
 }
 
-type t3 struct{} // unused
+type t3 struct{} //@ used(false)
 
-func (t3) fn() // unused
+func (t3) fn() //@ used(false)
diff -pruN 2022.1-1/unused/testdata/src/variables/variables.go 2022.1.3-1/unused/testdata/src/variables/variables.go
--- 2022.1-1/unused/testdata/src/variables/variables.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/variables/variables.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,23 +1,23 @@
 package pkg
 
-var a byte     // used
-var b [16]byte // used
+var a byte     //@ used(true)
+var b [16]byte //@ used(true)
 
-type t1 struct{} // used
-type t2 struct{} // used
-type t3 struct{} // used
-type t4 struct{} // used
-type t5 struct{} // used
-
-type iface interface{} // used
-
-var x t1           // used
-var y = t2{}       // used
-var j = t3{}       // used
-var k = t4{}       // used
-var l iface = t5{} // used
+type t1 struct{} //@ used(true)
+type t2 struct{} //@ used(true)
+type t3 struct{} //@ used(true)
+type t4 struct{} //@ used(true)
+type t5 struct{} //@ used(true)
+
+type iface interface{} //@ used(true)
+
+var x t1           //@ used(true)
+var y = t2{}       //@ used(true)
+var j = t3{}       //@ used(true)
+var k = t4{}       //@ used(true)
+var l iface = t5{} //@ used(true)
 
-func Fn() { // used
+func Fn() { //@ used(true)
 	println(a)
 	_ = b[:]
 
diff -pruN 2022.1-1/unused/testdata/src/variables/vartype.go 2022.1.3-1/unused/testdata/src/variables/vartype.go
--- 2022.1-1/unused/testdata/src/variables/vartype.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/testdata/src/variables/vartype.go	2022-07-31 15:38:22.000000000 +0000
@@ -1,10 +1,10 @@
 package pkg
 
-type t181025 struct{} // used
+type t181025 struct{} //@ used(true)
 
-func (t181025) F() {} // used
+func (t181025) F() {} //@ used(true)
 
 // package-level variable after function declaration used to trigger a
 // bug in unused.
 
-var V181025 t181025 // used
+var V181025 t181025 //@ used(true)
diff -pruN 2022.1-1/unused/unused.go 2022.1.3-1/unused/unused.go
--- 2022.1-1/unused/unused.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/unused.go	2022-07-31 15:38:22.000000000 +0000
@@ -13,7 +13,8 @@ import (
 	"strings"
 
 	"honnef.co/go/tools/analysis/code"
-	"honnef.co/go/tools/analysis/facts"
+	"honnef.co/go/tools/analysis/facts/directives"
+	"honnef.co/go/tools/analysis/facts/generated"
 	"honnef.co/go/tools/analysis/lint"
 	"honnef.co/go/tools/analysis/report"
 	"honnef.co/go/tools/go/ast/astutil"
@@ -432,7 +433,7 @@ var Analyzer = &lint.Analyzer{
 		Name:       "U1000",
 		Doc:        "Unused code",
 		Run:        run,
-		Requires:   []*analysis.Analyzer{buildir.Analyzer, facts.Generated, facts.Directives},
+		Requires:   []*analysis.Analyzer{buildir.Analyzer, generated.Analyzer, directives.Analyzer},
 		ResultType: reflect.TypeOf(Result{}),
 	},
 }
@@ -520,7 +521,7 @@ func debugf(f string, v ...interface{})
 
 func run(pass *analysis.Pass) (interface{}, error) {
 	irpkg := pass.ResultOf[buildir.Analyzer].(*buildir.IR)
-	dirs := pass.ResultOf[facts.Directives].([]lint.Directive)
+	dirs := pass.ResultOf[directives.Analyzer].([]lint.Directive)
 	pkg := &pkg{
 		Fset:       pass.Fset,
 		Files:      pass.Files,
@@ -832,6 +833,9 @@ func (g *graph) see(obj interface{}) *no
 	if fn, ok := obj.(*types.Func); ok {
 		obj = typeparams.OriginMethod(fn)
 	}
+	if t, ok := obj.(*types.Named); ok {
+		obj = typeparams.NamedTypeOrigin(t)
+	}
 
 	// add new node to graph
 	node, _ := g.node(obj)
@@ -871,6 +875,13 @@ func (g *graph) use(used, by interface{}
 		by = typeparams.OriginMethod(fn)
 	}
 
+	if t, ok := used.(*types.Named); ok {
+		used = typeparams.NamedTypeOrigin(t)
+	}
+	if t, ok := by.(*types.Named); ok {
+		by = typeparams.NamedTypeOrigin(t)
+	}
+
 	usedNode, new := g.node(used)
 	assert(!new)
 	if by == nil {
@@ -1427,13 +1438,14 @@ func (g *graph) typ(t types.Type, parent
 		// Nothing to do
 	case *types.Named:
 		// (9.3) types use their underlying and element types
-		g.seeAndUse(t.Underlying(), t, edgeUnderlyingType)
+		origin := typeparams.NamedTypeOrigin(t)
+		g.seeAndUse(origin.Underlying(), t, edgeUnderlyingType)
 		g.seeAndUse(t.Obj(), t, edgeTypeName)
 		g.seeAndUse(t, t.Obj(), edgeNamedType)
 
 		// (2.4) named types use the pointer type
 		if _, ok := t.Underlying().(*types.Interface); !ok && t.NumMethods() > 0 {
-			g.seeAndUse(g.newPointer(t), t, edgePointerType)
+			g.seeAndUse(g.newPointer(origin), t, edgePointerType)
 		}
 
 		// (2.5) named types use their type parameters
@@ -1462,7 +1474,7 @@ func (g *graph) typ(t types.Type, parent
 			g.function(g.pkg.IR.Prog.FuncValue(t.Method(i)))
 		}
 
-		g.typ(t.Underlying(), t)
+		g.typ(origin.Underlying(), t)
 	case *types.Slice:
 		// (9.3) types use their underlying and element types
 		g.seeAndUse(t.Elem(), t, edgeElementType)
@@ -1619,12 +1631,17 @@ func (g *graph) instructions(fn *ir.Func
 			}
 			switch instr := instr.(type) {
 			case *ir.Field:
+				// Can't access fields via generics, for now.
+
 				st := instr.X.Type().Underlying().(*types.Struct)
 				field := st.Field(instr.Field)
 				// (4.7) functions use fields they access
 				g.seeAndUse(field, fnObj, edgeFieldAccess)
 			case *ir.FieldAddr:
-				st := typeutil.Dereference(instr.X.Type()).Underlying().(*types.Struct)
+				// User code can't access fields on type parameters, but composite literals are still possible, which
+				// compile to FieldAddr + Store.
+
+				st := typeutil.CoreType(typeutil.Dereference(instr.X.Type())).(*types.Struct)
 				field := st.Field(instr.Field)
 				// (4.7) functions use fields they access
 				g.seeAndUse(field, fnObj, edgeFieldAccess)
@@ -1646,8 +1663,8 @@ func (g *graph) instructions(fn *ir.Func
 			case *ir.ChangeType:
 				// conversion type handled generically
 
-				s1, ok1 := typeutil.Dereference(instr.Type()).Underlying().(*types.Struct)
-				s2, ok2 := typeutil.Dereference(instr.X.Type()).Underlying().(*types.Struct)
+				s1, ok1 := typeutil.CoreType(typeutil.Dereference(instr.Type())).(*types.Struct)
+				s2, ok2 := typeutil.CoreType(typeutil.Dereference(instr.X.Type())).(*types.Struct)
 				if ok1 && ok2 {
 					// Converting between two structs. The fields are
 					// relevant for the conversion, but only if the
diff -pruN 2022.1-1/unused/unused_test.go 2022.1.3-1/unused/unused_test.go
--- 2022.1-1/unused/unused_test.go	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/unused/unused_test.go	2022-07-31 15:38:22.000000000 +0000
@@ -9,6 +9,7 @@ import (
 
 	"golang.org/x/exp/typeparams"
 	"golang.org/x/tools/go/analysis/analysistest"
+	"golang.org/x/tools/go/expect"
 )
 
 type expectation bool
@@ -56,42 +57,20 @@ func check(t *testing.T, res *analysiste
 			continue
 		}
 		files[filename] = struct{}{}
-		for _, cgroup := range f.Comments {
-		commentLoop:
-			for _, c := range cgroup.List {
-				text := strings.TrimPrefix(c.Text, "//")
-				if text == c.Text {
-					continue // not a //-comment
-				}
-
-				fields := strings.Fields(text)
-				posn := res.Pass.Fset.Position(c.Pos())
-				for _, field := range fields {
-					switch field {
-					case "used", "unused", "used_test", "unused_test":
-					default:
-						continue commentLoop
-					}
+		notes, err := expect.ExtractGo(res.Pass.Fset, f)
+		if err != nil {
+			t.Fatal(err)
+		}
+		for _, note := range notes {
+			posn := res.Pass.Fset.PositionFor(note.Pos, false)
+			switch note.Name {
+			case "used":
+				if !isTest {
+					want[key{posn.Filename, posn.Line}] = expectation(note.Args[0].(bool))
 				}
-				for _, field := range fields {
-					switch field {
-					case "used":
-						if !isTest {
-							want[key{posn.Filename, posn.Line}] = shouldBeUsed
-						}
-					case "unused":
-						if !isTest {
-							want[key{posn.Filename, posn.Line}] = shouldBeUnused
-						}
-					case "used_test":
-						if isTest {
-							want[key{posn.Filename, posn.Line}] = shouldBeUsed
-						}
-					case "unused_test":
-						if isTest {
-							want[key{posn.Filename, posn.Line}] = shouldBeUnused
-						}
-					}
+			case "used_test":
+				if isTest {
+					want[key{posn.Filename, posn.Line}] = expectation(note.Args[0].(bool))
 				}
 			}
 		}
@@ -140,7 +119,7 @@ func check(t *testing.T, res *analysiste
 		if b {
 			exp = "used"
 		} else {
-			exp = "unused "
+			exp = "unused"
 		}
 		t.Errorf("did not see expected %s object %s:%d", exp, key.file, key.line)
 	}
diff -pruN 2022.1-1/website/content/changes/2022.1.md 2022.1.3-1/website/content/changes/2022.1.md
--- 2022.1-1/website/content/changes/2022.1.md	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/website/content/changes/2022.1.md	2022-07-31 15:38:22.000000000 +0000
@@ -47,3 +47,48 @@ The following checks have been improved:
 - Numerous checks have a better understanding of integer literals and can detect mistakes involving unconventional
   literals such as `---1` instead of `-1`
 - Some runtime crashes have been fixed
+
+## Staticcheck 2022.1.1 release notes {#2022.1.1}
+
+This release addresses the following false positives, crashes, and infinite loops:
+
+- {{< check "SA1026" >}} and {{< check "SA5008" >}} no longer get stuck in infinite loops when code attempts to marshal cyclic pointer types ({{< issue "1202" >}})
+- U1000 no longer crashes when code contains mutually recursive type instantiations ({{< issue "1247" >}})
+- U1000 no longer crashes when generic functions use composite literals of type parameter types ({{< commit "0ccdb5c9dad7e96a8e3a3136738192491b37dbdb" >}})
+- {{< check "ST1021" >}} now understands type names that are also English articles ({{< issue "1187" >}})
+- {{< check "SA4023" >}} no longer gets confused by the nilness of type parameters ({{< issue "1242" >}})
+- Some checks no longer crash when trying to generate automated code fixes that involve function literals ({{< issue "1134" >}})
+- {{< check "SA1026" >}} no longer claims that `encoding/json` cannot marshal generic maps ([golang/go#52467](https://golang.org/issue/52467))
+- The `binary` format has been improved to handle OS-specific file paths correctly, in turn making the `-merge` flag work more reliably ({{< commit "1846305a946b13d350894512c7ac1e5ed71dc331" >}})
+- When using the `-merge` or `-matrix` flags, diagnostics reported by {{< check "SA4008" >}} now have to occur in all runs to be reported, reducing the number of false positives ({{< commit "0e678cbe1c8b3f09ac481673453886b1afc9906a" >}})
+- U1000 now understands struct type conversions involving type parameters, reducing the number of false positives ({{< commit "90804df0287d9265e565bcabbe19568efbe374fa" >}})
+
+## Staticcheck 2022.1.2 release notes {#2022.1.2}
+
+This release addresses the following false positives, crashes, infinite loops, and performance issues:
+
+- For certain packages that contain tens of thousands of types and methods, such as those generated by
+  [ygot](https://github.com/openconfig/ygot), Staticcheck now finishes [much
+  faster](https://github.com/openconfig/featureprofiles/pull/181#issuecomment-1119250596).
+- Several infinite loops when handling recursive type parameters have been fixed
+- {{< check "S1009" >}} no longer mistakes user-defined functions named `len` for the builtin ({{< issue "1181" >}})
+- {{< check "ST1015" >}} no longer reorders `switch` statements if their order is significant due to the use of `fallthrough` ({{< issue "1188" >}})
+- {{< check "SA1013" >}} now detects constants more robustly, avoiding both false negatives and false positives.
+  Furthermore, it makes sure that offending methods implement io.Seeker and doesn't just rely on the name `Seek` ({{< issue "1213" >}}).
+- {{< check "SA5008" >}} now understands more third-party extensions to `json` struct tags
+- A crash involving functions named `_` has been fixed ({{< issue "1268" >}})
+- A crash involving slicing type parameters of type `string | []byte` has been fixed ({{< issue "1270" >}})
+- {{< check "SA1019" >}} now handles imports of deprecated standard library packages in the same way it handles other
+  deprecated API, taking the targeted Go version into consideration ({{< issue "1117" >}})
+
+Additionally it is strongly recommended to use Go 1.18.2 for building Staticcheck, as it fixes further generics-related
+bugs in the type checker.
+
+## Staticcheck 2022.1.3 release notes {#2022.1.3}
+
+This release addresses the following issues:
+
+- Staticcheck maintains a cache to speed up repeated runs. This cache needs to be pruned regularly to keep its size in
+  check. This is meant to happen automatically, but it hasn't since Staticcheck 2020.2. This release corrects that ({{<
+  issue "1283" >}}.)
+- Some type sets containing both bidirectional and unidirectional channels would lead to panics ({{< issue "1304" >}})
diff -pruN 2022.1-1/website/data/checks.json 2022.1.3-1/website/data/checks.json
--- 2022.1-1/website/data/checks.json	2022-03-30 17:05:24.000000000 +0000
+++ 2022.1.3-1/website/data/checks.json	2022-07-31 15:38:22.000000000 +0000
@@ -1155,7 +1155,7 @@
 			"NonDefault": false,
 			"Options": null,
 			"Severity": 3,
-			"MergeIf": 0
+			"MergeIf": 1
 		},
 		"SA4009": {
 			"Title": "A function argument is overwritten before its first use",
diff -pruN 2022.1-1/website/layouts/shortcodes/commit.html 2022.1.3-1/website/layouts/shortcodes/commit.html
--- 2022.1-1/website/layouts/shortcodes/commit.html	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/website/layouts/shortcodes/commit.html	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1 @@
+{{ with .Get 0 }}<a title="commit {{ . }}" href="https://github.com/dominikh/go-tools/commit/{{ . }}">{{ . }}</a>{{ end -}}
diff -pruN 2022.1-1/website/layouts/shortcodes/issue.html 2022.1.3-1/website/layouts/shortcodes/issue.html
--- 2022.1-1/website/layouts/shortcodes/issue.html	1970-01-01 00:00:00.000000000 +0000
+++ 2022.1.3-1/website/layouts/shortcodes/issue.html	2022-07-31 15:38:22.000000000 +0000
@@ -0,0 +1 @@
+{{ with .Get 0 }}<a title="issue {{ . }}" href="https://staticcheck.io/issues/{{ . }}">issue {{ . }}</a>{{ end -}}
