go: cmd/vet: warn when errors.As target has type *error
What version of Go are you using (go version
)?
$ go version go version go1.16.6 darwin/arm64
Does this issue reproduce with the latest release?
yes
What did you do?
Wrote this code https://play.golang.org/p/16cU0kc8Lku and wondered why the errors matched.
var Err = errors.New("sentinel")
err := errors.New("foo")
if errors.As(err, &Err) {
fmt.Println("why?")
}
Discussion in https://groups.google.com/g/golang-nuts/c/MaYJy_IRbYA/m/uCHV6P87EQAJ?utm_medium=email&utm_source=footer
What did you expect to see?
Of course the code above is wrong, yet I didn’t spot it. It would be nice if this kind of programming error could be detected:
- add a
govet
check that flags using plainerror
s witherrors.As
or - @merovius suggested
errors.errorString
should implementAs()
and returnfalse
, unless the pointers match.
I’m unsure if the latter is possible. It would strictly break BC (and the function’s description). On the other hand ist should only change behaviour in cases that seem invalid from the start?
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 4
- Comments: 22 (20 by maintainers)
No change in consensus, so accepted. 🎉 This issue now tracks the work of implementing the proposal. — rsc for the proposal review group
Perhaps
cmd/vet
should be changed to warn when the second argument toerrors.As
is statically known to have type*error
?That is pretty much guaranteed to indicate a bug, because it is trivially true that the first argument (of type
error
) “is assignable to the value pointed to by” a second argument of type*error
.Change https://go.dev/cl/403034 mentions this issue:
go/analysis/passes/errorsas: update testdata for new warning
Based on the discussion above, this proposal seems like a likely accept. — rsc for the proposal review group
Warning on
*interface{}
doesn’t seem like it would have any false positives, but I suspect it’s unlikely to show up in practice.Would it make sense to apply the same warning to pointers to empty interface types, too? They are trivial in essentially the same way, in that they cause
errors.As
to decay to a nil-check.But the complete paragraph is
The existence of the
As
optional interface is specifically for cases like this, so that error types can overwrite the pure “assignability” behavior.