Skip to content

x/xerrors: xerrors.As unable to take in literal as target argument #34779

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
neetle opened this issue Oct 8, 2019 · 3 comments
Closed

x/xerrors: xerrors.As unable to take in literal as target argument #34779

neetle opened this issue Oct 8, 2019 · 3 comments

Comments

@neetle
Copy link

neetle commented Oct 8, 2019

What version of Go are you using (go version)?

$ go version
go version go1.13.1 darwin/amd64

Does this issue reproduce with the latest release?

I believe so

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/me/Library/Caches/go-build"
GOENV="/Users/me/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/me/go"
GOPRIVATE=""
GOPROXY="direct"
GOROOT="/usr/local/Cellar/go/1.13.1/libexec"
GOSUMDB="off"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.13.1/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/wf/rt6m9wzx4js08mbqtbczcycm0000gn/T/go-build670191544=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

See goplay link:
https://play.golang.org/p/NAROTLJUM9H

What did you expect to see?

I expected to be able to use the xerrors.As using a literal argument like xerrors.As(testcase, &Err{})

What did you see instead?

xerrors.As(testcase, &Err{}) panics.

It seems like it's unwrapping the interface{} argument, deref-ing the pointer at the same time(*Err -> Err). The struct itself doesn't implement error, as the error interface was implemented using a pointer receiver. This causes input validation to fail and panic.

@gopherbot gopherbot added this to the Unreleased milestone Oct 8, 2019
@dpinela
Copy link
Contributor

dpinela commented Oct 9, 2019

This is working as intended. If Err implements the error interface with a pointer receiver, the type that implements it is *Err, so you have to pass a pointer to that (**Err) to xerrors.As. &Err{} gives you a value of type *Err, which is why your first call in the playground works (you're taking the address of an *Err, which is an **Err) but the second doesn't.

@ianlancetaylor
Copy link
Member

This is how the language works. It doesn't seem to be a bug.

@neetle
Copy link
Author

neetle commented Oct 9, 2019

Is there any chance that we can have some documentation stating that xerrors.Is(x, y) being true doesn't imply that xerrors.As(x, y) would be true then? I realise the language doesn't work in a way that allows complete symmetry between these calls. However, in the api it looks like xerrors.Is(x, y) implies xerrors.As(x, y) whereas that's not the case.

I'm happy to throw together a PR for this if needed.

@golang golang locked and limited conversation to collaborators Oct 8, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants