Skip to content

Commit 6971090

Browse files
griesemerandybons
authored andcommitted
[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 <[email protected]> Reviewed-on: https://go-review.googlesource.com/c/151500 Run-TryBot: Andrew Bonventre <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Andrew Bonventre <[email protected]>
1 parent ba4638d commit 6971090

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

src/go/types/resolver.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,25 @@ func (check *Checker) packageObjects() {
538538
// pre-allocate space for type declaration paths so that the underlying array is reused
539539
typePath := make([]*TypeName, 0, 8)
540540

541+
// We process non-alias declarations first, in order to avoid situations where
542+
// the type of an alias declaration is needed before it is available. In general
543+
// this is still not enough, as it is possible to create sufficiently convoluted
544+
// recursive type definitions that will cause a type alias to be needed before it
545+
// is available (see issue #25838 for examples).
546+
// As an aside, the cmd/compiler suffers from the same problem (#25838).
547+
var aliasList []*TypeName
548+
// phase 1
541549
for _, obj := range objList {
550+
// If we have a type alias, collect it for the 2nd phase.
551+
if tname, _ := obj.(*TypeName); tname != nil && check.objMap[tname].alias {
552+
aliasList = append(aliasList, tname)
553+
continue
554+
}
555+
556+
check.objDecl(obj, nil, typePath)
557+
}
558+
// phase 2
559+
for _, obj := range aliasList {
542560
check.objDecl(obj, nil, typePath)
543561
}
544562

0 commit comments

Comments
 (0)