// Code generated by "precompile.go". DO NOT EDIT.

package rulesdata

import "github.com/quasilyte/go-ruleguard/ruleguard/ir"

var PrecompiledRules = &ir.File{
	PkgPath:       "gorules",
	CustomDecls:   []string{},
	BundleImports: []ir.BundleImport{},
	RuleGroups: []ir.RuleGroup{
		ir.RuleGroup{
			Line:        11,
			Name:        "redundantSprint",
			MatcherName: "m",
			DocTags: []string{
				"style",
				"experimental",
			},
			DocSummary: "Detects redundant fmt.Sprint calls",
			DocBefore:  "fmt.Sprint(x)",
			DocAfter:   "x.String()",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 12,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 12, Value: "fmt.Sprint($x)"},
						ir.PatternString{Line: 12, Value: "fmt.Sprintf(\"%s\", $x)"},
						ir.PatternString{Line: 12, Value: "fmt.Sprintf(\"%v\", $x)"},
					},
					ReportTemplate:  "use $x.String() instead",
					SuggestTemplate: "$x.String()",
					WhereExpr: ir.FilterExpr{
						Line:  13,
						Op:    ir.FilterVarTypeImplementsOp,
						Src:   "m[\"x\"].Type.Implements(`fmt.Stringer`)",
						Value: "x",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 13, Op: ir.FilterStringOp, Src: "`fmt.Stringer`", Value: "fmt.Stringer"},
						},
					},
				},
				ir.Rule{
					Line: 17,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 17, Value: "fmt.Sprint($x)"},
						ir.PatternString{Line: 17, Value: "fmt.Sprintf(\"%s\", $x)"},
						ir.PatternString{Line: 17, Value: "fmt.Sprintf(\"%v\", $x)"},
					},
					ReportTemplate:  "use $x.Error() instead",
					SuggestTemplate: "$x.Error()",
					WhereExpr: ir.FilterExpr{
						Line:  18,
						Op:    ir.FilterVarTypeImplementsOp,
						Src:   "m[\"x\"].Type.Implements(`error`)",
						Value: "x",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 18, Op: ir.FilterStringOp, Src: "`error`", Value: "error"},
						},
					},
				},
				ir.Rule{
					Line: 22,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 22, Value: "fmt.Sprint($x)"},
						ir.PatternString{Line: 22, Value: "fmt.Sprintf(\"%s\", $x)"},
						ir.PatternString{Line: 22, Value: "fmt.Sprintf(\"%v\", $x)"},
					},
					ReportTemplate:  "$x is already string",
					SuggestTemplate: "$x",
					WhereExpr: ir.FilterExpr{
						Line:  23,
						Op:    ir.FilterVarTypeIsOp,
						Src:   "m[\"x\"].Type.Is(`string`)",
						Value: "x",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 23, Op: ir.FilterStringOp, Src: "`string`", Value: "string"},
						},
					},
				},
			},
		},
		ir.RuleGroup{
			Line:        32,
			Name:        "deferUnlambda",
			MatcherName: "m",
			DocTags: []string{
				"style",
				"experimental",
			},
			DocSummary: "Detects deferred function literals that can be simplified",
			DocBefore:  "defer func() { f() }()",
			DocAfter:   "defer f()",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 33,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 33, Value: "defer func() { $f($*args) }()"},
					},
					ReportTemplate: "can rewrite as `defer $f($args)`",
					WhereExpr: ir.FilterExpr{
						Line: 34,
						Op:   ir.FilterAndOp,
						Src:  "m[\"f\"].Node.Is(`Ident`) && m[\"f\"].Text != \"panic\" && m[\"f\"].Text != \"recover\" && m[\"args\"].Const",
						Args: []ir.FilterExpr{
							ir.FilterExpr{
								Line: 34,
								Op:   ir.FilterAndOp,
								Src:  "m[\"f\"].Node.Is(`Ident`) && m[\"f\"].Text != \"panic\" && m[\"f\"].Text != \"recover\"",
								Args: []ir.FilterExpr{
									ir.FilterExpr{
										Line: 34,
										Op:   ir.FilterAndOp,
										Src:  "m[\"f\"].Node.Is(`Ident`) && m[\"f\"].Text != \"panic\"",
										Args: []ir.FilterExpr{
											ir.FilterExpr{
												Line:  34,
												Op:    ir.FilterVarNodeIsOp,
												Src:   "m[\"f\"].Node.Is(`Ident`)",
												Value: "f",
												Args: []ir.FilterExpr{
													ir.FilterExpr{Line: 34, Op: ir.FilterStringOp, Src: "`Ident`", Value: "Ident"},
												},
											},
											ir.FilterExpr{
												Line: 34,
												Op:   ir.FilterNeqOp,
												Src:  "m[\"f\"].Text != \"panic\"",
												Args: []ir.FilterExpr{
													ir.FilterExpr{Line: 34, Op: ir.FilterVarTextOp, Src: "m[\"f\"].Text", Value: "f"},
													ir.FilterExpr{Line: 34, Op: ir.FilterStringOp, Src: "\"panic\"", Value: "panic"},
												},
											},
										},
									},
									ir.FilterExpr{
										Line: 34,
										Op:   ir.FilterNeqOp,
										Src:  "m[\"f\"].Text != \"recover\"",
										Args: []ir.FilterExpr{
											ir.FilterExpr{Line: 34, Op: ir.FilterVarTextOp, Src: "m[\"f\"].Text", Value: "f"},
											ir.FilterExpr{Line: 34, Op: ir.FilterStringOp, Src: "\"recover\"", Value: "recover"},
										},
									},
								},
							},
							ir.FilterExpr{
								Line:  34,
								Op:    ir.FilterVarConstOp,
								Src:   "m[\"args\"].Const",
								Value: "args",
							},
						},
					},
				},
				ir.Rule{
					Line: 37,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 37, Value: "defer func() { $pkg.$f($*args) }()"},
					},
					ReportTemplate: "can rewrite as `defer $pkg.$f($args)`",
					WhereExpr: ir.FilterExpr{
						Line: 38,
						Op:   ir.FilterAndOp,
						Src:  "m[\"f\"].Node.Is(`Ident`) && m[\"args\"].Const && m[\"pkg\"].Object.Is(`PkgName`)",
						Args: []ir.FilterExpr{
							ir.FilterExpr{
								Line: 38,
								Op:   ir.FilterAndOp,
								Src:  "m[\"f\"].Node.Is(`Ident`) && m[\"args\"].Const",
								Args: []ir.FilterExpr{
									ir.FilterExpr{
										Line:  38,
										Op:    ir.FilterVarNodeIsOp,
										Src:   "m[\"f\"].Node.Is(`Ident`)",
										Value: "f",
										Args: []ir.FilterExpr{
											ir.FilterExpr{Line: 38, Op: ir.FilterStringOp, Src: "`Ident`", Value: "Ident"},
										},
									},
									ir.FilterExpr{
										Line:  38,
										Op:    ir.FilterVarConstOp,
										Src:   "m[\"args\"].Const",
										Value: "args",
									},
								},
							},
							ir.FilterExpr{
								Line:  38,
								Op:    ir.FilterVarObjectIsOp,
								Src:   "m[\"pkg\"].Object.Is(`PkgName`)",
								Value: "pkg",
								Args: []ir.FilterExpr{
									ir.FilterExpr{Line: 38, Op: ir.FilterStringOp, Src: "`PkgName`", Value: "PkgName"},
								},
							},
						},
					},
				},
			},
		},
		ir.RuleGroup{
			Line:        46,
			Name:        "ioutilDeprecated",
			MatcherName: "m",
			DocTags: []string{
				"style",
				"experimental",
			},
			DocSummary: "Detects deprecated io/ioutil package usages",
			DocBefore:  "ioutil.ReadAll(r)",
			DocAfter:   "io.ReadAll(r)",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 47,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 47, Value: "ioutil.ReadAll($_)"},
					},
					ReportTemplate: "ioutil.ReadAll is deprecated, use io.ReadAll instead",
					WhereExpr: ir.FilterExpr{
						Line:  48,
						Op:    ir.FilterGoVersionGreaterEqThanOp,
						Src:   "m.GoVersion().GreaterEqThan(\"1.16\")",
						Value: "1.16",
					},
				},
				ir.Rule{
					Line: 51,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 51, Value: "ioutil.ReadFile($_)"},
					},
					ReportTemplate: "ioutil.ReadFile is deprecated, use os.ReadFile instead",
					WhereExpr: ir.FilterExpr{
						Line:  52,
						Op:    ir.FilterGoVersionGreaterEqThanOp,
						Src:   "m.GoVersion().GreaterEqThan(\"1.16\")",
						Value: "1.16",
					},
				},
				ir.Rule{
					Line: 55,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 55, Value: "ioutil.WriteFile($_, $_, $_)"},
					},
					ReportTemplate: "ioutil.WriteFile is deprecated, use os.WriteFile instead",
					WhereExpr: ir.FilterExpr{
						Line:  56,
						Op:    ir.FilterGoVersionGreaterEqThanOp,
						Src:   "m.GoVersion().GreaterEqThan(\"1.16\")",
						Value: "1.16",
					},
				},
				ir.Rule{
					Line: 59,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 59, Value: "ioutil.ReadDir($_)"},
					},
					ReportTemplate: "ioutil.ReadDir is deprecated, use os.ReadDir instead",
					WhereExpr: ir.FilterExpr{
						Line:  60,
						Op:    ir.FilterGoVersionGreaterEqThanOp,
						Src:   "m.GoVersion().GreaterEqThan(\"1.16\")",
						Value: "1.16",
					},
				},
				ir.Rule{
					Line: 63,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 63, Value: "ioutil.NopCloser($_)"},
					},
					ReportTemplate: "ioutil.NopCloser is deprecated, use io.NopCloser instead",
					WhereExpr: ir.FilterExpr{
						Line:  64,
						Op:    ir.FilterGoVersionGreaterEqThanOp,
						Src:   "m.GoVersion().GreaterEqThan(\"1.16\")",
						Value: "1.16",
					},
				},
				ir.Rule{
					Line: 67,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 67, Value: "ioutil.Discard"},
					},
					ReportTemplate: "ioutil.Discard is deprecated, use io.Discard instead",
					WhereExpr: ir.FilterExpr{
						Line:  68,
						Op:    ir.FilterGoVersionGreaterEqThanOp,
						Src:   "m.GoVersion().GreaterEqThan(\"1.16\")",
						Value: "1.16",
					},
				},
			},
		},
		ir.RuleGroup{
			Line:        76,
			Name:        "badLock",
			MatcherName: "m",
			DocTags: []string{
				"diagnostic",
				"experimental",
			},
			DocSummary: "Detects suspicious mutex lock/unlock operations",
			DocBefore:  "mu.Lock(); mu.Unlock()",
			DocAfter:   "mu.Lock(); defer mu.Unlock()",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 80,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 80, Value: "$mu1.Lock(); $mu2.Unlock()"},
					},
					ReportTemplate: "defer is missing, mutex is unlocked immediately",
					WhereExpr: ir.FilterExpr{
						Line: 81,
						Op:   ir.FilterEqOp,
						Src:  "m[\"mu1\"].Text == m[\"mu2\"].Text",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 81, Op: ir.FilterVarTextOp, Src: "m[\"mu1\"].Text", Value: "mu1"},
							ir.FilterExpr{Line: 81, Op: ir.FilterVarTextOp, Src: "m[\"mu2\"].Text", Value: "mu2"},
						},
					},
					LocationVar: "mu2",
				},
				ir.Rule{
					Line: 85,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 85, Value: "$mu1.RLock(); $mu2.RUnlock()"},
					},
					ReportTemplate: "defer is missing, mutex is unlocked immediately",
					WhereExpr: ir.FilterExpr{
						Line: 86,
						Op:   ir.FilterEqOp,
						Src:  "m[\"mu1\"].Text == m[\"mu2\"].Text",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 86, Op: ir.FilterVarTextOp, Src: "m[\"mu1\"].Text", Value: "mu1"},
							ir.FilterExpr{Line: 86, Op: ir.FilterVarTextOp, Src: "m[\"mu2\"].Text", Value: "mu2"},
						},
					},
					LocationVar: "mu2",
				},
				ir.Rule{
					Line: 91,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 91, Value: "$mu1.Lock(); defer $mu2.RUnlock()"},
					},
					ReportTemplate: "suspicious unlock, maybe Unlock was intended?",
					WhereExpr: ir.FilterExpr{
						Line: 92,
						Op:   ir.FilterEqOp,
						Src:  "m[\"mu1\"].Text == m[\"mu2\"].Text",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 92, Op: ir.FilterVarTextOp, Src: "m[\"mu1\"].Text", Value: "mu1"},
							ir.FilterExpr{Line: 92, Op: ir.FilterVarTextOp, Src: "m[\"mu2\"].Text", Value: "mu2"},
						},
					},
					LocationVar: "mu2",
				},
				ir.Rule{
					Line: 96,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 96, Value: "$mu1.RLock(); defer $mu2.Unlock()"},
					},
					ReportTemplate: "suspicious unlock, maybe RUnlock was intended?",
					WhereExpr: ir.FilterExpr{
						Line: 97,
						Op:   ir.FilterEqOp,
						Src:  "m[\"mu1\"].Text == m[\"mu2\"].Text",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 97, Op: ir.FilterVarTextOp, Src: "m[\"mu1\"].Text", Value: "mu1"},
							ir.FilterExpr{Line: 97, Op: ir.FilterVarTextOp, Src: "m[\"mu2\"].Text", Value: "mu2"},
						},
					},
					LocationVar: "mu2",
				},
				ir.Rule{
					Line: 102,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 102, Value: "$mu1.Lock(); defer $mu2.Lock()"},
					},
					ReportTemplate: "maybe defer $mu1.Unlock() was intended?",
					WhereExpr: ir.FilterExpr{
						Line: 103,
						Op:   ir.FilterEqOp,
						Src:  "m[\"mu1\"].Text == m[\"mu2\"].Text",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 103, Op: ir.FilterVarTextOp, Src: "m[\"mu1\"].Text", Value: "mu1"},
							ir.FilterExpr{Line: 103, Op: ir.FilterVarTextOp, Src: "m[\"mu2\"].Text", Value: "mu2"},
						},
					},
					LocationVar: "mu2",
				},
				ir.Rule{
					Line: 107,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 107, Value: "$mu1.RLock(); defer $mu2.RLock()"},
					},
					ReportTemplate: "maybe defer $mu1.RUnlock() was intended?",
					WhereExpr: ir.FilterExpr{
						Line: 108,
						Op:   ir.FilterEqOp,
						Src:  "m[\"mu1\"].Text == m[\"mu2\"].Text",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 108, Op: ir.FilterVarTextOp, Src: "m[\"mu1\"].Text", Value: "mu1"},
							ir.FilterExpr{Line: 108, Op: ir.FilterVarTextOp, Src: "m[\"mu2\"].Text", Value: "mu2"},
						},
					},
					LocationVar: "mu2",
				},
			},
		},
		ir.RuleGroup{
			Line:        117,
			Name:        "httpNoBody",
			MatcherName: "m",
			DocTags: []string{
				"style",
				"experimental",
			},
			DocSummary: "Detects nil usages in http.NewRequest calls, suggesting http.NoBody as an alternative",
			DocBefore:  "http.NewRequest(\"GET\", url, nil)",
			DocAfter:   "http.NewRequest(\"GET\", url, http.NoBody)",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 118,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 118, Value: "http.NewRequest($method, $url, $nil)"},
					},
					ReportTemplate:  "http.NoBody should be preferred to the nil request body",
					SuggestTemplate: "http.NewRequest($method, $url, http.NoBody)",
					WhereExpr: ir.FilterExpr{
						Line: 119,
						Op:   ir.FilterEqOp,
						Src:  "m[\"nil\"].Text == \"nil\"",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 119, Op: ir.FilterVarTextOp, Src: "m[\"nil\"].Text", Value: "nil"},
							ir.FilterExpr{Line: 119, Op: ir.FilterStringOp, Src: "\"nil\"", Value: "nil"},
						},
					},
					LocationVar: "nil",
				},
				ir.Rule{
					Line: 124,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 124, Value: "http.NewRequestWithContext($ctx, $method, $url, $nil)"},
					},
					ReportTemplate:  "http.NoBody should be preferred to the nil request body",
					SuggestTemplate: "http.NewRequestWithContext($ctx, $method, $url, http.NoBody)",
					WhereExpr: ir.FilterExpr{
						Line: 125,
						Op:   ir.FilterEqOp,
						Src:  "m[\"nil\"].Text == \"nil\"",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 125, Op: ir.FilterVarTextOp, Src: "m[\"nil\"].Text", Value: "nil"},
							ir.FilterExpr{Line: 125, Op: ir.FilterStringOp, Src: "\"nil\"", Value: "nil"},
						},
					},
					LocationVar: "nil",
				},
			},
		},
		ir.RuleGroup{
			Line:        136,
			Name:        "preferDecodeRune",
			MatcherName: "m",
			DocTags: []string{
				"performance",
				"experimental",
			},
			DocSummary: "Detects expressions like []rune(s)[0] that may cause unwanted rune slice allocation",
			DocBefore:  "r := []rune(s)[0]",
			DocAfter:   "r, _ := utf8.DecodeRuneInString(s)",
			DocNote:    "See Go issue for details: https://github.com/golang/go/issues/45260",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 137,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 137, Value: "[]rune($s)[0]"},
					},
					ReportTemplate: "consider replacing $$ with utf8.DecodeRuneInString($s)",
					WhereExpr: ir.FilterExpr{
						Line:  138,
						Op:    ir.FilterVarTypeIsOp,
						Src:   "m[\"s\"].Type.Is(`string`)",
						Value: "s",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 138, Op: ir.FilterStringOp, Src: "`string`", Value: "string"},
						},
					},
				},
			},
		},
		ir.RuleGroup{
			Line:        146,
			Name:        "sloppyLen",
			MatcherName: "m",
			DocTags: []string{
				"style",
			},
			DocSummary: "Detects usage of `len` when result is obvious or doesn't make sense",
			DocBefore:  "len(arr) <= 0",
			DocAfter:   "len(arr) == 0",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 147,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 147, Value: "len($_) >= 0"},
					},
					ReportTemplate: "$$ is always true",
				},
				ir.Rule{
					Line: 148,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 148, Value: "len($_) < 0"},
					},
					ReportTemplate: "$$ is always false",
				},
				ir.Rule{
					Line: 149,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 149, Value: "len($x) <= 0"},
					},
					ReportTemplate: "$$ can be len($x) == 0",
				},
			},
		},
		ir.RuleGroup{
			Line:        156,
			Name:        "valSwap",
			MatcherName: "m",
			DocTags: []string{
				"style",
			},
			DocSummary: "Detects value swapping code that are not using parallel assignment",
			DocBefore:  "*tmp = *x; *x = *y; *y = *tmp",
			DocAfter:   "*x, *y = *y, *x",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 157,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 157, Value: "$tmp := $y; $y = $x; $x = $tmp"},
					},
					ReportTemplate: "can re-write as `$y, $x = $x, $y`",
				},
			},
		},
		ir.RuleGroup{
			Line:        165,
			Name:        "switchTrue",
			MatcherName: "m",
			DocTags: []string{
				"style",
			},
			DocSummary: "Detects switch-over-bool statements that use explicit `true` tag value",
			DocBefore:  "switch true {...}",
			DocAfter:   "switch {...}",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 166,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 166, Value: "switch true { $*_ }"},
					},
					ReportTemplate: "replace 'switch true {}' with 'switch {}'",
				},
				ir.Rule{
					Line: 168,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 168, Value: "switch $x; true { $*_ }"},
					},
					ReportTemplate: "replace 'switch $x; true {}' with 'switch $x; {}'",
				},
			},
		},
		ir.RuleGroup{
			Line:        176,
			Name:        "flagDeref",
			MatcherName: "m",
			DocTags: []string{
				"diagnostic",
			},
			DocSummary: "Detects immediate dereferencing of `flag` package pointers",
			DocBefore:  "b := *flag.Bool(\"b\", false, \"b docs\")",
			DocAfter:   "var b bool; flag.BoolVar(&b, \"b\", false, \"b docs\")",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 177,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 177, Value: "*flag.Bool($*_)"},
					},
					ReportTemplate: "immediate deref in $$ is most likely an error; consider using flag.BoolVar",
				},
				ir.Rule{
					Line: 178,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 178, Value: "*flag.Duration($*_)"},
					},
					ReportTemplate: "immediate deref in $$ is most likely an error; consider using flag.DurationVar",
				},
				ir.Rule{
					Line: 179,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 179, Value: "*flag.Float64($*_)"},
					},
					ReportTemplate: "immediate deref in $$ is most likely an error; consider using flag.Float64Var",
				},
				ir.Rule{
					Line: 180,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 180, Value: "*flag.Int($*_)"},
					},
					ReportTemplate: "immediate deref in $$ is most likely an error; consider using flag.IntVar",
				},
				ir.Rule{
					Line: 181,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 181, Value: "*flag.Int64($*_)"},
					},
					ReportTemplate: "immediate deref in $$ is most likely an error; consider using flag.Int64Var",
				},
				ir.Rule{
					Line: 182,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 182, Value: "*flag.String($*_)"},
					},
					ReportTemplate: "immediate deref in $$ is most likely an error; consider using flag.StringVar",
				},
				ir.Rule{
					Line: 183,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 183, Value: "*flag.Uint($*_)"},
					},
					ReportTemplate: "immediate deref in $$ is most likely an error; consider using flag.UintVar",
				},
				ir.Rule{
					Line: 184,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 184, Value: "*flag.Uint64($*_)"},
					},
					ReportTemplate: "immediate deref in $$ is most likely an error; consider using flag.Uint64Var",
				},
			},
		},
		ir.RuleGroup{
			Line:        191,
			Name:        "emptyStringTest",
			MatcherName: "m",
			DocTags: []string{
				"style",
				"experimental",
			},
			DocSummary: "Detects empty string checks that can be written more idiomatically",
			DocBefore:  "len(s) == 0",
			DocAfter:   "s == \"\"",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 192,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 192, Value: "len($s) != 0"},
					},
					ReportTemplate: "replace `$$` with `$s != \"\"`",
					WhereExpr: ir.FilterExpr{
						Line:  193,
						Op:    ir.FilterVarTypeIsOp,
						Src:   "m[\"s\"].Type.Is(`string`)",
						Value: "s",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 193, Op: ir.FilterStringOp, Src: "`string`", Value: "string"},
						},
					},
				},
				ir.Rule{
					Line: 196,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 196, Value: "len($s) == 0"},
					},
					ReportTemplate: "replace `$$` with `$s == \"\"`",
					WhereExpr: ir.FilterExpr{
						Line:  197,
						Op:    ir.FilterVarTypeIsOp,
						Src:   "m[\"s\"].Type.Is(`string`)",
						Value: "s",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 197, Op: ir.FilterStringOp, Src: "`string`", Value: "string"},
						},
					},
				},
			},
		},
		ir.RuleGroup{
			Line:        205,
			Name:        "stringXbytes",
			MatcherName: "m",
			DocTags: []string{
				"performance",
			},
			DocSummary: "Detects redundant conversions between string and []byte",
			DocBefore:  "copy(b, []byte(s))",
			DocAfter:   "copy(b, s)",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 206,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 206, Value: "copy($_, []byte($s))"},
					},
					ReportTemplate: "can simplify `[]byte($s)` to `$s`",
				},
				ir.Rule{
					Line: 208,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 208, Value: "string($b) == \"\""},
					},
					ReportTemplate:  "suggestion: len($b) == 0",
					SuggestTemplate: "len($b) == 0",
					WhereExpr: ir.FilterExpr{
						Line:  208,
						Op:    ir.FilterVarTypeIsOp,
						Src:   "m[\"b\"].Type.Is(`[]byte`)",
						Value: "b",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 208, Op: ir.FilterStringOp, Src: "`[]byte`", Value: "[]byte"},
						},
					},
				},
				ir.Rule{
					Line: 209,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 209, Value: "string($b) != \"\""},
					},
					ReportTemplate:  "suggestion: len($b) != 0",
					SuggestTemplate: "len($b) != 0",
					WhereExpr: ir.FilterExpr{
						Line:  209,
						Op:    ir.FilterVarTypeIsOp,
						Src:   "m[\"b\"].Type.Is(`[]byte`)",
						Value: "b",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 209, Op: ir.FilterStringOp, Src: "`[]byte`", Value: "[]byte"},
						},
					},
				},
				ir.Rule{
					Line: 211,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 211, Value: "len(string($b))"},
					},
					ReportTemplate:  "suggestion: len($b)",
					SuggestTemplate: "len($b)",
					WhereExpr: ir.FilterExpr{
						Line:  211,
						Op:    ir.FilterVarTypeIsOp,
						Src:   "m[\"b\"].Type.Is(`[]byte`)",
						Value: "b",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 211, Op: ir.FilterStringOp, Src: "`[]byte`", Value: "[]byte"},
						},
					},
				},
				ir.Rule{
					Line: 213,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 213, Value: "string($x) == string($y)"},
					},
					ReportTemplate:  "suggestion: bytes.Equal($x, $y)",
					SuggestTemplate: "bytes.Equal($x, $y)",
					WhereExpr: ir.FilterExpr{
						Line: 214,
						Op:   ir.FilterAndOp,
						Src:  "m[\"x\"].Type.Is(`[]byte`) && m[\"y\"].Type.Is(`[]byte`)",
						Args: []ir.FilterExpr{
							ir.FilterExpr{
								Line:  214,
								Op:    ir.FilterVarTypeIsOp,
								Src:   "m[\"x\"].Type.Is(`[]byte`)",
								Value: "x",
								Args: []ir.FilterExpr{
									ir.FilterExpr{Line: 214, Op: ir.FilterStringOp, Src: "`[]byte`", Value: "[]byte"},
								},
							},
							ir.FilterExpr{
								Line:  214,
								Op:    ir.FilterVarTypeIsOp,
								Src:   "m[\"y\"].Type.Is(`[]byte`)",
								Value: "y",
								Args: []ir.FilterExpr{
									ir.FilterExpr{Line: 214, Op: ir.FilterStringOp, Src: "`[]byte`", Value: "[]byte"},
								},
							},
						},
					},
				},
				ir.Rule{
					Line: 217,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 217, Value: "string($x) != string($y)"},
					},
					ReportTemplate:  "suggestion: !bytes.Equal($x, $y)",
					SuggestTemplate: "!bytes.Equal($x, $y)",
					WhereExpr: ir.FilterExpr{
						Line: 218,
						Op:   ir.FilterAndOp,
						Src:  "m[\"x\"].Type.Is(`[]byte`) && m[\"y\"].Type.Is(`[]byte`)",
						Args: []ir.FilterExpr{
							ir.FilterExpr{
								Line:  218,
								Op:    ir.FilterVarTypeIsOp,
								Src:   "m[\"x\"].Type.Is(`[]byte`)",
								Value: "x",
								Args: []ir.FilterExpr{
									ir.FilterExpr{Line: 218, Op: ir.FilterStringOp, Src: "`[]byte`", Value: "[]byte"},
								},
							},
							ir.FilterExpr{
								Line:  218,
								Op:    ir.FilterVarTypeIsOp,
								Src:   "m[\"y\"].Type.Is(`[]byte`)",
								Value: "y",
								Args: []ir.FilterExpr{
									ir.FilterExpr{Line: 218, Op: ir.FilterStringOp, Src: "`[]byte`", Value: "[]byte"},
								},
							},
						},
					},
				},
				ir.Rule{
					Line: 221,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 221, Value: "$re.Match([]byte($s))"},
					},
					ReportTemplate:  "suggestion: $re.MatchString($s)",
					SuggestTemplate: "$re.MatchString($s)",
					WhereExpr: ir.FilterExpr{
						Line: 222,
						Op:   ir.FilterAndOp,
						Src:  "m[\"re\"].Type.Is(`*regexp.Regexp`) && m[\"s\"].Type.Is(`string`)",
						Args: []ir.FilterExpr{
							ir.FilterExpr{
								Line:  222,
								Op:    ir.FilterVarTypeIsOp,
								Src:   "m[\"re\"].Type.Is(`*regexp.Regexp`)",
								Value: "re",
								Args: []ir.FilterExpr{
									ir.FilterExpr{Line: 222, Op: ir.FilterStringOp, Src: "`*regexp.Regexp`", Value: "*regexp.Regexp"},
								},
							},
							ir.FilterExpr{
								Line:  222,
								Op:    ir.FilterVarTypeIsOp,
								Src:   "m[\"s\"].Type.Is(`string`)",
								Value: "s",
								Args: []ir.FilterExpr{
									ir.FilterExpr{Line: 222, Op: ir.FilterStringOp, Src: "`string`", Value: "string"},
								},
							},
						},
					},
				},
				ir.Rule{
					Line: 225,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 225, Value: "$re.FindIndex([]byte($s))"},
					},
					ReportTemplate:  "suggestion: $re.FindStringIndex($s)",
					SuggestTemplate: "$re.FindStringIndex($s)",
					WhereExpr: ir.FilterExpr{
						Line: 226,
						Op:   ir.FilterAndOp,
						Src:  "m[\"re\"].Type.Is(`*regexp.Regexp`) && m[\"s\"].Type.Is(`string`)",
						Args: []ir.FilterExpr{
							ir.FilterExpr{
								Line:  226,
								Op:    ir.FilterVarTypeIsOp,
								Src:   "m[\"re\"].Type.Is(`*regexp.Regexp`)",
								Value: "re",
								Args: []ir.FilterExpr{
									ir.FilterExpr{Line: 226, Op: ir.FilterStringOp, Src: "`*regexp.Regexp`", Value: "*regexp.Regexp"},
								},
							},
							ir.FilterExpr{
								Line:  226,
								Op:    ir.FilterVarTypeIsOp,
								Src:   "m[\"s\"].Type.Is(`string`)",
								Value: "s",
								Args: []ir.FilterExpr{
									ir.FilterExpr{Line: 226, Op: ir.FilterStringOp, Src: "`string`", Value: "string"},
								},
							},
						},
					},
				},
				ir.Rule{
					Line: 229,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 229, Value: "$re.FindAllIndex([]byte($s), $n)"},
					},
					ReportTemplate:  "suggestion: $re.FindAllStringIndex($s, $n)",
					SuggestTemplate: "$re.FindAllStringIndex($s, $n)",
					WhereExpr: ir.FilterExpr{
						Line: 230,
						Op:   ir.FilterAndOp,
						Src:  "m[\"re\"].Type.Is(`*regexp.Regexp`) && m[\"s\"].Type.Is(`string`)",
						Args: []ir.FilterExpr{
							ir.FilterExpr{
								Line:  230,
								Op:    ir.FilterVarTypeIsOp,
								Src:   "m[\"re\"].Type.Is(`*regexp.Regexp`)",
								Value: "re",
								Args: []ir.FilterExpr{
									ir.FilterExpr{Line: 230, Op: ir.FilterStringOp, Src: "`*regexp.Regexp`", Value: "*regexp.Regexp"},
								},
							},
							ir.FilterExpr{
								Line:  230,
								Op:    ir.FilterVarTypeIsOp,
								Src:   "m[\"s\"].Type.Is(`string`)",
								Value: "s",
								Args: []ir.FilterExpr{
									ir.FilterExpr{Line: 230, Op: ir.FilterStringOp, Src: "`string`", Value: "string"},
								},
							},
						},
					},
				},
			},
		},
		ir.RuleGroup{
			Line:        239,
			Name:        "indexAlloc",
			MatcherName: "m",
			DocTags: []string{
				"performance",
			},
			DocSummary: "Detects strings.Index calls that may cause unwanted allocs",
			DocBefore:  "strings.Index(string(x), y)",
			DocAfter:   "bytes.Index(x, []byte(y))",
			DocNote:    "See Go issue for details: https://github.com/golang/go/issues/25864",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 240,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 240, Value: "strings.Index(string($x), $y)"},
					},
					ReportTemplate: "consider replacing $$ with bytes.Index($x, []byte($y))",
					WhereExpr: ir.FilterExpr{
						Line: 241,
						Op:   ir.FilterAndOp,
						Src:  "m[\"x\"].Pure && m[\"y\"].Pure",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 241, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"},
							ir.FilterExpr{Line: 241, Op: ir.FilterVarPureOp, Src: "m[\"y\"].Pure", Value: "y"},
						},
					},
				},
			},
		},
		ir.RuleGroup{
			Line:        249,
			Name:        "wrapperFunc",
			MatcherName: "m",
			DocTags: []string{
				"style",
			},
			DocSummary: "Detects function calls that can be replaced with convenience wrappers",
			DocBefore:  "wg.Add(-1)",
			DocAfter:   "wg.Done()",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 250,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 250, Value: "$wg.Add(-1)"},
					},
					ReportTemplate: "use WaitGroup.Done method in `$$`",
					WhereExpr: ir.FilterExpr{
						Line:  251,
						Op:    ir.FilterVarTypeIsOp,
						Src:   "m[\"wg\"].Type.Is(`sync.WaitGroup`)",
						Value: "wg",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 251, Op: ir.FilterStringOp, Src: "`sync.WaitGroup`", Value: "sync.WaitGroup"},
						},
					},
				},
				ir.Rule{
					Line: 254,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 254, Value: "$buf.Truncate(0)"},
					},
					ReportTemplate: "use Buffer.Reset method in `$$`",
					WhereExpr: ir.FilterExpr{
						Line:  255,
						Op:    ir.FilterVarTypeIsOp,
						Src:   "m[\"buf\"].Type.Is(`bytes.Buffer`)",
						Value: "buf",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 255, Op: ir.FilterStringOp, Src: "`bytes.Buffer`", Value: "bytes.Buffer"},
						},
					},
				},
				ir.Rule{
					Line: 258,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 258, Value: "http.HandlerFunc(http.NotFound)"},
					},
					ReportTemplate: "use http.NotFoundHandler method in `$$`",
				},
				ir.Rule{
					Line: 260,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 260, Value: "strings.SplitN($_, $_, -1)"},
					},
					ReportTemplate: "use strings.Split method in `$$`",
				},
				ir.Rule{
					Line: 261,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 261, Value: "strings.Replace($_, $_, $_, -1)"},
					},
					ReportTemplate: "use strings.ReplaceAll method in `$$`",
				},
				ir.Rule{
					Line: 262,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 262, Value: "strings.Map(unicode.ToTitle, $_)"},
					},
					ReportTemplate: "use strings.ToTitle method in `$$`",
				},
				ir.Rule{
					Line: 264,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 264, Value: "bytes.SplitN(b, []byte(\".\"), -1)"},
					},
					ReportTemplate: "use bytes.Split method in `$$`",
				},
				ir.Rule{
					Line: 265,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 265, Value: "bytes.Replace($_, $_, $_, -1)"},
					},
					ReportTemplate: "use bytes.ReplaceAll method in `$$`",
				},
				ir.Rule{
					Line: 266,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 266, Value: "bytes.Map(unicode.ToUpper, $_)"},
					},
					ReportTemplate: "use bytes.ToUpper method in `$$`",
				},
				ir.Rule{
					Line: 267,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 267, Value: "bytes.Map(unicode.ToLower, $_)"},
					},
					ReportTemplate: "use bytes.ToLower method in `$$`",
				},
				ir.Rule{
					Line: 268,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 268, Value: "bytes.Map(unicode.ToTitle, $_)"},
					},
					ReportTemplate: "use bytes.ToTitle method in `$$`",
				},
				ir.Rule{
					Line: 270,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 270, Value: "draw.DrawMask($_, $_, $_, $_, nil, image.Point{}, $_)"},
					},
					ReportTemplate: "use draw.Draw method in `$$`",
				},
			},
		},
		ir.RuleGroup{
			Line:        278,
			Name:        "regexpMust",
			MatcherName: "m",
			DocTags: []string{
				"style",
			},
			DocSummary: "Detects `regexp.Compile*` that can be replaced with `regexp.MustCompile*`",
			DocBefore:  "re, _ := regexp.Compile(\"const pattern\")",
			DocAfter:   "re := regexp.MustCompile(\"const pattern\")",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 279,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 279, Value: "regexp.Compile($pat)"},
					},
					ReportTemplate: "for const patterns like $pat, use regexp.MustCompile",
					WhereExpr: ir.FilterExpr{
						Line:  280,
						Op:    ir.FilterVarConstOp,
						Src:   "m[\"pat\"].Const",
						Value: "pat",
					},
				},
				ir.Rule{
					Line: 283,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 283, Value: "regexp.CompilePOSIX($pat)"},
					},
					ReportTemplate: "for const patterns like $pat, use regexp.MustCompilePOSIX",
					WhereExpr: ir.FilterExpr{
						Line:  284,
						Op:    ir.FilterVarConstOp,
						Src:   "m[\"pat\"].Const",
						Value: "pat",
					},
				},
			},
		},
		ir.RuleGroup{
			Line:        292,
			Name:        "badCall",
			MatcherName: "m",
			DocTags: []string{
				"diagnostic",
			},
			DocSummary: "Detects suspicious function calls",
			DocBefore:  "strings.Replace(s, from, to, 0)",
			DocAfter:   "strings.Replace(s, from, to, -1)",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 293,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 293, Value: "strings.Replace($_, $_, $_, $zero)"},
					},
					ReportTemplate: "suspicious arg 0, probably meant -1",
					WhereExpr: ir.FilterExpr{
						Line: 294,
						Op:   ir.FilterEqOp,
						Src:  "m[\"zero\"].Value.Int() == 0",
						Args: []ir.FilterExpr{
							ir.FilterExpr{
								Line:  294,
								Op:    ir.FilterVarValueIntOp,
								Src:   "m[\"zero\"].Value.Int()",
								Value: "zero",
							},
							ir.FilterExpr{
								Line:  294,
								Op:    ir.FilterIntOp,
								Src:   "0",
								Value: int64(0),
							},
						},
					},
					LocationVar: "zero",
				},
				ir.Rule{
					Line: 296,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 296, Value: "bytes.Replace($_, $_, $_, $zero)"},
					},
					ReportTemplate: "suspicious arg 0, probably meant -1",
					WhereExpr: ir.FilterExpr{
						Line: 297,
						Op:   ir.FilterEqOp,
						Src:  "m[\"zero\"].Value.Int() == 0",
						Args: []ir.FilterExpr{
							ir.FilterExpr{
								Line:  297,
								Op:    ir.FilterVarValueIntOp,
								Src:   "m[\"zero\"].Value.Int()",
								Value: "zero",
							},
							ir.FilterExpr{
								Line:  297,
								Op:    ir.FilterIntOp,
								Src:   "0",
								Value: int64(0),
							},
						},
					},
					LocationVar: "zero",
				},
				ir.Rule{
					Line: 300,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 300, Value: "strings.SplitN($_, $_, $zero)"},
					},
					ReportTemplate: "suspicious arg 0, probably meant -1",
					WhereExpr: ir.FilterExpr{
						Line: 301,
						Op:   ir.FilterEqOp,
						Src:  "m[\"zero\"].Value.Int() == 0",
						Args: []ir.FilterExpr{
							ir.FilterExpr{
								Line:  301,
								Op:    ir.FilterVarValueIntOp,
								Src:   "m[\"zero\"].Value.Int()",
								Value: "zero",
							},
							ir.FilterExpr{
								Line:  301,
								Op:    ir.FilterIntOp,
								Src:   "0",
								Value: int64(0),
							},
						},
					},
					LocationVar: "zero",
				},
				ir.Rule{
					Line: 303,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 303, Value: "bytes.SplitN($_, $_, $zero)"},
					},
					ReportTemplate: "suspicious arg 0, probably meant -1",
					WhereExpr: ir.FilterExpr{
						Line: 304,
						Op:   ir.FilterEqOp,
						Src:  "m[\"zero\"].Value.Int() == 0",
						Args: []ir.FilterExpr{
							ir.FilterExpr{
								Line:  304,
								Op:    ir.FilterVarValueIntOp,
								Src:   "m[\"zero\"].Value.Int()",
								Value: "zero",
							},
							ir.FilterExpr{
								Line:  304,
								Op:    ir.FilterIntOp,
								Src:   "0",
								Value: int64(0),
							},
						},
					},
					LocationVar: "zero",
				},
				ir.Rule{
					Line: 307,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 307, Value: "append($_)"},
					},
					ReportTemplate: "no-op append call, probably missing arguments",
				},
				ir.Rule{
					Line: 309,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 309, Value: "filepath.Join($_)"},
					},
					ReportTemplate: "suspicious Join on 1 argument",
				},
			},
		},
		ir.RuleGroup{
			Line:        316,
			Name:        "assignOp",
			MatcherName: "m",
			DocTags: []string{
				"style",
			},
			DocSummary: "Detects assignments that can be simplified by using assignment operators",
			DocBefore:  "x = x * 2",
			DocAfter:   "x *= 2",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 317,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 317, Value: "$x = $x + 1"},
					},
					ReportTemplate: "replace `$$` with `$x++`",
					WhereExpr:      ir.FilterExpr{Line: 317, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"},
				},
				ir.Rule{
					Line: 318,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 318, Value: "$x = $x - 1"},
					},
					ReportTemplate: "replace `$$` with `$x--`",
					WhereExpr:      ir.FilterExpr{Line: 318, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"},
				},
				ir.Rule{
					Line: 320,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 320, Value: "$x = $x + $y"},
					},
					ReportTemplate: "replace `$$` with `$x += $y`",
					WhereExpr:      ir.FilterExpr{Line: 320, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"},
				},
				ir.Rule{
					Line: 321,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 321, Value: "$x = $x - $y"},
					},
					ReportTemplate: "replace `$$` with `$x -= $y`",
					WhereExpr:      ir.FilterExpr{Line: 321, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"},
				},
				ir.Rule{
					Line: 323,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 323, Value: "$x = $x * $y"},
					},
					ReportTemplate: "replace `$$` with `$x *= $y`",
					WhereExpr:      ir.FilterExpr{Line: 323, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"},
				},
				ir.Rule{
					Line: 324,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 324, Value: "$x = $x / $y"},
					},
					ReportTemplate: "replace `$$` with `$x /= $y`",
					WhereExpr:      ir.FilterExpr{Line: 324, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"},
				},
				ir.Rule{
					Line: 325,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 325, Value: "$x = $x % $y"},
					},
					ReportTemplate: "replace `$$` with `$x %= $y`",
					WhereExpr:      ir.FilterExpr{Line: 325, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"},
				},
				ir.Rule{
					Line: 326,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 326, Value: "$x = $x & $y"},
					},
					ReportTemplate: "replace `$$` with `$x &= $y`",
					WhereExpr:      ir.FilterExpr{Line: 326, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"},
				},
				ir.Rule{
					Line: 327,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 327, Value: "$x = $x | $y"},
					},
					ReportTemplate: "replace `$$` with `$x |= $y`",
					WhereExpr:      ir.FilterExpr{Line: 327, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"},
				},
				ir.Rule{
					Line: 328,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 328, Value: "$x = $x ^ $y"},
					},
					ReportTemplate: "replace `$$` with `$x ^= $y`",
					WhereExpr:      ir.FilterExpr{Line: 328, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"},
				},
				ir.Rule{
					Line: 329,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 329, Value: "$x = $x << $y"},
					},
					ReportTemplate: "replace `$$` with `$x <<= $y`",
					WhereExpr:      ir.FilterExpr{Line: 329, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"},
				},
				ir.Rule{
					Line: 330,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 330, Value: "$x = $x >> $y"},
					},
					ReportTemplate: "replace `$$` with `$x >>= $y`",
					WhereExpr:      ir.FilterExpr{Line: 330, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"},
				},
				ir.Rule{
					Line: 331,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 331, Value: "$x = $x &^ $y"},
					},
					ReportTemplate: "replace `$$` with `$x &^= $y`",
					WhereExpr:      ir.FilterExpr{Line: 331, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"},
				},
			},
		},
		ir.RuleGroup{
			Line:        338,
			Name:        "preferWriteByte",
			MatcherName: "m",
			DocTags: []string{
				"performance",
				"experimental",
				"opinionated",
			},
			DocSummary: "Detects WriteRune calls with rune literal argument that is single byte and reports to use WriteByte instead",
			DocBefore:  "w.WriteRune('\\n')",
			DocAfter:   "w.WriteByte('\\n')",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 342,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 342, Value: "$w.WriteRune($c)"},
					},
					ReportTemplate: "consider writing single byte rune $c with $w.WriteByte($c)",
					WhereExpr: ir.FilterExpr{
						Line: 343,
						Op:   ir.FilterAndOp,
						Src:  "m[\"w\"].Type.Implements(\"io.ByteWriter\") && (m[\"c\"].Const && m[\"c\"].Value.Int() < runeSelf)",
						Args: []ir.FilterExpr{
							ir.FilterExpr{
								Line:  343,
								Op:    ir.FilterVarTypeImplementsOp,
								Src:   "m[\"w\"].Type.Implements(\"io.ByteWriter\")",
								Value: "w",
								Args: []ir.FilterExpr{
									ir.FilterExpr{Line: 343, Op: ir.FilterStringOp, Src: "\"io.ByteWriter\"", Value: "io.ByteWriter"},
								},
							},
							ir.FilterExpr{
								Line: 343,
								Op:   ir.FilterAndOp,
								Src:  "(m[\"c\"].Const && m[\"c\"].Value.Int() < runeSelf)",
								Args: []ir.FilterExpr{
									ir.FilterExpr{
										Line:  343,
										Op:    ir.FilterVarConstOp,
										Src:   "m[\"c\"].Const",
										Value: "c",
									},
									ir.FilterExpr{
										Line: 343,
										Op:   ir.FilterLtOp,
										Src:  "m[\"c\"].Value.Int() < runeSelf",
										Args: []ir.FilterExpr{
											ir.FilterExpr{
												Line:  343,
												Op:    ir.FilterVarValueIntOp,
												Src:   "m[\"c\"].Value.Int()",
												Value: "c",
											},
											ir.FilterExpr{
												Line:  343,
												Op:    ir.FilterIntOp,
												Src:   "runeSelf",
												Value: int64(128),
											},
										},
									},
								},
							},
						},
					},
				},
			},
		},
		ir.RuleGroup{
			Line:        351,
			Name:        "preferFprint",
			MatcherName: "m",
			DocTags: []string{
				"performance",
				"experimental",
			},
			DocSummary: "Detects fmt.Sprint(f/ln) calls which can be replaced with fmt.Fprint(f/ln)",
			DocBefore:  "w.Write([]byte(fmt.Sprintf(\"%x\", 10)))",
			DocAfter:   "fmt.Fprintf(w, \"%x\", 10)",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 352,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 352, Value: "$w.Write([]byte(fmt.Sprint($*args)))"},
					},
					ReportTemplate:  "fmt.Fprint($w, $args) should be preferred to the $$",
					SuggestTemplate: "fmt.Fprint($w, $args)",
					WhereExpr: ir.FilterExpr{
						Line:  353,
						Op:    ir.FilterVarTypeImplementsOp,
						Src:   "m[\"w\"].Type.Implements(\"io.Writer\")",
						Value: "w",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 353, Op: ir.FilterStringOp, Src: "\"io.Writer\"", Value: "io.Writer"},
						},
					},
				},
				ir.Rule{
					Line: 357,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 357, Value: "$w.Write([]byte(fmt.Sprintf($*args)))"},
					},
					ReportTemplate:  "fmt.Fprintf($w, $args) should be preferred to the $$",
					SuggestTemplate: "fmt.Fprintf($w, $args)",
					WhereExpr: ir.FilterExpr{
						Line:  358,
						Op:    ir.FilterVarTypeImplementsOp,
						Src:   "m[\"w\"].Type.Implements(\"io.Writer\")",
						Value: "w",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 358, Op: ir.FilterStringOp, Src: "\"io.Writer\"", Value: "io.Writer"},
						},
					},
				},
				ir.Rule{
					Line: 362,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 362, Value: "$w.Write([]byte(fmt.Sprintln($*args)))"},
					},
					ReportTemplate:  "fmt.Fprintln($w, $args) should be preferred to the $$",
					SuggestTemplate: "fmt.Fprintln($w, $args)",
					WhereExpr: ir.FilterExpr{
						Line:  363,
						Op:    ir.FilterVarTypeImplementsOp,
						Src:   "m[\"w\"].Type.Implements(\"io.Writer\")",
						Value: "w",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 363, Op: ir.FilterStringOp, Src: "\"io.Writer\"", Value: "io.Writer"},
						},
					},
				},
				ir.Rule{
					Line: 367,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 367, Value: "io.WriteString($w, fmt.Sprint($*args))"},
					},
					ReportTemplate:  "suggestion: fmt.Fprint($w, $args)",
					SuggestTemplate: "fmt.Fprint($w, $args)",
				},
				ir.Rule{
					Line: 368,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 368, Value: "io.WriteString($w, fmt.Sprintf($*args))"},
					},
					ReportTemplate:  "suggestion: fmt.Fprintf($w, $args)",
					SuggestTemplate: "fmt.Fprintf($w, $args)",
				},
				ir.Rule{
					Line: 369,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 369, Value: "io.WriteString($w, fmt.Sprintln($*args))"},
					},
					ReportTemplate:  "suggestion: fmt.Fprintln($w, $args)",
					SuggestTemplate: "fmt.Fprintln($w, $args)",
				},
			},
		},
		ir.RuleGroup{
			Line:        376,
			Name:        "dupArg",
			MatcherName: "m",
			DocTags: []string{
				"diagnostic",
			},
			DocSummary: "Detects suspicious duplicated arguments",
			DocBefore:  "copy(dst, dst)",
			DocAfter:   "copy(dst, src)",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 377,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 377, Value: "$x.Equal($x)"},
						ir.PatternString{Line: 377, Value: "$x.Equals($x)"},
						ir.PatternString{Line: 377, Value: "$x.Compare($x)"},
						ir.PatternString{Line: 377, Value: "$x.Cmp($x)"},
					},
					ReportTemplate: "suspicious method call with the same argument and receiver",
					WhereExpr:      ir.FilterExpr{Line: 378, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"},
				},
				ir.Rule{
					Line: 381,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 381, Value: "copy($x, $x)"},
						ir.PatternString{Line: 382, Value: "math.Max($x, $x)"},
						ir.PatternString{Line: 383, Value: "math.Min($x, $x)"},
						ir.PatternString{Line: 384, Value: "reflect.Copy($x, $x)"},
						ir.PatternString{Line: 385, Value: "reflect.DeepEqual($x, $x)"},
						ir.PatternString{Line: 386, Value: "strings.Contains($x, $x)"},
						ir.PatternString{Line: 387, Value: "strings.Compare($x, $x)"},
						ir.PatternString{Line: 388, Value: "strings.EqualFold($x, $x)"},
						ir.PatternString{Line: 389, Value: "strings.HasPrefix($x, $x)"},
						ir.PatternString{Line: 390, Value: "strings.HasSuffix($x, $x)"},
						ir.PatternString{Line: 391, Value: "strings.Index($x, $x)"},
						ir.PatternString{Line: 392, Value: "strings.LastIndex($x, $x)"},
						ir.PatternString{Line: 393, Value: "strings.Split($x, $x)"},
						ir.PatternString{Line: 394, Value: "strings.SplitAfter($x, $x)"},
						ir.PatternString{Line: 395, Value: "strings.SplitAfterN($x, $x, $_)"},
						ir.PatternString{Line: 396, Value: "strings.SplitN($x, $x, $_)"},
						ir.PatternString{Line: 397, Value: "strings.Replace($_, $x, $x, $_)"},
						ir.PatternString{Line: 398, Value: "strings.ReplaceAll($_, $x, $x)"},
						ir.PatternString{Line: 399, Value: "bytes.Contains($x, $x)"},
						ir.PatternString{Line: 400, Value: "bytes.Compare($x, $x)"},
						ir.PatternString{Line: 401, Value: "bytes.Equal($x, $x)"},
						ir.PatternString{Line: 402, Value: "bytes.EqualFold($x, $x)"},
						ir.PatternString{Line: 403, Value: "bytes.HasPrefix($x, $x)"},
						ir.PatternString{Line: 404, Value: "bytes.HasSuffix($x, $x)"},
						ir.PatternString{Line: 405, Value: "bytes.Index($x, $x)"},
						ir.PatternString{Line: 406, Value: "bytes.LastIndex($x, $x)"},
						ir.PatternString{Line: 407, Value: "bytes.Split($x, $x)"},
						ir.PatternString{Line: 408, Value: "bytes.SplitAfter($x, $x)"},
						ir.PatternString{Line: 409, Value: "bytes.SplitAfterN($x, $x, $_)"},
						ir.PatternString{Line: 410, Value: "bytes.SplitN($x, $x, $_)"},
						ir.PatternString{Line: 411, Value: "bytes.Replace($_, $x, $x, $_)"},
						ir.PatternString{Line: 412, Value: "bytes.ReplaceAll($_, $x, $x)"},
						ir.PatternString{Line: 413, Value: "types.Identical($x, $x)"},
						ir.PatternString{Line: 414, Value: "types.IdenticalIgnoreTags($x, $x)"},
						ir.PatternString{Line: 415, Value: "draw.Draw($x, $_, $x, $_, $_)"},
					},
					ReportTemplate: "suspicious duplicated args in $$",
					WhereExpr:      ir.FilterExpr{Line: 416, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"},
				},
			},
		},
		ir.RuleGroup{
			Line:        424,
			Name:        "returnAfterHttpError",
			MatcherName: "m",
			DocTags: []string{
				"diagnostic",
				"experimental",
			},
			DocSummary: "Detects suspicious http.Error call without following return",
			DocBefore:  "if err != nil { http.Error(...); }",
			DocAfter:   "if err != nil { http.Error(...); return; }",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 425,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 425, Value: "if $_ { $*_; http.Error($w, $err, $code) }"},
					},
					ReportTemplate: "Possibly return is missed after the http.Error call",
					LocationVar:    "w",
				},
			},
		},
		ir.RuleGroup{
			Line:        434,
			Name:        "preferFilepathJoin",
			MatcherName: "m",
			DocTags: []string{
				"style",
				"experimental",
			},
			DocSummary: "Detects concatenation with os.PathSeparator which can be replaced with filepath.Join",
			DocBefore:  "x + string(os.PathSeparator) + y",
			DocAfter:   "filepath.Join(x, y)",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 435,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 435, Value: "$x + string(os.PathSeparator) + $y"},
					},
					ReportTemplate:  "filepath.Join($x, $y) should be preferred to the $$",
					SuggestTemplate: "filepath.Join($x, $y)",
					WhereExpr: ir.FilterExpr{
						Line: 436,
						Op:   ir.FilterAndOp,
						Src:  "m[\"x\"].Type.Is(`string`) && m[\"y\"].Type.Is(`string`)",
						Args: []ir.FilterExpr{
							ir.FilterExpr{
								Line:  436,
								Op:    ir.FilterVarTypeIsOp,
								Src:   "m[\"x\"].Type.Is(`string`)",
								Value: "x",
								Args: []ir.FilterExpr{
									ir.FilterExpr{Line: 436, Op: ir.FilterStringOp, Src: "`string`", Value: "string"},
								},
							},
							ir.FilterExpr{
								Line:  436,
								Op:    ir.FilterVarTypeIsOp,
								Src:   "m[\"y\"].Type.Is(`string`)",
								Value: "y",
								Args: []ir.FilterExpr{
									ir.FilterExpr{Line: 436, Op: ir.FilterStringOp, Src: "`string`", Value: "string"},
								},
							},
						},
					},
				},
			},
		},
		ir.RuleGroup{
			Line:        445,
			Name:        "preferStringWriter",
			MatcherName: "m",
			DocTags: []string{
				"performance",
				"experimental",
			},
			DocSummary: "Detects w.Write or io.WriteString calls which can be replaced with w.WriteString",
			DocBefore:  "w.Write([]byte(\"foo\"))",
			DocAfter:   "w.WriteString(\"foo\")",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 446,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 446, Value: "$w.Write([]byte($s))"},
					},
					ReportTemplate:  "$w.WriteString($s) should be preferred to the $$",
					SuggestTemplate: "$w.WriteString($s)",
					WhereExpr: ir.FilterExpr{
						Line:  447,
						Op:    ir.FilterVarTypeImplementsOp,
						Src:   "m[\"w\"].Type.Implements(\"io.StringWriter\")",
						Value: "w",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 447, Op: ir.FilterStringOp, Src: "\"io.StringWriter\"", Value: "io.StringWriter"},
						},
					},
				},
				ir.Rule{
					Line: 451,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 451, Value: "io.WriteString($w, $s)"},
					},
					ReportTemplate:  "$w.WriteString($s) should be preferred to the $$",
					SuggestTemplate: "$w.WriteString($s)",
					WhereExpr: ir.FilterExpr{
						Line:  452,
						Op:    ir.FilterVarTypeImplementsOp,
						Src:   "m[\"w\"].Type.Implements(\"io.StringWriter\")",
						Value: "w",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 452, Op: ir.FilterStringOp, Src: "\"io.StringWriter\"", Value: "io.StringWriter"},
						},
					},
				},
			},
		},
		ir.RuleGroup{
			Line:        461,
			Name:        "sliceClear",
			MatcherName: "m",
			DocTags: []string{
				"performance",
				"experimental",
			},
			DocSummary: "Detects slice clear loops, suggests an idiom that is recognized by the Go compiler",
			DocBefore:  "for i := 0; i < len(buf); i++ { buf[i] = 0 }",
			DocAfter:   "for i := range buf { buf[i] = 0 }",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 462,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 462, Value: "for $i := 0; $i < len($xs); $i++ { $xs[$i] = $zero }"},
					},
					ReportTemplate: "rewrite as for-range so compiler can recognize this pattern",
					WhereExpr: ir.FilterExpr{
						Line: 463,
						Op:   ir.FilterEqOp,
						Src:  "m[\"zero\"].Value.Int() == 0",
						Args: []ir.FilterExpr{
							ir.FilterExpr{
								Line:  463,
								Op:    ir.FilterVarValueIntOp,
								Src:   "m[\"zero\"].Value.Int()",
								Value: "zero",
							},
							ir.FilterExpr{
								Line:  463,
								Op:    ir.FilterIntOp,
								Src:   "0",
								Value: int64(0),
							},
						},
					},
				},
			},
		},
		ir.RuleGroup{
			Line:        471,
			Name:        "syncMapLoadAndDelete",
			MatcherName: "m",
			DocTags: []string{
				"diagnostic",
				"experimental",
			},
			DocSummary: "Detects sync.Map load+delete operations that can be replaced with LoadAndDelete",
			DocBefore:  "v, ok := m.Load(k); if ok { m.Delete($k); f(v); }",
			DocAfter:   "v, deleted := m.LoadAndDelete(k); if deleted { f(v) }",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 472,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 472, Value: "$_, $ok := $m.Load($k); if $ok { $m.Delete($k); $*_ }"},
					},
					ReportTemplate: "use $m.LoadAndDelete to perform load+delete operations atomically",
					WhereExpr: ir.FilterExpr{
						Line: 473,
						Op:   ir.FilterAndOp,
						Src:  "m.GoVersion().GreaterEqThan(\"1.15\") &&\n\tm[\"m\"].Type.Is(`*sync.Map`)",
						Args: []ir.FilterExpr{
							ir.FilterExpr{
								Line:  473,
								Op:    ir.FilterGoVersionGreaterEqThanOp,
								Src:   "m.GoVersion().GreaterEqThan(\"1.15\")",
								Value: "1.15",
							},
							ir.FilterExpr{
								Line:  474,
								Op:    ir.FilterVarTypeIsOp,
								Src:   "m[\"m\"].Type.Is(`*sync.Map`)",
								Value: "m",
								Args: []ir.FilterExpr{
									ir.FilterExpr{Line: 474, Op: ir.FilterStringOp, Src: "`*sync.Map`", Value: "*sync.Map"},
								},
							},
						},
					},
				},
			},
		},
		ir.RuleGroup{
			Line:        482,
			Name:        "sprintfQuotedString",
			MatcherName: "m",
			DocTags: []string{
				"diagnostic",
				"experimental",
			},
			DocSummary: "Detects \"%s\" formatting directives that can be replaced with %q",
			DocBefore:  "fmt.Sprintf(`\"%s\"`, s)",
			DocAfter:   "fmt.Sprintf(`%q`, s)",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 483,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 483, Value: "fmt.Sprintf($s, $*_)"},
					},
					ReportTemplate: "use %q instead of \"%s\" for quoted strings",
					WhereExpr: ir.FilterExpr{
						Line: 484,
						Op:   ir.FilterOrOp,
						Src:  "m[\"s\"].Text.Matches(\"^`.*\\\"%s\\\".*`$\") ||\n\tm[\"s\"].Text.Matches(`^\".*\\\\\"%s\\\\\".*\"$`)",
						Args: []ir.FilterExpr{
							ir.FilterExpr{
								Line:  484,
								Op:    ir.FilterVarTextMatchesOp,
								Src:   "m[\"s\"].Text.Matches(\"^`.*\\\"%s\\\".*`$\")",
								Value: "s",
								Args: []ir.FilterExpr{
									ir.FilterExpr{Line: 484, Op: ir.FilterStringOp, Src: "\"^`.*\\\"%s\\\".*`$\"", Value: "^`.*\"%s\".*`$"},
								},
							},
							ir.FilterExpr{
								Line:  485,
								Op:    ir.FilterVarTextMatchesOp,
								Src:   "m[\"s\"].Text.Matches(`^\".*\\\\\"%s\\\\\".*\"$`)",
								Value: "s",
								Args: []ir.FilterExpr{
									ir.FilterExpr{Line: 485, Op: ir.FilterStringOp, Src: "`^\".*\\\\\"%s\\\\\".*\"$`", Value: "^\".*\\\\\"%s\\\\\".*\"$"},
								},
							},
						},
					},
				},
			},
		},
		ir.RuleGroup{
			Line:        493,
			Name:        "offBy1",
			MatcherName: "m",
			DocTags: []string{
				"diagnostic",
			},
			DocSummary: "Detects various off-by-one kind of errors",
			DocBefore:  "xs[len(xs)]",
			DocAfter:   "xs[len(xs)-1]",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 494,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 494, Value: "$x[len($x)]"},
					},
					ReportTemplate:  "index expr always panics; maybe you wanted $x[len($x)-1]?",
					SuggestTemplate: "$x[len($x)-1]",
					WhereExpr: ir.FilterExpr{
						Line: 495,
						Op:   ir.FilterAndOp,
						Src:  "m[\"x\"].Pure && m[\"x\"].Type.Is(`[]$_`)",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 495, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"},
							ir.FilterExpr{
								Line:  495,
								Op:    ir.FilterVarTypeIsOp,
								Src:   "m[\"x\"].Type.Is(`[]$_`)",
								Value: "x",
								Args: []ir.FilterExpr{
									ir.FilterExpr{Line: 495, Op: ir.FilterStringOp, Src: "`[]$_`", Value: "[]$_"},
								},
							},
						},
					},
				},
				ir.Rule{
					Line: 502,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 503, Value: "$i := strings.Index($s, $_); $_ := $slicing[$i:]"},
						ir.PatternString{Line: 504, Value: "$i := strings.Index($s, $_); $_ = $slicing[$i:]"},
						ir.PatternString{Line: 505, Value: "$i := bytes.Index($s, $_); $_ := $slicing[$i:]"},
						ir.PatternString{Line: 506, Value: "$i := bytes.Index($s, $_); $_ = $slicing[$i:]"},
					},
					ReportTemplate: "Index() can return -1; maybe you wanted to do $s[$i+1:]",
					WhereExpr: ir.FilterExpr{
						Line: 507,
						Op:   ir.FilterEqOp,
						Src:  "m[\"s\"].Text == m[\"slicing\"].Text",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 507, Op: ir.FilterVarTextOp, Src: "m[\"s\"].Text", Value: "s"},
							ir.FilterExpr{Line: 507, Op: ir.FilterVarTextOp, Src: "m[\"slicing\"].Text", Value: "slicing"},
						},
					},
					LocationVar: "slicing",
				},
				ir.Rule{
					Line: 511,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 512, Value: "$i := strings.Index($s, $_); $_ := $slicing[:$i]"},
						ir.PatternString{Line: 513, Value: "$i := strings.Index($s, $_); $_ = $slicing[:$i]"},
						ir.PatternString{Line: 514, Value: "$i := bytes.Index($s, $_); $_ := $slicing[:$i]"},
						ir.PatternString{Line: 515, Value: "$i := bytes.Index($s, $_); $_ = $slicing[:$i]"},
					},
					ReportTemplate: "Index() can return -1; maybe you wanted to do $s[:$i+1]",
					WhereExpr: ir.FilterExpr{
						Line: 516,
						Op:   ir.FilterEqOp,
						Src:  "m[\"s\"].Text == m[\"slicing\"].Text",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 516, Op: ir.FilterVarTextOp, Src: "m[\"s\"].Text", Value: "s"},
							ir.FilterExpr{Line: 516, Op: ir.FilterVarTextOp, Src: "m[\"slicing\"].Text", Value: "slicing"},
						},
					},
					LocationVar: "slicing",
				},
				ir.Rule{
					Line: 520,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 521, Value: "$s[strings.Index($s, $_):]"},
						ir.PatternString{Line: 522, Value: "$s[:strings.Index($s, $_)]"},
						ir.PatternString{Line: 523, Value: "$s[bytes.Index($s, $_):]"},
						ir.PatternString{Line: 524, Value: "$s[:bytes.Index($s, $_)]"},
					},
					ReportTemplate: "Index() can return -1; maybe you wanted to do Index()+1",
				},
			},
		},
		ir.RuleGroup{
			Line:        532,
			Name:        "unslice",
			MatcherName: "m",
			DocTags: []string{
				"style",
			},
			DocSummary: "Detects slice expressions that can be simplified to sliced expression itself",
			DocBefore:  "copy(b[:], values...)",
			DocAfter:   "copy(b, values...)",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 533,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 533, Value: "$s[:]"},
					},
					ReportTemplate:  "could simplify $$ to $s",
					SuggestTemplate: "$s",
					WhereExpr: ir.FilterExpr{
						Line: 534,
						Op:   ir.FilterOrOp,
						Src:  "m[\"s\"].Type.Is(`string`) || m[\"s\"].Type.Is(`[]$_`)",
						Args: []ir.FilterExpr{
							ir.FilterExpr{
								Line:  534,
								Op:    ir.FilterVarTypeIsOp,
								Src:   "m[\"s\"].Type.Is(`string`)",
								Value: "s",
								Args: []ir.FilterExpr{
									ir.FilterExpr{Line: 534, Op: ir.FilterStringOp, Src: "`string`", Value: "string"},
								},
							},
							ir.FilterExpr{
								Line:  534,
								Op:    ir.FilterVarTypeIsOp,
								Src:   "m[\"s\"].Type.Is(`[]$_`)",
								Value: "s",
								Args: []ir.FilterExpr{
									ir.FilterExpr{Line: 534, Op: ir.FilterStringOp, Src: "`[]$_`", Value: "[]$_"},
								},
							},
						},
					},
				},
			},
		},
		ir.RuleGroup{
			Line:        543,
			Name:        "yodaStyleExpr",
			MatcherName: "m",
			DocTags: []string{
				"style",
				"experimental",
			},
			DocSummary: "Detects Yoda style expressions and suggests to replace them",
			DocBefore:  "return nil != ptr",
			DocAfter:   "return ptr != nil",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 544,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 544, Value: "$constval != $x"},
					},
					ReportTemplate: "consider to change order in expression to $x != $constval",
					WhereExpr: ir.FilterExpr{
						Line: 544,
						Op:   ir.FilterAndOp,
						Src:  "m[\"constval\"].Node.Is(`BasicLit`) && !m[\"x\"].Node.Is(`BasicLit`)",
						Args: []ir.FilterExpr{
							ir.FilterExpr{
								Line:  544,
								Op:    ir.FilterVarNodeIsOp,
								Src:   "m[\"constval\"].Node.Is(`BasicLit`)",
								Value: "constval",
								Args: []ir.FilterExpr{
									ir.FilterExpr{Line: 544, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"},
								},
							},
							ir.FilterExpr{
								Line: 544,
								Op:   ir.FilterNotOp,
								Src:  "!m[\"x\"].Node.Is(`BasicLit`)",
								Args: []ir.FilterExpr{
									ir.FilterExpr{
										Line:  544,
										Op:    ir.FilterVarNodeIsOp,
										Src:   "m[\"x\"].Node.Is(`BasicLit`)",
										Value: "x",
										Args: []ir.FilterExpr{
											ir.FilterExpr{Line: 544, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"},
										},
									},
								},
							},
						},
					},
				},
				ir.Rule{
					Line: 546,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 546, Value: "$constval == $x"},
					},
					ReportTemplate: "consider to change order in expression to $x == $constval",
					WhereExpr: ir.FilterExpr{
						Line: 546,
						Op:   ir.FilterAndOp,
						Src:  "m[\"constval\"].Node.Is(`BasicLit`) && !m[\"x\"].Node.Is(`BasicLit`)",
						Args: []ir.FilterExpr{
							ir.FilterExpr{
								Line:  546,
								Op:    ir.FilterVarNodeIsOp,
								Src:   "m[\"constval\"].Node.Is(`BasicLit`)",
								Value: "constval",
								Args: []ir.FilterExpr{
									ir.FilterExpr{Line: 546, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"},
								},
							},
							ir.FilterExpr{
								Line: 546,
								Op:   ir.FilterNotOp,
								Src:  "!m[\"x\"].Node.Is(`BasicLit`)",
								Args: []ir.FilterExpr{
									ir.FilterExpr{
										Line:  546,
										Op:    ir.FilterVarNodeIsOp,
										Src:   "m[\"x\"].Node.Is(`BasicLit`)",
										Value: "x",
										Args: []ir.FilterExpr{
											ir.FilterExpr{Line: 546, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"},
										},
									},
								},
							},
						},
					},
				},
				ir.Rule{
					Line: 549,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 549, Value: "nil != $x"},
					},
					ReportTemplate: "consider to change order in expression to $x != nil",
					WhereExpr: ir.FilterExpr{
						Line: 549,
						Op:   ir.FilterNotOp,
						Src:  "!m[\"x\"].Node.Is(`BasicLit`)",
						Args: []ir.FilterExpr{
							ir.FilterExpr{
								Line:  549,
								Op:    ir.FilterVarNodeIsOp,
								Src:   "m[\"x\"].Node.Is(`BasicLit`)",
								Value: "x",
								Args: []ir.FilterExpr{
									ir.FilterExpr{Line: 549, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"},
								},
							},
						},
					},
				},
				ir.Rule{
					Line: 551,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 551, Value: "nil == $x"},
					},
					ReportTemplate: "consider to change order in expression to $x == nil",
					WhereExpr: ir.FilterExpr{
						Line: 551,
						Op:   ir.FilterNotOp,
						Src:  "!m[\"x\"].Node.Is(`BasicLit`)",
						Args: []ir.FilterExpr{
							ir.FilterExpr{
								Line:  551,
								Op:    ir.FilterVarNodeIsOp,
								Src:   "m[\"x\"].Node.Is(`BasicLit`)",
								Value: "x",
								Args: []ir.FilterExpr{
									ir.FilterExpr{Line: 551, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"},
								},
							},
						},
					},
				},
			},
		},
		ir.RuleGroup{
			Line:        559,
			Name:        "equalFold",
			MatcherName: "m",
			DocTags: []string{
				"performance",
				"experimental",
			},
			DocSummary: "Detects unoptimal strings/bytes case-insensitive comparison",
			DocBefore:  "strings.ToLower(x) == strings.ToLower(y)",
			DocAfter:   "strings.EqualFold(x, y)",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 568,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 569, Value: "strings.ToLower($x) == $y"},
						ir.PatternString{Line: 570, Value: "strings.ToLower($x) == strings.ToLower($y)"},
						ir.PatternString{Line: 571, Value: "$x == strings.ToLower($y)"},
						ir.PatternString{Line: 572, Value: "strings.ToUpper($x) == $y"},
						ir.PatternString{Line: 573, Value: "strings.ToUpper($x) == strings.ToUpper($y)"},
						ir.PatternString{Line: 574, Value: "$x == strings.ToUpper($y)"},
					},
					ReportTemplate:  "consider replacing with strings.EqualFold($x, $y)",
					SuggestTemplate: "strings.EqualFold($x, $y)",
					WhereExpr: ir.FilterExpr{
						Line: 575,
						Op:   ir.FilterAndOp,
						Src:  "m[\"x\"].Pure && m[\"y\"].Pure && m[\"x\"].Text != m[\"y\"].Text",
						Args: []ir.FilterExpr{
							ir.FilterExpr{
								Line: 575,
								Op:   ir.FilterAndOp,
								Src:  "m[\"x\"].Pure && m[\"y\"].Pure",
								Args: []ir.FilterExpr{
									ir.FilterExpr{Line: 575, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"},
									ir.FilterExpr{Line: 575, Op: ir.FilterVarPureOp, Src: "m[\"y\"].Pure", Value: "y"},
								},
							},
							ir.FilterExpr{
								Line: 575,
								Op:   ir.FilterNeqOp,
								Src:  "m[\"x\"].Text != m[\"y\"].Text",
								Args: []ir.FilterExpr{
									ir.FilterExpr{Line: 575, Op: ir.FilterVarTextOp, Src: "m[\"x\"].Text", Value: "x"},
									ir.FilterExpr{Line: 575, Op: ir.FilterVarTextOp, Src: "m[\"y\"].Text", Value: "y"},
								},
							},
						},
					},
				},
				ir.Rule{
					Line: 580,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 581, Value: "strings.ToLower($x) != $y"},
						ir.PatternString{Line: 582, Value: "strings.ToLower($x) != strings.ToLower($y)"},
						ir.PatternString{Line: 583, Value: "$x != strings.ToLower($y)"},
						ir.PatternString{Line: 584, Value: "strings.ToUpper($x) != $y"},
						ir.PatternString{Line: 585, Value: "strings.ToUpper($x) != strings.ToUpper($y)"},
						ir.PatternString{Line: 586, Value: "$x != strings.ToUpper($y)"},
					},
					ReportTemplate:  "consider replacing with !strings.EqualFold($x, $y)",
					SuggestTemplate: "!strings.EqualFold($x, $y)",
					WhereExpr: ir.FilterExpr{
						Line: 587,
						Op:   ir.FilterAndOp,
						Src:  "m[\"x\"].Pure && m[\"y\"].Pure && m[\"x\"].Text != m[\"y\"].Text",
						Args: []ir.FilterExpr{
							ir.FilterExpr{
								Line: 587,
								Op:   ir.FilterAndOp,
								Src:  "m[\"x\"].Pure && m[\"y\"].Pure",
								Args: []ir.FilterExpr{
									ir.FilterExpr{Line: 587, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"},
									ir.FilterExpr{Line: 587, Op: ir.FilterVarPureOp, Src: "m[\"y\"].Pure", Value: "y"},
								},
							},
							ir.FilterExpr{
								Line: 587,
								Op:   ir.FilterNeqOp,
								Src:  "m[\"x\"].Text != m[\"y\"].Text",
								Args: []ir.FilterExpr{
									ir.FilterExpr{Line: 587, Op: ir.FilterVarTextOp, Src: "m[\"x\"].Text", Value: "x"},
									ir.FilterExpr{Line: 587, Op: ir.FilterVarTextOp, Src: "m[\"y\"].Text", Value: "y"},
								},
							},
						},
					},
				},
				ir.Rule{
					Line: 592,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 593, Value: "bytes.Equal(bytes.ToLower($x), $y)"},
						ir.PatternString{Line: 594, Value: "bytes.Equal(bytes.ToLower($x), bytes.ToLower($y))"},
						ir.PatternString{Line: 595, Value: "bytes.Equal($x, bytes.ToLower($y))"},
						ir.PatternString{Line: 596, Value: "bytes.Equal(bytes.ToUpper($x), $y)"},
						ir.PatternString{Line: 597, Value: "bytes.Equal(bytes.ToUpper($x), bytes.ToUpper($y))"},
						ir.PatternString{Line: 598, Value: "bytes.Equal($x, bytes.ToUpper($y))"},
					},
					ReportTemplate:  "consider replacing with bytes.EqualFold($x, $y)",
					SuggestTemplate: "bytes.EqualFold($x, $y)",
					WhereExpr: ir.FilterExpr{
						Line: 599,
						Op:   ir.FilterAndOp,
						Src:  "m[\"x\"].Pure && m[\"y\"].Pure && m[\"x\"].Text != m[\"y\"].Text",
						Args: []ir.FilterExpr{
							ir.FilterExpr{
								Line: 599,
								Op:   ir.FilterAndOp,
								Src:  "m[\"x\"].Pure && m[\"y\"].Pure",
								Args: []ir.FilterExpr{
									ir.FilterExpr{Line: 599, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"},
									ir.FilterExpr{Line: 599, Op: ir.FilterVarPureOp, Src: "m[\"y\"].Pure", Value: "y"},
								},
							},
							ir.FilterExpr{
								Line: 599,
								Op:   ir.FilterNeqOp,
								Src:  "m[\"x\"].Text != m[\"y\"].Text",
								Args: []ir.FilterExpr{
									ir.FilterExpr{Line: 599, Op: ir.FilterVarTextOp, Src: "m[\"x\"].Text", Value: "x"},
									ir.FilterExpr{Line: 599, Op: ir.FilterVarTextOp, Src: "m[\"y\"].Text", Value: "y"},
								},
							},
						},
					},
				},
			},
		},
		ir.RuleGroup{
			Line:        608,
			Name:        "argOrder",
			MatcherName: "m",
			DocTags: []string{
				"diagnostic",
			},
			DocSummary: "Detects suspicious arguments order",
			DocBefore:  "strings.HasPrefix(\"#\", userpass)",
			DocAfter:   "strings.HasPrefix(userpass, \"#\")",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 609,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 610, Value: "strings.HasPrefix($lit, $s)"},
						ir.PatternString{Line: 611, Value: "bytes.HasPrefix($lit, $s)"},
						ir.PatternString{Line: 612, Value: "strings.HasSuffix($lit, $s)"},
						ir.PatternString{Line: 613, Value: "bytes.HasSuffix($lit, $s)"},
						ir.PatternString{Line: 614, Value: "strings.Contains($lit, $s)"},
						ir.PatternString{Line: 615, Value: "bytes.Contains($lit, $s)"},
						ir.PatternString{Line: 616, Value: "strings.TrimPrefix($lit, $s)"},
						ir.PatternString{Line: 617, Value: "bytes.TrimPrefix($lit, $s)"},
						ir.PatternString{Line: 618, Value: "strings.TrimSuffix($lit, $s)"},
						ir.PatternString{Line: 619, Value: "bytes.TrimSuffix($lit, $s)"},
						ir.PatternString{Line: 620, Value: "strings.Split($lit, $s)"},
						ir.PatternString{Line: 621, Value: "bytes.Split($lit, $s)"},
					},
					ReportTemplate: "$lit and $s arguments order looks reversed",
					WhereExpr: ir.FilterExpr{
						Line: 622,
						Op:   ir.FilterAndOp,
						Src:  "(m[\"lit\"].Const || m[\"lit\"].ConstSlice) &&\n\t!(m[\"s\"].Const || m[\"s\"].ConstSlice) &&\n\t!m[\"lit\"].Node.Is(`Ident`)",
						Args: []ir.FilterExpr{
							ir.FilterExpr{
								Line: 622,
								Op:   ir.FilterAndOp,
								Src:  "(m[\"lit\"].Const || m[\"lit\"].ConstSlice) &&\n\t!(m[\"s\"].Const || m[\"s\"].ConstSlice)",
								Args: []ir.FilterExpr{
									ir.FilterExpr{
										Line: 622,
										Op:   ir.FilterOrOp,
										Src:  "(m[\"lit\"].Const || m[\"lit\"].ConstSlice)",
										Args: []ir.FilterExpr{
											ir.FilterExpr{
												Line:  622,
												Op:    ir.FilterVarConstOp,
												Src:   "m[\"lit\"].Const",
												Value: "lit",
											},
											ir.FilterExpr{
												Line:  622,
												Op:    ir.FilterVarConstSliceOp,
												Src:   "m[\"lit\"].ConstSlice",
												Value: "lit",
											},
										},
									},
									ir.FilterExpr{
										Line: 623,
										Op:   ir.FilterNotOp,
										Src:  "!(m[\"s\"].Const || m[\"s\"].ConstSlice)",
										Args: []ir.FilterExpr{
											ir.FilterExpr{
												Line: 623,
												Op:   ir.FilterOrOp,
												Src:  "(m[\"s\"].Const || m[\"s\"].ConstSlice)",
												Args: []ir.FilterExpr{
													ir.FilterExpr{
														Line:  623,
														Op:    ir.FilterVarConstOp,
														Src:   "m[\"s\"].Const",
														Value: "s",
													},
													ir.FilterExpr{
														Line:  623,
														Op:    ir.FilterVarConstSliceOp,
														Src:   "m[\"s\"].ConstSlice",
														Value: "s",
													},
												},
											},
										},
									},
								},
							},
							ir.FilterExpr{
								Line: 624,
								Op:   ir.FilterNotOp,
								Src:  "!m[\"lit\"].Node.Is(`Ident`)",
								Args: []ir.FilterExpr{
									ir.FilterExpr{
										Line:  624,
										Op:    ir.FilterVarNodeIsOp,
										Src:   "m[\"lit\"].Node.Is(`Ident`)",
										Value: "lit",
										Args: []ir.FilterExpr{
											ir.FilterExpr{Line: 624, Op: ir.FilterStringOp, Src: "`Ident`", Value: "Ident"},
										},
									},
								},
							},
						},
					},
				},
			},
		},
		ir.RuleGroup{
			Line:        632,
			Name:        "stringConcatSimplify",
			MatcherName: "m",
			DocTags: []string{
				"style",
				"experimental",
			},
			DocSummary: "Detects string concat operations that can be simplified",
			DocBefore:  "strings.Join([]string{x, y}, \"_\")",
			DocAfter:   "x + \"_\" + y",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 633,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 633, Value: "strings.Join([]string{$x, $y}, \"\")"},
					},
					ReportTemplate:  "suggestion: $x + $y",
					SuggestTemplate: "$x + $y",
				},
				ir.Rule{
					Line: 634,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 634, Value: "strings.Join([]string{$x, $y, $z}, \"\")"},
					},
					ReportTemplate:  "suggestion: $x + $y + $z",
					SuggestTemplate: "$x + $y + $z",
				},
				ir.Rule{
					Line: 635,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 635, Value: "strings.Join([]string{$x, $y}, $glue)"},
					},
					ReportTemplate:  "suggestion: $x + $glue + $y",
					SuggestTemplate: "$x + $glue + $y",
				},
			},
		},
		ir.RuleGroup{
			Line:        642,
			Name:        "timeExprSimplify",
			MatcherName: "m",
			DocTags: []string{
				"style",
				"experimental",
			},
			DocSummary: "Detects manual conversion to milli- or microseconds",
			DocBefore:  "t.Unix() / 1000",
			DocAfter:   "t.UnixMilli()",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 647,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 647, Value: "$t.Unix() / 1000"},
					},
					ReportTemplate:  "use $t.UnixMilli() instead of $$",
					SuggestTemplate: "$t.UnixMilli()",
					WhereExpr: ir.FilterExpr{
						Line: 648,
						Op:   ir.FilterAndOp,
						Src:  "m.GoVersion().GreaterEqThan(\"1.17\") && isTime(m[\"t\"])",
						Args: []ir.FilterExpr{
							ir.FilterExpr{
								Line:  648,
								Op:    ir.FilterGoVersionGreaterEqThanOp,
								Src:   "m.GoVersion().GreaterEqThan(\"1.17\")",
								Value: "1.17",
							},
							ir.FilterExpr{
								Line: 648,
								Op:   ir.FilterOrOp,
								Src:  "isTime(m[\"t\"])",
								Args: []ir.FilterExpr{
									ir.FilterExpr{
										Line:  648,
										Op:    ir.FilterVarTypeIsOp,
										Src:   "m[\"t\"].Type.Is(`time.Time`)",
										Value: "t",
										Args: []ir.FilterExpr{
											ir.FilterExpr{Line: 644, Op: ir.FilterStringOp, Src: "`time.Time`", Value: "time.Time"},
										},
									},
									ir.FilterExpr{
										Line:  648,
										Op:    ir.FilterVarTypeIsOp,
										Src:   "m[\"t\"].Type.Is(`*time.Time`)",
										Value: "t",
										Args: []ir.FilterExpr{
											ir.FilterExpr{Line: 644, Op: ir.FilterStringOp, Src: "`*time.Time`", Value: "*time.Time"},
										},
									},
								},
							},
						},
					},
				},
				ir.Rule{
					Line: 652,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 652, Value: "$t.UnixNano() * 1000"},
					},
					ReportTemplate:  "use $t.UnixMicro() instead of $$",
					SuggestTemplate: "$t.UnixMicro()",
					WhereExpr: ir.FilterExpr{
						Line: 653,
						Op:   ir.FilterAndOp,
						Src:  "m.GoVersion().GreaterEqThan(\"1.17\") && isTime(m[\"t\"])",
						Args: []ir.FilterExpr{
							ir.FilterExpr{
								Line:  653,
								Op:    ir.FilterGoVersionGreaterEqThanOp,
								Src:   "m.GoVersion().GreaterEqThan(\"1.17\")",
								Value: "1.17",
							},
							ir.FilterExpr{
								Line: 653,
								Op:   ir.FilterOrOp,
								Src:  "isTime(m[\"t\"])",
								Args: []ir.FilterExpr{
									ir.FilterExpr{
										Line:  653,
										Op:    ir.FilterVarTypeIsOp,
										Src:   "m[\"t\"].Type.Is(`time.Time`)",
										Value: "t",
										Args: []ir.FilterExpr{
											ir.FilterExpr{Line: 644, Op: ir.FilterStringOp, Src: "`time.Time`", Value: "time.Time"},
										},
									},
									ir.FilterExpr{
										Line:  653,
										Op:    ir.FilterVarTypeIsOp,
										Src:   "m[\"t\"].Type.Is(`*time.Time`)",
										Value: "t",
										Args: []ir.FilterExpr{
											ir.FilterExpr{Line: 644, Op: ir.FilterStringOp, Src: "`*time.Time`", Value: "*time.Time"},
										},
									},
								},
							},
						},
					},
				},
			},
		},
		ir.RuleGroup{
			Line:        662,
			Name:        "exposedSyncMutex",
			MatcherName: "m",
			DocTags: []string{
				"style",
				"experimental",
			},
			DocSummary: "Detects exposed methods from sync.Mutex and sync.RWMutex",
			DocBefore:  "type Foo struct{ ...; sync.Mutex; ... }",
			DocAfter:   "type Foo struct{ ...; mu sync.Mutex; ... }",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 667,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 667, Value: "type $x struct { $*_; sync.Mutex; $*_ }"},
					},
					ReportTemplate: "don't embed sync.Mutex",
					WhereExpr: ir.FilterExpr{
						Line:  668,
						Op:    ir.FilterVarTextMatchesOp,
						Src:   "isExported(m[\"x\"])",
						Value: "x",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 664, Op: ir.FilterStringOp, Src: "`^\\p{Lu}`", Value: "^\\p{Lu}"},
						},
					},
				},
				ir.Rule{
					Line: 671,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 671, Value: "type $x struct { $*_; *sync.Mutex; $*_ }"},
					},
					ReportTemplate: "don't embed *sync.Mutex",
					WhereExpr: ir.FilterExpr{
						Line:  672,
						Op:    ir.FilterVarTextMatchesOp,
						Src:   "isExported(m[\"x\"])",
						Value: "x",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 664, Op: ir.FilterStringOp, Src: "`^\\p{Lu}`", Value: "^\\p{Lu}"},
						},
					},
				},
				ir.Rule{
					Line: 675,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 675, Value: "type $x struct { $*_; sync.RWMutex; $*_ }"},
					},
					ReportTemplate: "don't embed sync.RWMutex",
					WhereExpr: ir.FilterExpr{
						Line:  676,
						Op:    ir.FilterVarTextMatchesOp,
						Src:   "isExported(m[\"x\"])",
						Value: "x",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 664, Op: ir.FilterStringOp, Src: "`^\\p{Lu}`", Value: "^\\p{Lu}"},
						},
					},
				},
				ir.Rule{
					Line: 679,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 679, Value: "type $x struct { $*_; *sync.RWMutex; $*_ }"},
					},
					ReportTemplate: "don't embed *sync.RWMutex",
					WhereExpr: ir.FilterExpr{
						Line:  680,
						Op:    ir.FilterVarTextMatchesOp,
						Src:   "isExported(m[\"x\"])",
						Value: "x",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 664, Op: ir.FilterStringOp, Src: "`^\\p{Lu}`", Value: "^\\p{Lu}"},
						},
					},
				},
			},
		},
		ir.RuleGroup{
			Line:        688,
			Name:        "badSorting",
			MatcherName: "m",
			DocTags: []string{
				"diagnostic",
				"experimental",
			},
			DocSummary: "Detects bad usage of sort package",
			DocBefore:  "xs = sort.StringSlice(xs)",
			DocAfter:   "sort.Strings(xs)",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 689,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 689, Value: "$x = sort.IntSlice($x)"},
					},
					ReportTemplate:  "suspicious sort.IntSlice usage, maybe sort.Ints was intended?",
					SuggestTemplate: "sort.Ints($x)",
					WhereExpr: ir.FilterExpr{
						Line:  690,
						Op:    ir.FilterVarTypeIsOp,
						Src:   "m[\"x\"].Type.Is(`[]int`)",
						Value: "x",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 690, Op: ir.FilterStringOp, Src: "`[]int`", Value: "[]int"},
						},
					},
				},
				ir.Rule{
					Line: 694,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 694, Value: "$x = sort.Float64Slice($x)"},
					},
					ReportTemplate:  "suspicious sort.Float64s usage, maybe sort.Float64s was intended?",
					SuggestTemplate: "sort.Float64s($x)",
					WhereExpr: ir.FilterExpr{
						Line:  695,
						Op:    ir.FilterVarTypeIsOp,
						Src:   "m[\"x\"].Type.Is(`[]float64`)",
						Value: "x",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 695, Op: ir.FilterStringOp, Src: "`[]float64`", Value: "[]float64"},
						},
					},
				},
				ir.Rule{
					Line: 699,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 699, Value: "$x = sort.StringSlice($x)"},
					},
					ReportTemplate:  "suspicious sort.StringSlice usage, maybe sort.Strings was intended?",
					SuggestTemplate: "sort.Strings($x)",
					WhereExpr: ir.FilterExpr{
						Line:  700,
						Op:    ir.FilterVarTypeIsOp,
						Src:   "m[\"x\"].Type.Is(`[]string`)",
						Value: "x",
						Args: []ir.FilterExpr{
							ir.FilterExpr{Line: 700, Op: ir.FilterStringOp, Src: "`[]string`", Value: "[]string"},
						},
					},
				},
			},
		},
		ir.RuleGroup{
			Line:        709,
			Name:        "externalErrorReassign",
			MatcherName: "m",
			DocTags: []string{
				"diagnostic",
				"experimental",
			},
			DocSummary: "Detects suspicious reassigment of error from another package",
			DocBefore:  "io.EOF = nil",
			DocAfter:   "/* don't do it */",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 710,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 710, Value: "$pkg.$err = $x"},
					},
					ReportTemplate: "suspicious reassigment of error from another package",
					WhereExpr: ir.FilterExpr{
						Line: 711,
						Op:   ir.FilterAndOp,
						Src:  "m[\"err\"].Type.Is(`error`) && m[\"pkg\"].Object.Is(`PkgName`)",
						Args: []ir.FilterExpr{
							ir.FilterExpr{
								Line:  711,
								Op:    ir.FilterVarTypeIsOp,
								Src:   "m[\"err\"].Type.Is(`error`)",
								Value: "err",
								Args: []ir.FilterExpr{
									ir.FilterExpr{Line: 711, Op: ir.FilterStringOp, Src: "`error`", Value: "error"},
								},
							},
							ir.FilterExpr{
								Line:  711,
								Op:    ir.FilterVarObjectIsOp,
								Src:   "m[\"pkg\"].Object.Is(`PkgName`)",
								Value: "pkg",
								Args: []ir.FilterExpr{
									ir.FilterExpr{Line: 711, Op: ir.FilterStringOp, Src: "`PkgName`", Value: "PkgName"},
								},
							},
						},
					},
				},
			},
		},
		ir.RuleGroup{
			Line:        719,
			Name:        "emptyDecl",
			MatcherName: "m",
			DocTags: []string{
				"diagnostic",
				"experimental",
			},
			DocSummary: "Detects suspicious empty declarations blocks",
			DocBefore:  "var()",
			DocAfter:   "/* nothing */",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 720,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 720, Value: "var()"},
					},
					ReportTemplate: "empty var() block",
				},
				ir.Rule{
					Line: 721,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 721, Value: "const()"},
					},
					ReportTemplate: "empty const() block",
				},
				ir.Rule{
					Line: 722,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 722, Value: "type()"},
					},
					ReportTemplate: "empty type() block",
				},
			},
		},
		ir.RuleGroup{
			Line:        729,
			Name:        "dynamicFmtString",
			MatcherName: "m",
			DocTags: []string{
				"diagnostic",
				"experimental",
			},
			DocSummary: "Detects suspicious formatting strings usage",
			DocBefore:  "fmt.Errorf(msg)",
			DocAfter:   "fmt.Errorf(\"%s\", msg)",
			Rules: []ir.Rule{
				ir.Rule{
					Line: 730,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 730, Value: "fmt.Errorf($f)"},
					},
					ReportTemplate:  "use errors.New($f) or fmt.Errorf(\"%s\", $f) instead",
					SuggestTemplate: "errors.New($f)",
					WhereExpr: ir.FilterExpr{
						Line: 731,
						Op:   ir.FilterNotOp,
						Src:  "!m[\"f\"].Const",
						Args: []ir.FilterExpr{
							ir.FilterExpr{
								Line:  731,
								Op:    ir.FilterVarConstOp,
								Src:   "m[\"f\"].Const",
								Value: "f",
							},
						},
					},
				},
				ir.Rule{
					Line: 735,
					SyntaxPatterns: []ir.PatternString{
						ir.PatternString{Line: 735, Value: "fmt.Errorf($f($*args))"},
					},
					ReportTemplate:  "use errors.New($f($*args)) or fmt.Errorf(\"%s\", $f($*args)) instead",
					SuggestTemplate: "errors.New($f($*args))",
				},
			},
		},
	},
}

