<feed xmlns='http://www.w3.org/2005/Atom'>
<title>gocapturedrefrace, branch v0.0.2</title>
<subtitle>Analyser that reports captured variable references in goroutine closures</subtitle>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/gocapturedrefrace/'/>
<entry>
<title>Increase version v0.0.1 -&gt; v0.0.2</title>
<updated>2024-03-10T15:31:36+00:00</updated>
<author>
<name>Teddy Wing</name>
</author>
<published>2024-03-10T15:31:36+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/gocapturedrefrace/commit/?id=50d5b0becd6d2e98975afa6cb319bfce11af3da9'/>
<id>50d5b0becd6d2e98975afa6cb319bfce11af3da9</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>capturedrefrace.go: Update copyright year</title>
<updated>2024-03-10T15:29:27+00:00</updated>
<author>
<name>Teddy Wing</name>
</author>
<published>2024-03-10T15:29:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/gocapturedrefrace/commit/?id=3932a338b069f5b1dbc8e408764da719049cab98'/>
<id>3932a338b069f5b1dbc8e408764da719049cab98</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge branch 'fix-analysis-for-Go-1.22'</title>
<updated>2024-03-10T15:26:09+00:00</updated>
<author>
<name>Teddy Wing</name>
</author>
<published>2024-03-10T15:26:09+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/gocapturedrefrace/commit/?id=b2f90a88f468f35a125a23bb85214c9348ea1481'/>
<id>b2f90a88f468f35a125a23bb85214c9348ea1481</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Clean up Go 1.22 tests and fix broken analysis under Go 1.22</title>
<updated>2024-03-10T15:10:36+00:00</updated>
<author>
<name>Teddy Wing</name>
</author>
<published>2024-03-10T15:10:36+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/gocapturedrefrace/commit/?id=1926d13444dbde1bcd221029ec44bd6bd30396a7'/>
<id>1926d13444dbde1bcd221029ec44bd6bd30396a7</id>
<content type='text'>
* Remove my debugging tests from trying to understand the Go 1.22
  problem.
* Describe the problem caused by the change in 'go/types' starting in Go
  1.22.0.

The problem was caused by
https://github.com/golang/go/commit/a27a525d1b4df74989ac9f6ad10394391fe3eb88,
which resolved the following two issues related to 'gopls':

* https://github.com/golang/go/issues/64292
* https://github.com/golang/go/issues/64295
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* Remove my debugging tests from trying to understand the Go 1.22
  problem.
* Describe the problem caused by the change in 'go/types' starting in Go
  1.22.0.

The problem was caused by
https://github.com/golang/go/commit/a27a525d1b4df74989ac9f6ad10394391fe3eb88,
which resolved the following two issues related to 'gopls':

* https://github.com/golang/go/issues/64292
* https://github.com/golang/go/issues/64295
</pre>
</div>
</content>
</entry>
<entry>
<title>go.mod: Upgrade 'golang.org/x/tools' to latest v0.19.0</title>
<updated>2024-03-10T14:28:54+00:00</updated>
<author>
<name>Teddy Wing</name>
</author>
<published>2024-03-10T14:28:54+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/gocapturedrefrace/commit/?id=ba664a54c0e275c01709e393030aeeae607d0656'/>
<id>ba664a54c0e275c01709e393030aeeae607d0656</id>
<content type='text'>
We were previously using golang.org/x/tools v0.9.1, which caused a
segfault when running against the latest Go 1.22:

    $ go test
    panic: runtime error: invalid memory address or nil pointer dereference [recovered]
      panic: runtime error: invalid memory address or nil pointer dereference
    [signal SIGSEGV: segmentation violation code=0x2 addr=0x0 pc=0x100862f14]

    goroutine 76 [running]:
    go/types.(*Checker).handleBailout(0x14000184200, 0x14000639b98)
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/check.go:367 +0x9c
    panic({0x10097d640?, 0x100b50600?})
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/runtime/panic.go:770 +0x124
    go/types.(*StdSizes).Sizeof(0x0, {0x1009c9d28, 0x100b539a0})
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/sizes.go:228 +0x314
    go/types.(*Config).sizeof(...)
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/sizes.go:333
    go/types.representableConst.func1({0x1009c9d28?, 0x100b539a0?})
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/const.go:76 +0x9c
    go/types.representableConst({0x1009cb030, 0x100b47d80}, 0x14000184200, 0x100b539a0, 0x0)
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/const.go:92 +0x138
    go/types.(*Checker).arrayLength(0x14000184200, {0x1009ca168, 0x14000226b20?})
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/typexpr.go:510 +0x238
    go/types.(*Checker).typInternal(0x14000184200, {0x1009ca138, 0x140001a42a0}, 0x0)
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/typexpr.go:299 +0x3bc
    go/types.(*Checker).definedType(0x14000184200, {0x1009ca138, 0x140001a42a0}, 0x14000639158?)
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/typexpr.go:180 +0x2c
    go/types.(*Checker).varType(0x14000184200, {0x1009ca138, 0x140001a42a0})
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/typexpr.go:145 +0x2c
    go/types.(*Checker).structType(0x14000184200, 0x140001a49f0, 0x140001a49f0?)
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/struct.go:113 +0x128
    go/types.(*Checker).typInternal(0x14000184200, {0x1009ca3a8, 0x140001145b8}, 0x140001597c0)
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/typexpr.go:316 +0xed0
    go/types.(*Checker).definedType(0x14000184200, {0x1009ca3a8, 0x140001145b8}, 0x100690214?)
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/typexpr.go:180 +0x2c
    go/types.(*Checker).typeDecl(0x14000184200, 0x140001597c0, 0x1400022e8c0, 0x0)
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/decl.go:615 +0x39c
    go/types.(*Checker).objDecl(0x14000184200, {0x1009cd298, 0x140001597c0}, 0x0)
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/decl.go:197 +0x880
    go/types.(*Checker).packageObjects(0x14000184200)
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/resolver.go:681 +0x3c0
    go/types.(*Checker).checkFiles(0x14000184200, {0x1400061e2e8, 0x1, 0x1})
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/check.go:408 +0x164
    go/types.(*Checker).Files(...)
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/check.go:372
    golang.org/x/tools/go/packages.(*loader).loadPackage(0x140001881c0, 0x14000011110)
      ...go/pkg/mod/golang.org/x/tools@v0.9.1/go/packages/packages.go:1052 +0x870
    golang.org/x/tools/go/packages.(*loader).loadRecursive.func1()
      ...go/pkg/mod/golang.org/x/tools@v0.9.1/go/packages/packages.go:851 +0x178
    sync.(*Once).doSlow(0x0?, 0x0?)
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/sync/once.go:74 +0x100
    sync.(*Once).Do(...)
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/sync/once.go:65
    golang.org/x/tools/go/packages.(*loader).loadRecursive(0x0?, 0x0?)
      ...go/pkg/mod/golang.org/x/tools@v0.9.1/go/packages/packages.go:839 +0x50
    golang.org/x/tools/go/packages.(*loader).loadRecursive.func1.1(0x0?)
      ...go/pkg/mod/golang.org/x/tools@v0.9.1/go/packages/packages.go:846 +0x30
    created by golang.org/x/tools/go/packages.(*loader).loadRecursive.func1 in goroutine 67
      ...go/pkg/mod/golang.org/x/tools@v0.9.1/go/packages/packages.go:845 +0x84
    exit status 2
    FAIL	gopkg.teddywing.com/capturedrefrace	0.129s

