implement IsNil() bool for those types that can be nil.  most of them, anyway.

R=rsc
DELTA=97  (96 added, 0 deleted, 1 changed)
OCL=28596
CL=28702
diff --git a/src/lib/reflect/all_test.go b/src/lib/reflect/all_test.go
index cc61bbb..65c6ea2 100644
--- a/src/lib/reflect/all_test.go
+++ b/src/lib/reflect/all_test.go
@@ -507,3 +507,65 @@
 	x1 := T2{T2inner{2, 3}, 17};
 	check2ndField(x1, uintptr(unsafe.Pointer(&x1.f)) - uintptr(unsafe.Pointer(&x1)), t);
 }
+
+type Nillable interface {
+	IsNil() bool
+}
+
+func Nil(a interface{}, t *testing.T) {
+	n := NewValue(a).(Nillable);
+	if !n.IsNil() {
+		t.Errorf("%v should be nil", a)
+	}
+}
+
+func NotNil(a interface{}, t *testing.T) {
+	n := NewValue(a).(Nillable);
+	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 := []string{"int", "float32", "struct { a int }"};
+	// These do implement IsNil
+	doNil := []string{"*int", "interface{}", "map[string]int", "func() bool", "chan int", "[]string"};
+	for i, ts := range doNotNil {
+		ty := reflect.ParseTypeString("", ts);
+		v := reflect.NewInitValue(ty);
+		if nilable, ok := v.(Nillable); ok {
+			t.Errorf("%s is nilable; should not be", ts)
+		}
+	}
+
+	for i, ts := range doNil {
+		ty := reflect.ParseTypeString("", ts);
+		v := reflect.NewInitValue(ty);
+		if nilable, ok := v.(Nillable); !ok {
+			t.Errorf("%s is not nilable; should be", ts)
+		}
+	}
+	// Check the implementations
+	var pi *int;
+	Nil(pi, t);
+	pi = new(int);
+	NotNil(pi, t);
+
+	var si []int;
+	Nil(si, t);
+	si = make([]int, 10);
+	NotNil(si, t);
+
+	// TODO: map and chan don't work yet
+
+	var ii interface {};
+	Nil(ii, t);
+	ii = pi;
+	NotNil(ii, t);
+
+	var fi func(t *testing.T);
+	Nil(fi, t);
+	fi = TestIsNil;
+	NotNil(fi, t);
+}