Commit 65cb1904 authored by Robert Griesemer's avatar Robert Griesemer

go/types: "inherit" type in constant declarations w/o initialization expressions (bug fix)

R=adonovan
CC=golang-dev
https://golang.org/cl/7060054
parent 89a7c87e
......@@ -23,12 +23,12 @@ type checker struct {
files []*ast.File
// lazily initialized
pkgscope *ast.Scope
firsterr error
initexprs map[*ast.ValueSpec][]ast.Expr // "inherited" initialization expressions for constant declarations
funclist []function // list of functions/methods with correct signatures and non-empty bodies
funcsig *Signature // signature of currently typechecked function
pos []token.Pos // stack of expr positions; debugging support, used if trace is set
pkgscope *ast.Scope
firsterr error
initspec map[*ast.ValueSpec]*ast.ValueSpec // "inherited" type and initialization expressions for constant declarations
funclist []function // list of functions/methods with correct signatures and non-empty bodies
funcsig *Signature // signature of currently typechecked function
pos []token.Pos // stack of expr positions; debugging support, used if trace is set
}
type function struct {
......@@ -156,12 +156,12 @@ func (check *checker) object(obj *ast.Object, cycleOk bool) {
spec := obj.Decl.(*ast.ValueSpec)
iota := obj.Data.(int)
obj.Data = nil
// determine initialization expressions
values := spec.Values
if len(values) == 0 && obj.Kind == ast.Con {
values = check.initexprs[spec]
// determine spec for type and initialization expressions
init := spec
if len(init.Values) == 0 && obj.Kind == ast.Con {
init = check.initspec[spec]
}
check.valueSpec(spec.Pos(), obj, spec.Names, spec.Type, values, iota)
check.valueSpec(spec.Pos(), obj, spec.Names, init.Type, init.Values, iota)
case ast.Typ:
typ := &NamedType{Obj: obj}
......@@ -217,21 +217,21 @@ func (check *checker) object(obj *ast.Object, cycleOk bool) {
}
// assocInitvals associates "inherited" initialization expressions
// with the corresponding *ast.ValueSpec in the check.initexprs map
// with the corresponding *ast.ValueSpec in the check.initspec map
// for constant declarations without explicit initialization expressions.
//
func (check *checker) assocInitvals(decl *ast.GenDecl) {
var values []ast.Expr
var last *ast.ValueSpec
for _, s := range decl.Specs {
if s, ok := s.(*ast.ValueSpec); ok {
if len(s.Values) > 0 {
values = s.Values
last = s
} else {
check.initexprs[s] = values
check.initspec[s] = last
}
}
}
if len(values) == 0 {
if last == nil {
check.invalidAST(decl.Pos(), "no initialization values provided")
}
}
......@@ -370,10 +370,10 @@ type bailout struct{}
func check(ctxt *Context, fset *token.FileSet, files map[string]*ast.File) (pkg *ast.Package, err error) {
// initialize checker
check := checker{
ctxt: ctxt,
fset: fset,
files: sortedFiles(files),
initexprs: make(map[*ast.ValueSpec][]ast.Expr),
ctxt: ctxt,
fset: fset,
files: sortedFiles(files),
initspec: make(map[*ast.ValueSpec]*ast.ValueSpec),
}
// handle panics
......
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