Repository: mgechev/revive (go)

Issue:
confusing-naming FP on methods of generic types
**Describe the bug**
The `confusing-naming` check misfires on similarly named methods of distinct generic types.

**To Reproduce**
Steps to reproduce the behavior:
1. I updated revive `go install github.com/mgechev/revive@latest`
2. I run it with the following flags & configuration file:

```
revive -config revive.toml test.go
```

revive.toml:

```toml
[rule.confusing-naming]
```

test.go:

```go
package test

type x[T any] struct{}

func (x[T]) method() {
}

type y[T any] struct{}

func (y[T]) method() {
}
```

It's completely legitimate to define methods by the same name on different types.

The false positive only happens when both `x` and `y` are generic. Defining one or both as a concrete type (such as `type x struct{}`) makes the issue disappear.

**Expected behavior**
No `confusing-naming` issue is reported.

**Logs**
```
test.go:10:13: Method 'method' differs only by capitalization to function 'method' in the same source file
```

**Desktop (please complete the following information):**
 - OS: Ubuntu 23.04
 - `go version go1.20.6 linux/amd64`

Pull request:
fix #864: confusing-naming FP on methods of generic types
Closes #864


Patch:
diff --git a/rule/confusing-naming.go b/rule/confusing-naming.go
index 34cdb90..8b1c3ea 100644
--- a/rule/confusing-naming.go
+++ b/rule/confusing-naming.go
@@ -27,10 +27,10 @@ type packages struct {
 
 func (ps *packages) methodNames(lp *lint.Package) pkgMethods {
 	ps.mu.Lock()
+	defer ps.mu.Unlock()
 
 	for _, pkg := range ps.pkgs {
 		if pkg.pkg == lp {
-			ps.mu.Unlock()
 			return pkg
 		}
 	}
@@ -38,7 +38,6 @@ func (ps *packages) methodNames(lp *lint.Package) pkgMethods {
 	pkgm := pkgMethods{pkg: lp, methods: make(map[string]map[string]*referenceMethod), mu: &sync.Mutex{}}
 	ps.pkgs = append(ps.pkgs, pkgm)
 
-	ps.mu.Unlock()
 	return pkgm
 }
 
@@ -72,6 +71,7 @@ func (*ConfusingNamingRule) Name() string {
 
 // checkMethodName checks if a given method/function name is similar (just case differences) to other method/function of the same struct/file.
 func checkMethodName(holder string, id *ast.Ident, w *lintConfusingNames) {
+
 	if id.Name == "init" && holder == defaultStructName {
 		// ignore init functions
 		return
@@ -137,8 +137,11 @@ func getStructName(r *ast.FieldList) string {
 
 	t := r.List[0].Type
 
-	if p, _ := t.(*ast.StarExpr); p != nil { // if a pointer receiver => dereference pointer receiver types
-		t = p.X
+	switch v := t.(type) {
+	case *ast.StarExpr:
+		t = v.X
+	case *ast.IndexExpr:
+		t = v.X
 	}
 
 	if p, _ := t.(*ast.Ident); p != nil {


Test patch:
diff --git a/testdata/confusing-naming1.go b/testdata/confusing-naming1.go
index ba12b07..5b06bac 100644
--- a/testdata/confusing-naming1.go
+++ b/testdata/confusing-naming1.go
@@ -1,5 +1,4 @@
 // Test of confusing-naming rule.
-
 // Package pkg ...
 package pkg
 
@@ -60,3 +59,14 @@ type tBar struct {
 	qwe bool
 	zxc float32
 }
+
+// issue #864
+type x[T any] struct{}
+
+func (x[T]) method() {
+}
+
+type y[T any] struct{}
+
+func (y[T]) method() {
+}