tools: switch to standard go/types at tip

A few files have been forked and tagged "go1.5,!go1.6" to work around
minor API changes between the two types packages:
- constant.Value.String() in oracle/describe.go and its tests;
- constant.ToInt must now be called before constant.Int64Val.
- types.Config{Importer: importer.Default()} in a number of places
- go/types/typeutil/import_test.go uses lowercase names to avoid 'import "C"'.

Files in go/types/typesutil, missing from my previous CL, have been
tagged !go1.5; these files will be deleted in February.

All affected packages were tested using 1.4.1, 1.5, and ~1.6 (tip).

Change-Id: Iec7fd370e1434508149b378438fb37f65b8d2ba8
Reviewed-on: https://go-review.googlesource.com/18207
Reviewed-by: Robert Griesemer <gri@golang.org>
diff --git a/go/callgraph/cha/cha.go b/go/callgraph/cha/cha.go
index 962f919..e016649 100644
--- a/go/callgraph/cha/cha.go
+++ b/go/callgraph/cha/cha.go
@@ -26,10 +26,11 @@
 package cha // import "golang.org/x/tools/go/callgraph/cha"
 
 import (
+	"go/types"
+
 	"golang.org/x/tools/go/callgraph"
 	"golang.org/x/tools/go/ssa"
 	"golang.org/x/tools/go/ssa/ssautil"
-	"golang.org/x/tools/go/types"
 	"golang.org/x/tools/go/types/typeutil"
 )
 
diff --git a/go/callgraph/cha/cha_test.go b/go/callgraph/cha/cha_test.go
index a558074..332758c 100644
--- a/go/callgraph/cha/cha_test.go
+++ b/go/callgraph/cha/cha_test.go
@@ -16,6 +16,7 @@
 	"go/ast"
 	"go/parser"
 	"go/token"
+	"go/types"
 	"io/ioutil"
 	"sort"
 	"strings"
@@ -25,7 +26,6 @@
 	"golang.org/x/tools/go/callgraph/cha"
 	"golang.org/x/tools/go/loader"
 	"golang.org/x/tools/go/ssa/ssautil"
-	"golang.org/x/tools/go/types"
 )
 
 var inputs = []string{
diff --git a/go/callgraph/rta/rta.go b/go/callgraph/rta/rta.go
index 0d0b0d3..7c9379d 100644
--- a/go/callgraph/rta/rta.go
+++ b/go/callgraph/rta/rta.go
@@ -50,10 +50,10 @@
 
 import (
 	"fmt"
+	"go/types"
 
 	"golang.org/x/tools/go/callgraph"
 	"golang.org/x/tools/go/ssa"
-	"golang.org/x/tools/go/types"
 	"golang.org/x/tools/go/types/typeutil"
 )
 
diff --git a/go/callgraph/rta/rta_test.go b/go/callgraph/rta/rta_test.go
index d37cc5c..5046521 100644
--- a/go/callgraph/rta/rta_test.go
+++ b/go/callgraph/rta/rta_test.go
@@ -16,6 +16,7 @@
 	"go/ast"
 	"go/parser"
 	"go/token"
+	"go/types"
 	"io/ioutil"
 	"sort"
 	"strings"
@@ -26,7 +27,6 @@
 	"golang.org/x/tools/go/loader"
 	"golang.org/x/tools/go/ssa"
 	"golang.org/x/tools/go/ssa/ssautil"
-	"golang.org/x/tools/go/types"
 )
 
 var inputs = []string{
diff --git a/go/loader/loader.go b/go/loader/loader.go
index ecdc85d..41d5957 100644
--- a/go/loader/loader.go
+++ b/go/loader/loader.go
@@ -15,6 +15,7 @@
 	"go/build"
 	"go/parser"
 	"go/token"
+	"go/types"
 	"os"
 	"sort"
 	"strings"
@@ -23,7 +24,6 @@
 
 	"golang.org/x/tools/go/ast/astutil"
 	"golang.org/x/tools/go/buildutil"
-	"golang.org/x/tools/go/types"
 )
 
 const trace = false // show timing info for type-checking
@@ -1005,9 +1005,7 @@
 	if f := imp.conf.TypeCheckFuncBodies; f != nil {
 		tc.IgnoreFuncBodies = !f(path)
 	}
-	tc.Import = func(_ map[string]*types.Package, to string) (*types.Package, error) {
-		return imp.doImport(info, to)
-	}
+	tc.Importer = closure{imp, info}
 	tc.Error = info.appendError // appendError wraps the user's Error function
 
 	info.checker = types.NewChecker(&tc, imp.conf.fset(), pkg, &info.Info)
@@ -1016,3 +1014,10 @@
 	imp.progMu.Unlock()
 	return info
 }
+
+type closure struct {
+	imp  *importer
+	info *PackageInfo
+}
+
+func (c closure) Import(to string) (*types.Package, error) { return c.imp.doImport(c.info, to) }
diff --git a/go/loader/stdlib_test.go b/go/loader/stdlib_test.go
index 23f6f01..812a4a6 100644
--- a/go/loader/stdlib_test.go
+++ b/go/loader/stdlib_test.go
@@ -16,6 +16,7 @@
 	"go/ast"
 	"go/build"
 	"go/token"
+	"go/types"
 	"io/ioutil"
 	"path/filepath"
 	"runtime"
@@ -25,7 +26,6 @@
 
 	"golang.org/x/tools/go/buildutil"
 	"golang.org/x/tools/go/loader"
