diff options
author | Teddy Wing | 2024-03-10 16:26:09 +0100 |
---|---|---|
committer | Teddy Wing | 2024-03-10 16:26:09 +0100 |
commit | b2f90a88f468f35a125a23bb85214c9348ea1481 (patch) | |
tree | 1fef8a7fe16402fb21776d1b7b775229f411bbf7 /capturedrefrace.go | |
parent | 9aa2dfef38d08ba5a101a7c1b01fecbb1cec240d (diff) | |
parent | 1926d13444dbde1bcd221029ec44bd6bd30396a7 (diff) | |
download | gocapturedrefrace-b2f90a88f468f35a125a23bb85214c9348ea1481.tar.bz2 |
Merge branch 'fix-analysis-for-Go-1.22'
Diffstat (limited to 'capturedrefrace.go')
-rw-r--r-- | capturedrefrace.go | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/capturedrefrace.go b/capturedrefrace.go index c0bc646..66b59e5 100644 --- a/capturedrefrace.go +++ b/capturedrefrace.go @@ -196,7 +196,39 @@ func checkClosure(pass *analysis.Pass, funcLit *ast.FuncLit) { } // Find out whether `ident` was defined in an outer scope. - scope, scopeObj := funcScope.LookupParent(ident.Name, ident.NamePos) + // + // Starting in Go 1.22.0, function scopes in the 'go/types' package + // have changed: + // + // > The start position (Pos) of the lexical environment block + // > (Scope) that represents a function body has changed: it used + // > to start at the opening curly brace of the function body, but + // > now starts at the function's func token. + // + // (https://go.dev/doc/go1.22#go/types) + // + // This was caused by the following commit, which corrected + // behaviour for gopls: + // + // https://github.com/golang/go/commit/a27a525d1b4df74989ac9f6ad10394391fe3eb88 + // + // As a result, we can no longer use `ident.NamePos` as the + // position for `funcScope.LookupParent`. Doing so causes false + // positives for function arguments, incorrectly finding them to be + // captured references from the outer scope. + // + // The commit message of a27a525d1b4df74989ac9f6ad10394391fe3eb88 + // states: + // + // > set correct Var.scopePos for parameters/results + // > + // > Previously, its value was unset (NoPos), but the correct + // > value is a point after the signature (FuncType.End) and + // > before the body. + // + // We can restore the previous behaviour by using `token.NoPos` + // instead of `ident.NamePos`. + scope, scopeObj := funcScope.LookupParent(ident.Name, token.NoPos) // Identifier is local to the closure. if scope == nil && scopeObj == nil { |