diff options
author | Robert Griesemer <gri@golang.org> | 2018-11-05 15:51:11 -0800 |
---|---|---|
committer | Andrew Bonventre <andybons@golang.org> | 2018-11-27 22:39:26 +0000 |
commit | 6971090515bab8d4ecf19933736591904f8287bc (patch) | |
tree | 1f7885b93f9f7334e1a925af8dc9de5c7b0a975f | |
parent | ba4638df61506f5f5858730f9f6dc9c0dcce72e8 (diff) | |
download | go-6971090515bab8d4ecf19933736591904f8287bc.tar.gz go-6971090515bab8d4ecf19933736591904f8287bc.zip |
[release-branch.go1.11] go/types: avoid certain problems with recursive alias type declarations
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.
Fixes #28972.
Change-Id: If6f9656a95262e6575b01c4a003094d41551564b
Reviewed-on: https://go-review.googlesource.com/c/147597
Reviewed-by: Alan Donovan <adonovan@google.com>
Reviewed-on: https://go-review.googlesource.com/c/151500
Run-TryBot: Andrew Bonventre <andybons@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Andrew Bonventre <andybons@golang.org>
-rw-r--r-- | src/go/types/resolver.go | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/src/go/types/resolver.go b/src/go/types/resolver.go index 5cbaba187b..6646711e7f 100644 --- a/src/go/types/resolver.go +++ b/src/go/types/resolver.go @@ -538,7 +538,25 @@ func (check *Checker) packageObjects() { // pre-allocate space for type declaration paths so that the underlying array is reused typePath := make([]*TypeName, 0, 8) + // 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, typePath) + } + // phase 2 + for _, obj := range aliasList { check.objDecl(obj, nil, typePath) } |