Bump minimum version to Go1.8

Go1.8 went GA on AppEngine.
The lack of Go1.8 support was the primary reason for much
of these backwards compatibility hacks.

Bumping to Go1.8 still ensures that we're supporting at least
the latest 2 versions of Go, which are Go1.8 and Go1.9.
diff --git a/.travis.yml b/.travis.yml
index 9d9b7f9..0df64f8 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,7 +5,7 @@
   - master
 matrix:
   include:
-    - go: 1.6.x
+    - go: 1.8.x
       script: go test -v -race ./...
   allow_failures:
     - go: master
diff --git a/cmp/cmpopts/sort.go b/cmp/cmpopts/sort.go
index a566d24..d2e97dc 100644
--- a/cmp/cmpopts/sort.go
+++ b/cmp/cmpopts/sort.go
@@ -7,6 +7,7 @@
 import (
 	"fmt"
 	"reflect"
+	"sort"
 
 	"github.com/google/go-cmp/cmp"
 	"github.com/google/go-cmp/cmp/internal/function"
@@ -48,8 +49,8 @@
 	}
 	// Check whether the slices are already sorted to avoid an infinite
 	// recursion cycle applying the same transform to itself.
-	ok1 := sliceIsSorted(x, func(i, j int) bool { return ss.less(vx, i, j) })
-	ok2 := sliceIsSorted(y, func(i, j int) bool { return ss.less(vy, i, j) })
+	ok1 := sort.SliceIsSorted(x, func(i, j int) bool { return ss.less(vx, i, j) })
+	ok2 := sort.SliceIsSorted(y, func(i, j int) bool { return ss.less(vy, i, j) })
 	return !ok1 || !ok2
 }
 func (ss sliceSorter) sort(x interface{}) interface{} {
@@ -58,7 +59,7 @@
 	for i := 0; i < src.Len(); i++ {
 		dst.Index(i).Set(src.Index(i))
 	}
-	sortSliceStable(dst.Interface(), func(i, j int) bool { return ss.less(dst, i, j) })
+	sort.SliceStable(dst.Interface(), func(i, j int) bool { return ss.less(dst, i, j) })
 	ss.checkSort(dst)
 	return dst.Interface()
 }
@@ -118,7 +119,10 @@
 }
 func (ms mapSorter) sort(x interface{}) interface{} {
 	src := reflect.ValueOf(x)
-	outType := mapEntryType(src.Type())
+	outType := reflect.StructOf([]reflect.StructField{
+		{Name: "K", Type: src.Type().Key()},
+		{Name: "V", Type: src.Type().Elem()},
+	})
 	dst := reflect.MakeSlice(reflect.SliceOf(outType), src.Len(), src.Len())
 	for i, k := range src.MapKeys() {
 		v := reflect.New(outType).Elem()
@@ -126,7 +130,7 @@
 		v.Field(1).Set(src.MapIndex(k))
 		dst.Index(i).Set(v)
 	}
-	sortSlice(dst.Interface(), func(i, j int) bool { return ms.less(dst, i, j) })
+	sort.Slice(dst.Interface(), func(i, j int) bool { return ms.less(dst, i, j) })
 	ms.checkSort(dst)
 	return dst.Interface()
 }
@@ -139,8 +143,5 @@
 }
 func (ms mapSorter) less(v reflect.Value, i, j int) bool {
 	vx, vy := v.Index(i).Field(0), v.Index(j).Field(0)
-	if !hasReflectStructOf {
-		vx, vy = vx.Elem(), vy.Elem()
-	}
 	return ms.fnc.Call([]reflect.Value{vx, vy})[0].Bool()
 }
