]> Cypherpunks repositories - gostls13.git/commitdiff
go/types: avoid certain problems with recursive alias type declarations
authorRobert Griesemer <gri@golang.org>
Mon, 5 Nov 2018 23:51:11 +0000 (15:51 -0800)
committerRobert Griesemer <gri@golang.org>
Wed, 7 Nov 2018 18:25:08 +0000 (18:25 +0000)
It is possible to create certain recursive type declarations involving
alias types which cause the type-checker to produce an (invalid) type
for the alias because it is not yet available. By type-checking alias
declarations in a 2nd phase, the problem is mitigated a bit since it
requires more convoluted alias declarations for the problem to appear.

Also re-enable testing of fixedbugs/issue27232.go again (which was the
original cause for this change).

Updates #28576.

Change-Id: If6f9656a95262e6575b01c4a003094d41551564b
Reviewed-on: https://go-review.googlesource.com/c/147597
Reviewed-by: Alan Donovan <adonovan@google.com>
src/go/types/resolver.go
src/go/types/stdlib_test.go

index f6c3b601b24ee4d11c4ad3f327df40a9518aa220..41741e5882de5f4bbaf688730e46c4b12b098b1d 100644 (file)
@@ -570,7 +570,25 @@ func (check *Checker) packageObjects() {
                }
        }
 
+       // We process non-alias declarations first, in order to avoid situations where
+       // the type of an alias declaration is needed before it is available. In general
+       // this is still not enough, as it is possible to create sufficiently convoluted
+       // recursive type definitions that will cause a type alias to be needed before it
+       // is available (see issue #25838 for examples).
+       // As an aside, the cmd/compiler suffers from the same problem (#25838).
+       var aliasList []*TypeName
+       // phase 1
        for _, obj := range objList {
+               // If we have a type alias, collect it for the 2nd phase.
+               if tname, _ := obj.(*TypeName); tname != nil && check.objMap[tname].alias {
+                       aliasList = append(aliasList, tname)
+                       continue
+               }
+
+               check.objDecl(obj, nil)
+       }
+       // phase 2
+       for _, obj := range aliasList {
                check.objDecl(obj, nil)
        }
 
index a4ff1ab9a86de12691647fc536b8200940075194..84908fd190c4eedb6a709423e59ae3339ac8b8ab 100644 (file)
@@ -180,7 +180,6 @@ func TestStdFixed(t *testing.T) {
                "issue22200b.go", // go/types does not have constraints on stack size
                "issue25507.go",  // go/types does not have constraints on stack size
                "issue20780.go",  // go/types does not have constraints on stack size
-               "issue27232.go",  // go/types has a bug with alias type (issue #28576)
        )
 }