]> Cypherpunks repositories - gostls13.git/commitdiff
go/types: remove visited flag for constants and variables (cleanup)
authorRobert Griesemer <gri@golang.org>
Thu, 31 May 2018 22:18:21 +0000 (15:18 -0700)
committerRobert Griesemer <gri@golang.org>
Fri, 1 Jun 2018 17:36:40 +0000 (17:36 +0000)
Now that we have a color marking scheme for all objects, the
pre-existing 'visited' flag for constants and variables is
redundant: visited is the same as marking an object non-white.

Refactor the respective 'visited' flag logic from constDecl and
varDecl into the color switch in objDecl and remove the 'visited'
flag.

Follow-up on https://go-review.googlesource.com/c/go/+/114517 .

Change-Id: Ie20de65e3b26a5a6ff7b0eddc3d089f56be204e8
Reviewed-on: https://go-review.googlesource.com/115619
Reviewed-by: Alan Donovan <adonovan@google.com>
src/go/types/decl.go
src/go/types/object.go

index 9a27fbbed6f0ce7016712ad12d2e72b37545e5db..8430ebddb77c0096fbfb30e3d19baaa5459e1f45 100644 (file)
@@ -113,27 +113,29 @@ func (check *Checker) objDecl(obj Object, def *Named, path []*TypeName) {
        case grey:
                // We have a cycle.
                // In the existing code, this is marked by a non-nil type
-               // for the object except for constants and variables, which
-               // have their own "visited" flag (the new marking approach
-               // will allow us to remove that flag eventually). Their type
-               // may be nil because they haven't determined their init
-               // values yet (from which to deduce the type). But in that
-               // case, they must have been marked as visited.
-               // For now, handle constants and variables specially.
-               visited := false
+               // for the object except for constants and variables whose
+               // type may be non-nil (known), or nil if it depends on the
+               // not-yet known initialization value.
+               // In the former case, set the type to Typ[Invalid] because
+               // we have an initialization cycle. The cycle error will be
+               // reported later, when determining initialization order.
+               // TODO(gri) Report cycle here and simplify initialization
+               // order code.
                switch obj := obj.(type) {
                case *Const:
-                       visited = obj.visited
+                       if obj.typ == nil {
+                               obj.typ = Typ[Invalid]
+                       }
 
                case *Var:
-                       visited = obj.visited
+                       if obj.typ == nil {
+                               obj.typ = Typ[Invalid]
+                       }
 
                case *TypeName:
-                       assert(obj.Type() != nil)
                        if useCycleMarking {
                                check.typeCycle(obj)
                        }
-                       return
 
                case *Func:
                        // Cycles involving functions require variables in
@@ -142,19 +144,12 @@ func (check *Checker) objDecl(obj Object, def *Named, path []*TypeName) {
                        // function type is set to an empty signature which
                        // makes it impossible to initialize a variable with
                        // the function).
-                       assert(obj.Type() != nil)
-                       return
 
                default:
                        unreachable()
                }
-
-               // we have a *Const or *Var
-               if obj.Type() != nil {
-                       return
-               }
-               assert(visited)
-
+               assert(obj.Type() != nil)
+               return
        }
 
        if trace {
@@ -260,12 +255,6 @@ func (check *Checker) typeCycle(obj *TypeName) {
 func (check *Checker) constDecl(obj *Const, typ, init ast.Expr) {
        assert(obj.typ == nil)
 
-       if obj.visited {
-               obj.typ = Typ[Invalid]
-               return
-       }
-       obj.visited = true
-
        // use the correct value of iota
        check.iota = obj.val
        defer func() { check.iota = nil }()
@@ -299,12 +288,6 @@ func (check *Checker) constDecl(obj *Const, typ, init ast.Expr) {
 func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init ast.Expr) {
        assert(obj.typ == nil)
 
-       if obj.visited {
-               obj.typ = Typ[Invalid]
-               return
-       }
-       obj.visited = true
-
        // determine type, if any
        if typ != nil {
                obj.typ = check.typ(typ)
index 1305a9db6eb983a1ae7edbfc5d5bc205040b39c8..07adfbc34c3900dc1820429c1e3b84f3d9e9c38b 100644 (file)
@@ -197,14 +197,13 @@ func (obj *PkgName) Imported() *Package { return obj.imported }
 // A Const represents a declared constant.
 type Const struct {
        object
-       val     constant.Value
-       visited bool // for initialization cycle detection
+       val constant.Value
 }
 
 // NewConst returns a new constant with value val.
 // The remaining arguments set the attributes found with all Objects.
 func NewConst(pos token.Pos, pkg *Package, name string, typ Type, val constant.Value) *Const {
-       return &Const{object{nil, pos, pkg, name, typ, 0, colorFor(typ), token.NoPos}, val, false}
+       return &Const{object{nil, pos, pkg, name, typ, 0, colorFor(typ), token.NoPos}, val}
 }
 
 // Val returns the constant's value.
@@ -256,7 +255,6 @@ func (obj *TypeName) IsAlias() bool {
 type Var struct {
        object
        embedded bool // if set, the variable is an embedded struct field, and name is the type name
-       visited  bool // for initialization cycle detection
        isField  bool // var is struct field
        used     bool // set if the variable was used
 }