Given:
package p
type s struct { i i }
type i interface { s | any }
go/types currently reports:
/tmp/y.go:3:6: invalid recursive type s
/tmp/y.go:3:6: s refers to
/tmp/y.go:4:6: i refers to
/tmp/y.go:3:6: s
Notably, changing the field type from i
to *i
makes the error go away. I don't see any fundamental reason why that should make a difference though.
Synthetic test case, constructed while trying to write additional test cases for #60117.
/cc @adonovan @findleyr @griesemer @ianlancetaylor
Comment From: adonovan
Seems pretty clearly disallowed by the current spec wording:
https://go.dev/ref/spec#Interface_types:
An interface type T may not embed a type element that is, contains, or embeds T, directly or indirectly.
// illegal: Bad3 may not embed a union containing Bad3 type Bad3 interface { ~int | ~string | Bad3 }
But I don't see the technical reason why the restriction is necessary in this case, as s.i is an ordinary named field.
Comment From: griesemer
The spec rule seems not sufficiently precisely spelled out. And there's probably a bug in the cycle check. Not urgent but added to my plate. Thanks for reporting.
Comment From: griesemer
Too late for 1.21.
Comment From: griesemer
Too late for 1.23. Moving to 1.24.
Comment From: gopherbot
This issue is currently labeled as early-in-cycle for Go 1.24. That time is now, so a friendly reminder to look at it again.
Comment From: griesemer
Too late for 1.24. Moving to 1.25.
Comment From: gopherbot
This issue is currently labeled as early-in-cycle for Go 1.25. That time is now, so a friendly reminder to look at it again.