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