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

Open
tdakkota opened this issue Jun 23, 2020 · 4 comments
Open

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

tdakkota opened this issue Jun 23, 2020 · 4 comments
Assignees
Milestone

Comments

@tdakkota
Copy link

@tdakkota tdakkota commented Jun 23, 2020

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 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
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Jun 23, 2020

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

@tdakkota
Copy link
Author

@tdakkota 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

@gopherbot gopherbot commented Aug 13, 2020

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants
You can’t perform that action at this time.