reflect: allow Slice of arrays

R=r
CC=golang-dev
https://golang.org/cl/4444049
diff --git a/src/pkg/reflect/value.go b/src/pkg/reflect/value.go
index b31aa5a..44aaebd 100644
--- a/src/pkg/reflect/value.go
+++ b/src/pkg/reflect/value.go
@@ -1244,20 +1244,32 @@
 	*(*string)(iv.addr) = x
 }
 
-// BUG(rsc): Value.Slice should allow slicing arrays.
-
 // Slice returns a slice of v.
-// It panics if v's Kind is not Slice.
+// It panics if v's Kind is not Array or Slice.
 func (v Value) Slice(beg, end int) Value {
 	iv := v.internal()
-	iv.mustBe(Slice)
+	if iv.kind != Array && iv.kind != Slice {
+		panic(&ValueError{"reflect.Value.Slice", iv.kind})
+	}
 	cap := v.Cap()
 	if beg < 0 || end < beg || end > cap {
 		panic("reflect.Value.Slice: slice index out of bounds")
 	}
-	typ := iv.typ.toType()
+	var typ Type
+	var base uintptr
+	switch iv.kind {
+	case Array:
+		if iv.flag&flagAddr == 0 {
+			panic("reflect.Value.Slice: slice of unaddressable array")
+		}
+		typ = toType((*arrayType)(unsafe.Pointer(iv.typ)).slice)
+		base = uintptr(iv.addr)
+	case Slice:
+		typ = iv.typ.toType()
+		base = (*SliceHeader)(iv.addr).Data
+	}
 	s := new(SliceHeader)
-	s.Data = uintptr((*SliceHeader)(iv.addr).Data) + uintptr(beg)*typ.Elem().Size()
+	s.Data = base + uintptr(beg)*typ.Elem().Size()
 	s.Len = end - beg
 	s.Cap = cap - beg
 	return valueFromAddr(iv.flag&flagRO, typ, unsafe.Pointer(s))