golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
123.84k stars 17.65k forks source link

cmd/compile: internal compiler error using type parameters #48103

Closed dsnet closed 3 years ago

dsnet commented 3 years ago

This is a follow-up to #48016. I'm hitting another internal compiler error.

$ go.tip version
go version devel go1.18-891470fbf7 Tue Aug 31 19:07:50 2021 +0000 linux/amd64

$ go.tip build
# github.com/go-json-experiment/json
./value.go:315:6: internal compiler error: bad type kind UNSAFEPTR-unsafe.Pointer

goroutine 1 [running]:
runtime/debug.Stack()
    /usr/local/go.tip/src/runtime/debug/stack.go:24 +0x65
cmd/compile/internal/base.FatalfAt({0xc74780, 0x0}, {0xcf645b, 0x11}, {0xc0008425c8, 0x1, 0x1})
    /usr/local/go.tip/src/cmd/compile/internal/base/print.go:227 +0x154
cmd/compile/internal/base.Fatalf(...)
    /usr/local/go.tip/src/cmd/compile/internal/base/print.go:196
cmd/compile/internal/noder.parameterizedBy1(0xc000368f50, {0xc0007892b8, 0xc000bcd8f0, 0x1}, 0xc0004e03c0)
    /usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:1933 +0x3a7
cmd/compile/internal/noder.parameterizedBy1(0xc000bcd8f0, {0xc0007892b8, 0xc000bcd7a0, 0x1}, 0x0)
    /usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:1904 +0x418
cmd/compile/internal/noder.parameterizedBy1(0xc000bcd7a0, {0xc0007892b8, 0xc000bcd6c0, 0x1}, 0x0)
    /usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:1900 +0x2af
cmd/compile/internal/noder.parameterizedBy1(0xc000bcd6c0, {0xc0007892b8, 0xc000bcdb20, 0x1}, 0x58)
    /usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:1904 +0x418
cmd/compile/internal/noder.parameterizedBy1(0xc000bcdb20, {0xc0007892b8, 0xc000bcd650, 0x1}, 0xc000842930)
    /usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:1894 +0x349
cmd/compile/internal/noder.parameterizedBy1(0xc000bcd650, {0xc0007892b8, 0xc000bd9490, 0x1}, 0xc0002f96f3)
    /usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:1904 +0x418
cmd/compile/internal/noder.parameterizedBy1(0xc000bd9490, {0xc0007892b8, 0xc000bf0bd0, 0x1}, 0xc0002f9592)
    /usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:1904 +0x418
cmd/compile/internal/noder.parameterizedBy1(0xc000bf0bd0, {0xc0007892b8, 0xc000bf0a10, 0x1}, 0x0)
    /usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:1904 +0x418
cmd/compile/internal/noder.parameterizedBy1(0xc000bf0a10, {0xc0007892b8, 0xc000bd9500, 0x1}, 0x58)
    /usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:1900 +0x2e8
cmd/compile/internal/noder.parameterizedBy1(0xc000bd9500, {0xc0007892b8, 0xc000bcd490, 0x1}, 0x58)
    /usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:1912 +0x48a
cmd/compile/internal/noder.parameterizedBy1(0xc000bcd490, {0xc0007892b8, 0xc000bcd500, 0x1}, 0xc000842cf0)
    /usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:1904 +0x418
cmd/compile/internal/noder.parameterizedBy1(0xc000bcd500, {0xc0007892b8, 0xc000bcd3b0, 0x1}, 0xc000eab1d3)
    /usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:1894 +0x349
cmd/compile/internal/noder.parameterizedBy1(0xc000bcd3b0, {0xc0007892b8, 0xc000b976c0, 0x1}, 0x2)
    /usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:1904 +0x418
cmd/compile/internal/noder.parameterizedBy1(0xc000b976c0, {0xc0007892b8, 0xc000b97730, 0x1}, 0xc000843068)
    /usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:1904 +0x418
cmd/compile/internal/noder.parameterizedBy1(0xc000b97730, {0xc0007892b8, 0xc000b97650, 0x1}, 0xc000842ee8)
    /usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:1894 +0x349
cmd/compile/internal/noder.parameterizedBy1(0xc000b97650, {0xc0007892b8, 0xc00084c930, 0x1}, 0xc0005a7d50)
    /usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:1904 +0x418
cmd/compile/internal/noder.parameterizedBy1(0xc00084c930, {0xc0007892b8, 0xc00084c7e0, 0x1}, 0xcec7fa)
    /usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:1904 +0x418
cmd/compile/internal/noder.parameterizedBy1(0xc00084c7e0, {0xc0007892b8, 0x0, 0x1}, 0x203000)
    /usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:1900 +0x2af
cmd/compile/internal/noder.parameterizedBy(...)
    /usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:1865
cmd/compile/internal/noder.addType(0xc000f31110, {0xe65078, 0xc000921110}, 0xc00084c7e0)
    /usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:1847 +0x1b3
cmd/compile/internal/noder.(*irgen).getGfInfo(0xc000526800, 0xc0005a5790)
    /usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:1724 +0x285
cmd/compile/internal/noder.(*irgen).getInstantiation(0xc000526800, 0xc0005a5790, {0xc0007892a8, 0x1, 0x1}, 0x0)
    /usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:598 +0x21e