-	"golang.org/x/tools/go/types"
 )
 
 func TestStdlib(t *testing.T) {
diff --git a/go/pointer/analysis.go b/go/pointer/analysis.go
index 4a7439e..9f3476c 100644
--- a/go/pointer/analysis.go
+++ b/go/pointer/analysis.go
@@ -11,6 +11,7 @@
 import (
 	"fmt"
 	"go/token"
+	"go/types"
 	"io"
 	"os"
 	"reflect"
@@ -20,7 +21,6 @@
 
 	"golang.org/x/tools/go/callgraph"
 	"golang.org/x/tools/go/ssa"
-	"golang.org/x/tools/go/types"
 	"golang.org/x/tools/go/types/typeutil"
 )
 
diff --git a/go/pointer/constraint.go b/go/pointer/constraint.go
index 5b9265a..ea44287 100644
--- a/go/pointer/constraint.go
+++ b/go/pointer/constraint.go
@@ -6,9 +6,7 @@
 
 package pointer
 
-import (
-	"golang.org/x/tools/go/types"
-)
+import "go/types"
 
 type constraint interface {
 	// For a complex constraint, returns the nodeid of the pointer
diff --git a/go/pointer/gen.go b/go/pointer/gen.go
index 9d550a7..405a63b 100644
--- a/go/pointer/gen.go
+++ b/go/pointer/gen.go
@@ -15,10 +15,10 @@
 import (
 	"fmt"
 	"go/token"
+	"go/types"
 
 	"golang.org/x/tools/go/callgraph"
 	"golang.org/x/tools/go/ssa"
-	"golang.org/x/tools/go/types"
 )
 
 var (
diff --git a/go/pointer/hvn.go b/go/pointer/hvn.go
index c144559..e550bc9 100644
--- a/go/pointer/hvn.go
+++ b/go/pointer/hvn.go
@@ -165,11 +165,11 @@
 
 import (
 	"fmt"
+	"go/types"
 	"io"
 	"reflect"
 
 	"golang.org/x/tools/container/intsets"
-	"golang.org/x/tools/go/types"
 )
 
 // A peLabel is a pointer-equivalence label: two nodes with the same
diff --git a/go/pointer/intrinsics.go b/go/pointer/intrinsics.go
index 69da377..fbfb36d 100644
--- a/go/pointer/intrinsics.go
+++ b/go/pointer/intrinsics.go
@@ -19,9 +19,9 @@
 
 import (
 	"fmt"
+	"go/types"
 
 	"golang.org/x/tools/go/ssa"
-	"golang.org/x/tools/go/types"
 )
 
 // Instances of 'intrinsic' generate analysis constraints for calls to
diff --git a/go/pointer/labels.go b/go/pointer/labels.go
index 4709272..bfe60d2 100644
--- a/go/pointer/labels.go
+++ b/go/pointer/labels.go
@@ -9,10 +9,10 @@
 import (
 	"fmt"
 	"go/token"
+	"go/types"
 	"strings"
 
 	"golang.org/x/tools/go/ssa"
-	"golang.org/x/tools/go/types"
 )
 
 // A Label is an entity that may be pointed to by a pointer, map,
diff --git a/go/pointer/pointer_test.go b/go/pointer/pointer_test.go
index ddfacf7..52af485 100644
--- a/go/pointer/pointer_test.go
+++ b/go/pointer/pointer_test.go
@@ -19,6 +19,7 @@
 	"errors"
 	"fmt"
 	"go/token"
+	"go/types"
 	"io/ioutil"
 	"os"
 	"regexp"
@@ -31,7 +32,6 @@
 	"golang.org/x/tools/go/pointer"
 	"golang.org/x/tools/go/ssa"
 	"golang.org/x/tools/go/ssa/ssautil"
-	"golang.org/x/tools/go/types"
 	"golang.org/x/tools/go/types/typeutil"
 )
 
diff --git a/go/pointer/reflect.go b/go/pointer/reflect.go
index a0bfda6..bdb22cf 100644
--- a/go/pointer/reflect.go
+++ b/go/pointer/reflect.go
@@ -32,11 +32,11 @@
 
 import (
 	"fmt"
+	exact "go/constant"
+	"go/types"
 	"reflect"
 
-	"golang.org/x/tools/go/exact"
 	"golang.org/x/tools/go/ssa"
-	"golang.org/x/tools/go/types"
 )
 
 func init() {
diff --git a/go/pointer/solve.go b/go/pointer/solve.go
index 8cff32f..3c60685 100644
--- a/go/pointer/solve.go
+++ b/go/pointer/solve.go
@@ -11,8 +11,7 @@
 
 import (
 	"fmt"
-
-	"golang.org/x/tools/go/types"
+	"go/types"
 )
 
 type solverState struct {
diff --git a/go/pointer/util.go b/go/pointer/util.go
index 7a43187..4d2fa74 100644
--- a/go/pointer/util.go
+++ b/go/pointer/util.go
@@ -9,6 +9,7 @@
 import (
 	"bytes"
 	"fmt"
+	"go/types"
 	"log"
 	"os"
 	"os/exec"
@@ -16,7 +17,6 @@
 	"time"
 
 	"golang.org/x/tools/container/intsets"
-	"golang.org/x/tools/go/types"
 )
 
 // CanPoint reports whether the type T is pointerlike,
diff --git a/go/ssa/builder.go b/go/ssa/builder.go
index 9a0a474..4707ebe 100644
--- a/go/ssa/builder.go
+++ b/go/ssa/builder.go
@@ -34,12 +34,11 @@
 import (
 	"fmt"
 	"go/ast"
+	exact "go/constant"
 	"go/token"
+	"go/types"
 	"os"
 	"sync"
-
-	"golang.org/x/tools/go/exact"
-	"golang.org/x/tools/go/types"
 )
 
 type opaqueType struct {
@@ -244,7 +243,7 @@
 			}
 			if m, ok := m.(*Const); ok {
 				// treat make([]T, n, m) as new([m]T)[:n]
-				cap, _ := exact.Int64Val(m.Value)
+				cap := m.Int64()
 				at := types.NewArray(typ.Underlying().(*types.Slice).Elem(), cap)
 				alloc := emitNew(fn, at, pos)
 				alloc.Comment = "makeslice"
diff --git a/go/ssa/builder_test.go b/go/ssa/builder_test.go
index f055625..fdb58ff 100644
--- a/go/ssa/builder_test.go
+++ b/go/ssa/builder_test.go
@@ -9,8 +9,10 @@
 import (
 	"bytes"
 	"go/ast"
+	"go/importer"
 	"go/parser"
 	"go/token"
+	"go/types"
 	"reflect"
 	"sort"
 	"strings"
@@ -19,9 +21,6 @@
 	"golang.org/x/tools/go/loader"
 	"golang.org/x/tools/go/ssa"
 	"golang.org/x/tools/go/ssa/ssautil"
-	"golang.org/x/tools/go/types"
-
-	_ "golang.org/x/tools/go/gcimporter"
 )
 
 func isEmpty(f *ssa.Function) bool { return f.Blocks == nil }
@@ -59,7 +58,7 @@
 
 	// Build an SSA program from the parsed file.
 	// Load its dependencies from gc binary export data.
-	mainPkg, _, err := ssautil.BuildPackage(new(types.Config), fset,
+	mainPkg, _, err := ssautil.BuildPackage(&types.Config{Importer: importer.Default()}, fset,
 		types.NewPackage("main", ""), []*ast.File{f}, ssa.SanityCheckFunctions)
 	if err != nil {
 		t.Error(err)
@@ -227,7 +226,7 @@
 
 		// Create a single-file main package.
 		// Load dependencies from gc binary export data.
-		ssapkg, _, err := ssautil.BuildPackage(new(types.Config), fset,
+		ssapkg, _, err := ssautil.BuildPackage(&types.Config{Importer: importer.Default()}, fset,
 			types.NewPackage("p", ""), []*ast.File{f}, ssa.SanityCheckFunctions)
 		if err != nil {
 			t.Errorf("test %q: %s", test.input[:15], err)
diff --git a/go/ssa/const.go b/go/ssa/const.go
index 3a1746d..0690463 100644
--- a/go/ssa/const.go
+++ b/go/ssa/const.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build go1.5
+// +build go1.6
 
 package ssa
 
@@ -10,11 +10,10 @@
 
 import (
 	"fmt"
+	exact "go/constant"
 	"go/token"
+	"go/types"
 	"strconv"
-
-	"golang.org/x/tools/go/exact"
-	"golang.org/x/tools/go/types"
 )
 
 // NewConst returns a new constant of the specified value and type.
@@ -118,11 +117,13 @@
 	return c.Value == nil
 }
 
+// TODO(adonovan): move everything below into golang.org/x/tools/go/ssa/interp.
+
 // Int64 returns the numeric value of this constant truncated to fit
 // a signed 64-bit integer.
 //
 func (c *Const) Int64() int64 {
-	switch x := c.Value; x.Kind() {
+	switch x := exact.ToInt(c.Value); x.Kind() {
 	case exact.Int:
 		if i, ok := exact.Int64Val(x); ok {
 			return i
@@ -139,7 +140,7 @@
 // an unsigned 64-bit integer.
 //
 func (c *Const) Uint64() uint64 {
-	switch x := c.Value; x.Kind() {
+	switch x := exact.ToInt(c.Value); x.Kind() {
 	case exact.Int:
 		if u, ok := exact.Uint64Val(x); ok {
 			return u
diff --git a/go/ssa/const15.go b/go/ssa/const15.go
new file mode 100644
index 0000000..a42b255
--- /dev/null
+++ b/go/ssa/const15.go
@@ -0,0 +1,171 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build go1.5,!go1.6
+
+package ssa
+
+// This file defines the Const SSA value type.
+
+import (
+	"fmt"
+	exact "go/constant"
+	"go/token"
+	"go/types"
+	"strconv"
+)
+
+// NewConst returns a new constant of the specified value and type.
+// val must be valid according to the specification of Const.Value.
+//
+func NewConst(val exact.Value, typ types.Type) *Const {
+	return &Const{typ, val}
+}
+
+// intConst returns an 'int' constant that evaluates to i.
+// (i is an int64 in case the host is narrower than the target.)
+func intConst(i int64) *Const {
+	return NewConst(exact.MakeInt64(i), tInt)
+}
+
+// nilConst returns a nil constant of the specified type, which may
+// be any reference type, including interfaces.
+//
+func nilConst(typ types.Type) *Const {
+	return NewConst(nil, typ)
+}
+
+// stringConst returns a 'string' constant that evaluates to s.
+func stringConst(s string) *Const {
+	return NewConst(exact.MakeString(s), tString)
+}
+
+// zeroConst returns a new "zero" constant of the specified type,
+// which must not be an array or struct type: the zero values of
+// aggregates are well-defined but cannot be represented by Const.
+//
+func zeroConst(t types.Type) *Const {
+	switch t := t.(type) {
+	case *types.Basic:
+		switch {
+		case t.Info()&types.IsBoolean != 0:
+			return NewConst(exact.MakeBool(false), t)
+		case t.Info()&types.IsNumeric != 0:
+			return NewConst(exact.MakeInt64(0), t)
+		case t.Info()&types.IsString != 0:
+			return NewConst(exact.MakeString(""), t)
+		case t.Kind() == types.UnsafePointer:
+			fallthrough
+		case t.Kind() == types.UntypedNil:
+			return nilConst(t)
+		default:
+			panic(fmt.Sprint("zeroConst for unexpected type:", t))
+		}
+	case *types.Pointer, *types.Slice, *types.Interface, *types.Chan, *types.Map, *types.Signature:
+		return nilConst(t)
+	case *types.Named:
+		return NewConst(zeroConst(t.Underlying()).Value, t)
+	case *types.Array, *types.Struct, *types.Tuple:
+		panic(fmt.Sprint("zeroConst applied to aggregate:", t))
+	}
+	panic(fmt.Sprint("zeroConst: unexpected ", t))
+}
+
+func (c *Const) RelString(from *types.Package) string {
+	var s string
+	if c.Value == nil {
+		s = "nil"
+	} else if c.Value.Kind() == exact.String {
+		s = exact.StringVal(c.Value)
+		const max = 20
+		// TODO(adonovan): don't cut a rune in half.
+		if len(s) > max {
+			s = s[:max-3] + "..." // abbreviate
+		}
+		s = strconv.Quote(s)
+	} else {
+		s = c.Value.String()
+	}
+	return s + ":" + relType(c.Type(), from)
+}
+
+func (c *Const) Name() string {
+	return c.RelString(nil)
+}
+
+func (c *Const) String() string {
+	return c.Name()
+}
+
+func (c *Const) Type() types.Type {
+	return c.typ
+}
+
+func (c *Const) Referrers() *[]Instruction {
+	return nil
+}
+
+func (c *Const) Parent() *Function { return nil }
+
+func (c *Const) Pos() token.Pos {
+	return token.NoPos
+}
+
+// IsNil returns true if this constant represents a typed or untyped nil value.
+func (c *Const) IsNil() bool {
+	return c.Value == nil
+}
+
+// TODO(adonovan): move everything below into golang.org/x/tools/go/ssa/interp.
+
+// Int64 returns the numeric value of this constant truncated to fit
+// a signed 64-bit integer.
+//
+func (c *Const) Int64() int64 {
+	switch x := c.Value; x.Kind() {
+	case exact.Int:
+		if i, ok := exact.Int64Val(x); ok {
+			return i
+		}
+		return 0
+	case exact.Float:
+		f, _ := exact.Float64Val(x)
+		return int64(f)
+	}
+	panic(fmt.Sprintf("unexpected constant value: %T", c.Value))
+}
+
+// Uint64 returns the numeric value of this constant truncated to fit
+// an unsigned 64-bit integer.
+//
+func (c *Const) Uint64() uint64 {
+	switch x := c.Value; x.Kind() {
+	case exact.Int:
+		if u, ok := exact.Uint64Val(x); ok {
+			return u
+		}
+		return 0
+	case exact.Float:
+		f, _ := exact.Float64Val(x)
+		return uint64(f)
+	}
+	panic(fmt.Sprintf("unexpected constant value: %T", c.Value))
+}
+
+// Float64 returns the numeric value of this constant truncated to fit
+// a float64.
+//
+func (c *Const) Float64() float64 {
+	f, _ := exact.Float64Val(c.Value)
+	return f
+}
+
+// Complex128 returns the complex value of this constant truncated to
+// fit a complex128.
+//
+func (c *Const) Complex128() complex128 {
+	re, _ := exact.Float64Val(exact.Real(c.Value))
+	im, _ := exact.Float64Val(exact.Imag(c.Value))
+	return complex(re, im)
+}
diff --git a/go/ssa/create.go b/go/ssa/create.go
index b49a8be..372d1c7 100644
--- a/go/ssa/create.go
+++ b/go/ssa/create.go
@@ -13,10 +13,10 @@
 	"fmt"
 	"go/ast"
 	"go/token"
+	"go/types"
 	"os"
 	"sync"
 
-	"golang.org/x/tools/go/types"
 	"golang.org/x/tools/go/types/typeutil"
 )
 
diff --git a/go/ssa/emit.go b/go/ssa/emit.go
index dd4ff93..238c070 100644
--- a/go/ssa/emit.go
+++ b/go/ssa/emit.go
@@ -12,8 +12,7 @@
 	"fmt"
 	"go/ast"
 	"go/token"
-
-	"golang.org/x/tools/go/types"
+	"go/types"
 )
 
 // emitNew emits to f a new (heap Alloc) instruction allocating an
diff --git a/go/ssa/example_test.go b/go/ssa/example_test.go
index f25e31d..718817c 100644
--- a/go/ssa/example_test.go
+++ b/go/ssa/example_test.go
@@ -8,16 +8,16 @@
 
 import (
 	"fmt"
-	"os"
-
 	"go/ast"
+	"go/importer"
 	"go/parser"
 	"go/token"
+	"go/types"
+	"os"
 
 	"golang.org/x/tools/go/loader"
 	"golang.org/x/tools/go/ssa"
 	"golang.org/x/tools/go/ssa/ssautil"
-	"golang.org/x/tools/go/types"
 )
 
 const hello = `
@@ -66,7 +66,7 @@
 	// Type-check the package, load dependencies.
 	// Create and build the SSA program.
 	hello, _, err := ssautil.BuildPackage(
-		new(types.Config), fset, pkg, files, ssa.SanityCheckFunctions)
+		&types.Config{Importer: importer.Default()}, fset, pkg, files, ssa.SanityCheckFunctions)
 	if err != nil {
 		fmt.Print(err) // type error in some package
 		return
diff --git a/go/ssa/func.go b/go/ssa/func.go
index 7d9e8f9..88052c3 100644
--- a/go/ssa/func.go
+++ b/go/ssa/func.go
@@ -13,11 +13,10 @@
 	"fmt"
 	"go/ast"
 	"go/token"
+	"go/types"
 	"io"
 	"os"
 	"strings"
-
-	"golang.org/x/tools/go/types"
 )
 
 // addEdge adds a control-flow graph edge from from to to.
diff --git a/go/ssa/interp/external.go b/go/ssa/interp/external.go
index 2425163..8ae81b2 100644
--- a/go/ssa/interp/external.go
+++ b/go/ssa/interp/external.go
@@ -10,6 +10,7 @@
 // external or because they use "unsafe" or "reflect" operations.
 
 import (
+	"go/types"
 	"math"
 	"os"
 	"runtime"
@@ -19,7 +20,6 @@
 	"unsafe"
 
 	"golang.org/x/tools/go/ssa"
-	"golang.org/x/tools/go/types"
 )
 
 type externalFn func(fr *frame, args []value) value
diff --git a/go/ssa/interp/interp.go b/go/ssa/interp/interp.go
index 87e6b81..b855645 100644
--- a/go/ssa/interp/interp.go
+++ b/go/ssa/interp/interp.go
@@ -49,12 +49,12 @@
 import (
 	"fmt"
 	"go/token"
+	"go/types"
 	"os"
 	"reflect"
 	"runtime"
 
 	"golang.org/x/tools/go/ssa"
-	"golang.org/x/tools/go/types"
 )
 
 type continuation int
diff --git a/go/ssa/interp/interp_test.go b/go/ssa/interp/interp_test.go
index bcdd81c..5163816 100644
--- a/go/ssa/interp/interp_test.go
+++ b/go/ssa/interp/interp_test.go
@@ -12,6 +12,7 @@
 	"bytes"
 	"fmt"
 	"go/build"
+	"go/types"
 	"os"
 	"path/filepath"
 	"strings"
@@ -22,7 +23,6 @@
 	"golang.org/x/tools/go/ssa"
 	"golang.org/x/tools/go/ssa/interp"
 	"golang.org/x/tools/go/ssa/ssautil"
-	"golang.org/x/tools/go/types"
 )
 
 // Each line contains a space-separated list of $GOROOT/test/
diff --git a/go/ssa/interp/map.go b/go/ssa/interp/map.go
index 6d4c3ae..4c092b3 100644
--- a/go/ssa/interp/map.go
+++ b/go/ssa/interp/map.go
@@ -14,7 +14,7 @@
 // concurrent map access.
 
 import (
-	"golang.org/x/tools/go/types"
+	"go/types"
 )
 
 type hashable interface {
diff --git a/go/ssa/interp/ops.go b/go/ssa/interp/ops.go
index a76b579..c7a0a40 100644
--- a/go/ssa/interp/ops.go
+++ b/go/ssa/interp/ops.go
@@ -9,14 +9,14 @@
 import (
 	"bytes"
 	"fmt"
+	exact "go/constant"
 	"go/token"
+	"go/types"
 	"strings"
 	"sync"
 	"unsafe"
 
-	"golang.org/x/tools/go/exact"
 	"golang.org/x/tools/go/ssa"
-	"golang.org/x/tools/go/types"
 )
 
 // If the target program panics, the interpreter panics with this type.
diff --git a/go/ssa/interp/reflect.go b/go/ssa/interp/reflect.go
index 01cd00b..48bb911 100644
--- a/go/ssa/interp/reflect.go
+++ b/go/ssa/interp/reflect.go
@@ -15,11 +15,11 @@
 import (
 	"fmt"
 	"go/token"
+	"go/types"
 	"reflect"
 	"unsafe"
 
 	"golang.org/x/tools/go/ssa"
-	"golang.org/x/tools/go/types"
 )
 
 type opaqueType struct {
diff --git a/go/ssa/interp/value.go b/go/ssa/interp/value.go
index 37be184..2194b01 100644
--- a/go/ssa/interp/value.go
+++ b/go/ssa/interp/value.go
@@ -38,6 +38,7 @@
 import (
 	"bytes"
 	"fmt"
+	"go/types"
 	"io"
 	"reflect"
 	"strings"
@@ -45,7 +46,6 @@
 	"unsafe"
 
 	"golang.org/x/tools/go/ssa"
-	"golang.org/x/tools/go/types"
 	"golang.org/x/tools/go/types/typeutil"
 )
 
diff --git a/go/ssa/lift.go b/go/ssa/lift.go
index d0a145d..722d086 100644
--- a/go/ssa/lift.go
+++ b/go/ssa/lift.go
@@ -46,10 +46,9 @@
 import (
 	"fmt"
 	"go/token"
+	"go/types"
 	"math/big"
 	"os"
-
-	"golang.org/x/tools/go/types"
 )
 
 // If true, perform sanity checking and show diagnostic information at
diff --git a/go/ssa/lvalue.go b/go/ssa/lvalue.go
index 657204d..85e090f 100644
--- a/go/ssa/lvalue.go
+++ b/go/ssa/lvalue.go
@@ -12,8 +12,7 @@
 import (
 	"go/ast"
 	"go/token"
-
-	"golang.org/x/tools/go/types"
+	"go/types"
 )
 
 // An lvalue represents an assignable location that may appear on the
diff --git a/go/ssa/methods.go b/go/ssa/methods.go
index ba36bbf..7d1fb42 100644
--- a/go/ssa/methods.go
+++ b/go/ssa/methods.go
@@ -10,8 +10,7 @@
 
 import (
 	"fmt"
-
-	"golang.org/x/tools/go/types"
+	"go/types"
 )
 
 // MethodValue returns the Function implementing method sel, building
diff --git a/go/ssa/print.go b/go/ssa/print.go
index c389616..55c9266 100644
--- a/go/ssa/print.go
+++ b/go/ssa/print.go
@@ -12,11 +12,11 @@
 import (
 	"bytes"
 	"fmt"
+	"go/types"
 	"io"
 	"reflect"
 	"sort"
 
-	"golang.org/x/tools/go/types"
 	"golang.org/x/tools/go/types/typeutil"
 )
 
diff --git a/go/ssa/sanity.go b/go/ssa/sanity.go
index 01e97e5..4babb37 100644
--- a/go/ssa/sanity.go
+++ b/go/ssa/sanity.go
@@ -11,11 +11,10 @@
 
 import (
 	"fmt"
+	"go/types"
 	"io"
 	"os"
 	"strings"
-
-	"golang.org/x/tools/go/types"
 )
 
 type sanity struct {
diff --git a/go/ssa/source.go b/go/ssa/source.go
index 0926c05..3a6f039 100644
--- a/go/ssa/source.go
+++ b/go/ssa/source.go
@@ -15,8 +15,7 @@
 import (
 	"go/ast"
 	"go/token"
-
-	"golang.org/x/tools/go/types"
+	"go/types"
 )
 
 // EnclosingFunction returns the function that contains the syntax
diff --git a/go/ssa/source_test.go b/go/ssa/source_test.go
index 9146907..3fd7ac4 100644
--- a/go/ssa/source_test.go
+++ b/go/ssa/source_test.go
@@ -11,8 +11,10 @@
 import (
 	"fmt"
 	"go/ast"
+	exact "go/constant"
 	"go/parser"
 	"go/token"
+	"go/types"
 	"os"
 	"regexp"
 	"runtime"
@@ -20,11 +22,9 @@
 	"testing"
 
 	"golang.org/x/tools/go/ast/astutil"
-	"golang.org/x/tools/go/exact"
 	"golang.org/x/tools/go/loader"
 	"golang.org/x/tools/go/ssa"
 	"golang.org/x/tools/go/ssa/ssautil"
-	"golang.org/x/tools/go/types"
 )
 
 func TestObjValueLookup(t *testing.T) {
diff --git a/go/ssa/ssa.go b/go/ssa/ssa.go
index 513f87f..c547af8 100644
--- a/go/ssa/ssa.go
+++ b/go/ssa/ssa.go
@@ -12,11 +12,11 @@
 import (
 	"fmt"
 	"go/ast"
+	exact "go/constant"
 	"go/token"
+	"go/types"
 	"sync"
 
-	"golang.org/x/tools/go/exact"
-	"golang.org/x/tools/go/types"
 	"golang.org/x/tools/go/types/typeutil"
 )
 
diff --git a/go/ssa/ssautil/load.go b/go/ssa/ssautil/load.go
index 4061f49..7c57838 100644
--- a/go/ssa/ssautil/load.go
+++ b/go/ssa/ssautil/load.go
@@ -11,10 +11,10 @@
 import (
 	"go/ast"
 	"go/token"
+	"go/types"
 
 	"golang.org/x/tools/go/loader"
 	"golang.org/x/tools/go/ssa"
-	"golang.org/x/tools/go/types"
 )
 
 // CreateProgram returns a new program in SSA form, given a program
diff --git a/go/ssa/ssautil/load_test.go b/go/ssa/ssautil/load_test.go
index 31fe186..8ce73bc 100644
--- a/go/ssa/ssautil/load_test.go
+++ b/go/ssa/ssautil/load_test.go
@@ -8,15 +8,14 @@
 
 import (
 	"go/ast"
+	"go/importer"
 	"go/parser"
 	"go/token"
+	"go/types"
 	"os"
 	"testing"
 
 	"golang.org/x/tools/go/ssa/ssautil"
-	"golang.org/x/tools/go/types"
-
-	_ "golang.org/x/tools/go/gcimporter"
 )
 
 const hello = `package main
@@ -39,7 +38,7 @@
 	}
 
 	pkg := types.NewPackage("hello", "")
-	ssapkg, _, err := ssautil.BuildPackage(new(types.Config), fset, pkg, []*ast.File{f}, 0)
+	ssapkg, _, err := ssautil.BuildPackage(&types.Config{Importer: importer.Default()}, fset, pkg, []*ast.File{f}, 0)
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/go/ssa/ssautil/switch.go b/go/ssa/ssautil/switch.go
index 0cbcb3d..2fcc167 100644
--- a/go/ssa/ssautil/switch.go
+++ b/go/ssa/ssautil/switch.go
@@ -24,9 +24,9 @@
 	"bytes"
 	"fmt"
 	"go/token"
+	"go/types"
 
 	"golang.org/x/tools/go/ssa"
-	"golang.org/x/tools/go/types"
 )
 
 // A ConstCase represents a single constant comparison.
diff --git a/go/ssa/testmain.go b/go/ssa/testmain.go
index 13d7ac1..48b184a 100644
--- a/go/ssa/testmain.go
+++ b/go/ssa/testmain.go
@@ -12,13 +12,12 @@
 
 import (
 	"go/ast"
+	exact "go/constant"
 	"go/token"
+	"go/types"
 	"os"
 	"sort"
 	"strings"
-
-	"golang.org/x/tools/go/exact"
-	"golang.org/x/tools/go/types"
 )
 
 // FindTests returns the list of packages that define at least one Test,
diff --git a/go/ssa/util.go b/go/ssa/util.go
index e323553..317a013 100644
--- a/go/ssa/util.go
+++ b/go/ssa/util.go
@@ -12,11 +12,11 @@
 	"fmt"
 	"go/ast"
 	"go/token"
+	"go/types"
 	"io"
 	"os"
 
 	"golang.org/x/tools/go/ast/astutil"
-	"golang.org/x/tools/go/types"
 )
 
 //// AST utilities
diff --git a/go/ssa/wrappers.go b/go/ssa/wrappers.go
index 75ec596..6ca01ab 100644
--- a/go/ssa/wrappers.go
+++ b/go/ssa/wrappers.go
@@ -24,7 +24,7 @@
 import (
 	"fmt"
 
-	"golang.org/x/tools/go/types"
+	"go/types"
 )
 
 // -- wrappers -----------------------------------------------------------
diff --git a/go/types/typeutil/example_test.go b/go/types/typeutil/example_test.go
index 9e3ada7..fe49644 100644
--- a/go/types/typeutil/example_test.go
+++ b/go/types/typeutil/example_test.go
@@ -2,17 +2,18 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// +build go1.5
+
 package typeutil_test
 
 import (
 	"fmt"
-	"sort"
-
 	"go/ast"
 	"go/parser"
 	"go/token"
+	"go/types"
+	"sort"
 
-	"golang.org/x/tools/go/types"
 	"golang.org/x/tools/go/types/typeutil"
 )
 
diff --git a/go/types/typeutil/imports.go b/go/types/typeutil/imports.go
index 967fe1e..4b753f4 100644
--- a/go/types/typeutil/imports.go
+++ b/go/types/typeutil/imports.go
@@ -2,9 +2,11 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// +build go1.5
+
 package typeutil
 
-import "golang.org/x/tools/go/types"
+import "go/types"
 
 // Dependencies returns all dependencies of the specified packages.
 //
diff --git a/go/types/typeutil/imports14.go b/go/types/typeutil/imports14.go
new file mode 100644
index 0000000..9741df3
--- /dev/null
+++ b/go/types/typeutil/imports14.go
@@ -0,0 +1,33 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !go1.5
+
+package typeutil
+
+import "golang.org/x/tools/go/types"
+
+// Dependencies returns all dependencies of the specified packages.
+//
+// Dependent packages appear in topological order: if package P imports
+// package Q, Q appears earlier than P in the result.
+// The algorithm follows import statements in the order they
+// appear in the source code, so the result is a total order.
+//
+func Dependencies(pkgs ...*types.Package) []*types.Package {
+	var result []*types.Package
+	seen := make(map[*types.Package]bool)
+	var visit func(pkgs []*types.Package)
+	visit = func(pkgs []*types.Package) {
+		for _, p := range pkgs {
+			if !seen[p] {
+				seen[p] = true
+				visit(p.Imports())
+				result = append(result, p)
+			}
+		}
+	}
+	visit(pkgs)
+	return result
+}
diff --git a/go/types/typeutil/imports14_test.go b/go/types/typeutil/imports14_test.go
new file mode 100644
index 0000000..b70f5f0
--- /dev/null
+++ b/go/types/typeutil/imports14_test.go
@@ -0,0 +1,81 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !go1.5
+
+package typeutil_test
+
+import (
+	"fmt"
+	"go/ast"
+	"go/parser"
+	"go/token"
+	"testing"
+
+	"golang.org/x/tools/go/types"
+	"golang.org/x/tools/go/types/typeutil"
+)
+
+func TestDependencies(t *testing.T) {
+	packages := make(map[string]*types.Package)
+	conf := types.Config{
+		Packages: packages,
+		Import: func(_ map[string]*types.Package, path string) (*types.Package, error) {
+			return packages[path], nil
+		},
+	}
+	fset := token.NewFileSet()
+
+	// All edges go to the right.
+	//  /--D--B--A
+	// F    \_C_/
+	//  \__E_/
+	for i, content := range []string{
+		`package a`,
+		`package c; import (_ "a")`,
+		`package b; import (_ "a")`,
+		`package e; import (_ "c")`,
+		`package d; import (_ "b"; _ "c")`,
+		`package f; import (_ "d"; _ "e")`,
+	} {
+		f, err := parser.ParseFile(fset, fmt.Sprintf("%d.go", i), content, 0)
+		if err != nil {
+			t.Fatal(err)
+		}
+		pkg, err := conf.Check(f.Name.Name, fset, []*ast.File{f}, nil)
+		if err != nil {
+			t.Fatal(err)
+		}
+		packages[pkg.Path()] = pkg
+	}
+
+	for _, test := range []struct {
+		roots, want string
+	}{
+		{"a", "a"},
+		{"b", "ab"},
+		{"c", "ac"},
+		{"d", "abcd"},
+		{"e", "ace"},
+		{"f", "abcdef"},
+
+		{"be", "abce"},
+		{"eb", "aceb"},
+		{"de", "abcde"},
+		{"ed", "acebd"},
+		{"ef", "acebdf"},
+	} {
+		var pkgs []*types.Package
+		for _, r := range test.roots {
+			pkgs = append(pkgs, packages[string(r)])
+		}
+		var got string
+		for _, p := range typeutil.Dependencies(pkgs...) {
+			got += p.Path()
+		}
+		if got != test.want {
+			t.Errorf("Dependencies(%q) = %q, want %q", test.roots, got, test.want)
+		}
+	}
+}
diff --git a/go/types/typeutil/imports_test.go b/go/types/typeutil/imports_test.go
index 8071ae1..b846fbb 100644
--- a/go/types/typeutil/imports_test.go
+++ b/go/types/typeutil/imports_test.go
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// +build go1.5
+
 package typeutil_test
 
 import (
@@ -9,19 +11,20 @@
 	"go/ast"
 	"go/parser"
 	"go/token"
+	"go/types"
 	"testing"
 
-	"golang.org/x/tools/go/types"
 	"golang.org/x/tools/go/types/typeutil"
 )
 
+type closure map[string]*types.Package
+
+func (c closure) Import(path string) (*types.Package, error) { return c[path], nil }
+
 func TestDependencies(t *testing.T) {
 	packages := make(map[string]*types.Package)
 	conf := types.Config{
-		Packages: packages,
-		Import: func(_ map[string]*types.Package, path string) (*types.Package, error) {
-			return packages[path], nil
-		},
+		Importer: closure(packages),
 	}
 	fset := token.NewFileSet()
 
@@ -30,12 +33,12 @@
 	// F    \_C_/
 	//  \__E_/
 	for i, content := range []string{
-		`package A`,
-		`package C; import (_ "A")`,
-		`package B; import (_ "A")`,
-		`package E; import (_ "C")`,
-		`package D; import (_ "B"; _ "C")`,
-		`package F; import (_ "D"; _ "E")`,
+		`package a`,
+		`package c; import (_ "a")`,
+		`package b; import (_ "a")`,
+		`package e; import (_ "c")`,
+		`package d; import (_ "b"; _ "c")`,
+		`package f; import (_ "d"; _ "e")`,
 	} {
 		f, err := parser.ParseFile(fset, fmt.Sprintf("%d.go", i), content, 0)
 		if err != nil {
@@ -51,22 +54,22 @@
 	for _, test := range []struct {
 		roots, want string
 	}{
-		{"A", "A"},
-		{"B", "AB"},
-		{"C", "AC"},
-		{"D", "ABCD"},
-		{"E", "ACE"},
-		{"F", "ABCDEF"},
+		{"a", "a"},
+		{"b", "ab"},
+		{"c", "ac"},
+		{"d", "abcd"},
+		{"e", "ace"},
+		{"f", "abcdef"},
 
-		{"BE", "ABCE"},
-		{"EB", "ACEB"},
-		{"DE", "ABCDE"},
-		{"ED", "ACEBD"},
-		{"EF", "ACEBDF"},
+		{"be", "abce"},
+		{"eb", "aceb"},
+		{"de", "abcde"},
+		{"ed", "acebd"},
+		{"ef", "acebdf"},
 	} {
 		var pkgs []*types.Package
 		for _, r := range test.roots {
-			pkgs = append(pkgs, conf.Packages[string(r)])
+			pkgs = append(pkgs, packages[string(r)])
 		}
 		var got string
 		for _, p := range typeutil.Dependencies(pkgs...) {
diff --git a/go/types/typeutil/map.go b/go/types/typeutil/map.go
index b3a04cc..81dd556 100644
--- a/go/types/typeutil/map.go
+++ b/go/types/typeutil/map.go
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// +build go1.5
+
 // Package typeutil defines various utilities for types, such as Map,
 // a mapping from types.Type to interface{} values.
 package typeutil // import "golang.org/x/tools/go/types/typeutil"
@@ -9,9 +11,8 @@
 import (
 	"bytes"
 	"fmt"
+	"go/types"
 	"reflect"
-
-	"golang.org/x/tools/go/types"
 )
 
 // Map is a hash-table-based mapping from types (types.Type) to
diff --git a/go/types/typeutil/map14.go b/go/types/typeutil/map14.go
new file mode 100644
index 0000000..16209e3
--- /dev/null
+++ b/go/types/typeutil/map14.go
@@ -0,0 +1,316 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !go1.5
+
+// Package typeutil defines various utilities for types, such as Map,
+// a mapping from types.Type to interface{} values.
+package typeutil // import "golang.org/x/tools/go/types/typeutil"
+
+import (
+	"bytes"
+	"fmt"
+	"reflect"
+
+	"golang.org/x/tools/go/types"
+)
+
+// Map is a hash-table-based mapping from types (types.Type) to
+// arbitrary interface{} values.  The concrete types that implement
+// the Type interface are pointers.  Since they are not canonicalized,
+// == cannot be used to check for equivalence, and thus we cannot
+// simply use a Go map.
+//
+// Just as with map[K]V, a nil *Map is a valid empty map.
+//
+// Not thread-safe.
+//
+type Map struct {
+	hasher Hasher             // shared by many Maps
+	table  map[uint32][]entry // maps hash to bucket; entry.key==nil means unused
+	length int                // number of map entries
+}
+
+// entry is an entry (key/value association) in a hash bucket.
+type entry struct {
+	key   types.Type
+	value interface{}
+}
+
+// SetHasher sets the hasher used by Map.
+//
+// All Hashers are functionally equivalent but contain internal state
+// used to cache the results of hashing previously seen types.
+//
+// A single Hasher created by MakeHasher() may be shared among many
+// Maps.  This is recommended if the instances have many keys in
+// common, as it will amortize the cost of hash computation.
+//
+// A Hasher may grow without bound as new types are seen.  Even when a
+// type is deleted from the map, the Hasher never shrinks, since other
+// types in the map may reference the deleted type indirectly.
+//
+// Hashers are not thread-safe, and read-only operations such as
+// Map.Lookup require updates to the hasher, so a full Mutex lock (not a
+// read-lock) is require around all Map operations if a shared
+// hasher is accessed from multiple threads.
+//
+// If SetHasher is not called, the Map will create a private hasher at
+// the first call to Insert.
+//
+func (m *Map) SetHasher(hasher Hasher) {
+	m.hasher = hasher
+}
+
+// Delete removes the entry with the given key, if any.
+// It returns true if the entry was found.
+//
+func (m *Map) Delete(key types.Type) bool {
+	if m != nil && m.table != nil {
+		hash := m.hasher.Hash(key)
+		bucket := m.table[hash]
+		for i, e := range bucket {
+			if e.key != nil && types.Identical(key, e.key) {
+				// We can't compact the bucket as it
+				// would disturb iterators.
+				bucket[i] = entry{}
+				m.length--
+				return true
+			}
+		}
+	}
+	return false
+}
+
+// At returns the map entry for the given key.
+// The result is nil if the entry is not present.
+//
+func (m *Map) At(key types.Type) interface{} {
+	if m != nil && m.table != nil {
+		for _, e := range m.table[m.hasher.Hash(key)] {
+			if e.key != nil && types.Identical(key, e.key) {
+				return e.value
+			}
+		}
+	}
+	return nil
+}
+
+// Set sets the map entry for key to val,
+// and returns the previous entry, if any.
+func (m *Map) Set(key types.Type, value interface{}) (prev interface{}) {
+	if m.table != nil {
+		hash := m.hasher.Hash(key)
+		bucket := m.table[hash]
+		var hole *entry
+		for i, e := range bucket {
+			if e.key == nil {
+				hole = &bucket[i]
+			} else if types.Identical(key, e.key) {
+				prev = e.value
+				bucket[i].value = value
+				return
+			}
+		}
+
+		if hole != nil {
+			*hole = entry{key, value} // overwrite deleted entry
+		} else {
+			m.table[hash] = append(bucket, entry{key, value})
+		}
+	} else {
+		if m.hasher.memo == nil {
+			m.hasher = MakeHasher()
+		}
+		hash := m.hasher.Hash(key)
+		m.table = map[uint32][]entry{hash: {entry{key, value}}}
+	}
+
+	m.length++
+	return
+}
+
+// Len returns the number of map entries.
+func (m *Map) Len() int {
+	if m != nil {
+		return m.length
+	}
+	return 0
+}
+
+// Iterate calls function f on each entry in the map in unspecified order.
+//
+// If f should mutate the map, Iterate provides the same guarantees as
+// Go maps: if f deletes a map entry that Iterate has not yet reached,
+// f will not be invoked for it, but if f inserts a map entry that
+// Iterate has not yet reached, whether or not f will be invoked for
+// it is unspecified.
+//
+func (m *Map) Iterate(f func(key types.Type, value interface{})) {
+	if m != nil {
+		for _, bucket := range m.table {
+			for _, e := range bucket {
+				if e.key != nil {
+					f(e.key, e.value)
+				}
+			}
+		}
+	}
+}
+
+// Keys returns a new slice containing the set of map keys.
+// The order is unspecified.
+func (m *Map) Keys() []types.Type {
+	keys := make([]types.Type, 0, m.Len())
+	m.Iterate(func(key types.Type, _ interface{}) {
+		keys = append(keys, key)
+	})
+	return keys
+}
+
+func (m *Map) toString(values bool) string {
+	if m == nil {
+		return "{}"
+	}
+	var buf bytes.Buffer
+	fmt.Fprint(&buf, "{")
+	sep := ""
+	m.Iterate(func(key types.Type, value interface{}) {
+		fmt.Fprint(&buf, sep)
+		sep = ", "
+		fmt.Fprint(&buf, key)
+		if values {
+			fmt.Fprintf(&buf, ": %q", value)
+		}
+	})
+	fmt.Fprint(&buf, "}")
+	return buf.String()
+}
+
+// String returns a string representation of the map's entries.
+// Values are printed using fmt.Sprintf("%v", v).
+// Order is unspecified.
+//
+func (m *Map) String() string {
+	return m.toString(true)
+}
+
+// KeysString returns a string representation of the map's key set.
+// Order is unspecified.
+//
+func (m *Map) KeysString() string {
+	return m.toString(false)
+}
+
+////////////////////////////////////////////////////////////////////////
+// Hasher
+
+// A Hasher maps each type to its hash value.
+// For efficiency, a hasher uses memoization; thus its memory
+// footprint grows monotonically over time.
+// Hashers are not thread-safe.
+// Hashers have reference semantics.
+// Call MakeHasher to create a Hasher.
+type Hasher struct {
+	memo map[types.Type]uint32
+}
+
+// MakeHasher returns a new Hasher instance.
+func MakeHasher() Hasher {
+	return Hasher{make(map[types.Type]uint32)}
+}
+
+// Hash computes a hash value for the given type t such that
+// Identical(t, t') => Hash(t) == Hash(t').
+func (h Hasher) Hash(t types.Type) uint32 {
+	hash, ok := h.memo[t]
+	if !ok {
+		hash = h.hashFor(t)
+		h.memo[t] = hash
+	}
+	return hash
+}
+
+// hashString computes the Fowler–Noll–Vo hash of s.
+func hashString(s string) uint32 {
+	var h uint32
+	for i := 0; i < len(s); i++ {
+		h ^= uint32(s[i])
+		h *= 16777619
+	}
+	return h
+}
+
+// hashFor computes the hash of t.
+func (h Hasher) hashFor(t types.Type) uint32 {
+	// See Identical for rationale.
+	switch t := t.(type) {
+	case *types.Basic:
+		return uint32(t.Kind())
+
+	case *types.Array:
+		return 9043 + 2*uint32(t.Len()) + 3*h.Hash(t.Elem())
+
+	case *types.Slice:
+		return 9049 + 2*h.Hash(t.Elem())
+
+	case *types.Struct:
+		var hash uint32 = 9059
+		for i, n := 0, t.NumFields(); i < n; i++ {
+			f := t.Field(i)
+			if f.Anonymous() {
+				hash += 8861
+			}
+			hash += hashString(t.Tag(i))
+			hash += hashString(f.Name()) // (ignore f.Pkg)
+			hash += h.Hash(f.Type())
+		}
+		return hash
+
+	case *types.Pointer:
+		return 9067 + 2*h.Hash(t.Elem())
+
+	case *types.Signature:
+		var hash uint32 = 9091
+		if t.Variadic() {
+			hash *= 8863
+		}
+		return hash + 3*h.hashTuple(t.Params()) + 5*h.hashTuple(t.Results())
+
+	case *types.Interface:
+		var hash uint32 = 9103
+		for i, n := 0, t.NumMethods(); i < n; i++ {
+			// See go/types.identicalMethods for rationale.
+			// Method order is not significant.
+			// Ignore m.Pkg().
+			m := t.Method(i)
+			hash += 3*hashString(m.Name()) + 5*h.Hash(m.Type())
+		}
+		return hash
+
+	case *types.Map:
+		return 9109 + 2*h.Hash(t.Key()) + 3*h.Hash(t.Elem())
+
+	case *types.Chan:
+		return 9127 + 2*uint32(t.Dir()) + 3*h.Hash(t.Elem())
+
+	case *types.Named:
+		// Not safe with a copying GC; objects may move.
+		return uint32(reflect.ValueOf(t.Obj()).Pointer())
+
+	case *types.Tuple:
+		return h.hashTuple(t)
+	}
+	panic(t)
+}
+
+func (h Hasher) hashTuple(tuple *types.Tuple) uint32 {
+	// See go/types.identicalTypes for rationale.
+	n := tuple.Len()
+	var hash uint32 = 9137 + 2*uint32(n)
+	for i := 0; i < n; i++ {
+		hash += 3 * h.Hash(tuple.At(i).Type())
+	}
+	return hash
+}
diff --git a/go/types/typeutil/map14_test.go b/go/types/typeutil/map14_test.go
new file mode 100644
index 0000000..9043d05
--- /dev/null
+++ b/go/types/typeutil/map14_test.go
@@ -0,0 +1,176 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !go1.5
+
+package typeutil_test
+
+// TODO(adonovan):
+// - test use of explicit hasher across two maps.
+// - test hashcodes are consistent with equals for a range of types
+//   (e.g. all types generated by type-checking some body of real code).
+
+import (
+	"testing"
+
+	"golang.org/x/tools/go/types"
+	"golang.org/x/tools/go/types/typeutil"
+)
+
+var (
+	tStr      = types.Typ[types.String]             // string
+	tPStr1    = types.NewPointer(tStr)              // *string
+	tPStr2    = types.NewPointer(tStr)              // *string, again
+	tInt      = types.Typ[types.Int]                // int
+	tChanInt1 = types.NewChan(types.RecvOnly, tInt) // <-chan int
+	tChanInt2 = types.NewChan(types.RecvOnly, tInt) // <-chan int, again
+)
+
+func checkEqualButNotIdentical(t *testing.T, x, y types.Type, comment string) {
+	if !types.Identical(x, y) {
+		t.Errorf("%s: not equal: %s, %s", comment, x, y)
+	}
+	if x == y {
+		t.Errorf("%s: identical: %v, %v", comment, x, y)
+	}
+}
+
+func TestAxioms(t *testing.T) {
+	checkEqualButNotIdentical(t, tPStr1, tPStr2, "tPstr{1,2}")
+	checkEqualButNotIdentical(t, tChanInt1, tChanInt2, "tChanInt{1,2}")
+}
+
+func TestMap(t *testing.T) {
+	var tmap *typeutil.Map
+
+	// All methods but Set are safe on on (*T)(nil).
+	tmap.Len()
+	tmap.At(tPStr1)
+	tmap.Delete(tPStr1)
+	tmap.KeysString()
+	tmap.String()
+
+	tmap = new(typeutil.Map)
+
+	// Length of empty map.
+	if l := tmap.Len(); l != 0 {
+		t.Errorf("Len() on empty Map: got %d, want 0", l)
+	}
+	// At of missing key.
+	if v := tmap.At(tPStr1); v != nil {
+		t.Errorf("At() on empty Map: got %v, want nil", v)
+	}
+	// Deletion of missing key.
+	if tmap.Delete(tPStr1) {
+		t.Errorf("Delete() on empty Map: got true, want false")
+	}
+	// Set of new key.
+	if prev := tmap.Set(tPStr1, "*string"); prev != nil {
+		t.Errorf("Set() on empty Map returned non-nil previous value %s", prev)
+	}
+
+	// Now: {*string: "*string"}
+
+	// Length of non-empty map.
+	if l := tmap.Len(); l != 1 {
+		t.Errorf("Len(): got %d, want 1", l)
+	}
+	// At via insertion key.
+	if v := tmap.At(tPStr1); v != "*string" {
+		t.Errorf("At(): got %q, want \"*string\"", v)
+	}
+	// At via equal key.
+	if v := tmap.At(tPStr2); v != "*string" {
+		t.Errorf("At(): got %q, want \"*string\"", v)
+	}
+	// Iteration over sole entry.
+	tmap.Iterate(func(key types.Type, value interface{}) {
+		if key != tPStr1 {
+			t.Errorf("Iterate: key: got %s, want %s", key, tPStr1)
+		}
+		if want := "*string"; value != want {
+			t.Errorf("Iterate: value: got %s, want %s", value, want)
+		}
+	})
+
+	// Setion with key equal to present one.
+	if prev := tmap.Set(tPStr2, "*string again"); prev != "*string" {
+		t.Errorf("Set() previous value: got %s, want \"*string\"", prev)
+	}
+
+	// Setion of another association.
+	if prev := tmap.Set(tChanInt1, "<-chan int"); prev != nil {
+		t.Errorf("Set() previous value: got %s, want nil", prev)
+	}
+
+	// Now: {*string: "*string again", <-chan int: "<-chan int"}
+
+	want1 := "{*string: \"*string again\", <-chan int: \"<-chan int\"}"
+	want2 := "{<-chan int: \"<-chan int\", *string: \"*string again\"}"
+	if s := tmap.String(); s != want1 && s != want2 {
+		t.Errorf("String(): got %s, want %s", s, want1)
+	}
+
+	want1 = "{*string, <-chan int}"
+	want2 = "{<-chan int, *string}"
+	if s := tmap.KeysString(); s != want1 && s != want2 {
+		t.Errorf("KeysString(): got %s, want %s", s, want1)
+	}
+
+	// Keys().
+	I := types.Identical
+	switch k := tmap.Keys(); {
+	case I(k[0], tChanInt1) && I(k[1], tPStr1): // ok
+	case I(k[1], tChanInt1) && I(k[0], tPStr1): // ok
+	default:
+		t.Errorf("Keys(): got %v, want %s", k, want2)
+	}
+
+	if l := tmap.Len(); l != 2 {
+		t.Errorf("Len(): got %d, want 1", l)
+	}
+	// At via original key.
+	if v := tmap.At(tPStr1); v != "*string again" {
+		t.Errorf("At(): got %q, want \"*string again\"", v)
+	}
+	hamming := 1
+	tmap.Iterate(func(key types.Type, value interface{}) {
+		switch {
+		case I(key, tChanInt1):
+			hamming *= 2 // ok
+		case I(key, tPStr1):
+			hamming *= 3 // ok
+		}
+	})
+	if hamming != 6 {
+		t.Errorf("Iterate: hamming: got %d, want %d", hamming, 6)
+	}
+
+	if v := tmap.At(tChanInt2); v != "<-chan int" {
+		t.Errorf("At(): got %q, want \"<-chan int\"", v)
+	}
+	// Deletion with key equal to present one.
+	if !tmap.Delete(tChanInt2) {
+		t.Errorf("Delete() of existing key: got false, want true")
+	}
+
+	// Now: {*string: "*string again"}
+
+	if l := tmap.Len(); l != 1 {
+		t.Errorf("Len(): got %d, want 1", l)
+	}
+	// Deletion again.
+	if !tmap.Delete(tPStr2) {
+		t.Errorf("Delete() of existing key: got false, want true")
+	}
+
+	// Now: {}
+
+	if l := tmap.Len(); l != 0 {
+		t.Errorf("Len(): got %d, want %d", l, 0)
+	}
+	if s := tmap.String(); s != "{}" {
+		t.Errorf("Len(): got %q, want %q", s, "")
+	}
+}
diff --git a/go/types/typeutil/map_test.go b/go/types/typeutil/map_test.go
index 776b5e2..e5dc4e4 100644
--- a/go/types/typeutil/map_test.go
+++ b/go/types/typeutil/map_test.go
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// +build go1.5
+
 package typeutil_test
 
 // TODO(adonovan):
@@ -10,9 +12,9 @@
 //   (e.g. all types generated by type-checking some body of real code).
 
 import (
+	"go/types"
 	"testing"
 
-	"golang.org/x/tools/go/types"
 	"golang.org/x/tools/go/types/typeutil"
 )
 
diff --git a/go/types/typeutil/methodsetcache.go b/go/types/typeutil/methodsetcache.go
index daad644..edc3f5b 100644
--- a/go/types/typeutil/methodsetcache.go
+++ b/go/types/typeutil/methodsetcache.go
@@ -2,14 +2,15 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// +build go1.5
+
 // This file implements a cache of method sets.
 
 package typeutil
 
 import (
+	"go/types"
 	"sync"
-
-	"golang.org/x/tools/go/types"
 )
 
 // A MethodSetCache records the method set of each type T for which
diff --git a/go/types/typeutil/methodsetcache14.go b/go/types/typeutil/methodsetcache14.go
new file mode 100644
index 0000000..83b5e76
--- /dev/null
+++ b/go/types/typeutil/methodsetcache14.go
@@ -0,0 +1,75 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !go1.5
+
+// This file implements a cache of method sets.
+
+package typeutil
+
+import (
+	"sync"
+
+	"golang.org/x/tools/go/types"
+)
+
+// A MethodSetCache records the method set of each type T for which
+// MethodSet(T) is called so that repeat queries are fast.
+// The zero value is a ready-to-use cache instance.
+type MethodSetCache struct {
+	mu     sync.Mutex
+	named  map[*types.Named]struct{ value, pointer *types.MethodSet } // method sets for named N and *N
+	others map[types.Type]*types.MethodSet                            // all other types
+}
+
+// MethodSet returns the method set of type T.  It is thread-safe.
+//
+// If cache is nil, this function is equivalent to types.NewMethodSet(T).
+// Utility functions can thus expose an optional *MethodSetCache
+// parameter to clients that care about performance.
+//
+func (cache *MethodSetCache) MethodSet(T types.Type) *types.MethodSet {
+	if cache == nil {
+		return types.NewMethodSet(T)
+	}
+	cache.mu.Lock()
+	defer cache.mu.Unlock()
+
+	switch T := T.(type) {
+	case *types.Named:
+		return cache.lookupNamed(T).value
+
+	case *types.Pointer:
+		if N, ok := T.Elem().(*types.Named); ok {
+			return cache.lookupNamed(N).pointer
+		}
+	}
+
+	// all other types
+	// (The map uses pointer equivalence, not type identity.)
+	mset := cache.others[T]
+	if mset == nil {
+		mset = types.NewMethodSet(T)
+		if cache.others == nil {
+			cache.others = make(map[types.Type]*types.MethodSet)
+		}
+		cache.others[T] = mset
+	}
+	return mset
+}
+
+func (cache *MethodSetCache) lookupNamed(named *types.Named) struct{ value, pointer *types.MethodSet } {
+	if cache.named == nil {
+		cache.named = make(map[*types.Named]struct{ value, pointer *types.MethodSet })
+	}
+	// Avoid recomputing mset(*T) for each distinct Pointer
+	// instance whose underlying type is a named type.
+	msets, ok := cache.named[named]
+	if !ok {
+		msets.value = types.NewMethodSet(named)
+		msets.pointer = types.NewMethodSet(types.NewPointer(named))
+		cache.named[named] = msets
+	}
+	return msets
+}
diff --git a/go/types/typeutil/ui.go b/go/types/typeutil/ui.go
index 20c5249..945fb29 100644
--- a/go/types/typeutil/ui.go
+++ b/go/types/typeutil/ui.go
@@ -2,11 +2,13 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// +build go1.5
+
 package typeutil
 
 // This file defines utilities for user interfaces that display types.
 
-import "golang.org/x/tools/go/types"
+import "go/types"
 
 // IntuitiveMethodSet returns the intuitive method set of a type, T.
 //
diff --git a/go/types/typeutil/ui14.go b/go/types/typeutil/ui14.go
new file mode 100644
index 0000000..bb78e0b
--- /dev/null
+++ b/go/types/typeutil/ui14.go
@@ -0,0 +1,40 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !go1.5
+
+package typeutil
+
+// This file defines utilities for user interfaces that display types.
+
+import "golang.org/x/tools/go/types"
+
+// IntuitiveMethodSet returns the intuitive method set of a type, T.
+//
+// The result contains MethodSet(T) and additionally, if T is a
+// concrete type, methods belonging to *T if there is no identically
+// named method on T itself.  This corresponds to user intuition about
+// method sets; this function is intended only for user interfaces.
+//
+// The order of the result is as for types.MethodSet(T).
+//
+func IntuitiveMethodSet(T types.Type, msets *MethodSetCache) []*types.Selection {
+	var result []*types.Selection
+	mset := msets.MethodSet(T)
+	if _, ok := T.Underlying().(*types.Interface); ok {
+		for i, n := 0, mset.Len(); i < n; i++ {
+			result = append(result, mset.At(i))
+		}
+	} else {
+		pmset := msets.MethodSet(types.NewPointer(T))
+		for i, n := 0, pmset.Len(); i < n; i++ {
+			meth := pmset.At(i)
+			if m := mset.Lookup(meth.Obj().Pkg(), meth.Obj().Name()); m != nil {
+				meth = m
+			}
+			result = append(result, meth)
+		}
+	}
+	return result
+}