test: new nil semantics

R=gri
CC=golang-dev
https://golang.org/cl/4644052
diff --git a/test/nil.go b/test/nil.go
index 4f4c755..30cc270 100644
--- a/test/nil.go
+++ b/test/nil.go
@@ -6,6 +6,11 @@
 
 package main
 
+import (
+	"fmt"
+	"time"
+)
+
 type T struct {
 	i int
 }
@@ -33,4 +38,141 @@
 	ta[0] = nil
 
 	_, _, _, _, _, _, _, _ = i, f, s, m, c, t, in, ta
+
+	arraytest()
+	chantest()
+	maptest()
+	slicetest()
+}
+
+func shouldPanic(f func()) {
+	defer func() {
+		if recover() == nil {
+			panic("not panicking")
+		}
+	}()
+	f()
+}
+
+func shouldBlock(f func()) {
+	go func() {
+		f()
+		panic("did not block")
+	}()
+	time.Sleep(1e7)
+}
+
+// nil array pointer
+
+func arraytest() {
+	var p *[10]int
+
+	// Looping over indices is fine.
+	s := 0
+	for i := range p {
+		s += i
+	}
+	if s != 45 {
+		panic(s)
+	}
+
+	s = 0
+	for i := 0; i < len(p); i++ {
+		s += i
+	}
+	if s != 45 {
+		panic(s)
+	}
+
+	// Looping over values is not.
+	shouldPanic(func() {
+		for i, v := range p {
+			s += i + v
+		}
+	})
+
+	shouldPanic(func() {
+		for i := 0; i < len(p); i++ {
+			s += p[i]
+		}
+	})
+}
+
+// nil channel
+// select tests already handle select on nil channel
+
+func chantest() {
+	var ch chan int
+
+	// nil channel is never ready
+	shouldBlock(func() {
+		ch <- 1
+	})
+	shouldBlock(func() {
+		<-ch
+	})
+	shouldBlock(func() {
+		x, ok := <-ch
+		println(x, ok)
+	})
+
+	if len(ch) != 0 {
+		panic(len(ch))
+	}
+	if cap(ch) != 0 {
+		panic(cap(ch))
+	}
+}
+
+// nil map
+
+func maptest() {
+	var m map[int]int
+
+	// nil map appears empty
+	if len(m) != 0 {
+		panic(len(m))
+	}
+	if m[1] != 0 {
+		panic(m[1])
+	}
+	if x, ok := m[1]; x != 0 || ok {
+		panic(fmt.Sprint(x, ok))
+	}
+
+	for k, v := range m {
+		panic(k)
+		panic(v)
+	}
+
+	// but cannot be written to
+	shouldPanic(func() {
+		m[2] = 3
+	})
+	shouldPanic(func() {
+		m[2] = 0, false
+	})
+}
+
+// nil slice
+
+func slicetest() {
+	var x []int
+
+	// nil slice is just a 0-element slice.
+	if len(x) != 0 {
+		panic(len(x))
+	}
+	if cap(x) != 0 {
+		panic(cap(x))
+	}
+
+	// no 0-element slices can be read from or written to
+	var s int
+	shouldPanic(func() {
+		s += x[1]
+	})
+	shouldPanic(func() {
+		x[2] = s
+	})
 }