]> Cypherpunks.ru repositories - gostls13.git/commitdiff
go/types: remove the concept of finals
authorRob Findley <rfindley@google.com>
Tue, 9 Mar 2021 04:38:42 +0000 (23:38 -0500)
committerRobert Findley <rfindley@google.com>
Mon, 19 Apr 2021 23:08:21 +0000 (23:08 +0000)
Checker.finals and the corresponding atEnd were added in CL 191418 as a
mechanism to postpone interface type comparison until after all
interfaces were complete. In the intervening CL 195837 we've adopted a
convention of ensuring that interfaces are complete before comparing
them. Since then we've also added the additional case of expansion for
lazily resolving syntax.

Checker.later defers resolution of types until points in the checking
pass where all reachable types can be fully type checked, so the concept
of finals should no longer be necessary.

Change-Id: I58818c1a6b605dccc9b0ecb3a1f6859c138175d5
Reviewed-on: https://go-review.googlesource.com/c/go/+/299590
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/go/types/check.go
src/go/types/typexpr.go

index 69e9466a8b9a879651b4167b8a7bbf6fbc07fe8d..b28481d7bd683a116f4c8f9404e1692afad7192f 100644 (file)
@@ -104,7 +104,6 @@ type Checker struct {
        methods  map[*TypeName][]*Func // maps package scope type names to associated non-blank (non-interface) methods
        untyped  map[ast.Expr]exprInfo // map of expressions without final type
        delayed  []func()              // stack of delayed action segments; segments are processed in FIFO order
-       finals   []func()              // list of final actions; processed at the end of type-checking the current set of files
        objPath  []Object              // path of object dependencies during type inference (for cycle reporting)
 
        // context within which the current object is type-checked
@@ -144,14 +143,6 @@ func (check *Checker) later(f func()) {
        check.delayed = append(check.delayed, f)
 }
 
-// atEnd adds f to the list of actions processed at the end
-// of type-checking, before initialization order computation.
-// Actions added by atEnd are processed after any actions
-// added by later.
-func (check *Checker) atEnd(f func()) {
-       check.finals = append(check.finals, f)
-}
-
 // push pushes obj onto the object path and returns its index in the path.
 func (check *Checker) push(obj Object) int {
        check.objPath = append(check.objPath, obj)
@@ -212,7 +203,6 @@ func (check *Checker) initFiles(files []*ast.File) {
        check.methods = nil
        check.untyped = nil
        check.delayed = nil
-       check.finals = nil
 
        // determine package name and collect valid files
        pkg := check.pkg
@@ -269,7 +259,6 @@ func (check *Checker) checkFiles(files []*ast.File) (err error) {
        check.packageObjects()
 
        check.processDelayed(0) // incl. all functions
-       check.processFinals()
 
        check.initOrder()
 
@@ -308,16 +297,6 @@ func (check *Checker) processDelayed(top int) {
        check.delayed = check.delayed[:top]
 }
 
-func (check *Checker) processFinals() {
-       n := len(check.finals)
-       for _, f := range check.finals {
-               f() // must not append to check.finals
-       }
-       if len(check.finals) != n {
-               panic("internal error: final action list grew")
-       }
-}
-
 func (check *Checker) recordUntyped() {
        if !debug && check.Types == nil {
                return // nothing to do
index e6846545c63c1034343e483750be72d5c1b8e65d..5185c33fcbf012cd0a3d95ad317cc25fbee4f0f2 100644 (file)
@@ -140,7 +140,7 @@ func (check *Checker) ordinaryType(pos positioner, typ Type) {
        // while we are in the middle of type-checking parameter declarations that
        // might belong to interface methods. Delay this check to the end of
        // type-checking.
-       check.atEnd(func() {
+       check.later(func() {
                if t := asInterface(typ); t != nil {
                        check.completeInterface(pos.Pos(), t) // TODO(gri) is this the correct position?
                        if t.allTypes != nil {
@@ -531,7 +531,7 @@ func (check *Checker) typInternal(e0 ast.Expr, def *Named) (T Type) {
                //
                // Delay this check because it requires fully setup types;
                // it is safe to continue in any case (was issue 6667).
-               check.atEnd(func() {
+               check.later(func() {
                        if !Comparable(typ.key) {
                                var why string
                                if asTypeParam(typ.key) != nil {
@@ -635,7 +635,7 @@ func (check *Checker) instantiatedType(x ast.Expr, targs []ast.Expr, def *Named)
 
        // make sure we check instantiation works at least once
        // and that the resulting type is valid
-       check.atEnd(func() {
+       check.later(func() {
                t := typ.expand()
                check.validType(t, nil)
        })
@@ -905,7 +905,7 @@ func (check *Checker) completeInterface(pos token.Pos, ityp *Interface) {
                        // If we're pre-go1.14 (overlapping embeddings are not permitted), report that
                        // error here as well (even though we could do it eagerly) because it's the same
                        // error message.
-                       check.atEnd(func() {
+                       check.later(func() {
                                if !check.allowVersion(m.pkg, 1, 14) || !check.identical(m.typ, other.Type()) {
                                        check.errorf(atPos(pos), _DuplicateDecl, "duplicate method %s", m.name)
                                        check.errorf(atPos(mpos[other.(*Func)]), _DuplicateDecl, "\tother declaration of %s", m.name) // secondary error, \t indented
@@ -1119,7 +1119,7 @@ func (check *Checker) structType(styp *Struct, e *ast.StructType) {
                        embeddedTyp := typ
                        embeddedPos := f.Type
 
-                       check.atEnd(func() {
+                       check.later(func() {
                                t, isPtr := deref(embeddedTyp)
                                switch t := optype(t).(type) {
                                case *Basic:
@@ -1177,7 +1177,7 @@ func (check *Checker) collectTypeConstraints(pos token.Pos, types []ast.Expr) []
        // interfaces, which may not be complete yet. It's ok to do this check at the
        // end because it's not a requirement for correctness of the code.
        // Note: This is a quadratic algorithm, but type lists tend to be short.
-       check.atEnd(func() {
+       check.later(func() {
                for i, t := range list {
                        if t := asInterface(t); t != nil {
                                check.completeInterface(types[i].Pos(), t)