summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2010-01-25 18:23:20 -0800
committerRuss Cox <rsc@golang.org>2010-01-25 18:23:20 -0800
commit45eb8c4fba671baee65ac0c15ccc589cd7880499 (patch)
treeaead1d8e45cabfd97850848252a9e9accfebd261 /test
parent95d998b02811bf00ef97b66ac7d7b4db9708bfa5 (diff)
downloadgolang-45eb8c4fba671baee65ac0c15ccc589cd7880499.tar.gz
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 http://codereview.appspot.com/194053
Diffstat (limited to 'test')
-rw-r--r--test/fixedbugs/bug248.dir/bug0.go9
-rw-r--r--test/fixedbugs/bug248.dir/bug1.go9
-rw-r--r--test/fixedbugs/bug248.dir/bug2.go92
-rw-r--r--test/fixedbugs/bug248.dir/bug3.go69
-rw-r--r--test/fixedbugs/bug248.go12
-rw-r--r--test/golden.out2
-rw-r--r--test/typeswitch2.go28
7 files changed, 220 insertions, 1 deletions
diff --git a/test/fixedbugs/bug248.dir/bug0.go b/test/fixedbugs/bug248.dir/bug0.go
new file mode 100644
index 000000000..7fc7401c5
--- /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 000000000..7fc7401c5
--- /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 000000000..d562bf604
--- /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 000000000..e59982fd7
--- /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 000000000..055bf1fd7
--- /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 906ecac2b..d87842e4f 100644
--- a/test/golden.out
+++ b/test/golden.out
@@ -138,7 +138,7 @@ panic PC=xxx
=========== 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 000000000..f8fe396ea
--- /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 ""
+}