]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] cmd/compile: explain how pkgReader.typIdx handles alias cyclic
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Sat, 19 Jun 2021 19:06:45 +0000 (02:06 +0700)
committerCuong Manh Le <cuong.manhle.vn@gmail.com>
Sun, 20 Jun 2021 06:27:46 +0000 (06:27 +0000)
Change-Id: Ib9357c21bb010abf0d5fd17c3bee3197854c3a8a
Reviewed-on: https://go-review.googlesource.com/c/go/+/329570
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/cmd/compile/internal/noder/reader.go

index efa607e13bafc573b058eda36c450e1f65ed54be..004f9cc271d34653770e18cd4462f2871b2ff42a 100644 (file)
@@ -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 : [<T> I <T>]
+       //  - 0 -> 1 -> 2      : [func(I) I <T>]
+       //  - 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
        }