Skip to content

Panic with generics on protobuf messages #57

@RouquinBlanc

Description

@RouquinBlanc

Hi,

I'm getting the following issue on lates (v0.7.8) and various variants of it on previous versions when running golds ./... on our (close source) repo:

1.18+.go:326: Message
panic: should not

goroutine 3 [running]:
go101.org/golds/code.(*CodeAnalyzer).comfirmDirectSelectorsForInstantiatedType(0x140000be008, 0x1402a943a20, 0x11a, 0x1401ef97bc8, 0x1401ef97b98)
	/Users/user/go/pkg/mod/go101.org/golds@v0.7.8/code/1.18+.go:327 +0xde4
go101.org/golds/code.(*CodeAnalyzer).comfirmDirectSelectorsForInstantiatedTypes(0x140000be008)
	/Users/user/go/pkg/mod/go101.org/golds@v0.7.8/code/code-analyse.go:2813 +0x194
go101.org/golds/code.(*CodeAnalyzer).AnalyzePackages(0x140000be008, 0x1401ef97e10)
	/Users/user/go/pkg/mod/go101.org/golds@v0.7.8/code/code-analyse.go:59 +0x1c4
go101.org/golds/internal/server.(*docServer).analyze(0x1400008a700, {0x14000132060, 0x1, 0x1}, {{0x1050ea2c8, 0x6}, {0x1400000e035, 0xb}, 0x1, 0x1, ...}, ...)
	/Users/user/go/pkg/mod/go101.org/golds@v0.7.8/internal/server/server.go:366 +0x48c
go101.org/golds/internal/server.Run.func1()
	/Users/user/go/pkg/mod/go101.org/golds@v0.7.8/internal/server/server.go:139 +0x78
created by go101.org/golds/internal/server.Run in goroutine 1
	/Users/user/go/pkg/mod/go101.org/golds@v0.7.8/internal/server/server.go:138 +0x458

Sorry, line numbers may be offset as I instrumented the code to see a bit better what happens.

After some investigations, the smallest snippet I could find to reproduce is something like this:

package main

import (
	"google.golang.org/protobuf/proto"
)

type ProtoContent struct {
	Proto proto.Message
}

// ProtoMessage interface is used for generics and represents a pointer on proto.Message.
// For various cases, T cannot be used directly as proto Structs are pointer receivers,
// and that does not work well with generics.
type ProtoMessage[T any] interface {
	proto.Message
	*T
}

// This is the definition which makes the crash happen.
func MakeFoo[T proto.Message, SubT ProtoMessage[T]](t T) ProtoContent {
	return ProtoContent{Proto: t}
}

func main() {
}

We found it very hard to work with generics and protobuf 😅

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions