From d24c90a1534a1399cc667696e05a0dcf2d15aa6d Mon Sep 17 00:00:00 2001 From: Cuong Manh Le Date: Sun, 20 Jun 2021 02:06:45 +0700 Subject: [PATCH] [dev.typeparams] cmd/compile: explain how pkgReader.typIdx handles alias cyclic Change-Id: Ib9357c21bb010abf0d5fd17c3bee3197854c3a8a Reviewed-on: https://go-review.googlesource.com/c/go/+/329570 Trust: Cuong Manh Le Run-TryBot: Cuong Manh Le TryBot-Result: Go Bot Reviewed-by: Matthew Dempsky --- src/cmd/compile/internal/noder/reader.go | 41 ++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/src/cmd/compile/internal/noder/reader.go b/src/cmd/compile/internal/noder/reader.go index efa607e13b..004f9cc271 100644 --- a/src/cmd/compile/internal/noder/reader.go +++ b/src/cmd/compile/internal/noder/reader.go @@ -295,9 +295,46 @@ func (pr *pkgReader) typIdx(idx int, implicits, explicits []*types.Type) *types. typ := r.doTyp() assert(typ != nil) + // For recursive type declarations involving interfaces and aliases, + // above r.doTyp() call may have already set pr.typs[idx], so just + // double check and return the type. + // + // Example: + // + // type F = func(I) + // + // type I interface { + // m(F) + // } + // + // The writer writes data types in following index order: + // + // 0: func(I) + // 1: I + // 2: interface{m(func(I))} + // + // The reader resolves it in following index order: + // + // 0 -> 1 -> 2 -> 0 -> 1 + // + // and can divide in logically 2 steps: + // + // - 0 -> 1 : first time the reader reach type I, + // it creates new named type with symbol I. + // + // - 2 -> 0 -> 1: the reader ends up reaching symbol I again, + // now the symbol I was setup in above step, so + // the reader just return the named type. + // + // Now, the functions called return, the pr.typs looks like below: + // + // - 0 -> 1 -> 2 -> 0 : [ I ] + // - 0 -> 1 -> 2 : [func(I) I ] + // - 0 -> 1 : [func(I) I interface { "".m(func("".I)) }] + // + // The idx 1, corresponding with type I was resolved successfully + // after r.doTyp() call. if typ := pr.typs[idx]; typ != nil { - // This happens in fixedbugs/issue27232.go. - // TODO(mdempsky): Explain why/how this happens. return typ }