Robert Griesemer wrote in https://github.com/golang/go/issues/25305#issuecomment-387624488
at May 9th:
I'm probably using incorrect assumptions. Let me summarize them here:
1) A type is cyclical iff its size is not computable.
I'm really not sure if this is what the specification really means. If not then I wonder why not, because
2) Determining computability of the size of a type is trivial (wrt "we go through great lengths to detect such cycles").
AFAICT, there are two classes of types.
In the first (scalar) class the size of T is a constant fully determined by the kind of T: bool, integers, real and complex types, slices, interfaces, pointers, maps, channels, functions. (The last three being just a special case of a pointer.)
In the second (non-scalar) class a type T has size dependent (transitively) on other types (T_1, ... T_n), possibly including T itself. Scalar T_i brings no problem in computing the size of T.
For non-scalar T_i, all we need is a sentinel provided by knowing if the size of a type is a) not yet determined, b) being determined, c) determined/valid. When the size of T is needed, but not yet determined, it's first marked as "being determined". If, during computation of the size of T, we run into the sentinel, ie. we need to know the size of T_i marked "size being determined", we have proved the size of T is not computable. Otherwise the size of T is computed, stored and T is marked as "size determined/valid".
Wrt "even if they are "obviously" not cyclic to a human reader."
I think there's no difference between cyclic type determined by a program or by a human reader except for a bit higher error rate in the later case ;-)