runtime, type switch: eliminate package global name space assumption

bonus: type switch now detects multiple uses of identical interface types.
bonus: interface types are now order-independent, following the spec.

R=ken2
CC=golang-dev
https://golang.org/cl/194053
diff --git a/test/fixedbugs/bug248.dir/bug0.go b/test/fixedbugs/bug248.dir/bug0.go
new file mode 100644
index 0000000..7fc7401
--- /dev/null
+++ b/test/fixedbugs/bug248.dir/bug0.go
@@ -0,0 +1,9 @@
+package p
+
+type T struct {
+	X, Y int
+}
+
+type I interface {
+	M(T)
+}
diff --git a/test/fixedbugs/bug248.dir/bug1.go b/test/fixedbugs/bug248.dir/bug1.go
new file mode 100644
index 0000000..7fc7401
--- /dev/null
+++ b/test/fixedbugs/bug248.dir/bug1.go
@@ -0,0 +1,9 @@
+package p
+
+type T struct {
+	X, Y int
+}
+
+type I interface {
+	M(T)
+}
diff --git a/test/fixedbugs/bug248.dir/bug2.go b/test/fixedbugs/bug248.dir/bug2.go
new file mode 100644
index 0000000..d562bf6
--- /dev/null
+++ b/test/fixedbugs/bug248.dir/bug2.go
@@ -0,0 +1,92 @@
+package main
+
+import (
+	p0 "./bug0"
+	p1 "./bug1"
+
+	"reflect"
+	"strings"
+)
+
+var v0 p0.T
+var v1 p1.T
+
+type I0 interface {
+	M(p0.T)
+}
+
+type I1 interface {
+	M(p1.T)
+}
+
+type t0 int
+
+func (t0) M(p0.T) {}
+
+type t1 float
+
+func (t1) M(p1.T) {}
+
+var i0 I0 = t0(0) // ok
+var i1 I1 = t1(0) // ok
+
+var p0i p0.I = t0(0) // ok
+var p1i p1.I = t1(0) // ok
+
+func main() {
+	// check that reflect paths are correct,
+	// meaning that reflect data for v0, v1 didn't get confused.
+
+	// path is full (rooted) path name.  check suffix only.
+	if s := reflect.Typeof(v0).PkgPath(); !strings.HasSuffix(s, "/bug0") {
+		panicln("bad v0 path", len(s), s)
+	}
+	if s := reflect.Typeof(v1).PkgPath(); !strings.HasSuffix(s, "/bug1") {
+		panicln("bad v1 path", s)
+	}
+
+	// check that dynamic interface check doesn't get confused
+	var i interface{} = t0(0)
+	if _, ok := i.(I1); ok {
+		panicln("used t0 as i1")
+	}
+	if _, ok := i.(p1.I); ok {
+		panicln("used t0 as p1.I")
+	}
+
+	i = t1(1)
+	if _, ok := i.(I0); ok {
+		panicln("used t1 as i0")
+	}
+	if _, ok := i.(p0.I); ok {
+		panicln("used t1 as p0.I")
+	}
+
+	// check that type switch works.
+	// the worry is that if p0.T and p1.T have the same hash,
+	// the binary search will handle one of them incorrectly.
+	for j := 0; j < 3; j++ {
+		switch j {
+		case 0:
+			i = p0.T{}
+		case 1:
+			i = p1.T{}
+		case 2:
+			i = 3.14
+		}
+		switch k := i.(type) {
+		case p0.T:
+			if j != 0 {
+				panicln("type switch p0.T")
+			}
+		case p1.T:
+			if j != 1 {
+				panicln("type switch p1.T")
+			}
+		default:
+			if j != 2 {
+				panicln("type switch default", j)
+			}
+		}
+	}
+}
diff --git a/test/fixedbugs/bug248.dir/bug3.go b/test/fixedbugs/bug248.dir/bug3.go
new file mode 100644
index 0000000..e59982f
--- /dev/null
+++ b/test/fixedbugs/bug248.dir/bug3.go
@@ -0,0 +1,69 @@
+package main
+
+import (
+	p0 "./bug0"
+	p1 "./bug1"
+)
+
+// both p0.T and p1.T are struct { X, Y int }.
+
+var v0 p0.T
+var v1 p1.T
+
+// interfaces involving the two
+
+type I0 interface {
+	M(p0.T)
+}
+
+type I1 interface {
+	M(p1.T)
+}
+
+// t0 satisfies I0 and p0.I
+type t0 int
+
+func (t0) M(p0.T) {}
+
+// t1 satisfies I1 and p1.I
+type t1 float
+
+func (t1) M(p1.T) {}
+
+// check static interface assignments
+var i0 I0 = t0(0) // ok
+var i1 I1 = t1(0) // ok
+
+var i2 I0 = t1(0) // ERROR "is not"
+var i3 I1 = t0(0) // ERROR "is not"
+
+var p0i p0.I = t0(0) // ok
+var p1i p1.I = t1(0) // ok
+
+var p0i1 p0.I = t1(0) // ERROR "is not"
+var p0i2 p1.I = t0(0) // ERROR "is not"
+
+func main() {
+	// check that cannot assign one to the other,
+	// but can convert.
+	v0 = v1 // ERROR "assign"
+	v1 = v0 // ERROR "assign"
+
+	v0 = p0.T(v1)
+	v1 = p1.T(v0)
+
+	i0 = i1   // ERROR "need type assertion"
+	i1 = i0   // ERROR "need type assertion"
+	p0i = i1  // ERROR "need type assertion"
+	p1i = i0  // ERROR "need type assertion"
+	i0 = p1i  // ERROR "need type assertion"
+	i1 = p0i  // ERROR "need type assertion"
+	p0i = p1i // ERROR "need type assertion"
+	p1i = p0i // ERROR "need type assertion"
+
+	i0 = p0i
+	p0i = i0
+
+	i1 = p1i
+	p1i = i1
+}
diff --git a/test/fixedbugs/bug248.go b/test/fixedbugs/bug248.go
new file mode 100644
index 0000000..055bf1f
--- /dev/null
+++ b/test/fixedbugs/bug248.go
@@ -0,0 +1,12 @@
+// $G $D/$F.dir/bug0.go &&
+// $G $D/$F.dir/bug1.go &&
+// $G $D/$F.dir/bug2.go &&
+// errchk $G -e $D/$F.dir/bug3.go &&
+// $L bug2.$A &&
+// ./$A.out || echo BUG: failed to compile
+
+// Copyright 2009 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 file.
+
+ignored
diff --git a/test/golden.out b/test/golden.out
index 906ecac..d87842e 100644
--- a/test/golden.out
+++ b/test/golden.out
@@ -138,7 +138,7 @@
 
 =========== fixedbugs/bug148.go
 2 3
-interface is main.T, not main.T·1
+interface is main.T, not main.T
 throw: interface conversion
 
 panic PC=xxx
diff --git a/test/typeswitch2.go b/test/typeswitch2.go
new file mode 100644
index 0000000..f8fe396
--- /dev/null
+++ b/test/typeswitch2.go
@@ -0,0 +1,28 @@
+// errchk $G -e $D/$F.go
+
+// Copyright 2009 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 file.
+
+package main
+
+import "io"
+
+func whatis(x interface{}) string {
+	switch x.(type) {
+	case int:
+		return "int"
+	case int: // ERROR "duplicate"
+		return "int8"
+	case io.Reader:
+		return "Reader1"
+	case io.Reader: // ERROR "duplicate"
+		return "Reader2"
+	case interface { r(); w() }:
+		return "rw"
+	case interface { w(); r() }:	// ERROR "duplicate"
+		return "wr"
+	
+	}
+	return ""
+}