go.tools/go/types: combine Info.{Types,Values} maps.

This results in significant improvement to type-checking time:
it reduces by 4% the entire running time of ssa/stdlib_test
(GOMAXPROCS=8, n=7).

LGTM=gri
R=gri
CC=golang-codereviews
https://golang.org/cl/57770043
diff --git a/go/loader/loader.go b/go/loader/loader.go
index cf5d914..06c2603 100644
--- a/go/loader/loader.go
+++ b/go/loader/loader.go
@@ -107,7 +107,6 @@
 	"strings"
 
 	"code.google.com/p/go.tools/astutil"
-	"code.google.com/p/go.tools/go/exact"
 	"code.google.com/p/go.tools/go/gcimporter"
 	"code.google.com/p/go.tools/go/types"
 )
@@ -620,8 +619,7 @@
 	info := &PackageInfo{
 		Files: files,
 		Info: types.Info{
-			Types:      make(map[ast.Expr]types.Type),
-			Values:     make(map[ast.Expr]exact.Value),
+			Types:      make(map[ast.Expr]types.TypeAndValue),
 			Objects:    make(map[*ast.Ident]types.Object),
 			Implicits:  make(map[ast.Node]types.Object),
 			Scopes:     make(map[ast.Node]*types.Scope),
diff --git a/go/loader/pkginfo.go b/go/loader/pkginfo.go
index ca25057..bb43ff1 100644
--- a/go/loader/pkginfo.go
+++ b/go/loader/pkginfo.go
@@ -34,7 +34,7 @@
 //
 func (info *PackageInfo) TypeOf(e ast.Expr) types.Type {
 	if t, ok := info.Types[e]; ok {
-		return t
+		return t.Type
 	}
 	// Defining ast.Idents (id := expr) get only Ident callbacks
 	// but not Expr callbacks.
@@ -49,7 +49,7 @@
 // Precondition: e belongs to the package's ASTs.
 //
 func (info *PackageInfo) ValueOf(e ast.Expr) exact.Value {
-	return info.Values[e]
+	return info.Types[e].Value
 }
 
 // ObjectOf returns the typechecker object denoted by the specified id.
diff --git a/go/types/api.go b/go/types/api.go
index 6403bf4..99cf5d2 100644
--- a/go/types/api.go
+++ b/go/types/api.go
@@ -14,11 +14,11 @@
 //
 // Constant folding computes the exact constant value (exact.Value) for
 // every expression (ast.Expr) that is a compile-time constant.
-// Use Info.Values for the results of constant folding.
+// Use Info.Types[expr].Value for the results of constant folding.
 //
 // Type inference computes the type (Type) of every expression (ast.Expr)
 // and checks for compliance with the language specification.
-// Use Info.Types for the results of type evaluation.
+// Use Info.Types[expr].Type for the results of type inference.
 //
 package types
 
@@ -115,22 +115,26 @@
 // in a client of go/types will initialize DefaultImport to gcimporter.Import.
 var DefaultImport Importer
 
+type TypeAndValue struct {
+	Type  Type
+	Value exact.Value
+}
+
 // Info holds result type information for a type-checked package.
 // Only the information for which a map is provided is collected.
 // If the package has type errors, the collected information may
 // be incomplete.
 type Info struct {
-	// Types maps expressions to their types. Identifiers on the
-	// lhs of declarations are collected in Objects, not Types.
+	// Types maps expressions to their types, and for constant
+	// expressions, their values.
+	// Identifiers on the lhs of declarations are collected in
+	// Objects, not Types.
 	//
 	// For an expression denoting a predeclared built-in function
 	// the recorded signature is call-site specific. If the call
 	// result is not a constant, the recorded type is an argument-
 	// specific signature. Otherwise, the recorded type is invalid.
-	Types map[ast.Expr]Type
-
-	// Values maps constant expressions to their values.
-	Values map[ast.Expr]exact.Value
+	Types map[ast.Expr]TypeAndValue
 
 	// Objects maps identifiers to their corresponding objects (including
 	// package names, dots "." of dot-imports, and blank "_" identifiers).
diff --git a/go/types/api_test.go b/go/types/api_test.go
index 6742a3e..147282b 100644
--- a/go/types/api_test.go
+++ b/go/types/api_test.go
@@ -13,7 +13,6 @@
 	"strings"
 	"testing"
 
-	"code.google.com/p/go.tools/go/exact"
 	_ "code.google.com/p/go.tools/go/gcimporter"
 	. "code.google.com/p/go.tools/go/types"
 )
@@ -94,14 +93,13 @@
 
 	for _, test := range tests {
 		info := Info{
-			Types:  make(map[ast.Expr]Type),
-			Values: make(map[ast.Expr]exact.Value),
+			Types: make(map[ast.Expr]TypeAndValue),
 		}
 		name := mustTypecheck(t, "ValuesInfo", test.src, &info)
 
 		// look for constant expression
 		var expr ast.Expr
-		for e := range info.Values {
+		for e := range info.Types {
 			if ExprString(e) == test.expr {
 				expr = e
 				break
@@ -111,15 +109,16 @@
 			t.Errorf("package %s: no expression found for %s", name, test.expr)
 			continue
 		}
+		tv := info.Types[expr]
 
 		// check that type is correct
-		if got := info.Types[expr].String(); got != test.typ {
+		if got := tv.Type.String(); got != test.typ {
 			t.Errorf("package %s: got type %s; want %s", name, got, test.typ)
 			continue
 		}
 
 		// check that value is correct
-		if got := info.Values[expr].String(); got != test.val {
+		if got := tv.Value.String(); got != test.val {
 			t.Errorf("package %s: got value %s; want %s", name, got, test.val)
 		}
 	}
@@ -206,14 +205,14 @@
 	}
 
 	for _, test := range tests {
-		info := Info{Types: make(map[ast.Expr]Type)}
+		info := Info{Types: make(map[ast.Expr]TypeAndValue)}
 		name := mustTypecheck(t, "TypesInfo", test.src, &info)
 
 		// look for expression type
 		var typ Type
-		for e, t := range info.Types {
+		for e, tv := range info.Types {
 			if ExprString(e) == test.expr {
-				typ = t
+				typ = tv.Type
 				break
 			}
 		}
diff --git a/go/types/builtins_test.go b/go/types/builtins_test.go
index fecc531..c33f63c 100644
--- a/go/types/builtins_test.go
+++ b/go/types/builtins_test.go
@@ -134,7 +134,7 @@
 
 	var conf Config
 	objects := make(map[*ast.Ident]Object)
-	types := make(map[ast.Expr]Type)
+	types := make(map[ast.Expr]TypeAndValue)
 	_, err = conf.Check(f.Name.Name, fset, []*ast.File{f}, &Info{Objects: objects, Types: types})
 	if err != nil {
 		t.Errorf("%s: %s", src0, err)
@@ -144,7 +144,7 @@
 	// find called function
 	n := 0
 	var fun ast.Expr
-	for x, _ := range types {
+	for x := range types {
 		if call, _ := x.(*ast.CallExpr); call != nil {
 			fun = call.Fun
 			n++
@@ -158,7 +158,7 @@
 	// check recorded types for fun and descendents (may be parenthesized)
 	for {
 		// the recorded type for the built-in must match the wanted signature
-		typ := types[fun]
+		typ := types[fun].Type
 		if typ == nil {
 			t.Errorf("%s: no type recorded for %s", src0, ExprString(fun))
 			return
diff --git a/go/types/check.go b/go/types/check.go
index 734cbf6..c4694be 100644
--- a/go/types/check.go
+++ b/go/types/check.go
@@ -92,14 +92,11 @@
 
 func (check *checker) recordTypeAndValue(x ast.Expr, typ Type, val exact.Value) {
 	assert(x != nil && typ != nil)
-	if m := check.Types; m != nil {
-		m[x] = typ
-	}
 	if val != nil {
 		assert(isConstType(typ))
-		if m := check.Values; m != nil {
-			m[x] = val
-		}
+	}
+	if m := check.Types; m != nil {
+		m[x] = TypeAndValue{typ, val}
 	}
 }
 
@@ -129,12 +126,14 @@
 	assert(isTyped(a[0]) && isTyped(a[1]) && isBoolean(a[1]))
 	if m := check.Types; m != nil {
 		for {
-			assert(m[x] != nil) // should have been recorded already
+			tv := m[x]
+			assert(tv.Type != nil) // should have been recorded already
 			pos := x.Pos()
-			m[x] = NewTuple(
+			tv.Type = NewTuple(
 				NewVar(pos, check.pkg, "", a[0]),
 				NewVar(pos, check.pkg, "", a[1]),
 			)
+			m[x] = tv
 			// if x is a parenthesized expression (p.X), update p.X
 			p, _ := x.(*ast.ParenExpr)
 			if p == nil {
@@ -248,7 +247,7 @@
 	// TODO(gri) Consider doing this before and
 	// after function body checking for smaller
 	// map size and more immediate feedback.
-	if check.Types != nil || check.Values != nil {
+	if check.Types != nil {
 		for x, info := range check.untyped {
 			check.recordTypeAndValue(x, info.typ, info.val)
 		}
diff --git a/go/types/expr.go b/go/types/expr.go
index f7d1ed9..6b102d0 100644
--- a/go/types/expr.go
+++ b/go/types/expr.go
@@ -53,8 +53,7 @@
 
 When an expression gets its final type, either on the way out from rawExpr,
 on the way down in updateExprType, or at the end of the type checker run,
-the type (and constant value, if any) is recorded via Info.Types and Values,
-if present.
+the type (and constant value, if any) is recorded via Info.Types, if present.
 */
 
 type opPredicates map[token.Token]func(Type) bool
diff --git a/go/types/issues_test.go b/go/types/issues_test.go
index 67d9e13..e61f0ef 100644
--- a/go/types/issues_test.go
+++ b/go/types/issues_test.go
@@ -48,13 +48,13 @@
 	}
 
 	var conf Config
-	types := make(map[ast.Expr]Type)
+	types := make(map[ast.Expr]TypeAndValue)
 	_, err = conf.Check(f.Name.Name, fset, []*ast.File{f}, &Info{Types: types})
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	for x, typ := range types {
+	for x, tv := range types {
 		var want Type
 		switch x := x.(type) {
 		case *ast.BasicLit:
@@ -75,8 +75,8 @@
 				want = Typ[UntypedNil]
 			}
 		}
-		if want != nil && !Identical(typ, want) {
-			t.Errorf("got %s; want %s", typ, want)
+		if want != nil && !Identical(tv.Type, want) {
+			t.Errorf("got %s; want %s", tv.Type, want)
 		}
 	}
 }
@@ -96,7 +96,7 @@
 	}
 
 	var conf Config
-	types := make(map[ast.Expr]Type)
+	types := make(map[ast.Expr]TypeAndValue)
 	_, err = conf.Check(f.Name.Name, fset, []*ast.File{f}, &Info{Types: types})
 	if err != nil {
 		t.Fatal(err)
@@ -104,10 +104,10 @@
 
 	want := Typ[Int]
 	n := 0
-	for x, got := range types {
+	for x, tv := range types {
 		if _, ok := x.(*ast.CallExpr); ok {
-			if got != want {
-				t.Errorf("%s: got %s; want %s", fset.Position(x.Pos()), got, want)
+			if tv.Type != want {
+				t.Errorf("%s: got %s; want %s", fset.Position(x.Pos()), tv.Type, want)
 			}
 			n++
 		}