reflect: new Type and Value definitions

Type is now an interface that implements all the possible type methods.
Instead of a type switch on a reflect.Type t, switch on t.Kind().
If a method is invoked on the wrong kind of type (for example,
calling t.Field(0) when t.Kind() != Struct), the call panics.

There is one method renaming: t.(*ChanType).Dir() is now t.ChanDir().

Value is now a struct value that implements all the possible value methods.
Instead of a type switch on a reflect.Value v, switch on v.Kind().
If a method is invoked on the wrong kind of value (for example,
calling t.Recv() when t.Kind() != Chan), the call panics.

Since Value is now a struct, not an interface, its zero value
cannot be compared to nil.  Instead of v != nil, use v.IsValid().
Instead of other uses of nil as a Value, use Value{}, the zero value.

Many methods have been renamed, most due to signature conflicts:

           OLD                          NEW

    v.(*ArrayValue).Elem             v.Index
    v.(*BoolValue).Get               v.Bool
    v.(*BoolValue).Set               v.SetBool
    v.(*ChanType).Dir                v.ChanDir
    v.(*ChanValue).Get               v.Pointer
    v.(*ComplexValue).Get            v.Complex
    v.(*ComplexValue).Overflow       v.OverflowComplex
    v.(*ComplexValue).Set            v.SetComplex
    v.(*FloatValue).Get              v.Float
    v.(*FloatValue).Overflow         v.OverflowFloat
    v.(*FloatValue).Set              v.SetFloat
    v.(*FuncValue).Get               v.Pointer
    v.(*InterfaceValue).Get          v.InterfaceData
    v.(*IntValue).Get                v.Int
    v.(*IntValue).Overflow           v.OverflowInt
    v.(*IntValue).Set                v.SetInt
    v.(*MapValue).Elem               v.MapIndex
    v.(*MapValue).Get                v.Pointer
    v.(*MapValue).Keys               v.MapKeys
    v.(*MapValue).SetElem            v.SetMapIndex
    v.(*PtrValue).Get                v.Pointer
    v.(*SliceValue).Elem             v.Index
    v.(*SliceValue).Get              v.Pointer
    v.(*StringValue).Get             v.String
    v.(*StringValue).Set             v.SetString
    v.(*UintValue).Get               v.Uint
    v.(*UintValue).Overflow          v.OverflowUint
    v.(*UintValue).Set               v.SetUint
    v.(*UnsafePointerValue).Get      v.Pointer
    v.(*UnsafePointerValue).Set      v.SetPointer

Part of the motivation for this change is to enable a more
efficient implementation of Value, one that does not allocate
memory during most operations.  To reduce the size of the CL,
this CL's implementation is a wrapper around the old API.
Later CLs will make the implementation more efficient without
changing the API.

Other CLs to be submitted at the same time as this one
add support for this change to gofix (4343047) and update
the Go source tree (4353043).

