go: cmd/compile: endless compilation for code that cannot be monomorphised
This code corresponds to Fig. 10 in the paper “Featherweight Go” (“FGG”); it’s an example of a program that cannot be monomorphised.
The type checker (types2
, go/types
) accept this fine, but the compiler runs “forever”.
package main
type Box[A any] struct {
value A
}
func Nest[A any](b Box[A], n int) interface{} {
if n == 0 {
return b
}
return Nest(Box[Box[A]]{b}, n-1)
}
func main() {
Nest(Box[int]{0}, 10)
}
The FGG paper suggests a check to detect such cases. We may want to implement that eventually. For 1.18, maybe we can have some sort of “time-out” with a suitable error message for now.
cc: @randall77
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 3
- Comments: 15 (12 by maintainers)
See link in first comment. Or search for “featherweight go” using your favorite search engine.
A depth limit may be prudent to add anyway. There is probably not much difference between a very large type and an infinite type from a user point of view. Maybe it’s easier to create an infinite type by accident.
For example, this program requires more than 60G of memory to compile (as of 9e6ad46bccfa7a63e768236bcd1fd54dab38e4d1), and its types are finite.
Is it reasonable for go/types / types2 to implement the “nomono” check from the paper? If monomorphisation is supposed to be an acceptable implementation strategy for generic Go, then it seems like the type checker should enforce that for consistency across implementations.