Upgrade to the latest version of the library, which doesn't cause the
problem.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
We were previously using golang.org/x/tools v0.9.1, which caused a
segfault when running against the latest Go 1.22:

    $ go test
    panic: runtime error: invalid memory address or nil pointer dereference [recovered]
      panic: runtime error: invalid memory address or nil pointer dereference
    [signal SIGSEGV: segmentation violation code=0x2 addr=0x0 pc=0x100862f14]

    goroutine 76 [running]:
    go/types.(*Checker).handleBailout(0x14000184200, 0x14000639b98)
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/check.go:367 +0x9c
    panic({0x10097d640?, 0x100b50600?})
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/runtime/panic.go:770 +0x124
    go/types.(*StdSizes).Sizeof(0x0, {0x1009c9d28, 0x100b539a0})
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/sizes.go:228 +0x314
    go/types.(*Config).sizeof(...)
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/sizes.go:333
    go/types.representableConst.func1({0x1009c9d28?, 0x100b539a0?})
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/const.go:76 +0x9c
    go/types.representableConst({0x1009cb030, 0x100b47d80}, 0x14000184200, 0x100b539a0, 0x0)
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/const.go:92 +0x138
    go/types.(*Checker).arrayLength(0x14000184200, {0x1009ca168, 0x14000226b20?})
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/typexpr.go:510 +0x238
    go/types.(*Checker).typInternal(0x14000184200, {0x1009ca138, 0x140001a42a0}, 0x0)
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/typexpr.go:299 +0x3bc
    go/types.(*Checker).definedType(0x14000184200, {0x1009ca138, 0x140001a42a0}, 0x14000639158?)
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/typexpr.go:180 +0x2c
    go/types.(*Checker).varType(0x14000184200, {0x1009ca138, 0x140001a42a0})
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/typexpr.go:145 +0x2c
    go/types.(*Checker).structType(0x14000184200, 0x140001a49f0, 0x140001a49f0?)
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/struct.go:113 +0x128
    go/types.(*Checker).typInternal(0x14000184200, {0x1009ca3a8, 0x140001145b8}, 0x140001597c0)
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/typexpr.go:316 +0xed0
    go/types.(*Checker).definedType(0x14000184200, {0x1009ca3a8, 0x140001145b8}, 0x100690214?)
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/typexpr.go:180 +0x2c
    go/types.(*Checker).typeDecl(0x14000184200, 0x140001597c0, 0x1400022e8c0, 0x0)
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/decl.go:615 +0x39c
    go/types.(*Checker).objDecl(0x14000184200, {0x1009cd298, 0x140001597c0}, 0x0)
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/decl.go:197 +0x880
    go/types.(*Checker).packageObjects(0x14000184200)
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/resolver.go:681 +0x3c0
    go/types.(*Checker).checkFiles(0x14000184200, {0x1400061e2e8, 0x1, 0x1})
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/check.go:408 +0x164
    go/types.(*Checker).Files(...)
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/check.go:372
    golang.org/x/tools/go/packages.(*loader).loadPackage(0x140001881c0, 0x14000011110)
      ...go/pkg/mod/golang.org/x/tools@v0.9.1/go/packages/packages.go:1052 +0x870
    golang.org/x/tools/go/packages.(*loader).loadRecursive.func1()
      ...go/pkg/mod/golang.org/x/tools@v0.9.1/go/packages/packages.go:851 +0x178
    sync.(*Once).doSlow(0x0?, 0x0?)
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/sync/once.go:74 +0x100
    sync.(*Once).Do(...)
      /opt/homebrew/Cellar/go/1.22.1/libexec/src/sync/once.go:65
    golang.org/x/tools/go/packages.(*loader).loadRecursive(0x0?, 0x0?)
      ...go/pkg/mod/golang.org/x/tools@v0.9.1/go/packages/packages.go:839 +0x50
    golang.org/x/tools/go/packages.(*loader).loadRecursive.func1.1(0x0?)
      ...go/pkg/mod/golang.org/x/tools@v0.9.1/go/packages/packages.go:846 +0x30
    created by golang.org/x/tools/go/packages.(*loader).loadRecursive.func1 in goroutine 67
      ...go/pkg/mod/golang.org/x/tools@v0.9.1/go/packages/packages.go:845 +0x84
    exit status 2
    FAIL	gopkg.teddywing.com/capturedrefrace	0.129s

Upgrade to the latest version of the library, which doesn't cause the
problem.
</pre>
</div>
</content>
</entry>
<entry>
<title>Fiddle with `pos` in `funcScope.LookupParent` for Go 1.22 breakage</title>
<updated>2024-03-09T20:20:32+00:00</updated>
<author>
<name>Teddy Wing</name>
</author>
<published>2024-03-09T20:20:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/gocapturedrefrace/commit/?id=b1b311caf11e9e88ef5735dc4e5512dcd4725059'/>
<id>b1b311caf11e9e88ef5735dc4e5512dcd4725059</id>
<content type='text'>
First I tried changing `funcScope.LookupParent` to use the starting
brace ("{") of the function, but that didn't work for redeclarations:

    $ go test -v
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:38:6: unexpected diagnostic: captured reference err in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:39:14: unexpected diagnostic: captured reference err in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:47:3: unexpected diagnostic: captured reference err in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:48:6: unexpected diagnostic: captured reference err in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:49:14: unexpected diagnostic: captured reference err in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:66:3: unexpected diagnostic: captured reference err1 in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:67:3: unexpected diagnostic: captured reference err2 in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:68:6: unexpected diagnostic: captured reference err1 in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:68:21: unexpected diagnostic: captured reference err2 in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:69:14: unexpected diagnostic: captured reference err1 in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:69:20: unexpected diagnostic: captured reference err2 in goroutine closure
    --- FAIL: Test (0.43s)

The commit that breaks the analyzer says:

&gt; Previously, its value was unset (NoPos), but the correct
&gt; value is a point after the signature (FuncType.End) and
&gt; before the body.

