aboutsummaryrefslogtreecommitdiffstats
path: root/capturedrefrace.go
diff options
context:
space:
mode:
authorTeddy Wing2024-03-10 16:26:09 +0100
committerTeddy Wing2024-03-10 16:26:09 +0100
commitb2f90a88f468f35a125a23bb85214c9348ea1481 (patch)
tree1fef8a7fe16402fb21776d1b7b775229f411bbf7 /capturedrefrace.go
parent9aa2dfef38d08ba5a101a7c1b01fecbb1cec240d (diff)
parent1926d13444dbde1bcd221029ec44bd6bd30396a7 (diff)
downloadgocapturedrefrace-b2f90a88f468f35a125a23bb85214c9348ea1481.tar.bz2
Merge branch 'fix-analysis-for-Go-1.22'
Diffstat (limited to 'capturedrefrace.go')
-rw-r--r--capturedrefrace.go34
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 {