Sorry, I'm not exactly sure how to categorize this because the panic happens at runtime but the issue seems to be the result of something funky that happened during compilation:
What version of Go are you using (go version)?
$ go version
go version devel go1.18-df778e6fd9 Sat Jul 17 01:52:18 2021 +0000 darwin/amd64
Does this issue reproduce with the latest release?
N/A
What operating system and processor architecture are you using (go env)?
Running on: macOS Big Sur 11.4 with 2.6 GHz 6-Core Intel Core i7 and 16 GB 2667 MHz DDR4
go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/jmccollum/Library/Caches/go-build"
GOENV="/Users/jmccollum/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/jmccollum/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/jmccollum/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/Users/jmccollum/go/src/github.com/golang/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/Users/jmccollum/go/src/github.com/golang/go/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="devel go1.18-df778e6fd9 Sat Jul 17 01:52:18 2021 +0000"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/jmccollum/go/src/local/other/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/0d/ncmx73fn4s1_n9bz83jdl0lh0000gn/T/go-build4256324592=/tmp/go-build -gno-record-gcc-switches -fno-common"
What did you do?
Ran this code with go run -gcflags="-G=3" .:
package main
import (
"errors"
"fmt"
)
type Option[T any] struct {
ok bool
val T
}
func (o Option[T]) String() string {
if o.ok {
return fmt.Sprintf("Some(%v)", o.val)
}
return "None"
}
func Some[T any](val T) Option[T] { return Option[T]{ok: true, val: val} }
func None[T any]() Option[T] { return Option[T]{ok: false} }
type Result[T, E any] struct {
ok bool
val T
err E
}
func (r Result[T, E]) String() string {
if r.ok {
return fmt.Sprintf("Ok(%v)", r.val)
}
return fmt.Sprintf("Err(%v)", r.err)
}
func Ok[T, E any](val T) Result[T, E] { return Result[T, E]{ok: true, val: val} }
func Err[T, E any](err E) Result[T, E] { return Result[T, E]{ok: false, err: err} }
func main() {
a := Some[int](1)
b := None[int]()
fmt.Println(a, b)
x := Ok[int, error](1)
y := Err[int, error](errors.New("test"))
fmt.Println(x, y)
// fmt.Println(x)
_, _, _, _ = a, b, x, y
}
What did you expect to see?
$ go run -gcflags="-G=3" .
Some(1) None
Ok(1) Err(test)
What did you see instead?
$ go run -gcflags="-G=3" .
Details
Some(1) None
unexpected fault address 0xb01dfacedebac1e
fatal error: fault
[signal SIGSEGV: segmentation violation code=0x1 addr=0xb01dfacedebac1e pc=0x106eee5]
goroutine 1 [running]:
runtime.throw({0x10a2e1e, 0x401})
/Users/jmccollum/go/src/github.com/golang/go/src/runtime/panic.go:1003 +0x71 fp=0xc000072608 sp=0xc0000725d8 pc=0x102eb31
runtime.sigpanic()
/Users/jmccollum/go/src/github.com/golang/go/src/runtime/signal_unix.go:743 +0x2f6 fp=0xc000072658 sp=0xc000072608 pc=0x10425f6
reflect.(*rtype).Kind(...)
/Users/jmccollum/go/src/github.com/golang/go/src/reflect/type.go:820
reflect.unpackEface(...)
/Users/jmccollum/go/src/github.com/golang/go/src/reflect/value.go:150
reflect.Value.Elem({0x1096460, 0xc000010250, 0x726c0})
/Users/jmccollum/go/src/github.com/golang/go/src/reflect/value.go:1154 +0xc5 fp=0xc000072698 sp=0xc000072658 pc=0x106eee5
fmt.(*pp).printValue(0xc000078b60, {0x1096460, 0xc000010250, 0x113e6c0}, 0x76, 0x0)
/Users/jmccollum/go/src/github.com/golang/go/src/fmt/print.go:810 +0x50a fp=0xc000072880 sp=0xc000072698 pc=0x108764a
fmt.(*pp).printArg(0xc000078b60, {0x1096460, 0xc000010250}, 0x76)
/Users/jmccollum/go/src/github.com/golang/go/src/fmt/print.go:712 +0x74c fp=0xc000072920 sp=0xc000072880 pc=0x10870ac
fmt.(*pp).doPrintf(0xc000078b60, {0x10a30db, 0x7}, {0xc000072aa0, 0x5, 0x7600000005})
/Users/jmccollum/go/src/github.com/golang/go/src/fmt/print.go:1026 +0x288 fp=0xc000072a18 sp=0xc000072920 pc=0x10898a8
fmt.Sprintf({0x10a30db, 0x7}, {0xc000072aa0, 0x1, 0x1})
/Users/jmccollum/go/src/github.com/golang/go/src/fmt/print.go:219 +0x59 fp=0xc000072a70 sp=0xc000072a18 pc=0x1083f79
main..inst.Result[int,error].String(0x10094f4, {0xe0, 0x102d20a, {0x10c0680, 0xc000010250}})
/Users/jmccollum/go/src/local/other/main.go:112 +0xd1 fp=0xc000072ac0 sp=0xc000072a70 pc=0x108ae11
main.(*Result[int,error]).String(0xc000062040)
:1 +0x45 fp=0xc000072af8 sp=0xc000072ac0 pc=0x108b065
fmt.(*pp).handleMethods(0xc000078c30, 0x11a7108)
/Users/jmccollum/go/src/github.com/golang/go/src/fmt/print.go:626 +0x322 fp=0xc000072d48 sp=0xc000072af8 pc=0x1086422
fmt.(*pp).printArg(0xc000078c30, {0x109b580, 0xc000062040}, 0x76)
/Users/jmccollum/go/src/github.com/golang/go/src/fmt/print.go:709 +0x693 fp=0xc000072de8 sp=0xc000072d48 pc=0x1086ff3
fmt.(*pp).doPrintln(0xc000078c30, {0xc000072ef0, 0x2, 0x109b580})
/Users/jmccollum/go/src/github.com/golang/go/src/fmt/print.go:1169 +0x149 fp=0xc000072e58 sp=0xc000072de8 pc=0x108a789
fmt.Fprintln({0x10c06e0, 0xc00000e018}, {0xc000072ef0, 0x2, 0x2})
/Users/jmccollum/go/src/github.com/golang/go/src/fmt/print.go:264 +0x4f fp=0xc000072ea8 sp=0xc000072e58 pc=0x108404f
fmt.Println(...)
/Users/jmccollum/go/src/github.com/golang/go/src/fmt/print.go:274
main.main()
/Users/jmccollum/go/src/local/other/main.go:125 +0x210 fp=0xc000072f80 sp=0xc000072ea8 pc=0x108abf0
runtime.main()
/Users/jmccollum/go/src/github.com/golang/go/src/runtime/proc.go:255 +0x227 fp=0xc000072fe0 sp=0xc000072f80 pc=0x10311a7
runtime.goexit()
/Users/jmccollum/go/src/github.com/golang/go/src/runtime/asm_amd64.s:1571 +0x1 fp=0xc000072fe8 sp=0xc000072fe0 pc=0x105a321
exit status 2
Apparently related to 0xb01dfacedebac1e
Notes:
- Replacing the line
fmt.Println(x, y) with fmt.Println(x) avoids the above fault
- Replacing the line
y := Err[int, error](errors.New("test")) with y := Err[int, string]("test") avoids the fault
This seems to be related to instantiating the generic Result[T,E any] with an E of error and then trying to use reflection on that value from fmt.Sprintf("Err(%v)", <val of type E>)
Sorry, I'm not exactly sure how to categorize this because the panic happens at runtime but the issue seems to be the result of something funky that happened during compilation:
What version of Go are you using (
go version)?Does this issue reproduce with the latest release?
N/A
What operating system and processor architecture are you using (
go env)?Running on:
macOS Big Sur 11.4with2.6 GHz 6-Core Intel Core i7and16 GB 2667 MHz DDR4go envOutputWhat did you do?
Ran this code with
go run -gcflags="-G=3" .:What did you expect to see?
What did you see instead?
Apparently related to 0xb01dfacedebac1e
Notes:
fmt.Println(x, y)withfmt.Println(x)avoids the above faulty := Err[int, error](errors.New("test"))withy := Err[int, string]("test")avoids the faultThis seems to be related to instantiating the generic
Result[T,E any]with anEoferrorand then trying to use reflection on that value fromfmt.Sprintf("Err(%v)", <val of type E>)