(https://github.com/golang/go/commit/a27a525d1b4df74989ac9f6ad10394391fe3eb88)

Recalling that, I tried setting the position to `token.NoPos`, which
fixes the analyser and allows the tests to pass.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
First I tried changing `funcScope.LookupParent` to use the starting
brace ("{") of the function, but that didn't work for redeclarations:

    $ go test -v
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:38:6: unexpected diagnostic: captured reference err in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:39:14: unexpected diagnostic: captured reference err in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:47:3: unexpected diagnostic: captured reference err in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:48:6: unexpected diagnostic: captured reference err in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:49:14: unexpected diagnostic: captured reference err in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:66:3: unexpected diagnostic: captured reference err1 in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:67:3: unexpected diagnostic: captured reference err2 in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:68:6: unexpected diagnostic: captured reference err1 in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:68:21: unexpected diagnostic: captured reference err2 in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:69:14: unexpected diagnostic: captured reference err1 in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:69:20: unexpected diagnostic: captured reference err2 in goroutine closure
    --- FAIL: Test (0.43s)

The commit that breaks the analyzer says:

&gt; Previously, its value was unset (NoPos), but the correct
&gt; value is a point after the signature (FuncType.End) and
&gt; before the body.

(https://github.com/golang/go/commit/a27a525d1b4df74989ac9f6ad10394391fe3eb88)

Recalling that, I tried setting the position to `token.NoPos`, which
fixes the analyser and allows the tests to pass.
</pre>
</div>
</content>
</entry>
<entry>
<title>Try checking if the same variable in inner scope is in parent scope</title>
<updated>2024-03-09T19:58:56+00:00</updated>
<author>
<name>Teddy Wing</name>
</author>
<published>2024-03-09T19:58:56+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/gocapturedrefrace/commit/?id=f923099c4302e49a1563183c5217e1e5cf017d85'/>
<id>f923099c4302e49a1563183c5217e1e5cf017d85</id>
<content type='text'>
Can't figure out how to resolve the `funcScope != scope` problem in Go
1.22.

Saw the `Names` method in the documentation and out of curiosity tried
to see if that could be used as an alternate means of checking if a
variable is declared in the parent scope.

Turns out I get a bunch of false positives with that so I can't use it:

    $ go test -v
    === RUN   Test
    identifier: &amp;ast.Ident{NamePos:4069121, Name:"copied", Obj:(*ast.Object)(0x1400206b720)}, obj: &amp;ast.Object{Kind:4, Name:"copied", Decl:(*ast.Field)(0x140067420c0), Data:interface {}(nil), Type:interface {}(nil)}, decl: &amp;ast.Field{Doc:(*ast.CommentGroup)(nil), Names:[]*ast.Ident{(*ast.Ident)(0x1400215fea0)}, Type:(*ast.Ident)(0x1400215fec0), Tag:(*ast.BasicLit)(nil), Comment:(*ast.CommentGroup)(nil)}
      scope: &amp;types.Scope{parent:(*types.Scope)(0x14002164960), children:[]*types.Scope{(*types.Scope)(0x14003b12d80)}, number:1, elems:map[string]types.Object{"capturedReference":(*types.Var)(0x14003b12c60), "capturedReference2":(*types.Var)(0x14003b12cc0), "copied":(*types.Var)(0x14003b12d20)}, pos:4069035, end:4069588, comment:"function", isFunc:true}
        Names: []string{"capturedReference", "capturedReference2", "copied"}
      funcScope: &amp;types.Scope{parent:(*types.Scope)(0x14002165620), children:[]*types.Scope{(*types.Scope)(0x14003b12ea0)}, number:1, elems:map[string]types.Object{"copied":(*types.Var)(0x14003b12e40), "decl":(*types.Var)(0x14003b13020), "newVar":(*types.Var)(0x14003b12f60), "str":(*types.Var)(0x14003b12fc0)}, pos:4069116, end:4069578, comment:"function", isFunc:true}
        Names: []string{"copied", "decl", "newVar", "str"}

    identifier: &amp;ast.Ident{NamePos:4069325, Name:"copied", Obj:(*ast.Object)(0x1400206b720)}, obj: &amp;ast.Object{Kind:4, Name:"copied", Decl:(*ast.Field)(0x140067420c0), Data:interface {}(nil), Type:interface {}(nil)}, decl: &amp;ast.Field{Doc:(*ast.CommentGroup)(nil), Names:[]*ast.Ident{(*ast.Ident)(0x1400215fea0)}, Type:(*ast.Ident)(0x1400215fec0), Tag:(*ast.BasicLit)(nil), Comment:(*ast.CommentGroup)(nil)}
      scope: &amp;types.Scope{parent:(*types.Scope)(0x14002165620), children:[]*types.Scope{(*types.Scope)(0x14003b12ea0)}, number:1, elems:map[string]types.Object{"copied":(*types.Var)(0x14003b12e40), "decl":(*types.Var)(0x14003b13020), "newVar":(*types.Var)(0x14003b12f60), "str":(*types.Var)(0x14003b12fc0)}, pos:4069116, end:4069578, comment:"function", isFunc:true}
        Names: []string{"copied", "decl", "newVar", "str"}
      funcScope: &amp;types.Scope{parent:(*types.Scope)(0x14002165620), children:[]*types.Scope{(*types.Scope)(0x14003b12ea0)}, number:1, elems:map[string]types.Object{"copied":(*types.Var)(0x14003b12e40), "decl":(*types.Var)(0x14003b13020), "newVar":(*types.Var)(0x14003b12f60), "str":(*types.Var)(0x14003b12fc0)}, pos:4069116, end:4069578, comment:"function", isFunc:true}
        Names: []string{"copied", "decl", "newVar", "str"}

        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:38:6: unexpected diagnostic: captured reference err in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:39:14: unexpected diagnostic: captured reference err in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:47:3: unexpected diagnostic: captured reference err in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:48:6: unexpected diagnostic: captured reference err in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:49:14: unexpected diagnostic: captured reference err in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:66:3: unexpected diagnostic: captured reference err1 in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:67:3: unexpected diagnostic: captured reference err2 in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:68:6: unexpected diagnostic: captured reference err1 in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:68:21: unexpected diagnostic: captured reference err2 in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:69:14: unexpected diagnostic: captured reference err1 in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:69:20: unexpected diagnostic: captured reference err2 in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/simple.go:29:10: unexpected diagnostic: captured reference copied in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/simple.go:32:3: unexpected diagnostic: captured reference copied in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/simple.go:39:3: unexpected diagnostic: captured reference newVar in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/simple.go:42:18: unexpected diagnostic: captured reference str in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/simple.go:45:3: unexpected diagnostic: captured reference decl in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/simple.go:46:18: unexpected diagnostic: captured reference decl in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/simple.go:57:10: unexpected diagnostic: captured reference s in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/simple.go:58:3: unexpected diagnostic: captured reference s in goroutine closure
    --- FAIL: Test (0.40s)
    FAIL
    exit status 1
    FAIL	gopkg.teddywing.com/capturedrefrace	0.414s
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Can't figure out how to resolve the `funcScope != scope` problem in Go
1.22.

Saw the `Names` method in the documentation and out of curiosity tried
to see if that could be used as an alternate means of checking if a
variable is declared in the parent scope.

Turns out I get a bunch of false positives with that so I can't use it:

    $ go test -v
    === RUN   Test
    identifier: &amp;ast.Ident{NamePos:4069121, Name:"copied", Obj:(*ast.Object)(0x1400206b720)}, obj: &amp;ast.Object{Kind:4, Name:"copied", Decl:(*ast.Field)(0x140067420c0), Data:interface {}(nil), Type:interface {}(nil)}, decl: &amp;ast.Field{Doc:(*ast.CommentGroup)(nil), Names:[]*ast.Ident{(*ast.Ident)(0x1400215fea0)}, Type:(*ast.Ident)(0x1400215fec0), Tag:(*ast.BasicLit)(nil), Comment:(*ast.CommentGroup)(nil)}
      scope: &amp;types.Scope{parent:(*types.Scope)(0x14002164960), children:[]*types.Scope{(*types.Scope)(0x14003b12d80)}, number:1, elems:map[string]types.Object{"capturedReference":(*types.Var)(0x14003b12c60), "capturedReference2":(*types.Var)(0x14003b12cc0), "copied":(*types.Var)(0x14003b12d20)}, pos:4069035, end:4069588, comment:"function", isFunc:true}
        Names: []string{"capturedReference", "capturedReference2", "copied"}
      funcScope: &amp;types.Scope{parent:(*types.Scope)(0x14002165620), children:[]*types.Scope{(*types.Scope)(0x14003b12ea0)}, number:1, elems:map[string]types.Object{"copied":(*types.Var)(0x14003b12e40), "decl":(*types.Var)(0x14003b13020), "newVar":(*types.Var)(0x14003b12f60), "str":(*types.Var)(0x14003b12fc0)}, pos:4069116, end:4069578, comment:"function", isFunc:true}
        Names: []string{"copied", "decl", "newVar", "str"}

    identifier: &amp;ast.Ident{NamePos:4069325, Name:"copied", Obj:(*ast.Object)(0x1400206b720)}, obj: &amp;ast.Object{Kind:4, Name:"copied", Decl:(*ast.Field)(0x140067420c0), Data:interface {}(nil), Type:interface {}(nil)}, decl: &amp;ast.Field{Doc:(*ast.CommentGroup)(nil), Names:[]*ast.Ident{(*ast.Ident)(0x1400215fea0)}, Type:(*ast.Ident)(0x1400215fec0), Tag:(*ast.BasicLit)(nil), Comment:(*ast.CommentGroup)(nil)}
      scope: &amp;types.Scope{parent:(*types.Scope)(0x14002165620), children:[]*types.Scope{(*types.Scope)(0x14003b12ea0)}, number:1, elems:map[string]types.Object{"copied":(*types.Var)(0x14003b12e40), "decl":(*types.Var)(0x14003b13020), "newVar":(*types.Var)(0x14003b12f60), "str":(*types.Var)(0x14003b12fc0)}, pos:4069116, end:4069578, comment:"function", isFunc:true}
        Names: []string{"copied", "decl", "newVar", "str"}
      funcScope: &amp;types.Scope{parent:(*types.Scope)(0x14002165620), children:[]*types.Scope{(*types.Scope)(0x14003b12ea0)}, number:1, elems:map[string]types.Object{"copied":(*types.Var)(0x14003b12e40), "decl":(*types.Var)(0x14003b13020), "newVar":(*types.Var)(0x14003b12f60), "str":(*types.Var)(0x14003b12fc0)}, pos:4069116, end:4069578, comment:"function", isFunc:true}
        Names: []string{"copied", "decl", "newVar", "str"}

        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:38:6: unexpected diagnostic: captured reference err in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:39:14: unexpected diagnostic: captured reference err in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:47:3: unexpected diagnostic: captured reference err in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:48:6: unexpected diagnostic: captured reference err in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:49:14: unexpected diagnostic: captured reference err in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:66:3: unexpected diagnostic: captured reference err1 in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:67:3: unexpected diagnostic: captured reference err2 in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:68:6: unexpected diagnostic: captured reference err1 in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:68:21: unexpected diagnostic: captured reference err2 in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:69:14: unexpected diagnostic: captured reference err1 in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/shadow.go:69:20: unexpected diagnostic: captured reference err2 in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/simple.go:29:10: unexpected diagnostic: captured reference copied in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/simple.go:32:3: unexpected diagnostic: captured reference copied in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/simple.go:39:3: unexpected diagnostic: captured reference newVar in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/simple.go:42:18: unexpected diagnostic: captured reference str in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/simple.go:45:3: unexpected diagnostic: captured reference decl in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/simple.go:46:18: unexpected diagnostic: captured reference decl in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/simple.go:57:10: unexpected diagnostic: captured reference s in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/simple.go:58:3: unexpected diagnostic: captured reference s in goroutine closure
    --- FAIL: Test (0.40s)
    FAIL
    exit status 1
    FAIL	gopkg.teddywing.com/capturedrefrace	0.414s
</pre>
</div>
</content>
</entry>
<entry>
<title>Debug broken behaviour caused by Go 1.22</title>
<updated>2024-03-09T17:45:48+00:00</updated>
<author>
<name>Teddy Wing</name>
</author>
<published>2024-03-09T17:45:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/gocapturedrefrace/commit/?id=bf64f32a1a8099ee45d66796b5f60f9ae10a2436'/>
<id>bf64f32a1a8099ee45d66796b5f60f9ae10a2436</id>
<content type='text'>
The Go 1.22 release notes mention in passing:

&gt; The start position (Pos) of the lexical environment block (Scope) that
&gt; represents a function body has changed: it used to start at the
&gt; opening curly brace of the function body, but now starts at the
&gt; function's func token.

(https://go.dev/doc/go1.22#go/types)

That looked like what was causing the breakage in Capturedrefrace.

I started by trying to compare the differences between Go 1.21 and Go
1.22:

    $ go install golang.org/dl/go1.22.0@latest
    $ go1.22.0 download
    $ go install golang.org/dl/go1.21.8@latest
    $ go1.21.8 download

    $ go1.22.0 test
    === RUN   Test
        analysistest.go:522: gocapturedrefrace/testdata/simple.go:29:10: unexpected diagnostic: captured reference copied in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/simple.go:57:10: unexpected diagnostic: captured reference s in goroutine closure
    --- FAIL: Test (0.40s)
    FAIL
    exit status 1
    FAIL	gopkg.teddywing.com/capturedrefrace	0.410s

    $ go1.21.8 test -v
    === RUN   Test
    --- PASS: Test (0.38s)
    PASS
    ok  	gopkg.teddywing.com/capturedrefrace	0.389s

Printing different AST values showed differences, but it was difficult
to see what was going on. What was clear was that the problem came from
the `if funcScope != scope` line.

Since it was clear the problem came from the Go standard library rather
than the golang.org/x/tools package, I tried bisecting Go (with some
guidance from
https://scribe.rip/@fzambia/bisecting-go-performance-degradation-4d4a7ee83a63):

    $ git clone https://github.com/golang/go.git
    $ git checkout go1.22.0
    $ git bisect start
    $ git bisect good go1.21.8
    $ git bisect bad
    $ cd src/
    $ ./make.bash
    ...

And in this repository:

    $ /tmp/go/bin/go test -v

That turned up this commit:
https://github.com/golang/go/commit/a27a525d1b4df74989ac9f6ad10394391fe3eb88.

Now I know what's causing the problem, and that the change isn't likely
to be reverted because the issues it references describe it as a bug.
Next, I'll have to work out how to work around the change in the
analyzer.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The Go 1.22 release notes mention in passing:

&gt; The start position (Pos) of the lexical environment block (Scope) that
&gt; represents a function body has changed: it used to start at the
&gt; opening curly brace of the function body, but now starts at the
&gt; function's func token.

(https://go.dev/doc/go1.22#go/types)

That looked like what was causing the breakage in Capturedrefrace.

I started by trying to compare the differences between Go 1.21 and Go
1.22:

    $ go install golang.org/dl/go1.22.0@latest
    $ go1.22.0 download
    $ go install golang.org/dl/go1.21.8@latest
    $ go1.21.8 download

    $ go1.22.0 test
    === RUN   Test
        analysistest.go:522: gocapturedrefrace/testdata/simple.go:29:10: unexpected diagnostic: captured reference copied in goroutine closure
        analysistest.go:522: gocapturedrefrace/testdata/simple.go:57:10: unexpected diagnostic: captured reference s in goroutine closure
    --- FAIL: Test (0.40s)
    FAIL
    exit status 1
    FAIL	gopkg.teddywing.com/capturedrefrace	0.410s

    $ go1.21.8 test -v
    === RUN   Test
    --- PASS: Test (0.38s)
    PASS
    ok  	gopkg.teddywing.com/capturedrefrace	0.389s

Printing different AST values showed differences, but it was difficult
to see what was going on. What was clear was that the problem came from
the `if funcScope != scope` line.

Since it was clear the problem came from the Go standard library rather
than the golang.org/x/tools package, I tried bisecting Go (with some
guidance from
https://scribe.rip/@fzambia/bisecting-go-performance-degradation-4d4a7ee83a63):

    $ git clone https://github.com/golang/go.git
    $ git checkout go1.22.0
    $ git bisect start
    $ git bisect good go1.21.8
    $ git bisect bad
    $ cd src/
    $ ./make.bash
    ...

And in this repository:

    $ /tmp/go/bin/go test -v

That turned up this commit:
https://github.com/golang/go/commit/a27a525d1b4df74989ac9f6ad10394391fe3eb88.

Now I know what's causing the problem, and that the change isn't likely
to be reverted because the issues it references describe it as a bug.
Next, I'll have to work out how to work around the change in the
analyzer.
</pre>
</div>
</content>
</entry>
<entry>
<title>go.mod: Upgrade to golang.org/x/tools v0.15.0</title>
<updated>2024-03-09T17:37:00+00:00</updated>
<author>
<name>Teddy Wing</name>
</author>
<published>2024-03-09T17:37:00+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/gocapturedrefrace/commit/?id=160d3bef43b386e6a3db8990ad78c3177c56fc3a'/>
<id>160d3bef43b386e6a3db8990ad78c3177c56fc3a</id>
<content type='text'>
The version previously declared caused a panic when running under Go
1.22:

    $ go1.22.0 test -v
    === RUN   Test
    panic: runtime error: invalid memory address or nil pointer dereference [recovered]
      panic: runtime error: invalid memory address or nil pointer dereference
    [signal SIGSEGV: segmentation violation code=0x2 addr=0x0 pc=0x102ffd84c]

    goroutine 92 [running]:
    go/types.(*Checker).handleBailout(0x140002e0000, 0x140002ddb68)
      /tmp/go/src/go/types/check.go:339 +0x9c
    panic({0x103110f80?, 0x1032d4670?})
      /tmp/go/src/runtime/panic.go:765 +0x124
    go/types.(*StdSizes).Sizeof(0x0, {0x10315b768?, 0x1032d56a0})
      /tmp/go/src/go/types/sizes.go:228 +0x2fc
    go/types.(*Config).sizeof(...)
      /tmp/go/src/go/types/sizes.go:331
    go/types.representableConst.func1({0x10315b768?, 0x1032d56a0?})
      /tmp/go/src/go/types/const.go:76 +0x9c
    go/types.representableConst({0x10315ca48, 0x1032cbe00}, 0x140002e0000, 0x1032d56a0, 0x0)
      /tmp/go/src/go/types/const.go:92 +0x138
    go/types.(*Checker).arrayLength(0x140002e0000, {0x10315bb80?, 0x140002b2160?})
      /tmp/go/src/go/types/typexpr.go:504 +0x23c
    go/types.(*Checker).typInternal(0x140002e0000, {0x10315bb50?, 0x140002ac090?}, 0x1033453c8?)
      /tmp/go/src/go/types/typexpr.go:299 +0x934
    go/types.(*Checker).definedType(0x140002b23e0?, {0x10315bb50?, 0x140002ac090}, 0x102ff9fd8?)
      /tmp/go/src/go/types/typexpr.go:180 +0x30
    go/types.(*Checker).varType(0x140002e0000, {0x10315bb50?, 0x140002ac090})
      /tmp/go/src/go/types/typexpr.go:145 +0x30
    go/types.(*Checker).structType(0x140002e0000, 0x140002ac3c0, 0x140002ac3c0?)
      /tmp/go/src/go/types/struct.go:113 +0x128
    go/types.(*Checker).typInternal(0x140002e0000, {0x10315bdc0?, 0x14000290468?}, 0x102e87278?)
      /tmp/go/src/go/types/typexpr.go:316 +0xb14
    go/types.(*Checker).definedType(0x0?, {0x10315bdc0?, 0x14000290468}, 0x102e3c294?)
      /tmp/go/src/go/types/typexpr.go:180 +0x30
    go/types.(*Checker).typeDecl(0x140002e0000, 0x140002d4370, 0x140002c2040, 0x778?)
      /tmp/go/src/go/types/decl.go:595 +0x544
    go/types.(*Checker).objDecl(0x140002e0000, {0x10315df58, 0x140002d4370}, 0x102fc77b8?)
      /tmp/go/src/go/types/decl.go:197 +0x7d0
    go/types.(*Checker).packageObjects(0x140002e0000)
      /tmp/go/src/go/types/resolver.go:675 +0x350
    go/types.(*Checker).checkFiles(0x140002e0000, {0x140002ae000, 0x1, 0x1})
      /tmp/go/src/go/types/check.go:387 +0x1d8
    go/types.(*Checker).Files(...)
      /tmp/go/src/go/types/check.go:344
    golang.org/x/tools/go/packages.(*loader).loadPackage(0x140001501c0, 0x1400016b1a0)
      ...go/pkg/mod/golang.org/x/tools@v0.9.1/go/packages/packages.go:1052 +0x97c
    golang.org/x/tools/go/packages.(*loader).loadRecursive.func1()
      ...go/pkg/mod/golang.org/x/tools@v0.9.1/go/packages/packages.go:851 +0x178
    sync.(*Once).doSlow(0x0?, 0x0?)
      /tmp/go/src/sync/once.go:74 +0x100
    sync.(*Once).Do(...)
      /tmp/go/src/sync/once.go:65
    golang.org/x/tools/go/packages.(*loader).loadRecursive(0x0?, 0x0?)
      ...go/pkg/mod/golang.org/x/tools@v0.9.1/go/packages/packages.go:839 +0x50
    golang.org/x/tools/go/packages.(*loader).loadRecursive.func1.1(0x0?)
      ...go/pkg/mod/golang.org/x/tools@v0.9.1/go/packages/packages.go:846 +0x30
    created by golang.org/x/tools/go/packages.(*loader).loadRecursive.func1 in goroutine 40
      ...go/pkg/mod/golang.org/x/tools@v0.9.1/go/packages/packages.go:845 +0x84
    panic: runtime error: invalid memory address or nil pointer dereference [recovered]
      panic: runtime error: invalid memory address or nil pointer dereference
    [signal SIGSEGV: segmentation violation code=0x2 addr=0x0 pc=0x102ffd84c]

    goroutine 65 [running]:
    go/types.(*Checker).handleBailout(0x140001c2000, 0x14000171b68)
      /tmp/go/src/go/types/check.go:339 +0x9c
    panic({0x103110f80?, 0x1032d4670?})
      /tmp/go/src/runtime/panic.go:765 +0x124
    go/types.(*StdSizes).Sizeof(0x0, {0x10315b768?, 0x1032d56a0})
      /tmp/go/src/go/types/sizes.go:228 +0x2fc
    go/types.(*Config).sizeof(...)
      /tmp/go/src/go/types/sizes.go:331
    go/types.representableConst.func1({0x10315b768?, 0x1032d56a0?})
      /tmp/go/src/go/types/const.go:76 +0x9c
    go/types.representableConst({0x10315ca48, 0x1032cbd80}, 0x140001c2000, 0x1032d56a0, 0x1400016fec8)
      /tmp/go/src/go/types/const.go:92 +0x138
    go/types.(*Checker).representation(0x10315b768?, 0x140001b0ec0, 0x1400016ff48?)
      /tmp/go/src/go/types/const.go:256 +0x68
    go/types.(*Checker).implicitTypeAndValue(0x140001c2000, 0x140001b0ec0, {0x10315b768?, 0x1032d56a0?})
      /tmp/go/src/go/types/expr.go:375 +0x2e8
    go/types.(*Checker).convertUntyped(0x140001c2000, 0x140001b0ec0, {0x10315b768, 0x1032d56a0})
      /tmp/go/src/go/types/const.go:289 +0x30
    go/types.(*Checker).matchTypes(0x14000170698?, 0x140001b0e80, 0x140001b0ec0)
      /tmp/go/src/go/types/expr.go:926 +0x7c
    go/types.(*Checker).binary(0x14000170818?, 0x140001b0e80, {0x10315bf40?, 0x140001a20f0}, {0x10315ba90?, 0x140001a8100}, {0x10315bb80?, 0x140001a8120}, 0x28, 0x102e6da60?)
      /tmp/go/src/go/types/expr.go:800 +0x128
    go/types.(*Checker).exprInternal(0x140001c2000, {0x0, 0x0}, 0x140001b0e80, {0x10315bf40, 0x140001a20f0?}, {0x0?, 0x0?})
      /tmp/go/src/go/types/expr.go:1401 +0x1634
    go/types.(*Checker).rawExpr(0x140001c2000, {0x0, 0x0}, 0x140001b0e80, {0x10315bf40?, 0x140001a20f0?}, {0x0?, 0x0?}, 0x0)
      /tmp/go/src/go/types/expr.go:965 +0x134
    go/types.(*Checker).expr(0x140001c2000?, {0x0?, 0x0?}, 0x103076b67?, {0x10315bf40?, 0x140001a20f0?})
      /tmp/go/src/go/types/expr.go:1498 +0x40
    go/types.(*Checker).stmt(0x140001c2000, 0x0, {0x10315c270?, 0x140001b0140?})
      /tmp/go/src/go/types/stmt.go:574 +0x1314
    go/types.(*Checker).stmtList(0x140002c78e8?, 0x0, {0x140001a8280?, 0x0?, 0x0?})
      /tmp/go/src/go/types/stmt.go:125 +0x88
    go/types.(*Checker).funcBody(0x140001c2000, 0x14000196720, {0x14000198068?, 0x10315e1d8?}, 0x140001b0bc0, 0x140001a2180, {0x0, 0x0})
      /tmp/go/src/go/types/stmt.go:45 +0x244
    go/types.(*Checker).funcDecl.func1()
      /tmp/go/src/go/types/decl.go:826 +0x44
    go/types.(*Checker).processDelayed(0x140001c2000, 0x0)
      /tmp/go/src/go/types/check.go:446 +0x12c
    go/types.(*Checker).checkFiles(0x140001c2000, {0x140001a4000, 0x1, 0x1})
      /tmp/go/src/go/types/check.go:390 +0x1fc
    go/types.(*Checker).Files(...)
      /tmp/go/src/go/types/check.go:344
    golang.org/x/tools/go/packages.(*loader).loadPackage(0x140001501c0, 0x1400016b2f0)
      ...go/pkg/mod/golang.org/x/tools@v0.9.1/go/packages/packages.go:1052 +0x97c
    golang.org/x/tools/go/packages.(*loader).loadRecursive.func1()
      ...go/pkg/mod/golang.org/x/tools@v0.9.1/go/packages/packages.go:851 +0x178
    sync.(*Once).doSlow(0x0?, 0x0?)
      /tmp/go/src/sync/once.go:74 +0x100
    sync.(*Once).Do(...)
      /tmp/go/src/sync/once.go:65
    golang.org/x/tools/go/packages.(*loader).loadRecursive(0x0?, 0x0?)
      ...go/pkg/mod/golang.org/x/tools@v0.9.1/go/packages/packages.go:839 +0x50
    golang.org/x/tools/go/packages.(*loader).loadRecursive.func1.1(0x0?)
      ...go/pkg/mod/golang.org/x/tools@v0.9.1/go/packages/packages.go:846 +0x30
    created by golang.org/x/tools/go/packages.(*loader).loadRecursive.func1 in goroutine 61
      ...go/pkg/mod/golang.org/x/tools@v0.9.1/go/packages/packages.go:845 +0x84
    exit status 2
    FAIL	gopkg.teddywing.com/capturedrefrace	0.140s

I tried upgrading to the latest version of golang.org/x/tools, v0.19.0,
but this caused the following error while bisecting the Go compiler:

    $ /tmp/go/bin/go test -v
    # golang.org/x/tools/internal/aliases
    ...go/pkg/mod/golang.org/x/tools@v0.19.0/internal/aliases/aliases_go122.go:21:20: undefined: types.Alias
    ...go/pkg/mod/golang.org/x/tools@v0.19.0/internal/aliases/aliases_go122.go:24:54: undefined: types.Unalias
    ...go/pkg/mod/golang.org/x/tools@v0.19.0/internal/aliases/aliases_go122.go:30:13: undefined: types.NewAlias
    ...go/pkg/mod/golang.org/x/tools@v0.19.0/internal/aliases/aliases_go122.go:66:67: undefined: types.Alias
    # golang.org/x/tools/internal/versions
    ...go/pkg/mod/golang.org/x/tools@v0.19.0/internal/versions/types_go122.go:30:15: info.FileVersions undefined (type *types.Info has no field or method FileVersions)
    ...go/pkg/mod/golang.org/x/tools@v0.19.0/internal/versions/types_go122.go:40:7: info.FileVersions undefined (type *types.Info has no field or method FileVersions)
    FAIL	gopkg.teddywing.com/capturedrefrace [build failed]

The error was caused by the addition of special `types.Alias` handling
for Go 1.21 and Go 1.22
(https://github.com/golang/tools/commit/0be034b1e193e98221abc05e710b8ecbf8cc9d45).
The earliest tagged version of golang.org/x/tools that I could find
without the `internal/aliases` package was v0.15.0, so use that to
bisect the Go codebase.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The version previously declared caused a panic when running under Go
1.22:

    $ go1.22.0 test -v
    === RUN   Test
    panic: runtime error: invalid memory address or nil pointer dereference [recovered]
      panic: runtime error: invalid memory address or nil pointer dereference
    [signal SIGSEGV: segmentation violation code=0x2 addr=0x0 pc=0x102ffd84c]

    goroutine 92 [running]:
    go/types.(*Checker).handleBailout(0x140002e0000, 0x140002ddb68)
      /tmp/go/src/go/types/check.go:339 +0x9c
    panic({0x103110f80?, 0x1032d4670?})
      /tmp/go/src/runtime/panic.go:765 +0x124
    go/types.(*StdSizes).Sizeof(0x0, {0x10315b768?, 0x1032d56a0})
      /tmp/go/src/go/types/sizes.go:228 +0x2fc
    go/types.(*Config).sizeof(...)
      /tmp/go/src/go/types/sizes.go:331
    go/types.representableConst.func1({0x10315b768?, 0x1032d56a0?})
      /tmp/go/src/go/types/const.go:76 +0x9c
    go/types.representableConst({0x10315ca48, 0x1032cbe00}, 0x140002e0000, 0x1032d56a0, 0x0)
      /tmp/go/src/go/types/const.go:92 +0x138
    go/types.(*Checker).arrayLength(0x140002e0000, {0x10315bb80?, 0x140002b2160?})
      /tmp/go/src/go/types/typexpr.go:504 +0x23c
    go/types.(*Checker).typInternal(0x140002e0000, {0x10315bb50?, 0x140002ac090?}, 0x1033453c8?)
      /tmp/go/src/go/types/typexpr.go:299 +0x934
    go/types.(*Checker).definedType(0x140002b23e0?, {0x10315bb50?, 0x140002ac090}, 0x102ff9fd8?)
      /tmp/go/src/go/types/typexpr.go:180 +0x30
    go/types.(*Checker).varType(0x140002e0000, {0x10315bb50?, 0x140002ac090})
      /tmp/go/src/go/types/typexpr.go:145 +0x30
    go/types.(*Checker).structType(0x140002e0000, 0x140002ac3c0, 0x140002ac3c0?)
      /tmp/go/src/go/types/struct.go:113 +0x128
    go/types.(*Checker).typInternal(0x140002e0000, {0x10315bdc0?, 0x14000290468?}, 0x102e87278?)
      /tmp/go/src/go/types/typexpr.go:316 +0xb14
    go/types.(*Checker).definedType(0x0?, {0x10315bdc0?, 0x14000290468}, 0x102e3c294?)
      /tmp/go/src/go/types/typexpr.go:180 +0x30
    go/types.(*Checker).typeDecl(0x140002e0000, 0x140002d4370, 0x140002c2040, 0x778?)
      /tmp/go/src/go/types/decl.go:595 +0x544
    go/types.(*Checker).objDecl(0x140002e0000, {0x10315df58, 0x140002d4370}, 0x102fc77b8?)
      /tmp/go/src/go/types/decl.go:197 +0x7d0
    go/types.(*Checker).packageObjects(0x140002e0000)
      /tmp/go/src/go/types/resolver.go:675 +0x350
    go/types.(*Checker).checkFiles(0x140002e0000, {0x140002ae000, 0x1, 0x1})
      /tmp/go/src/go/types/check.go:387 +0x1d8
    go/types.(*Checker).Files(...)
      /tmp/go/src/go/types/check.go:344
    golang.org/x/tools/go/packages.(*loader).loadPackage(0x140001501c0, 0x1400016b1a0)
      ...go/pkg/mod/golang.org/x/tools@v0.9.1/go/packages/packages.go:1052 +0x97c
    golang.org/x/tools/go/packages.(*loader).loadRecursive.func1()
      ...go/pkg/mod/golang.org/x/tools@v0.9.1/go/packages/packages.go:851 +0x178
    sync.(*Once).doSlow(0x0?, 0x0?)
      /tmp/go/src/sync/once.go:74 +0x100
    sync.(*Once).Do(...)
      /tmp/go/src/sync/once.go:65
    golang.org/x/tools/go/packages.(*loader).loadRecursive(0x0?, 0x0?)
      ...go/pkg/mod/golang.org/x/tools@v0.9.1/go/packages/packages.go:839 +0x50
    golang.org/x/tools/go/packages.(*loader).loadRecursive.func1.1(0x0?)
      ...go/pkg/mod/golang.org/x/tools@v0.9.1/go/packages/packages.go:846 +0x30
    created by golang.org/x/tools/go/packages.(*loader).loadRecursive.func1 in goroutine 40
      ...go/pkg/mod/golang.org/x/tools@v0.9.1/go/packages/packages.go:845 +0x84
    panic: runtime error: invalid memory address or nil pointer dereference [recovered]
      panic: runtime error: invalid memory address or nil pointer dereference
    [signal SIGSEGV: segmentation violation code=0x2 addr=0x0 pc=0x102ffd84c]

    goroutine 65 [running]:
    go/types.(*Checker).handleBailout(0x140001c2000, 0x14000171b68)
      /tmp/go/src/go/types/check.go:339 +0x9c
    panic({0x103110f80?, 0x1032d4670?})
      /tmp/go/src/runtime/panic.go:765 +0x124
    go/types.(*StdSizes).Sizeof(0x0, {0x10315b768?, 0x1032d56a0})
      /tmp/go/src/go/types/sizes.go:228 +0x2fc
    go/types.(*Config).sizeof(...)
      /tmp/go/src/go/types/sizes.go:331
    go/types.representableConst.func1({0x10315b768?, 0x1032d56a0?})
      /tmp/go/src/go/types/const.go:76 +0x9c
    go/types.representableConst({0x10315ca48, 0x1032cbd80}, 0x140001c2000, 0x1032d56a0, 0x1400016fec8)
      /tmp/go/src/go/types/const.go:92 +0x138
    go/types.(*Checker).representation(0x10315b768?, 0x140001b0ec0, 0x1400016ff48?)
      /tmp/go/src/go/types/const.go:256 +0x68
    go/types.(*Checker).implicitTypeAndValue(0x140001c2000, 0x140001b0ec0, {0x10315b768?, 0x1032d56a0?})
      /tmp/go/src/go/types/expr.go:375 +0x2e8
    go/types.(*Checker).convertUntyped(0x140001c2000, 0x140001b0ec0, {0x10315b768, 0x1032d56a0})
      /tmp/go/src/go/types/const.go:289 +0x30
    go/types.(*Checker).matchTypes(0x14000170698?, 0x140001b0e80, 0x140001b0ec0)
      /tmp/go/src/go/types/expr.go:926 +0x7c
    go/types.(*Checker).binary(0x14000170818?, 0x140001b0e80, {0x10315bf40?, 0x140001a20f0}, {0x10315ba90?, 0x140001a8100}, {0x10315bb80?, 0x140001a8120}, 0x28, 0x102e6da60?)
      /tmp/go/src/go/types/expr.go:800 +0x128
    go/types.(*Checker).exprInternal(0x140001c2000, {0x0, 0x0}, 0x140001b0e80, {0x10315bf40, 0x140001a20f0?}, {0x0?, 0x0?})
      /tmp/go/src/go/types/expr.go:1401 +0x1634
    go/types.(*Checker).rawExpr(0x140001c2000, {0x0, 0x0}, 0x140001b0e80, {0x10315bf40?, 0x140001a20f0?}, {0x0?, 0x0?}, 0x0)
      /tmp/go/src/go/types/expr.go:965 +0x134
    go/types.(*Checker).expr(0x140001c2000?, {0x0?, 0x0?}, 0x103076b67?, {0x10315bf40?, 0x140001a20f0?})
      /tmp/go/src/go/types/expr.go:1498 +0x40
    go/types.(*Checker).stmt(0x140001c2000, 0x0, {0x10315c270?, 0x140001b0140?})
      /tmp/go/src/go/types/stmt.go:574 +0x1314
    go/types.(*Checker).stmtList(0x140002c78e8?, 0x0, {0x140001a8280?, 0x0?, 0x0?})
      /tmp/go/src/go/types/stmt.go:125 +0x88
    go/types.(*Checker).funcBody(0x140001c2000, 0x14000196720, {0x14000198068?, 0x10315e1d8?}, 0x140001b0bc0, 0x140001a2180, {0x0, 0x0})
      /tmp/go/src/go/types/stmt.go:45 +0x244
    go/types.(*Checker).funcDecl.func1()
      /tmp/go/src/go/types/decl.go:826 +0x44
    go/types.(*Checker).processDelayed(0x140001c2000, 0x0)
      /tmp/go/src/go/types/check.go:446 +0x12c
    go/types.(*Checker).checkFiles(0x140001c2000, {0x140001a4000, 0x1, 0x1})
      /tmp/go/src/go/types/check.go:390 +0x1fc
    go/types.(*Checker).Files(...)
      /tmp/go/src/go/types/check.go:344
    golang.org/x/tools/go/packages.(*loader).loadPackage(0x140001501c0, 0x1400016b2f0)
      ...go/pkg/mod/golang.org/x/tools@v0.9.1/go/packages/packages.go:1052 +0x97c
    golang.org/x/tools/go/packages.(*loader).loadRecursive.func1()
      ...go/pkg/mod/golang.org/x/tools@v0.9.1/go/packages/packages.go:851 +0x178
    sync.(*Once).doSlow(0x0?, 0x0?)
      /tmp/go/src/sync/once.go:74 +0x100
    sync.(*Once).Do(...)
      /tmp/go/src/sync/once.go:65
    golang.org/x/tools/go/packages.(*loader).loadRecursive(0x0?, 0x0?)
      ...go/pkg/mod/golang.org/x/tools@v0.9.1/go/packages/packages.go:839 +0x50
    golang.org/x/tools/go/packages.(*loader).loadRecursive.func1.1(0x0?)
      ...go/pkg/mod/golang.org/x/tools@v0.9.1/go/packages/packages.go:846 +0x30
    created by golang.org/x/tools/go/packages.(*loader).loadRecursive.func1 in goroutine 61
      ...go/pkg/mod/golang.org/x/tools@v0.9.1/go/packages/packages.go:845 +0x84
    exit status 2
    FAIL	gopkg.teddywing.com/capturedrefrace	0.140s

I tried upgrading to the latest version of golang.org/x/tools, v0.19.0,
but this caused the following error while bisecting the Go compiler:

    $ /tmp/go/bin/go test -v
    # golang.org/x/tools/internal/aliases
    ...go/pkg/mod/golang.org/x/tools@v0.19.0/internal/aliases/aliases_go122.go:21:20: undefined: types.Alias
    ...go/pkg/mod/golang.org/x/tools@v0.19.0/internal/aliases/aliases_go122.go:24:54: undefined: types.Unalias
    ...go/pkg/mod/golang.org/x/tools@v0.19.0/internal/aliases/aliases_go122.go:30:13: undefined: types.NewAlias
    ...go/pkg/mod/golang.org/x/tools@v0.19.0/internal/aliases/aliases_go122.go:66:67: undefined: types.Alias
    # golang.org/x/tools/internal/versions
    ...go/pkg/mod/golang.org/x/tools@v0.19.0/internal/versions/types_go122.go:30:15: info.FileVersions undefined (type *types.Info has no field or method FileVersions)
    ...go/pkg/mod/golang.org/x/tools@v0.19.0/internal/versions/types_go122.go:40:7: info.FileVersions undefined (type *types.Info has no field or method FileVersions)
    FAIL	gopkg.teddywing.com/capturedrefrace [build failed]

The error was caused by the addition of special `types.Alias` handling
for Go 1.21 and Go 1.22
(https://github.com/golang/tools/commit/0be034b1e193e98221abc05e710b8ecbf8cc9d45).
The earliest tagged version of golang.org/x/tools that I could find
without the `internal/aliases` package was v0.15.0, so use that to
bisect the Go codebase.
</pre>
</div>
</content>
</entry>
<entry>
<title>README: Add documentation link</title>
<updated>2023-05-20T17:06:23+00:00</updated>
<author>
<name>Teddy Wing</name>
</author>
<published>2023-05-20T17:06:23+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/gocapturedrefrace/commit/?id=9aa2dfef38d08ba5a101a7c1b01fecbb1cec240d'/>
<id>9aa2dfef38d08ba5a101a7c1b01fecbb1cec240d</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
</feed>