R=gri, iant, niemeyer, r, rog, gustavo, r2
CC=golang-dev
https://golang.org/cl/4281055
diff --git a/src/pkg/reflect/all_test.go b/src/pkg/reflect/all_test.go
index f616ada..bc91576 100644
--- a/src/pkg/reflect/all_test.go
+++ b/src/pkg/reflect/all_test.go
@@ -207,58 +207,46 @@
 
 func TestTypes(t *testing.T) {
 	for i, tt := range typeTests {
-		testType(t, i, NewValue(tt.i).(*StructValue).Field(0).Type(), tt.s)
+		testType(t, i, NewValue(tt.i).Field(0).Type(), tt.s)
 	}
 }
 
 func TestSet(t *testing.T) {
 	for i, tt := range valueTests {
 		v := NewValue(tt.i)
-		switch v := v.(type) {
-		case *IntValue:
-			switch v.Type().Kind() {
-			case Int:
-				v.Set(132)
-			case Int8:
-				v.Set(8)
-			case Int16:
-				v.Set(16)
-			case Int32:
-				v.Set(32)
-			case Int64:
-				v.Set(64)
-			}
-		case *UintValue:
-			switch v.Type().Kind() {
-			case Uint:
-				v.Set(132)
-			case Uint8:
-				v.Set(8)
-			case Uint16:
-				v.Set(16)
-			case Uint32:
-				v.Set(32)
-			case Uint64:
-				v.Set(64)
-			}
-		case *FloatValue:
-			switch v.Type().Kind() {
-			case Float32:
-				v.Set(256.25)
-			case Float64:
-				v.Set(512.125)
-			}
-		case *ComplexValue:
-			switch v.Type().Kind() {
-			case Complex64:
-				v.Set(532.125 + 10i)
-			case Complex128:
-				v.Set(564.25 + 1i)
-			}
-		case *StringValue:
-			v.Set("stringy cheese")
-		case *BoolValue:
-			v.Set(true)
+		switch v.Kind() {
+		case Int:
+			v.SetInt(132)
+		case Int8:
+			v.SetInt(8)
+		case Int16:
+			v.SetInt(16)
+		case Int32:
+			v.SetInt(32)
+		case Int64:
+			v.SetInt(64)
+		case Uint:
+			v.SetUint(132)
+		case Uint8:
+			v.SetUint(8)
+		case Uint16:
+			v.SetUint(16)
+		case Uint32:
+			v.SetUint(32)
+		case Uint64:
+			v.SetUint(64)
+		case Float32:
+			v.SetFloat(256.25)
+		case Float64:
+			v.SetFloat(512.125)
+		case Complex64:
+			v.SetComplex(532.125 + 10i)
+		case Complex128:
+			v.SetComplex(564.25 + 1i)
+		case String:
+			v.SetString("stringy cheese")
+		case Bool:
+			v.SetBool(true)
 		}
 		s := valueToString(v)
 		if s != tt.s {
@@ -270,52 +258,39 @@
 func TestSetValue(t *testing.T) {
 	for i, tt := range valueTests {
 		v := NewValue(tt.i)
-		switch v := v.(type) {
-		case *IntValue:
-			switch v.Type().Kind() {
-			case Int:
-				v.SetValue(NewValue(int(132)))
-			case Int8:
-				v.SetValue(NewValue(int8(8)))
-			case Int16:
-				v.SetValue(NewValue(int16(16)))
-			case Int32:
-				v.SetValue(NewValue(int32(32)))
-			case Int64:
-				v.SetValue(NewValue(int64(64)))
-			}
-		case *UintValue:
-			switch v.Type().Kind() {
-			case Uint:
-				v.SetValue(NewValue(uint(132)))
-			case Uint8:
-				v.SetValue(NewValue(uint8(8)))
-			case Uint16:
-				v.SetValue(NewValue(uint16(16)))
-			case Uint32:
-				v.SetValue(NewValue(uint32(32)))
-			case Uint64:
-				v.SetValue(NewValue(uint64(64)))
-			}
-		case *FloatValue:
-			switch v.Type().Kind() {
-			case Float32:
-				v.SetValue(NewValue(float32(256.25)))
-			case Float64:
-				v.SetValue(NewValue(512.125))
-			}
-		case *ComplexValue:
-			switch v.Type().Kind() {
-			case Complex64:
-				v.SetValue(NewValue(complex64(532.125 + 10i)))
-			case Complex128:
-				v.SetValue(NewValue(complex128(564.25 + 1i)))
-			}
-
-		case *StringValue:
-			v.SetValue(NewValue("stringy cheese"))
-		case *BoolValue:
-			v.SetValue(NewValue(true))
+		switch v.Kind() {
+		case Int:
+			v.Set(NewValue(int(132)))
+		case Int8:
+			v.Set(NewValue(int8(8)))
+		case Int16:
+			v.Set(NewValue(int16(16)))
+		case Int32:
+			v.Set(NewValue(int32(32)))
+		case Int64:
+			v.Set(NewValue(int64(64)))
+		case Uint:
+			v.Set(NewValue(uint(132)))
+		case Uint8:
+			v.Set(NewValue(uint8(8)))
+		case Uint16:
+			v.Set(NewValue(uint16(16)))
+		case Uint32:
+			v.Set(NewValue(uint32(32)))
+		case Uint64:
+			v.Set(NewValue(uint64(64)))
+		case Float32:
+			v.Set(NewValue(float32(256.25)))
+		case Float64:
+			v.Set(NewValue(512.125))
+		case Complex64:
+			v.Set(NewValue(complex64(532.125 + 10i)))
+		case Complex128:
+			v.Set(NewValue(complex128(564.25 + 1i)))
+		case String:
+			v.Set(NewValue("stringy cheese"))
+		case Bool:
+			v.Set(NewValue(true))
 		}
 		s := valueToString(v)
 		if s != tt.s {
@@ -350,7 +325,7 @@
 
 func TestArrayElemSet(t *testing.T) {
 	v := NewValue([10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
-	v.(*ArrayValue).Elem(4).(*IntValue).Set(123)
+	v.Index(4).SetInt(123)
 	s := valueToString(v)
 	const want = "[10]int{1, 2, 3, 4, 123, 6, 7, 8, 9, 10}"
 	if s != want {
@@ -358,7 +333,7 @@
 	}
 
 	v = NewValue([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
-	v.(*SliceValue).Elem(4).(*IntValue).Set(123)
+	v.Index(4).SetInt(123)
 	s = valueToString(v)
 	const want1 = "[]int{1, 2, 3, 4, 123, 6, 7, 8, 9, 10}"
 	if s != want1 {
@@ -371,14 +346,14 @@
 	var i int32 = 1234
 	vip := NewValue(&ip)
 	vi := NewValue(i)
-	vip.(*PtrValue).Elem().(*PtrValue).PointTo(vi)
+	vip.Elem().Set(vi.Addr())
 	if *ip != 1234 {
 		t.Errorf("got %d, want 1234", *ip)
 	}
 
 	ip = nil
-	vp := NewValue(ip).(*PtrValue)
-	vp.PointTo(vp.Elem())
+	vp := NewValue(ip)
+	vp.Set(Zero(vp.Type()))
 	if ip != nil {
 		t.Errorf("got non-nil (%p), want nil", ip)
 	}
@@ -388,7 +363,7 @@
 	var i int32 = 1234
 	ip := &i
 	vip := NewValue(&ip)
-	vip.(*PtrValue).Elem().(*PtrValue).Set(nil)
+	vip.Elem().Set(Zero(vip.Elem().Type()))
 	if ip != nil {
 		t.Errorf("got non-nil (%d), want nil", *ip)
 	}
@@ -397,7 +372,7 @@
 func TestMapSetNil(t *testing.T) {
 	m := make(map[string]int)
 	vm := NewValue(&m)
-	vm.(*PtrValue).Elem().(*MapValue).Set(nil)
+	vm.Elem().Set(Zero(vm.Elem().Type()))
 	if m != nil {
 		t.Errorf("got non-nil (%p), want nil", m)
 	}
@@ -406,16 +381,16 @@
 
 func TestAll(t *testing.T) {
 	testType(t, 1, Typeof((int8)(0)), "int8")
-	testType(t, 2, Typeof((*int8)(nil)).(*PtrType).Elem(), "int8")
+	testType(t, 2, Typeof((*int8)(nil)).Elem(), "int8")
 
 	typ := Typeof((*struct {
 		c chan *int32
 		d float32
 	})(nil))
 	testType(t, 3, typ, "*struct { c chan *int32; d float32 }")
-	etyp := typ.(*PtrType).Elem()
+	etyp := typ.Elem()
 	testType(t, 4, etyp, "struct { c chan *int32; d float32 }")
-	styp := etyp.(*StructType)
+	styp := etyp
 	f := styp.Field(0)
 	testType(t, 5, f.Type, "chan *int32")
 
@@ -432,22 +407,22 @@
 
 	typ = Typeof([32]int32{})
 	testType(t, 7, typ, "[32]int32")
-	testType(t, 8, typ.(*ArrayType).Elem(), "int32")
+	testType(t, 8, typ.Elem(), "int32")
 
 	typ = Typeof((map[string]*int32)(nil))
 	testType(t, 9, typ, "map[string] *int32")
-	mtyp := typ.(*MapType)
+	mtyp := typ
 	testType(t, 10, mtyp.Key(), "string")
 	testType(t, 11, mtyp.Elem(), "*int32")
 
 	typ = Typeof((chan<- string)(nil))
 	testType(t, 12, typ, "chan<- string")
-	testType(t, 13, typ.(*ChanType).Elem(), "string")
+	testType(t, 13, typ.Elem(), "string")
 
 	// make sure tag strings are not part of element type
 	typ = Typeof(struct {
 		d []uint32 "TAG"
-	}{}).(*StructType).Field(0).Type
+	}{}).Field(0).Type
 	testType(t, 14, typ, "[]uint32")
 }
 
@@ -457,9 +432,9 @@
 	}
 	inter.e = 123.456
 	v1 := NewValue(&inter)
-	v2 := v1.(*PtrValue).Elem().(*StructValue).Field(0)
+	v2 := v1.Elem().Field(0)
 	assert(t, v2.Type().String(), "interface { }")
-	i2 := v2.(*InterfaceValue).Interface()
+	i2 := v2.Interface()
 	v3 := NewValue(i2)
 	assert(t, v3.Type().String(), "float64")
 }
@@ -470,9 +445,9 @@
 	}
 	inter.e = 123.456
 	v1 := NewValue(&inter)
-	v2 := v1.(*PtrValue).Elem().(*StructValue).Field(0)
+	v2 := v1.Elem().Field(0)
 	assert(t, v2.Type().String(), "interface { }")
-	v3 := v2.(*InterfaceValue).Elem()
+	v3 := v2.Elem()
 	assert(t, v3.Type().String(), "float64")
 
 	i3 := v2.Interface()
@@ -506,9 +481,9 @@
 			e0[j] = NewValue(e)
 		}
 		// Convert extra from []int to *SliceValue.
-		e1 := NewValue(test.extra).(*SliceValue)
+		e1 := NewValue(test.extra)
 		// Test Append.
-		a0 := NewValue(test.orig).(*SliceValue)
+		a0 := NewValue(test.orig)
 		have0 := Append(a0, e0...).Interface().([]int)
 		if !DeepEqual(have0, want) {
 			t.Errorf("Append #%d: have %v, want %v", i, have0, want)
@@ -521,7 +496,7 @@
 			t.Errorf("Append #%d extraLen: have %v, want %v", i, len(test.extra), extraLen)
 		}
 		// Test AppendSlice.
-		a1 := NewValue(test.orig).(*SliceValue)
+		a1 := NewValue(test.orig)
 		have1 := AppendSlice(a1, e1).Interface().([]int)
 		if !DeepEqual(have1, want) {
 			t.Errorf("AppendSlice #%d: have %v, want %v", i, have1, want)
@@ -545,8 +520,8 @@
 			t.Fatalf("b != c before test")
 		}
 	}
-	aa := NewValue(a).(*SliceValue)
-	ab := NewValue(b).(*SliceValue)
+	aa := NewValue(a)
+	ab := NewValue(b)
 	for tocopy := 1; tocopy <= 7; tocopy++ {
 		aa.SetLen(tocopy)
 		Copy(ab, aa)
@@ -660,7 +635,7 @@
 func TestTypeof(t *testing.T) {
 	for _, test := range deepEqualTests {
 		v := NewValue(test.a)
-		if v == nil {
+		if !v.IsValid() {
 			continue
 		}
 		typ := Typeof(test.a)
@@ -715,8 +690,8 @@
 
 
 func check2ndField(x interface{}, offs uintptr, t *testing.T) {
-	s := NewValue(x).(*StructValue)
-	f := s.Type().(*StructType).Field(1)
+	s := NewValue(x)
+	f := s.Type().Field(1)
 	if f.Offset != offs {
 		t.Error("mismatched offsets in structure alignment:", f.Offset, offs)
 	}
@@ -747,36 +722,22 @@
 	check2ndField(x1, uintptr(unsafe.Pointer(&x1.f))-uintptr(unsafe.Pointer(&x1)), t)
 }
 
-type IsNiller interface {
-	IsNil() bool
-}
-
 func Nil(a interface{}, t *testing.T) {
-	n := NewValue(a).(*StructValue).Field(0).(IsNiller)
+	n := NewValue(a).Field(0)
 	if !n.IsNil() {
 		t.Errorf("%v should be nil", a)
 	}
 }
 
 func NotNil(a interface{}, t *testing.T) {
-	n := NewValue(a).(*StructValue).Field(0).(IsNiller)
+	n := NewValue(a).Field(0)
 	if n.IsNil() {
 		t.Errorf("value of type %v should not be nil", NewValue(a).Type().String())
 	}
 }
 
 func TestIsNil(t *testing.T) {
-	// These do not implement IsNil
-	doNotNil := []interface{}{int(0), float32(0), struct{ a int }{}}
-	for _, ts := range doNotNil {
-		ty := Typeof(ts)
-		v := MakeZero(ty)
-		if _, ok := v.(IsNiller); ok {
-			t.Errorf("%s is nilable; should not be", ts)
-		}
-	}
-
-	// These do implement IsNil.
+	// These implement IsNil.
 	// Wrap in extra struct to hide interface type.
 	doNil := []interface{}{
 		struct{ x *int }{},
@@ -787,11 +748,9 @@
 		struct{ x []string }{},
 	}
 	for _, ts := range doNil {
-		ty := Typeof(ts).(*StructType).Field(0).Type
-		v := MakeZero(ty)
-		if _, ok := v.(IsNiller); !ok {
-			t.Errorf("%s %T is not nilable; should be", ts, v)
-		}
+		ty := Typeof(ts).Field(0).Type
+		v := Zero(ty)
+		v.IsNil() // panics if not okay to call
 	}
 
 	// Check the implementations
@@ -844,7 +803,7 @@
 	}
 
 	s.w = os.Stdout
-	v := Indirect(NewValue(&s)).(*StructValue).Field(0).Interface()
+	v := Indirect(NewValue(&s)).Field(0).Interface()
 	if v != s.w.(interface{}) {
 		t.Error("Interface() on interface: ", v, s.w)
 	}
@@ -864,7 +823,7 @@
 
 	// and setting that copy to "bye" should
 	// not change the value stored in i.
-	v.(*StringValue).Set("bye")
+	v.SetString("bye")
 	if i.(string) != "hello" {
 		t.Errorf(`Set("bye") changed i to %s`, i.(string))
 	}
@@ -872,7 +831,7 @@
 	// the same should be true of smaller items.
 	i = 123
 	v = NewValue(i)
-	v.(*IntValue).Set(234)
+	v.SetInt(234)
 	if i.(int) != 123 {
 		t.Errorf("Set(234) changed i to %d", i.(int))
 	}
@@ -880,20 +839,20 @@
 
 func TestNilPtrValueSub(t *testing.T) {
 	var pi *int
-	if pv := NewValue(pi).(*PtrValue); pv.Elem() != nil {
-		t.Error("NewValue((*int)(nil)).(*PtrValue).Elem() != nil")
+	if pv := NewValue(pi); pv.Elem().IsValid() {
+		t.Error("NewValue((*int)(nil)).Elem().IsValid()")
 	}
 }
 
 func TestMap(t *testing.T) {
 	m := map[string]int{"a": 1, "b": 2}
-	mv := NewValue(m).(*MapValue)
+	mv := NewValue(m)
 	if n := mv.Len(); n != len(m) {
 		t.Errorf("Len = %d, want %d", n, len(m))
 	}
-	keys := mv.Keys()
+	keys := mv.MapKeys()
 	i := 0
-	newmap := MakeMap(mv.Type().(*MapType))
+	newmap := MakeMap(mv.Type())
 	for k, v := range m {
 		// Check that returned Keys match keys in range.
 		// These aren't required to be in the same order,
@@ -901,22 +860,22 @@
 		// the test easier.
 		if i >= len(keys) {
 			t.Errorf("Missing key #%d %q", i, k)
-		} else if kv := keys[i].(*StringValue); kv.Get() != k {
-			t.Errorf("Keys[%d] = %q, want %q", i, kv.Get(), k)
+		} else if kv := keys[i]; kv.String() != k {
+			t.Errorf("Keys[%q] = %d, want %d", i, kv.Int(), k)
 		}
 		i++
 
 		// Check that value lookup is correct.
-		vv := mv.Elem(NewValue(k))
-		if vi := vv.(*IntValue).Get(); vi != int64(v) {
+		vv := mv.MapIndex(NewValue(k))
+		if vi := vv.Int(); vi != int64(v) {
 			t.Errorf("Key %q: have value %d, want %d", k, vi, v)
 		}
 
 		// Copy into new map.
-		newmap.SetElem(NewValue(k), NewValue(v))
+		newmap.SetMapIndex(NewValue(k), NewValue(v))
 	}
-	vv := mv.Elem(NewValue("not-present"))
-	if vv != nil {
+	vv := mv.MapIndex(NewValue("not-present"))
+	if vv.IsValid() {
 		t.Errorf("Invalid key: got non-nil value %s", valueToString(vv))
 	}
 
@@ -932,14 +891,14 @@
 		}
 	}
 
-	newmap.SetElem(NewValue("a"), nil)
+	newmap.SetMapIndex(NewValue("a"), Value{})
 	v, ok := newm["a"]
 	if ok {
 		t.Errorf("newm[\"a\"] = %d after delete", v)
 	}
 
-	mv = NewValue(&m).(*PtrValue).Elem().(*MapValue)
-	mv.Set(nil)
+	mv = NewValue(&m).Elem()
+	mv.Set(Zero(mv.Type()))
 	if m != nil {
 		t.Errorf("mv.Set(nil) failed")
 	}
@@ -948,15 +907,15 @@
 func TestChan(t *testing.T) {
 	for loop := 0; loop < 2; loop++ {
 		var c chan int
-		var cv *ChanValue
+		var cv Value
 
 		// check both ways to allocate channels
 		switch loop {
 		case 1:
 			c = make(chan int, 1)
-			cv = NewValue(c).(*ChanValue)
+			cv = NewValue(c)
 		case 0:
-			cv = MakeChan(Typeof(c).(*ChanType), 1)
+			cv = MakeChan(Typeof(c), 1)
 			c = cv.Interface().(chan int)
 		}
 
@@ -968,22 +927,22 @@
 
 		// Recv
 		c <- 3
-		if i, ok := cv.Recv(); i.(*IntValue).Get() != 3 || !ok {
-			t.Errorf("native send 3, reflect Recv %d, %t", i.(*IntValue).Get(), ok)
+		if i, ok := cv.Recv(); i.Int() != 3 || !ok {
+			t.Errorf("native send 3, reflect Recv %d, %t", i.Int(), ok)
 		}
 
 		// TryRecv fail
 		val, ok := cv.TryRecv()
-		if val != nil || ok {
+		if val.IsValid() || ok {
 			t.Errorf("TryRecv on empty chan: %s, %t", valueToString(val), ok)
 		}
 
 		// TryRecv success
 		c <- 4
 		val, ok = cv.TryRecv()
-		if val == nil {
+		if !val.IsValid() {
 			t.Errorf("TryRecv on ready chan got nil")
-		} else if i := val.(*IntValue).Get(); i != 4 || !ok {
+		} else if i := val.Int(); i != 4 || !ok {
 			t.Errorf("native send 4, TryRecv %d, %t", i, ok)
 		}
 
@@ -1008,27 +967,27 @@
 		// Close
 		c <- 123
 		cv.Close()
-		if i, ok := cv.Recv(); i.(*IntValue).Get() != 123 || !ok {
-			t.Errorf("send 123 then close; Recv %d, %t", i.(*IntValue).Get(), ok)
+		if i, ok := cv.Recv(); i.Int() != 123 || !ok {
+			t.Errorf("send 123 then close; Recv %d, %t", i.Int(), ok)
 		}
-		if i, ok := cv.Recv(); i.(*IntValue).Get() != 0 || ok {
-			t.Errorf("after close Recv %d, %t", i.(*IntValue).Get(), ok)
+		if i, ok := cv.Recv(); i.Int() != 0 || ok {
+			t.Errorf("after close Recv %d, %t", i.Int(), ok)
 		}
 	}
 
 	// check creation of unbuffered channel
 	var c chan int
-	cv := MakeChan(Typeof(c).(*ChanType), 0)
+	cv := MakeChan(Typeof(c), 0)
 	c = cv.Interface().(chan int)
 	if cv.TrySend(NewValue(7)) {
 		t.Errorf("TrySend on sync chan succeeded")
 	}
-	if v, ok := cv.TryRecv(); v != nil || ok {
+	if v, ok := cv.TryRecv(); v.IsValid() || ok {
 		t.Errorf("TryRecv on sync chan succeeded")
 	}
 
 	// len/cap
-	cv = MakeChan(Typeof(c).(*ChanType), 10)
+	cv = MakeChan(Typeof(c), 10)
 	c = cv.Interface().(chan int)
 	for i := 0; i < 3; i++ {
 		c <- i
@@ -1046,14 +1005,14 @@
 }
 
 func TestFunc(t *testing.T) {
-	ret := NewValue(dummy).(*FuncValue).Call([]Value{NewValue(byte(10)), NewValue(20), NewValue(byte(30))})
+	ret := NewValue(dummy).Call([]Value{NewValue(byte(10)), NewValue(20), NewValue(byte(30))})
 	if len(ret) != 3 {
 		t.Fatalf("Call returned %d values, want 3", len(ret))
 	}
 
-	i := ret[0].(*UintValue).Get()
-	j := ret[1].(*IntValue).Get()
-	k := ret[2].(*UintValue).Get()
+	i := byte(ret[0].Uint())
+	j := int(ret[1].Int())
+	k := byte(ret[2].Uint())
 	if i != 10 || j != 20 || k != 30 {
 		t.Errorf("Call returned %d, %d, %d; want 10, 20, 30", i, j, k)
 	}
@@ -1068,30 +1027,30 @@
 func TestMethod(t *testing.T) {
 	// Non-curried method of type.
 	p := Point{3, 4}
-	i := Typeof(p).Method(0).Func.Call([]Value{NewValue(p), NewValue(10)})[0].(*IntValue).Get()
+	i := Typeof(p).Method(0).Func.Call([]Value{NewValue(p), NewValue(10)})[0].Int()
 	if i != 250 {
 		t.Errorf("Type Method returned %d; want 250", i)
 	}
 
-	i = Typeof(&p).Method(0).Func.Call([]Value{NewValue(&p), NewValue(10)})[0].(*IntValue).Get()
+	i = Typeof(&p).Method(0).Func.Call([]Value{NewValue(&p), NewValue(10)})[0].Int()
 	if i != 250 {
 		t.Errorf("Pointer Type Method returned %d; want 250", i)
 	}
 
 	// Curried method of value.
-	i = NewValue(p).Method(0).Call([]Value{NewValue(10)})[0].(*IntValue).Get()
+	i = NewValue(p).Method(0).Call([]Value{NewValue(10)})[0].Int()
 	if i != 250 {
 		t.Errorf("Value Method returned %d; want 250", i)
 	}
 
 	// Curried method of pointer.
-	i = NewValue(&p).Method(0).Call([]Value{NewValue(10)})[0].(*IntValue).Get()
+	i = NewValue(&p).Method(0).Call([]Value{NewValue(10)})[0].Int()
 	if i != 250 {
 		t.Errorf("Value Method returned %d; want 250", i)
 	}
 
 	// Curried method of pointer to value.
-	i = NewValue(p).Addr().Method(0).Call([]Value{NewValue(10)})[0].(*IntValue).Get()
+	i = NewValue(p).Addr().Method(0).Call([]Value{NewValue(10)})[0].Int()
 	if i != 250 {
 		t.Errorf("Value Method returned %d; want 250", i)
 	}
@@ -1105,8 +1064,8 @@
 			Dist(int) int
 		}
 	}{p}
-	pv := NewValue(s).(*StructValue).Field(0)
-	i = pv.Method(0).Call([]Value{NewValue(10)})[0].(*IntValue).Get()
+	pv := NewValue(s).Field(0)
+	i = pv.Method(0).Call([]Value{NewValue(10)})[0].Int()
 	if i != 250 {
 		t.Errorf("Interface Method returned %d; want 250", i)
 	}
@@ -1121,19 +1080,19 @@
 			Dist(int) int
 		}
 	}
-	sv := NewValue(&s).(*PtrValue).Elem().(*StructValue)
-	sv.Field(0).(*InterfaceValue).Set(NewValue(p))
+	sv := NewValue(&s).Elem()
+	sv.Field(0).Set(NewValue(p))
 	if q := s.I.(*Point); q != p {
 		t.Errorf("i: have %p want %p", q, p)
 	}
 
-	pv := sv.Field(1).(*InterfaceValue)
+	pv := sv.Field(1)
 	pv.Set(NewValue(p))
 	if q := s.P.(*Point); q != p {
 		t.Errorf("i: have %p want %p", q, p)
 	}
 
-	i := pv.Method(0).Call([]Value{NewValue(10)})[0].(*IntValue).Get()
+	i := pv.Method(0).Call([]Value{NewValue(10)})[0].Int()
 	if i != 250 {
 		t.Errorf("Interface Method returned %d; want 250", i)
 	}
@@ -1148,7 +1107,7 @@
 	var field StructField
 	var ok bool
 	var t1 T1
-	type1 := Typeof(t1).(*StructType)
+	type1 := Typeof(t1)
 	if field, ok = type1.FieldByName("int"); !ok {
 		t.Error("no field 'int'")
 	}
@@ -1232,7 +1191,7 @@
 
 func TestFieldByIndex(t *testing.T) {
 	for _, test := range fieldTests {
-		s := Typeof(test.s).(*StructType)
+		s := Typeof(test.s)
 		f := s.FieldByIndex(test.index)
 		if f.Name != "" {
 			if test.index != nil {
@@ -1247,8 +1206,8 @@
 		}
 
 		if test.value != 0 {
-			v := NewValue(test.s).(*StructValue).FieldByIndex(test.index)
-			if v != nil {
+			v := NewValue(test.s).FieldByIndex(test.index)
+			if v.IsValid() {
 				if x, ok := v.Interface().(int); ok {
 					if x != test.value {
 						t.Errorf("%s%v is %d; want %d", s.Name(), test.index, x, test.value)
@@ -1265,7 +1224,7 @@
 
 func TestFieldByName(t *testing.T) {
 	for _, test := range fieldTests {
-		s := Typeof(test.s).(*StructType)
+		s := Typeof(test.s)
 		f, found := s.FieldByName(test.name)
 		if found {
 			if test.index != nil {
@@ -1287,8 +1246,8 @@
 		}
 
 		if test.value != 0 {
-			v := NewValue(test.s).(*StructValue).FieldByName(test.name)
-			if v != nil {
+			v := NewValue(test.s).FieldByName(test.name)
+			if v.IsValid() {
 				if x, ok := v.Interface().(int); ok {
 					if x != test.value {
 						t.Errorf("%s.%s is %d; want %d", s.Name(), test.name, x, test.value)
@@ -1312,10 +1271,10 @@
 func TestDotDotDot(t *testing.T) {
 	// Test example from FuncType.DotDotDot documentation.
 	var f func(x int, y ...float64)
-	typ := Typeof(f).(*FuncType)
+	typ := Typeof(f)
 	if typ.NumIn() == 2 && typ.In(0) == Typeof(int(0)) {
-		sl, ok := typ.In(1).(*SliceType)
-		if ok {
+		sl := typ.In(1)
+		if sl.Kind() == Slice {
 			if sl.Elem() == Typeof(0.0) {
 				// ok
 				return
@@ -1346,11 +1305,11 @@
 
 func TestNestedMethods(t *testing.T) {
 	typ := Typeof((*outer)(nil))
-	if typ.NumMethod() != 1 || typ.Method(0).Func.Get() != NewValue((*outer).m).(*FuncValue).Get() {
+	if typ.NumMethod() != 1 || typ.Method(0).Func.Pointer() != NewValue((*outer).m).Pointer() {
 		t.Errorf("Wrong method table for outer: (m=%p)", (*outer).m)
 		for i := 0; i < typ.NumMethod(); i++ {
 			m := typ.Method(i)
-			t.Errorf("\t%d: %s %#x\n", i, m.Name, m.Func.Get())
+			t.Errorf("\t%d: %s %#x\n", i, m.Name, m.Func.Pointer())
 		}
 	}
 }
@@ -1370,21 +1329,21 @@
 
 func TestEmbeddedMethods(t *testing.T) {
 	typ := Typeof((*outerInt)(nil))
-	if typ.NumMethod() != 1 || typ.Method(0).Func.Get() != NewValue((*outerInt).m).(*FuncValue).Get() {
+	if typ.NumMethod() != 1 || typ.Method(0).Func.Pointer() != NewValue((*outerInt).m).Pointer() {
 		t.Errorf("Wrong method table for outerInt: (m=%p)", (*outerInt).m)
 		for i := 0; i < typ.NumMethod(); i++ {
 			m := typ.Method(i)
-			t.Errorf("\t%d: %s %#x\n", i, m.Name, m.Func.Get())
+			t.Errorf("\t%d: %s %#x\n", i, m.Name, m.Func.Pointer())
 		}
 	}
 
 	i := &innerInt{3}
-	if v := NewValue(i).Method(0).Call(nil)[0].(*IntValue).Get(); v != 3 {
+	if v := NewValue(i).Method(0).Call(nil)[0].Int(); v != 3 {
 		t.Errorf("i.m() = %d, want 3", v)
 	}
 
 	o := &outerInt{1, innerInt{2}}
-	if v := NewValue(o).Method(0).Call(nil)[0].(*IntValue).Get(); v != 2 {
+	if v := NewValue(o).Method(0).Call(nil)[0].Int(); v != 2 {
 		t.Errorf("i.m() = %d, want 2", v)
 	}
 
@@ -1402,7 +1361,7 @@
 		typ = PtrTo(typ)
 	}
 	for i = 0; i < 100; i++ {
-		typ = typ.(*PtrType).Elem()
+		typ = typ.Elem()
 	}
 	if typ != Typeof(i) {
 		t.Errorf("after 100 PtrTo and Elem, have %s, want %s", typ, Typeof(i))
@@ -1415,11 +1374,11 @@
 	}
 
 	v := NewValue(&p)
-	v = v.(*PtrValue).Elem()
+	v = v.Elem()
 	v = v.Addr()
-	v = v.(*PtrValue).Elem()
-	v = v.(*StructValue).Field(0)
-	v.(*IntValue).Set(2)
+	v = v.Elem()
+	v = v.Field(0)
+	v.SetInt(2)
 	if p.X != 2 {
 		t.Errorf("Addr.Elem.Set failed to set value")
 	}
@@ -1428,12 +1387,12 @@
 	// Exercises generation of PtrTypes not present in the binary.
 	v = NewValue(&p)
 	v = v.Addr()
-	v = v.(*PtrValue).Elem()
-	v = v.(*PtrValue).Elem()
+	v = v.Elem()
+	v = v.Elem()
 	v = v.Addr()
-	v = v.(*PtrValue).Elem()
-	v = v.(*StructValue).Field(0)
-	v.(*IntValue).Set(3)
+	v = v.Elem()
+	v = v.Field(0)
+	v.SetInt(3)
 	if p.X != 3 {
 		t.Errorf("Addr.Elem.Set failed to set value")
 	}
@@ -1443,9 +1402,9 @@
 	v = NewValue(p)
 	v0 := v
 	v = v.Addr()
-	v = v.(*PtrValue).Elem()
-	v = v.(*StructValue).Field(0)
-	v.(*IntValue).Set(4)
+	v = v.Elem()
+	v = v.Field(0)
+	v.SetInt(4)
 	if p.X != 3 { // should be unchanged from last time
 		t.Errorf("somehow value Set changed original p")
 	}