cmd/compile/internal/noder.(*irgen).stencil.func1({0xe63a98, 0xc000926c60})
    /usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:109 +0x2df
cmd/compile/internal/ir.Visit.func1({0xe63a98, 0xc000926c60})
    /usr/local/go.tip/src/cmd/compile/internal/ir/visit.go:105 +0x30
cmd/compile/internal/ir.(*AssignStmt).doChildren(0xc000935360, 0xc000f2d200)
    /usr/local/go.tip/src/cmd/compile/internal/ir/node_gen.go:152 +0x82
cmd/compile/internal/ir.DoChildren(...)
    /usr/local/go.tip/src/cmd/compile/internal/ir/visit.go:94
cmd/compile/internal/ir.Visit.func1({0xe636b0, 0xc000935360})
    /usr/local/go.tip/src/cmd/compile/internal/ir/visit.go:106 +0x57
cmd/compile/internal/ir.doNodes({0xc000ab9240, 0x1, 0x0}, 0xc000f2d200)
    /usr/local/go.tip/src/cmd/compile/internal/ir/node_gen.go:1512 +0x67
cmd/compile/internal/ir.(*Func).doChildren(0xe643f8, 0xc00084b080)
    /usr/local/go.tip/src/cmd/compile/internal/ir/func.go:152 +0x2e
cmd/compile/internal/ir.DoChildren(...)
    /usr/local/go.tip/src/cmd/compile/internal/ir/visit.go:94
cmd/compile/internal/ir.Visit.func1({0xe643f8, 0xc00084b080})
    /usr/local/go.tip/src/cmd/compile/internal/ir/visit.go:106 +0x57
cmd/compile/internal/ir.Visit({0xe643f8, 0xc00084b080}, 0xc0007ffe80)
    /usr/local/go.tip/src/cmd/compile/internal/ir/visit.go:108 +0xb8
cmd/compile/internal/noder.(*irgen).stencil(0xc000526800)
    /usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:91 +0x26a
cmd/compile/internal/noder.(*irgen).generate(0xc000526800, {0xc0000b7a40, 0xb, 0x0})
    /usr/local/go.tip/src/cmd/compile/internal/noder/irgen.go:294 +0x2d8
cmd/compile/internal/noder.check2({0xc0000b7a40, 0xb, 0xb})
    /usr/local/go.tip/src/cmd/compile/internal/noder/irgen.go:92 +0x175
cmd/compile/internal/noder.LoadPackage({0xc000082aa0, 0xb, 0x0})
    /usr/local/go.tip/src/cmd/compile/internal/noder/noder.go:90 +0x335
cmd/compile/internal/gc.Main(0xd1cc08)
    /usr/local/go.tip/src/cmd/compile/internal/gc/main.go:190 +0xaf3
main.main()
    /usr/local/go.tip/src/cmd/compile/main.go:55 +0xdd

Reproduction:

$ git clone https://github.com/go-json-experiment/json.git
$ cd json
$ git checkout origin/generics-bug2
$ go build

Based on @mdempsky's comment in https://github.com/golang/go/issues/48016#issuecomment-907524160, I tried building this with GOEXPERIMENT=unified and it seems to work.

\cc @danscales @mdempsky

dsnet commented 3 years ago

The relevant snippet that seems to exercise the error:


type typedUnmarshaler struct {
    typ     reflect.Type
    fnc     unmarshaler
    maySkip bool
}

func UnmarshalFuncV2[T any](fn func(UnmarshalOptions, *Decoder, T) error) *Unmarshalers {
    t := reflect.TypeOf((*T)(nil)).Elem()
    // checkConvertTo(t, false)
    typFnc := typedUnmarshaler{
        typ: t,
        fnc: func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error {
            prevDepth, prevLength := dec.tokens.depthLength()
            err := fn(uo, dec, va.Convert(t).Interface().(T))
            currDepth, currLength := dec.tokens.depthLength()
            if (prevDepth != currDepth || prevLength+1 != currLength) && err == nil {
                err = errors.New("must read exactly one JSON value")
            }
            if err != nil {
                if err == SkipFunc {
                    if prevDepth == currDepth && prevLength == currLength {
                        return SkipFunc
                    }
                    err = errors.New("must not read any JSON tokens when skipping")
                }
                // TODO: Avoid wrapping semantic, syntactic, or I/O errors.
                return &SemanticError{action: "unmarshal", GoType: t, Err: err}
            }
            return nil
        },
        maySkip: true,
    }
    return &Unmarshalers{unmarshalers{fncVals: []typedUnmarshaler{typFnc}}}
}

func init() {
    _ = UnmarshalFuncV2(func(UnmarshalOptions, *Decoder, string) error {
        return nil
    })
}

I'm not sure I understand why the error message implicates ./value.go:315, when the error occurs whether the init function in my snippet is present or not.

griesemer commented 3 years ago

cc: @danscales

danscales commented 3 years ago

Just a missing type case (for unsafe pointer) in our code that is doing some double-checking related to dictionaries/shapes. Will put the simple fix out shortly.

gopherbot commented 3 years ago

Change https://golang.org/cl/346669 mentions this issue: cmd/compile: fix missing case for shape double-check function

dsnet commented 3 years ago

Thanks @danscales for the fix! I confirmed that it fixes my use case and thus far I've run into no more issues.