Commit 6cfeedb2 authored by Robert Griesemer's avatar Robert Griesemer

go/types: remove visited flag for constants and variables (cleanup)

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/115619Reviewed-by: default avatarAlan Donovan <adonovan@google.com>
parent 3d6e4ec0
...@@ -113,27 +113,29 @@ func (check *Checker) objDecl(obj Object, def *Named, path []*TypeName) { ...@@ -113,27 +113,29 @@ func (check *Checker) objDecl(obj Object, def *Named, path []*TypeName) {
case grey: case grey:
// We have a cycle. // We have a cycle.
// In the existing code, this is marked by a non-nil type // In the existing code, this is marked by a non-nil type
// for the object except for constants and variables, which // for the object except for constants and variables whose
// have their own "visited" flag (the new marking approach // type may be non-nil (known), or nil if it depends on the
// will allow us to remove that flag eventually). Their type // not-yet known initialization value.
// may be nil because they haven't determined their init // In the former case, set the type to Typ[Invalid] because
// values yet (from which to deduce the type). But in that // we have an initialization cycle. The cycle error will be
// case, they must have been marked as visited. // reported later, when determining initialization order.
// For now, handle constants and variables specially. // TODO(gri) Report cycle here and simplify initialization
visited := false // order code.
switch obj := obj.(type) { switch obj := obj.(type) {
case *Const: case *Const:
visited = obj.visited if obj.typ == nil {
obj.typ = Typ[Invalid]
}
case *Var: case *Var:
visited = obj.visited if obj.typ == nil {
obj.typ = Typ[Invalid]
}
case *TypeName: case *TypeName:
assert(obj.Type() != nil)
if useCycleMarking { if useCycleMarking {
check.typeCycle(obj) check.typeCycle(obj)
} }
return
case *Func: case *Func:
// Cycles involving functions require variables in // Cycles involving functions require variables in
...@@ -142,20 +144,13 @@ func (check *Checker) objDecl(obj Object, def *Named, path []*TypeName) { ...@@ -142,20 +144,13 @@ func (check *Checker) objDecl(obj Object, def *Named, path []*TypeName) {
// function type is set to an empty signature which // function type is set to an empty signature which
// makes it impossible to initialize a variable with // makes it impossible to initialize a variable with
// the function). // the function).
assert(obj.Type() != nil)
return
default: default:
unreachable() unreachable()
} }
assert(obj.Type() != nil)
// we have a *Const or *Var
if obj.Type() != nil {
return return
} }
assert(visited)
}
if trace { if trace {
check.trace(obj.Pos(), "-- checking %s (path = %s, objPath = %s)", obj, pathString(path), check.pathString()) check.trace(obj.Pos(), "-- checking %s (path = %s, objPath = %s)", obj, pathString(path), check.pathString())
...@@ -260,12 +255,6 @@ func (check *Checker) typeCycle(obj *TypeName) { ...@@ -260,12 +255,6 @@ func (check *Checker) typeCycle(obj *TypeName) {
func (check *Checker) constDecl(obj *Const, typ, init ast.Expr) { func (check *Checker) constDecl(obj *Const, typ, init ast.Expr) {
assert(obj.typ == nil) assert(obj.typ == nil)
if obj.visited {
obj.typ = Typ[Invalid]
return
}
obj.visited = true
// use the correct value of iota // use the correct value of iota
check.iota = obj.val check.iota = obj.val
defer func() { check.iota = nil }() defer func() { check.iota = nil }()
...@@ -299,12 +288,6 @@ func (check *Checker) constDecl(obj *Const, typ, init ast.Expr) { ...@@ -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) { func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init ast.Expr) {
assert(obj.typ == nil) assert(obj.typ == nil)
if obj.visited {
obj.typ = Typ[Invalid]
return
}
obj.visited = true
// determine type, if any // determine type, if any
if typ != nil { if typ != nil {
obj.typ = check.typ(typ) obj.typ = check.typ(typ)
......
...@@ -198,13 +198,12 @@ func (obj *PkgName) Imported() *Package { return obj.imported } ...@@ -198,13 +198,12 @@ func (obj *PkgName) Imported() *Package { return obj.imported }
type Const struct { type Const struct {
object object
val constant.Value val constant.Value
visited bool // for initialization cycle detection
} }
// NewConst returns a new constant with value val. // NewConst returns a new constant with value val.
// The remaining arguments set the attributes found with all Objects. // 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 { 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. // Val returns the constant's value.
...@@ -256,7 +255,6 @@ func (obj *TypeName) IsAlias() bool { ...@@ -256,7 +255,6 @@ func (obj *TypeName) IsAlias() bool {
type Var struct { type Var struct {
object object
embedded bool // if set, the variable is an embedded struct field, and name is the type name 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 isField bool // var is struct field
used bool // set if the variable was used used bool // set if the variable was used
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment