mirror of
https://github.com/golang/go
synced 2024-11-17 06:04:47 -07:00
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 <mdempsky@google.com>
This commit is contained in:
parent
bc405df391
commit
bdd0ff08db
@ -269,6 +269,21 @@ func (check *Checker) checkFiles(files []*ast.File) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// processDelayed processes all delayed actions pushed after top.
|
||||
func (check *Checker) processDelayed(top int) {
|
||||
// If each delayed action pushes a new action, the
|
||||
// stack will continue to grow during this loop.
|
||||
// However, it is only processing functions (which
|
||||
// are processed in a delayed fashion) that may
|
||||
// add more actions (such as nested functions), so
|
||||
// this is a sufficiently bounded process.
|
||||
for i := top; i < len(check.delayed); i++ {
|
||||
check.delayed[i]() // may append to check.delayed
|
||||
}
|
||||
assert(top <= len(check.delayed)) // stack must not have shrunk
|
||||
check.delayed = check.delayed[:top]
|
||||
}
|
||||
|
||||
func (check *Checker) processFinals() {
|
||||
n := len(check.finals)
|
||||
for _, f := range check.finals {
|
||||
|
@ -607,16 +607,6 @@ func (a inSourceOrder) Len() int { return len(a) }
|
||||
func (a inSourceOrder) Less(i, j int) bool { return a[i].order() < a[j].order() }
|
||||
func (a inSourceOrder) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
|
||||
// processDelayed processes all delayed actions pushed after top.
|
||||
func (check *Checker) processDelayed(top int) {
|
||||
for len(check.delayed) > top {
|
||||
i := len(check.delayed) - 1
|
||||
f := check.delayed[i]
|
||||
check.delayed = check.delayed[:i]
|
||||
f() // may append to check.delayed
|
||||
}
|
||||
}
|
||||
|
||||
// unusedImports checks for unused imports.
|
||||
func (check *Checker) unusedImports() {
|
||||
// if function bodies are not checked, packages' uses are likely missing - don't check
|
||||
|
Loading…
Reference in New Issue
Block a user