mirror of
https://github.com/mgechev/revive.git
synced 2025-11-23 22:04:49 +02:00
adds tests for specific go versions (#1043)
Co-authored-by: chavacava <salvador.cavadini@gmail.com>
This commit is contained in:
@@ -9,3 +9,7 @@ import (
|
|||||||
func TestDatarace(t *testing.T) {
|
func TestDatarace(t *testing.T) {
|
||||||
testRule(t, "datarace", &rule.DataRaceRule{})
|
testRule(t, "datarace", &rule.DataRaceRule{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDataraceAfterGo1_22(t *testing.T) {
|
||||||
|
testRule(t, "go1.22/datarace", &rule.DataRaceRule{})
|
||||||
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ func TestFileExcludeFilterAtRuleLevel(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("not called if exclude not match", func(t *testing.T) {
|
t.Run("not called if exclude not match", func(t *testing.T) {
|
||||||
rule := &TestFileFilterRule{}
|
rule := &TestFileFilterRule{}
|
||||||
cfg := &lint.RuleConfig{Exclude: []string{"file-to-exclude.go"}}
|
cfg := &lint.RuleConfig{Exclude: []string{"../testdata/file-to-exclude.go"}}
|
||||||
cfg.Initialize()
|
cfg.Initialize()
|
||||||
testRule(t, "file-to-exclude", rule, cfg)
|
testRule(t, "file-to-exclude", rule, cfg)
|
||||||
if rule.WasApplyed {
|
if rule.WasApplyed {
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ func TestAll(t *testing.T) {
|
|||||||
t.Fatalf("Failed reading %s: %v", fi.Name(), err)
|
t.Fatalf("Failed reading %s: %v", fi.Name(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := assertFailures(t, baseDir, fileInfo, src, rules, map[string]lint.RuleConfig{}); err != nil {
|
if err := assertFailures(t, path.Dir(baseDir), fileInfo, src, rules, map[string]lint.RuleConfig{}); err != nil {
|
||||||
t.Errorf("Linting %s: %v", fi.Name(), err)
|
t.Errorf("Linting %s: %v", fi.Name(), err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -10,3 +10,7 @@ import (
|
|||||||
func TestRangeValAddress(t *testing.T) {
|
func TestRangeValAddress(t *testing.T) {
|
||||||
testRule(t, "range-val-address", &rule.RangeValAddress{}, &lint.RuleConfig{})
|
testRule(t, "range-val-address", &rule.RangeValAddress{}, &lint.RuleConfig{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRangeValAddressAfterGo1_22(t *testing.T) {
|
||||||
|
testRule(t, "go1.22/range-val-address", &rule.RangeValAddress{}, &lint.RuleConfig{})
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,3 +10,7 @@ import (
|
|||||||
func TestRangeValInClosure(t *testing.T) {
|
func TestRangeValInClosure(t *testing.T) {
|
||||||
testRule(t, "range-val-in-closure", &rule.RangeValInClosureRule{}, &lint.RuleConfig{})
|
testRule(t, "range-val-in-closure", &rule.RangeValInClosureRule{}, &lint.RuleConfig{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRangeValInClosureAfterGo1_22(t *testing.T) {
|
||||||
|
testRule(t, "go1.22/range-val-in-closure", &rule.RangeValInClosureRule{}, &lint.RuleConfig{})
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,3 +10,7 @@ import (
|
|||||||
func TestRedefinesBuiltinID(t *testing.T) {
|
func TestRedefinesBuiltinID(t *testing.T) {
|
||||||
testRule(t, "redefines-builtin-id", &rule.RedefinesBuiltinIDRule{})
|
testRule(t, "redefines-builtin-id", &rule.RedefinesBuiltinIDRule{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRedefinesBuiltinIDAfterGo1_21(t *testing.T) {
|
||||||
|
testRule(t, "go1.21/redefines-builtin-id", &rule.RedefinesBuiltinIDRule{})
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"go/token"
|
"go/token"
|
||||||
"go/types"
|
"go/types"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -18,13 +19,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func testRule(t *testing.T, filename string, rule lint.Rule, config ...*lint.RuleConfig) {
|
func testRule(t *testing.T, filename string, rule lint.Rule, config ...*lint.RuleConfig) {
|
||||||
baseDir := "../testdata/"
|
baseDir := path.Join("../testdata/" + path.Dir(filename))
|
||||||
filename = filename + ".go"
|
filename = path.Base(filename) + ".go"
|
||||||
src, err := os.ReadFile(baseDir + filename)
|
fullFilePath := path.Join(baseDir, filename)
|
||||||
|
src, err := os.ReadFile(fullFilePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Bad filename path in test for %s: %v", rule.Name(), err)
|
t.Fatalf("Bad filename path in test for %s: %v", rule.Name(), err)
|
||||||
}
|
}
|
||||||
stat, err := os.Stat(baseDir + filename)
|
stat, err := os.Stat(fullFilePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Cannot get file info for %s: %v", rule.Name(), err)
|
t.Fatalf("Cannot get file info for %s: %v", rule.Name(), err)
|
||||||
}
|
}
|
||||||
@@ -32,7 +34,7 @@ func testRule(t *testing.T, filename string, rule lint.Rule, config ...*lint.Rul
|
|||||||
if config != nil {
|
if config != nil {
|
||||||
c[rule.Name()] = *config[0]
|
c[rule.Name()] = *config[0]
|
||||||
}
|
}
|
||||||
if parseInstructions(t, filename, src) == nil {
|
if parseInstructions(t, fullFilePath, src) == nil {
|
||||||
assertSuccess(t, baseDir, stat, []lint.Rule{rule}, c)
|
assertSuccess(t, baseDir, stat, []lint.Rule{rule}, c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -41,10 +43,11 @@ func testRule(t *testing.T, filename string, rule lint.Rule, config ...*lint.Rul
|
|||||||
|
|
||||||
func assertSuccess(t *testing.T, baseDir string, fi os.FileInfo, rules []lint.Rule, config map[string]lint.RuleConfig) error {
|
func assertSuccess(t *testing.T, baseDir string, fi os.FileInfo, rules []lint.Rule, config map[string]lint.RuleConfig) error {
|
||||||
l := lint.New(func(file string) ([]byte, error) {
|
l := lint.New(func(file string) ([]byte, error) {
|
||||||
return os.ReadFile(baseDir + file)
|
return os.ReadFile(file)
|
||||||
}, 0)
|
}, 0)
|
||||||
|
|
||||||
ps, err := l.Lint([][]string{{fi.Name()}}, rules, lint.Config{
|
filePath := path.Join(baseDir, fi.Name())
|
||||||
|
ps, err := l.Lint([][]string{{filePath}}, rules, lint.Config{
|
||||||
Rules: config,
|
Rules: config,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -63,15 +66,15 @@ func assertSuccess(t *testing.T, baseDir string, fi os.FileInfo, rules []lint.Ru
|
|||||||
|
|
||||||
func assertFailures(t *testing.T, baseDir string, fi os.FileInfo, src []byte, rules []lint.Rule, config map[string]lint.RuleConfig) error {
|
func assertFailures(t *testing.T, baseDir string, fi os.FileInfo, src []byte, rules []lint.Rule, config map[string]lint.RuleConfig) error {
|
||||||
l := lint.New(func(file string) ([]byte, error) {
|
l := lint.New(func(file string) ([]byte, error) {
|
||||||
return os.ReadFile(baseDir + file)
|
return os.ReadFile(file)
|
||||||
}, 0)
|
}, 0)
|
||||||
|
|
||||||
ins := parseInstructions(t, fi.Name(), src)
|
ins := parseInstructions(t, path.Join(baseDir, fi.Name()), src)
|
||||||
if ins == nil {
|
if ins == nil {
|
||||||
return fmt.Errorf("Test file %v does not have instructions", fi.Name())
|
return fmt.Errorf("Test file %v does not have instructions", fi.Name())
|
||||||
}
|
}
|
||||||
|
|
||||||
ps, err := l.Lint([][]string{{fi.Name()}}, rules, lint.Config{
|
ps, err := l.Lint([][]string{{path.Join(baseDir, fi.Name())}}, rules, lint.Config{
|
||||||
Rules: config,
|
Rules: config,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
5
testdata/go.mod
vendored
Normal file
5
testdata/go.mod
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
module github.com/mgechev/revive/testdata
|
||||||
|
|
||||||
|
// set the lowest go version
|
||||||
|
// to trigger testing of all rules
|
||||||
|
go 1.0
|
||||||
3
testdata/go1.21/go.mod
vendored
Normal file
3
testdata/go1.21/go.mod
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
module github.com/mgechev/revive/testdata
|
||||||
|
|
||||||
|
go 1.21
|
||||||
54
testdata/go1.21/redefines-builtin-id.go
vendored
Normal file
54
testdata/go1.21/redefines-builtin-id.go
vendored
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
package fixtures
|
||||||
|
|
||||||
|
func (this data) vmethod() {
|
||||||
|
nil := true // MATCH /assignment creates a shadow of built-in identifier nil/
|
||||||
|
iota = 1 // MATCH /assignment modifies built-in identifier iota/
|
||||||
|
}
|
||||||
|
|
||||||
|
func append(i, j int) { // MATCH /redefinition of the built-in function append/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
type string int16 // MATCH /redefinition of the built-in type string/
|
||||||
|
|
||||||
|
func delete(set []int64, i int) (y []int64) { // MATCH /redefinition of the built-in function delete/
|
||||||
|
for j, v := range set {
|
||||||
|
if j != i {
|
||||||
|
y = append(y, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type any int // MATCH /redefinition of the built-in type any/
|
||||||
|
|
||||||
|
func any() {} // MATCH /redefinition of the built-in type any/
|
||||||
|
|
||||||
|
var any int // MATCH /redefinition of the built-in type any/
|
||||||
|
|
||||||
|
const any = 1 // MATCH /redefinition of the built-in type any/
|
||||||
|
|
||||||
|
var i, copy int // MATCH /redefinition of the built-in function copy/
|
||||||
|
|
||||||
|
// issue #792
|
||||||
|
type ()
|
||||||
|
|
||||||
|
func foo() {
|
||||||
|
clear := 0 // MATCH /redefinition of the built-in function clear/
|
||||||
|
max := 0 // MATCH /redefinition of the built-in function max/
|
||||||
|
min := 0 // MATCH /redefinition of the built-in function min/
|
||||||
|
_ = clear
|
||||||
|
_ = max
|
||||||
|
_ = min
|
||||||
|
}
|
||||||
|
|
||||||
|
func foo1(new int) { // MATCH /redefinition of the built-in function new/
|
||||||
|
_ = new
|
||||||
|
}
|
||||||
|
|
||||||
|
func foo2() (new int) { // MATCH /redefinition of the built-in function new/
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func foo3[new any]() { // MATCH /redefinition of the built-in function new/
|
||||||
|
}
|
||||||
30
testdata/go1.22/datarace.go
vendored
Normal file
30
testdata/go1.22/datarace.go
vendored
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package fixtures
|
||||||
|
|
||||||
|
func datarace() (r int, c char) {
|
||||||
|
for _, p := range []int{1, 2} {
|
||||||
|
go func() {
|
||||||
|
print(r) // MATCH /potential datarace: return value r is captured (by-reference) in goroutine/
|
||||||
|
print(p) // Shall not match /datarace: range value p is captured (by-reference) in goroutine/
|
||||||
|
}()
|
||||||
|
for i, p1 := range []int{1, 2} {
|
||||||
|
a := p1
|
||||||
|
go func() {
|
||||||
|
print(r) // MATCH /potential datarace: return value r is captured (by-reference) in goroutine/
|
||||||
|
print(p) // Shall not match /datarace: range value p is captured (by-reference) in goroutine/
|
||||||
|
print(p1) // Shall not match /datarace: range value p1 is captured (by-reference) in goroutine/
|
||||||
|
print(a)
|
||||||
|
print(i) // Shall not match /datarace: range value i is captured (by-reference) in goroutine/
|
||||||
|
}()
|
||||||
|
print(i)
|
||||||
|
print(p)
|
||||||
|
go func() {
|
||||||
|
_ = c // MATCH /potential datarace: return value c is captured (by-reference) in goroutine/
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
print(p1)
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
print(r) // MATCH /potential datarace: return value r is captured (by-reference) in goroutine/
|
||||||
|
}()
|
||||||
|
print(r)
|
||||||
|
}
|
||||||
3
testdata/go1.22/go.mod
vendored
Normal file
3
testdata/go1.22/go.mod
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
module github.com/mgechev/revive/testdata
|
||||||
|
|
||||||
|
go 1.22
|
||||||
163
testdata/go1.22/range-val-address.go
vendored
Normal file
163
testdata/go1.22/range-val-address.go
vendored
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
package fixtures
|
||||||
|
|
||||||
|
func rangeValAddress() {
|
||||||
|
m := map[string]*string{}
|
||||||
|
|
||||||
|
mySlice := []string{"A", "B", "C"}
|
||||||
|
for _, value := range mySlice {
|
||||||
|
m["address"] = &value // Shall not match /suspicious assignment of 'value'. range-loop variables always have the same address/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func rangeValAddress2() {
|
||||||
|
m := map[string]*string{}
|
||||||
|
|
||||||
|
mySlice := []string{"A", "B", "C"}
|
||||||
|
for i := range mySlice {
|
||||||
|
m["address"] = &mySlice[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func rangeValAddress3() {
|
||||||
|
m := map[string]*string{}
|
||||||
|
|
||||||
|
mySlice := []string{"A", "B", "C"}
|
||||||
|
for _, value := range mySlice {
|
||||||
|
a := &value // Shall not match /suspicious assignment of 'value'. range-loop variables always have the same address/
|
||||||
|
m["address"] = a
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func rangeValAddress4() {
|
||||||
|
m := []*string{}
|
||||||
|
|
||||||
|
mySlice := []string{"A", "B", "C"}
|
||||||
|
for _, value := range mySlice {
|
||||||
|
m = append(m, &value) // Shall not match /suspicious assignment of 'value'. range-loop variables always have the same address/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func rangeValAddress5() {
|
||||||
|
m := map[*string]string{}
|
||||||
|
|
||||||
|
mySlice := []string{"A", "B", "C"}
|
||||||
|
for _, value := range mySlice {
|
||||||
|
m[&value] = value // Shall not match /suspicious assignment of 'value'. range-loop variables always have the same address/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func rangeValAddress6() {
|
||||||
|
type v struct {
|
||||||
|
id string
|
||||||
|
}
|
||||||
|
m := []*string{}
|
||||||
|
|
||||||
|
mySlice := []v{{id: "A"}, {id: "B"}, {id: "C"}}
|
||||||
|
for _, value := range mySlice {
|
||||||
|
m = append(m, &value.id) // Shall not match /suspicious assignment of 'value'. range-loop variables always have the same address/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func rangeValAddress7() {
|
||||||
|
type v struct {
|
||||||
|
id string
|
||||||
|
}
|
||||||
|
m := []*string{}
|
||||||
|
|
||||||
|
for _, value := range []v{{id: "A"}, {id: "B"}, {id: "C"}} {
|
||||||
|
m = append(m, &value.id) // Shall not match /suspicious assignment of 'value'. range-loop variables always have the same address/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func rangeValAddress8() {
|
||||||
|
type v struct {
|
||||||
|
id string
|
||||||
|
}
|
||||||
|
m := []*string{}
|
||||||
|
|
||||||
|
mySlice := []*v{{id: "A"}, {id: "B"}, {id: "C"}}
|
||||||
|
for _, value := range mySlice {
|
||||||
|
m = append(m, &value.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func rangeValAddress9() {
|
||||||
|
type v struct {
|
||||||
|
id string
|
||||||
|
}
|
||||||
|
m := []*string{}
|
||||||
|
|
||||||
|
mySlice := map[string]*v{"a": {id: "A"}, "b": {id: "B"}, "c": {id: "C"}}
|
||||||
|
for _, value := range mySlice {
|
||||||
|
m = append(m, &value.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func rangeValAddress10() {
|
||||||
|
type v struct {
|
||||||
|
id string
|
||||||
|
}
|
||||||
|
m := []*string{}
|
||||||
|
|
||||||
|
for _, value := range map[string]*v{"a": {id: "A"}, "b": {id: "B"}, "c": {id: "C"}} {
|
||||||
|
m = append(m, &value.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func rangeValAddress11() {
|
||||||
|
type v struct {
|
||||||
|
id string
|
||||||
|
}
|
||||||
|
m := map[string]*string{}
|
||||||
|
|
||||||
|
for key, value := range map[string]*v{"a": {id: "A"}, "b": {id: "B"}, "c": {id: "C"}} {
|
||||||
|
m[key] = &value.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func rangeValAddress12() {
|
||||||
|
type v struct {
|
||||||
|
id string
|
||||||
|
}
|
||||||
|
m := map[string]*string{}
|
||||||
|
|
||||||
|
for key, value := range map[string]v{"a": {id: "A"}, "b": {id: "B"}, "c": {id: "C"}} {
|
||||||
|
m[key] = &value.id // Shall not match /suspicious assignment of 'value'. range-loop variables always have the same address/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func rangeValAddress13() {
|
||||||
|
type v struct {
|
||||||
|
id string
|
||||||
|
}
|
||||||
|
m := []*string{}
|
||||||
|
|
||||||
|
otherSlice := map[string]*v{"a": {id: "A"}, "b": {id: "B"}, "c": {id: "C"}}
|
||||||
|
mySlice := otherSlice
|
||||||
|
for _, value := range mySlice {
|
||||||
|
m = append(m, &value.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func rangeValAddress14() {
|
||||||
|
type v struct {
|
||||||
|
id *string
|
||||||
|
}
|
||||||
|
|
||||||
|
m := []v{}
|
||||||
|
for _, value := range []string{"A", "B", "C"} {
|
||||||
|
a := v{id: &value} // Shall not match /suspicious assignment of 'value'. range-loop variables always have the same address/
|
||||||
|
m = append(m, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func rangeValAddress15() {
|
||||||
|
type v struct {
|
||||||
|
id *string
|
||||||
|
}
|
||||||
|
|
||||||
|
m := []v{}
|
||||||
|
for _, value := range []string{"A", "B", "C"} {
|
||||||
|
m = append(m, v{id: &value}) // Shall not match /suspicious assignment of 'value'. range-loop variables always have the same address/
|
||||||
|
}
|
||||||
|
}
|
||||||
49
testdata/go1.22/range-val-in-closure.go
vendored
Normal file
49
testdata/go1.22/range-val-in-closure.go
vendored
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
package fixtures
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func foo() {
|
||||||
|
mySlice := []string{"A", "B", "C"}
|
||||||
|
for index, value := range mySlice {
|
||||||
|
go func() {
|
||||||
|
fmt.Printf("Index: %d\n", index) // Shall not match
|
||||||
|
fmt.Printf("Value: %s\n", value) // Shall not match
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
myDict := make(map[string]int)
|
||||||
|
myDict["A"] = 1
|
||||||
|
myDict["B"] = 2
|
||||||
|
myDict["C"] = 3
|
||||||
|
for key, value := range myDict {
|
||||||
|
defer func() {
|
||||||
|
fmt.Printf("Index: %d\n", key) // Shall not match
|
||||||
|
fmt.Printf("Value: %s\n", value) // Shall not match
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, newg := range groups {
|
||||||
|
go func(newg int) {
|
||||||
|
newg.run(m.opts.Context, i) // Shall not match
|
||||||
|
}(newg)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, newg := range groups {
|
||||||
|
newg := newg
|
||||||
|
go func() {
|
||||||
|
newg.run(m.opts.Context, i) // Shall not match
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func issue637() {
|
||||||
|
for key := range m {
|
||||||
|
myKey := key
|
||||||
|
go func() {
|
||||||
|
println(t{
|
||||||
|
key: myKey,
|
||||||
|
otherField: (10 + key), // Shall not match
|
||||||
|
})
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
}
|
||||||
6
testdata/redefines-builtin-id.go
vendored
6
testdata/redefines-builtin-id.go
vendored
@@ -34,9 +34,9 @@ var i, copy int // MATCH /redefinition of the built-in function copy/
|
|||||||
type ()
|
type ()
|
||||||
|
|
||||||
func foo() {
|
func foo() {
|
||||||
clear := 0 // MATCH /redefinition of the built-in function clear/
|
clear := 0 // Shall not match /redefinition of the built-in function clear/
|
||||||
max := 0 // MATCH /redefinition of the built-in function max/
|
max := 0 // Shall not match /redefinition of the built-in function max/
|
||||||
min := 0 // MATCH /redefinition of the built-in function min/
|
min := 0 // Shall not match /redefinition of the built-in function min/
|
||||||
_ = clear
|
_ = clear
|
||||||
_ = max
|
_ = max
|
||||||
_ = min
|
_ = min
|
||||||
|
|||||||
Reference in New Issue
Block a user