diff options
author | Russ Cox <rsc@golang.org> | 2010-01-25 18:23:20 -0800 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2010-01-25 18:23:20 -0800 |
commit | 45eb8c4fba671baee65ac0c15ccc589cd7880499 (patch) | |
tree | aead1d8e45cabfd97850848252a9e9accfebd261 /test | |
parent | 95d998b02811bf00ef97b66ac7d7b4db9708bfa5 (diff) | |
download | golang-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.go | 9 | ||||
-rw-r--r-- | test/fixedbugs/bug248.dir/bug1.go | 9 | ||||
-rw-r--r-- | test/fixedbugs/bug248.dir/bug2.go | 92 | ||||
-rw-r--r-- | test/fixedbugs/bug248.dir/bug3.go | 69 | ||||
-rw-r--r-- | test/fixedbugs/bug248.go | 12 | ||||
-rw-r--r-- | test/golden.out | 2 | ||||
-rw-r--r-- | test/typeswitch2.go | 28 |
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 "" +} |