Age | Commit message (Collapse) | Author |
|
|
|
After upgrading to Go 1.22.0, I ended up with a segfault:
$ go 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=0x1006fef14]
goroutine 44 [running]:
go/types.(*Checker).handleBailout(0x140003e8c00, 0x14000027b98)
/opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/check.go:367 +0x9c
panic({0x100815520?, 0x1009e85d0?})
/opt/homebrew/Cellar/go/1.22.1/libexec/src/runtime/panic.go:770 +0x124
go/types.(*StdSizes).Sizeof(0x0, {0x100861ca8, 0x1009eb9a0})
/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({0x100861ca8?, 0x1009eb9a0?})
/opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/const.go:76 +0x9c
go/types.representableConst({0x100862fb0, 0x1009dfd60}, 0x140003e8c00, 0x1009eb9a0, 0x0)
/opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/const.go:92 +0x138
go/types.(*Checker).arrayLength(0x140003e8c00, {0x100862088, 0x140002f5c00?})
/opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/typexpr.go:510 +0x238
go/types.(*Checker).typInternal(0x140003e8c00, {0x100862058, 0x140003f6a80}, 0x0)
/opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/typexpr.go:299 +0x3bc
go/types.(*Checker).definedType(0x140003e8c00, {0x100862058, 0x140003f6a80}, 0x14000027158?)
/opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/typexpr.go:180 +0x2c
go/types.(*Checker).varType(0x140003e8c00, {0x100862058, 0x140003f6a80})
/opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/typexpr.go:145 +0x2c
go/types.(*Checker).structType(0x140003e8c00, 0x140003f6de0, 0x140003f6de0?)
/opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/struct.go:113 +0x128
go/types.(*Checker).typInternal(0x140003e8c00, {0x100862328, 0x1400000d368}, 0x140004220a0)
/opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/typexpr.go:316 +0xed0
go/types.(*Checker).definedType(0x140003e8c00, {0x100862328, 0x1400000d368}, 0x10052c214?)
/opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/typexpr.go:180 +0x2c
go/types.(*Checker).typeDecl(0x140003e8c00, 0x140004220a0, 0x140003bd940, 0x0)
/opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/decl.go:615 +0x39c
go/types.(*Checker).objDecl(0x140003e8c00, {0x100865178, 0x140004220a0}, 0x0)
/opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/decl.go:197 +0x880
go/types.(*Checker).packageObjects(0x140003e8c00)
/opt/homebrew/Cellar/go/1.22.1/libexec/src/go/types/resolver.go:681 +0x3c0
go/types.(*Checker).checkFiles(0x140003e8c00, {0x14000052660, 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(0x140001581c0, 0x14000169230)
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 43
go/pkg/mod/golang.org/x/tools@v0.9.1/go/packages/packages.go:845 +0x84
exit status 2
FAIL gopkg.teddywing.com/defererr 0.130s
Upgrading to the latest version of 'golang.org/x/tools' resolved the
problem.
|
|
|
|
|
|
Tried the sample code and it looks like the `return err` is not
necessary. The `err` set in `defer` does work find even when using
`return nil`. Oh well, we can adjust that check later if needed.
|
|
|
|
|
|
Since we don't want to bother with functions that return multiple
values, don't actually report a suggested return signature replacement.
|
|
When I was first coming up with ideas for the project, I thought that
this line is one I might need to report a diagnostic for, but since the
compiler will catch it, we don't need to bother.
|
|
The previous message which reported when a function's return signature
didn't declare an error variable didn't work for functions with multiple
return values.
I thought about extending it and coming up with generated variable names
for the non-error types to be able to support automatic fixing, but this
idea ended up being too complicated. Also, I didn't like the idea of an
automated fixer coming up with generated variable names, because you'd
need to manually rename them anyway. That kind of defeats the purpose of
it being automated.
Instead, change the diagnostic message to only refer to the error
variable and recommend what the declared variable name should be based
on the identifier the error was assigned to in the defer.
Modify our multiple return value test functions according to this new
approach.
|
|
|
|
Makes more sense to me to show the `&`s when we pass the value as an
argument to functions. That makes it clearer that the functions are
taking a reference type.
|
|
Clean up the rest of `checkFunctions`.
|
|
Looks like the return value type is always an `*ast.Ident`. Use
`continue` instead of `return true` to be more tolerant of unexpected
values.
|
|
|
|
* Add some explanatory comments.
* Fix return value loop: don't stop the function analysis if one of the
items isn't an identifier. (Wait, is this really fixing the loop or did
I get it right the first time, and the return was when the function
results don't have variable declarations? Will have to check that.)
* Remove `funcReturnsError` which is redundant now that we have
`errorReturnIndex`.
|
|
The previous function didn't make enough sense without the context of
when `firstErrorDeferEndPos` is set. Use a different function named for
what we actually want to know.
|
|
Wasn't using the correct case because I had auto-completed from the
field name.
|
|
Was returning the opposite of what it said.
|
|
|
|
|
|
|
|
Don't pass yet as we currently only suggest `(errorVar error)` as the
return signature.
|
|
* Remove debug prints.
* Reorganise the code so that similar things are together.
* Add comments describing the logic.
|
|
I had previously hard-coded the variable name "err" as the recommended
name declaration in the function signature for simplicity.
Now, use the name assigned in the `defer` instead, which is more
correct.
|
|
Based on the code from 'gocapturedrefrace'.
|
|
This reports diagnostics when using `return nil` instead of `return err`
when `err` is an error variable assigned in the first `defer` closure.
|
|
|
|
Ensure the name of the returned error variable matches the name of the
error variable assigned in the `defer` statement.
|
|
Want to check that the `return` statement uses the same variable used in
the `defer` closure. Start inspecting the values to figure out how we
can narrow that down.
Add a test case for a "good" assignment of a returned error in `defer`.
|
|
|
|
|
|
|
|
Since `ident.Obj.Decl` is a `*ast.ValueSpec` in
`shouldDeclareErrInSignature` but a `*ast.Field` in
`doesDeclareErrInSignature`, we need to handle both declaration types.
Turn the value into an `ast.Node`, which covers both, and use that to
determine whether the variable is declared in the closure.
|
|
We were looking for a `*ast.ValueSpec`, but it looks like when `err` is
declared in the function signature, the type is `*ast.Field`.
|
|
Show me which function the debug print statements belong to.
|
|
The idea is to store the end position of the first defer closure that
assigns an error variable from the outer scope. Then, we can check the
`return` statements in the rest of the function after that position to
ensure they use the error variable.
|
|
Clarify intended contents.
|
|
|
|
|
|
|
|
Give the check a name.
|
|
We don't want to report error variables that were declared inside the
closure, as those don't depend on the outside scope.
|
|
|
|
Give it a name.
|
|
Trying to make this easier to read.
|
|
|
|
While looking at the assignments in the `defer`, if we encounter an
`error`-type assignment, emit a diagnostic if the error named in the lhs
of the assignment is not present in the return signature's names.
Not sure if this makes sense to me yet. I probably only want to report a
problem for a non-declare assignment of an error value when the error
type in the return signature is _not_ named at all.
|
|
Store the index where we find the `error` type in the function
signature's return list so we can use it later to get the corresponding
variable names, if any.
|
|
And add a test function that does have named returned values.
|