Skip to content
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

cmd/go2go: endless recursion on recursive type constraints #39781

Closed
tdakkota opened this issue Jun 23, 2020 · 5 comments
Closed

cmd/go2go: endless recursion on recursive type constraints #39781

tdakkota opened this issue Jun 23, 2020 · 5 comments
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@tdakkota
Copy link

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

$ go version
go version devel +2faeebf4e5 Tue Jun 23 04:54:48 2020 +0000 windows/amd64

Does this issue reproduce with the latest release?

reproduces with 2faeebf
playground doesn't crash

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

n/a

What did you do?

https://go2goplay.golang.org/p/G9DePoefrx0

What did you expect to see?

Successful compilation

What did you see instead?

Partial stack trace:

runtime: goroutine stack exceeds 1000000000-byte limit
runtime: sp=0xc020161450 stack=[0xc020160000, 0xc040160000]
fatal error: stack overflow

runtime stack:
runtime.throw(0xded113, 0xe)
	G:/workspace/exprm/go/src/runtime/panic.go:1116 +0x79
runtime.newstack()
	G:/workspace/exprm/go/src/runtime/stack.go:1059 +0x791
runtime.morestack()
	G:/workspace/exprm/go/src/runtime/asm_amd64.s:449 +0x97

goroutine 1 [running]:
go/types.(*Checker).completeInterface(0xc0001046c0, 0x0, 0xc00010a280)
	G:/workspace/exprm/go/src/go/types/typexpr.go:819 +0x791 fp=0xc020161460 sp=0xc020161458 pc=0xcca951
go/types.(*TypeParam).Bound(0xc00003c4c0, 0xc00003c4c0)
	G:/workspace/exprm/go/src/go/types/type.go:811 +0x88 fp=0xc020161490 sp=0xc020161460 pc=0xcbec48
go/types.optype(0xe3ca20, 0xc00003c4c0, 0xe3ca20, 0xc00003c4c0)
	G:/workspace/exprm/go/src/go/types/type.go:830 +0x56 fp=0xc0201614d0 sp=0xc020161490 pc=0xcbecd6
go/types.(*TypeParam).Interface(0xc00003c4c0, 0xc00003c480)
	G:/workspace/exprm/go/src/go/types/type.go:848 +0x3e fp=0xc020161500 sp=0xc0201614d0 pc=0xcbf1fe
go/types.(*TypeParam).Interface(0xc00003c480, 0xc00003c4c0)
	G:/workspace/exprm/go/src/go/types/type.go:848 +0x52 fp=0xc020161530 sp=0xc020161500 pc=0xcbf212
go/types.(*TypeParam).Interface(0xc00003c4c0, 0xc00003c480)
	G:/workspace/exprm/go/src/go/types/type.go:848 +0x52 fp=0xc020161560 sp=0xc020161530 pc=0xcbf212
go/types.(*TypeParam).Interface(0xc00003c480, 0xc00003c4c0)
	G:/workspace/exprm/go/src/go/types/type.go:848 +0x52 fp=0xc020161590 sp=0xc020161560 pc=0xcbf212
go/types.(*TypeParam).Interface(0xc00003c4c0, 0xc00003c480)
	G:/workspace/exprm/go/src/go/types/type.go:848 +0x52 fp=0xc0201615c0 sp=0xc020161590 pc=0xcbf212
go/types.(*TypeParam).Interface(0xc00003c480, 0xc00003c4c0)
	G:/workspace/exprm/go/src/go/types/type.go:848 +0x52 fp=0xc0201615f0 sp=0xc0201615c0 pc=0xcbf212
go/types.(*TypeParam).Interface(0xc00003c4c0, 0xc00003c480)
	G:/workspace/exprm/go/src/go/types/type.go:848 +0x52 fp=0xc020161620 sp=0xc0201615f0 pc=0xcbf212
go/types.(*TypeParam).Interface(0xc00003c480, 0xc00003c4c0)
	G:/workspace/exprm/go/src/go/types/type.go:848 +0x52 fp=0xc020161650 sp=0xc020161620 pc=0xcbf212
go/types.(*TypeParam).Interface(0xc00003c4c0, 0xc00003c480)
	G:/workspace/exprm/go/src/go/types/type.go:848 +0x52 fp=0xc020161680 sp=0xc020161650 pc=0xcbf212
go/types.(*TypeParam).Interface(0xc00003c480, 0xc00003c4c0)
@tdakkota
Copy link
Author

tdakkota commented Jun 23, 2020

This issue seems similar to issue #39680 but more complex.
Fix of previous issue resolves T requires type T, but not T1 requires type T2, T2 requires type T1
or any other complex cycle.

@ianlancetaylor ianlancetaylor added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Jun 23, 2020
@ianlancetaylor ianlancetaylor added this to the Unreleased milestone Jun 23, 2020
@ianlancetaylor
Copy link
Contributor

This is an infinite loop in the type checker. It should probably return an error.

@tdakkota
Copy link
Author

tdakkota commented Jun 26, 2020

Hi @griesemer @ianlancetaylor.

So, I think I found a way to fix it

func optype(typ Type) Type {
	if t := typ.TypeParam(); t != nil {
		// If the optype is typ, return the top type as we have
		// no information. It also prevents infinite recursion
		// via the TypeParam converter methods. This can happen
		// for a type parameter list of the form:
		// (type T interface { type T }).
		// See also issue #39680.
		if u := t.Bound().allTypes; u != nil && u != typ {
			if t2 := u.TypeParam(); t2 != nil && t2.Bound().allTypes == typ {
				return theTop
			}

			// u != typ and u is a type parameter => u.Under() != typ, so this is ok
			return u.Under()
		}
		return theTop
	}
	return typ
}

@gopherbot
Copy link

Change https://golang.org/cl/248357 mentions this issue: [dev.go2go] go/types: fix endless recursion on recursive type constra…

@griesemer
Copy link
Contributor

Go 1.18 doesn't allow to embed type parameters (adjusted example). This reports now a proper error. Closing.

@golang golang locked and limited conversation to collaborators Jun 23, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

4 participants