diff --git a/cmp/cmpopts/sort_go17.go b/cmp/cmpopts/sort_go17.go
deleted file mode 100644
index 839b88c..0000000
--- a/cmp/cmpopts/sort_go17.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2017, 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.md file.
-
-// +build !go1.8
-
-package cmpopts
-
-import (
-	"reflect"
-	"sort"
-)
-
-const hasReflectStructOf = false
-
-func mapEntryType(reflect.Type) reflect.Type {
-	return reflect.TypeOf(struct{ K, V interface{} }{})
-}
-
-func sliceIsSorted(slice interface{}, less func(i, j int) bool) bool {
-	return sort.IsSorted(reflectSliceSorter{reflect.ValueOf(slice), less})
-}
-func sortSlice(slice interface{}, less func(i, j int) bool) {
-	sort.Sort(reflectSliceSorter{reflect.ValueOf(slice), less})
-}
-func sortSliceStable(slice interface{}, less func(i, j int) bool) {
-	sort.Stable(reflectSliceSorter{reflect.ValueOf(slice), less})
-}
-
-type reflectSliceSorter struct {
-	slice reflect.Value
-	less  func(i, j int) bool
-}
-
-func (ss reflectSliceSorter) Len() int {
-	return ss.slice.Len()
-}
-func (ss reflectSliceSorter) Less(i, j int) bool {
-	return ss.less(i, j)
-}
-func (ss reflectSliceSorter) Swap(i, j int) {
-	vi := ss.slice.Index(i).Interface()
-	vj := ss.slice.Index(j).Interface()
-	ss.slice.Index(i).Set(reflect.ValueOf(vj))
-	ss.slice.Index(j).Set(reflect.ValueOf(vi))
-}
diff --git a/cmp/cmpopts/sort_go18.go b/cmp/cmpopts/sort_go18.go
deleted file mode 100644
index 8a59c0d..0000000
--- a/cmp/cmpopts/sort_go18.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2017, 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.md file.
-
-// +build go1.8
-
-package cmpopts
-
-import (
-	"reflect"
-	"sort"
-)
-
-const hasReflectStructOf = true
-
-func mapEntryType(t reflect.Type) reflect.Type {
-	return reflect.StructOf([]reflect.StructField{
-		{Name: "K", Type: t.Key()},
-		{Name: "V", Type: t.Elem()},
-	})
-}
-
-func sliceIsSorted(slice interface{}, less func(i, j int) bool) bool {
-	return sort.SliceIsSorted(slice, less)
-}
-func sortSlice(slice interface{}, less func(i, j int) bool) {
-	sort.Slice(slice, less)
-}
-func sortSliceStable(slice interface{}, less func(i, j int) bool) {
-	sort.SliceStable(slice, less)
-}
diff --git a/cmp/cmpopts/util_test.go b/cmp/cmpopts/util_test.go
index f532789..1140941 100644
--- a/cmp/cmpopts/util_test.go
+++ b/cmp/cmpopts/util_test.go
@@ -719,7 +719,7 @@
 	}}
 
 	for _, tt := range tests {
-		tRun(t, tt.label, func(t *testing.T) {
+		t.Run(tt.label, func(t *testing.T) {
 			var gotEqual bool
 			var gotPanic string
 			func() {
@@ -939,7 +939,7 @@
 	}}
 
 	for _, tt := range tests {
-		tRun(t, tt.label, func(t *testing.T) {
+		t.Run(tt.label, func(t *testing.T) {
 			// Prepare function arguments.
 			vf := reflect.ValueOf(tt.fnc)
 			var vargs []reflect.Value
@@ -980,17 +980,3 @@
 		})
 	}
 }
-
-// TODO: Delete this hack when we drop Go1.6 support.
-func tRun(t *testing.T, name string, f func(t *testing.T)) {
-	type runner interface {
-		Run(string, func(t *testing.T)) bool
-	}
-	var ti interface{} = t
-	if r, ok := ti.(runner); ok {
-		r.Run(name, f)
-	} else {
-		t.Logf("Test: %s", name)
-		f(t)
-	}
-}
diff --git a/cmp/compare_test.go b/cmp/compare_test.go
index 6a69ad3..f596788 100644
--- a/cmp/compare_test.go
+++ b/cmp/compare_test.go
@@ -51,7 +51,8 @@
 
 	for _, tt := range tests {
 		tt := tt
-		tRunParallel(t, tt.label, func(t *testing.T) {
+		t.Run(tt.label, func(t *testing.T) {
+			t.Parallel()
 			var gotDiff, gotPanic string
 			func() {
 				defer func() {
@@ -1928,21 +1929,3 @@
 	+: <non-existent>`,
 	}}
 }
-
-// TODO: Delete this hack when we drop Go1.6 support.
-func tRunParallel(t *testing.T, name string, f func(t *testing.T)) {
-	type runner interface {
-		Run(string, func(t *testing.T)) bool
-	}
-	var ti interface{} = t
-	if r, ok := ti.(runner); ok {
-		r.Run(name, func(t *testing.T) {
-			t.Parallel()
-			f(t)
-		})
-	} else {
-		// Cannot run sub-tests in parallel in Go1.6.
-		t.Logf("Test: %s", name)
-		f(t)
-	}
-}
diff --git a/cmp/internal/diff/diff_test.go b/cmp/internal/diff/diff_test.go
index 6399509..0752f4a 100644
--- a/cmp/internal/diff/diff_test.go
+++ b/cmp/internal/diff/diff_test.go
@@ -242,7 +242,7 @@
 	}}
 
 	for _, tt := range tests {
-		tRun(t, "", func(t *testing.T) {
+		t.Run("", func(t *testing.T) {
 			x := strings.Replace(tt.x, " ", "", -1)
 			y := strings.Replace(tt.y, " ", "", -1)
 			es := testStrings(t, x, y)
@@ -273,10 +273,10 @@
 	}
 
 	for i, tt := range tests {
-		tRun(t, fmt.Sprintf("P%d", i), func(t *testing.T) {
+		t.Run(fmt.Sprintf("P%d", i), func(t *testing.T) {
 			// Sweep from 1B to 1KiB.
 			for n := 1; n <= 1024; n <<= 1 {
-				tRun(t, fmt.Sprintf("N%d", n), func(t *testing.T) {
+				t.Run(fmt.Sprintf("N%d", n), func(t *testing.T) {
 					for j := 0; j < 10; j++ {
 						x, y := generateStrings(n, tt.px, tt.py, tt.pm, int64(j))
 						testStrings(t, x, y)
@@ -287,23 +287,20 @@
 	}
 }
 
-func benchmarkDifference(b *testing.B, n int) {
-	// TODO: Use testing.B.Run when we drop Go1.6 support.
-	x, y := generateStrings(n, 0.05, 0.05, 0.10, 0)
-	b.ReportAllocs()
-	b.SetBytes(int64(len(x) + len(y)))
-	for i := 0; i < b.N; i++ {
-		Difference(len(x), len(y), func(ix, iy int) Result {
-			return compareByte(x[ix], y[iy])
+func BenchmarkDifference(b *testing.B) {
+	for n := 1 << 10; n <= 1<<20; n <<= 2 {
+		b.Run(fmt.Sprintf("N%d", n), func(b *testing.B) {
+			x, y := generateStrings(n, 0.05, 0.05, 0.10, 0)
+			b.ReportAllocs()
+			b.SetBytes(int64(len(x) + len(y)))
+			for i := 0; i < b.N; i++ {
+				Difference(len(x), len(y), func(ix, iy int) Result {
+					return compareByte(x[ix], y[iy])
+				})
+			}
 		})
 	}
 }
-func BenchmarkDifference1K(b *testing.B)   { benchmarkDifference(b, 1<<10) }
-func BenchmarkDifference4K(b *testing.B)   { benchmarkDifference(b, 1<<12) }
-func BenchmarkDifference16K(b *testing.B)  { benchmarkDifference(b, 1<<14) }
-func BenchmarkDifference64K(b *testing.B)  { benchmarkDifference(b, 1<<16) }
-func BenchmarkDifference256K(b *testing.B) { benchmarkDifference(b, 1<<18) }
-func BenchmarkDifference1M(b *testing.B)   { benchmarkDifference(b, 1<<20) }
 
 func generateStrings(n int, px, py, pm float32, seed int64) (string, string) {
 	if px+py+pm > 1.0 {
@@ -445,17 +442,3 @@
 		}
 	}
 }
-
-// TODO: Delete this hack when we drop Go1.6 support.
-func tRun(t *testing.T, name string, f func(t *testing.T)) {
-	type runner interface {
-		Run(string, func(t *testing.T)) bool
-	}
-	var ti interface{} = t
-	if r, ok := ti.(runner); ok {
-		r.Run(name, f)
-	} else {
-		t.Logf("Test: %s", name)
-		f(t)
-	}
-}
diff --git a/cmp/internal/value/sort.go b/cmp/internal/value/sort.go
index fe8aa27..938f646 100644
--- a/cmp/internal/value/sort.go
+++ b/cmp/internal/value/sort.go
@@ -19,7 +19,7 @@
 	}
 
 	// Sort the map keys.
-	sort.Sort(valueSorter(vs))
+	sort.Slice(vs, func(i, j int) bool { return isLess(vs[i], vs[j]) })
 
 	// Deduplicate keys (fails for NaNs).
 	vs2 := vs[:1]
@@ -31,13 +31,6 @@
 	return vs2
 }
 
-// TODO: Use sort.Slice once Google AppEngine is on Go1.8 or above.
-type valueSorter []reflect.Value
-
-func (vs valueSorter) Len() int           { return len(vs) }
-func (vs valueSorter) Less(i, j int) bool { return isLess(vs[i], vs[j]) }
-func (vs valueSorter) Swap(i, j int)      { vs[i], vs[j] = vs[j], vs[i] }
-
 // isLess is a generic function for sorting arbitrary map keys.
 // The inputs must be of the same type and must be comparable.
 func isLess(x, y reflect.Value) bool {
diff --git a/cmp/options_test.go b/cmp/options_test.go
index 009b524..7d1af1c 100644
--- a/cmp/options_test.go
+++ b/cmp/options_test.go
@@ -185,7 +185,7 @@
 	}}
 
 	for _, tt := range tests {
-		tRun(t, tt.label, func(t *testing.T) {
+		t.Run(tt.label, func(t *testing.T) {
 			var gotPanic string
 			func() {
 				defer func() {
@@ -215,17 +215,3 @@
 		})
 	}
 }
-
-// TODO: Delete this hack when we drop Go1.6 support.
-func tRun(t *testing.T, name string, f func(t *testing.T)) {
-	type runner interface {
-		Run(string, func(t *testing.T)) bool
-	}
-	var ti interface{} = t
-	if r, ok := ti.(runner); ok {
-		r.Run(name, f)
-	} else {
-		t.Logf("Test: %s", name)
-		f(t)
-	}
-}