Skip to content

cmd/compile: fails with stack overflow using generics and self referential function type #51832

@noclue

Description

@noclue

What version of Go are you using (go version)? go version go1.18 windows/amd64

$ go version
 go version go1.18 windows/amd64

Does this issue reproduce with the latest release? Yes

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

go env Output
$ go env
set GO111MODULE=
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\karaa\AppData\Local\go-build
set GOENV=C:\Users\karaa\AppData\Roaming\go\env
set GOEXE=.exe
set GOEXPERIMENT=
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMODCACHE=C:\Users\karaa\go\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=C:\Users\karaa\go
set CGO_ENABLED=1
set GOMOD=C:\Users\karaa\projects\go\generics\go.mod
set GOWORK=
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=C:\Users\karaa\AppData\Local\Temp\go-build2344714082=/tmp/go-build -gno-record-gcc-switches

What did you do?

I want to define a constraint on the pointer receiver of a type and also have a self referential function type.

This combination seem to trigger infinite recursion and stack overflow

Here is link to the go playground https://go.dev/play/p/aOb7OSImUuf

Here are the stack overflow discussions about adding interface constraint on the pointer receiver of a type T

https://stackoverflow.com/questions/71547015/how-to-define-type-constraint-on-pointer-receiver-ingolang/71547820#71547820
https://stackoverflow.com/questions/69573113/how-can-i-instantiate-a-new-pointer-of-type-argument-with-generic-go

Here is a working sample that does not have the self referring function type https://go.dev/play/p/myw6FAosPjK

Here is the failing code just in case

package main

import "fmt"

// In the real solution this function receives parameters and also returns error. As it has to process recursive structures 
// it sometimes has to create a new function with the same signature.
type Consumer func() Consumer 

type Doer[T any] interface {
	Do()
	*T
}

type Struct struct{}

func (s *Struct) Do() {
	return
}

// PT is a constraint on the T pointer receiver based on these discussions. In short I am trying to make sure *T implements Doer.
// https://stackoverflow.com/questions/71547015/how-to-define-type-constraint-on-pointer-receiver-ingolang/71547820#71547820
// https://stackoverflow.com/questions/69573113/how-can-i-instantiate-a-new-pointer-of-type-argument-with-generic-go
// and working sample https://go.dev/play/p/myw6FAosPjK
func CreateConsumer[PT Doer[T], T any]() Consumer {
	return nil
}

func main() {
	fmt.Println("Slice Consumer", CreateConsumer[*Struct]())
}

What did you expect to see?

Successful compilation and run.

What did you see instead?

Stack overflow error on go build ./...

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsFixThe path to resolution is known, but the work has not been done.genericsIssue is related to genericsrelease-blocker

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions