Skip to content

Commit bdd0ff0

Browse files
committed
go/types: process each segment of delayed actions in FIFO order
The stack of delayed actions is grown by pushing a new action on top with Checker.later. Checker.processDelayed processes all actions above a top watermark and then resets the stack to top. Until now, pushed actions above the watermark were processed in LIFO order. This change processes them in FIFO order, which seems more natural (if an action A was delayed before an action B, A should be processed before B for that stack segment). (With this change, Checker.later could be used instead of Checker.atEnd to postpone interface method type comparison and then the specific example in issue #33656 does type-check. However, in general we want interface method type comparisons to run after all interfaces are completed. With Checker.later we may still end up mixing interface completions and interface method type comparisons in ways leading to other errors for sufficiently convoluted code.) Also, move Checker.processDelayed from resolver.go to check.go. Change-Id: Id31254605e6944c490eab410553fff907630cc64 Reviewed-on: https://go-review.googlesource.com/c/go/+/191458 Reviewed-by: Matthew Dempsky <[email protected]>
1 parent bc405df commit bdd0ff0

File tree

2 files changed

+15
-10
lines changed

2 files changed

+15
-10
lines changed

src/go/types/check.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,21 @@ func (check *Checker) checkFiles(files []*ast.File) (err error) {
269269
return
270270
}
271271

272+
// processDelayed processes all delayed actions pushed after top.
273+
func (check *Checker) processDelayed(top int) {
274+
// If each delayed action pushes a new action, the
275+
// stack will continue to grow during this loop.
276+
// However, it is only processing functions (which
277+
// are processed in a delayed fashion) that may
278+
// add more actions (such as nested functions), so
279+
// this is a sufficiently bounded process.
280+
for i := top; i < len(check.delayed); i++ {
281+
check.delayed[i]() // may append to check.delayed
282+
}
283+
assert(top <= len(check.delayed)) // stack must not have shrunk
284+
check.delayed = check.delayed[:top]
285+
}
286+
272287
func (check *Checker) processFinals() {
273288
n := len(check.finals)
274289
for _, f := range check.finals {

src/go/types/resolver.go

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -607,16 +607,6 @@ func (a inSourceOrder) Len() int { return len(a) }
607607
func (a inSourceOrder) Less(i, j int) bool { return a[i].order() < a[j].order() }
608608
func (a inSourceOrder) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
609609

610-
// processDelayed processes all delayed actions pushed after top.
611-
func (check *Checker) processDelayed(top int) {
612-
for len(check.delayed) > top {
613-
i := len(check.delayed) - 1
614-
f := check.delayed[i]
615-
check.delayed = check.delayed[:i]
616-
f() // may append to check.delayed
617-
}
618-
}
619-
620610
// unusedImports checks for unused imports.
621611
func (check *Checker) unusedImports() {
622612
// if function bodies are not checked, packages' uses are likely missing - don't check

0 commit comments

Comments
 (0)