diff options
| -rw-r--r-- | capturedrefrace.go | 27 | ||||
| -rw-r--r-- | go.mod | 7 | ||||
| -rw-r--r-- | go.sum | 5 | 
3 files changed, 35 insertions, 4 deletions
| diff --git a/capturedrefrace.go b/capturedrefrace.go index 52f7c34..e155470 100644 --- a/capturedrefrace.go +++ b/capturedrefrace.go @@ -56,6 +56,7 @@ import (  	"go/token"  	"go/types" +	"golang.org/x/exp/slices"  	"golang.org/x/tools/go/analysis"  	"golang.org/x/tools/go/analysis/passes/inspect"  	"golang.org/x/tools/go/ast/inspector" @@ -221,14 +222,36 @@ func checkClosure(pass *analysis.Pass, funcLit *ast.FuncLit) {  			if ident.Name == "copied" {  				fmt.Printf("identifier: %#v, obj: %#v, decl: %#v\n", ident, ident.Obj, ident.Obj.Decl) -				fmt.Printf("scope: %#v\n", scope) -				fmt.Printf("funcScope: %#v\n", funcScope) +				fmt.Printf("  scope: %#v\n", scope) +				fmt.Printf("    Names: %#v\n", scope.Names()) +				fmt.Printf("  funcScope: %#v\n", funcScope) +				fmt.Printf("    Names: %#v\n", funcScope.Names())  				fmt.Println()  			} +			za := slices.Index(funcScope.Names(), ident.Name) +			// if za == -1 { +			// 	return true +			// } +			zb := slices.Index(scope.Names(), ident.Name) +			// if zb == -1 { +			// 	return true +			// } +  			// TODO: Broken by golang/go a27a525d1b4df74989ac9f6ad10394391fe3eb88  			// Test with golang.org/x/tools@v0.15.0  			// Identifier was defined in a different scope. +			// if funcScope != scope { +			if za != -1 && zb != -1 && funcScope.Names()[za] == scope.Names()[zb] { +				pass.Reportf( +					ident.Pos(), +					"captured reference %s in goroutine closure", +					ident, +				) + +				return true +			} +  			if funcScope != scope {  				pass.Reportf(  					ident.Pos(), @@ -2,9 +2,12 @@ module gopkg.teddywing.com/capturedrefrace  go 1.20 -require golang.org/x/tools v0.15.0 +require ( +	golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 +	golang.org/x/tools v0.18.0 +)  require (  	golang.org/x/mod v0.16.0 // indirect -	golang.org/x/sys v0.14.0 // indirect +	golang.org/x/sys v0.17.0 // indirect  ) @@ -1,7 +1,12 @@ +golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ= +golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc=  golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic=  golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=  golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=  golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=  golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=  golang.org/x/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8=  golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk= +golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= +golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= | 
