add test for yesterday's interface rule change (interface/convert1.go).
move interface tests to subdirectory.

R=r
DELTA=1632  (827 added, 804 deleted, 1 changed)
OCL=29181
CL=29191
diff --git a/test/interface/bigdata.go b/test/interface/bigdata.go
new file mode 100644
index 0000000..674ea12
--- /dev/null
+++ b/test/interface/bigdata.go
@@ -0,0 +1,75 @@
+// $G $D/$F.go && $L $F.$A && ./$A.out
+
+// 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.
+
+// check that big vs small, pointer vs not
+// interface methods work.
+
+package main
+
+type I interface { M() int64 }
+
+type BigPtr struct { a, b, c, d int64 }
+func (z *BigPtr) M() int64 { return z.a+z.b+z.c+z.d }
+
+type SmallPtr struct { a int32 }
+func (z *SmallPtr) M() int64 { return int64(z.a) }
+
+type IntPtr int32
+func (z *IntPtr) M() int64 { return int64(*z) }
+
+var bad bool
+
+func test(name string, i I) {
+	m := i.M();
+	if m != 12345 {
+		println(name, m);
+		bad = true;
+	}
+}
+
+func ptrs() {
+	var bigptr BigPtr = BigPtr{ 10000, 2000, 300, 45 };
+	var smallptr SmallPtr = SmallPtr{ 12345 };
+	var intptr IntPtr = 12345;
+
+//	test("bigptr", bigptr);
+	test("&bigptr", &bigptr);
+//	test("smallptr", smallptr);
+	test("&smallptr", &smallptr);
+//	test("intptr", intptr);
+	test("&intptr", &intptr);
+}
+
+type Big struct { a, b, c, d int64 }
+func (z Big) M() int64 { return z.a+z.b+z.c+z.d }
+
+type Small struct { a int32 }
+func (z Small) M() int64 { return int64(z.a) }
+
+type Int int32
+func (z Int) M() int64 { return int64(z) }
+
+func nonptrs() {
+	var big Big = Big{ 10000, 2000, 300, 45 };
+	var small Small = Small{ 12345 };
+	var int Int = 12345;
+
+	test("big", big);
+	test("&big", &big);
+	test("small", small);
+	test("&small", &small);
+	test("int", int);
+	test("&int", &int);
+}
+
+func main() {
+	ptrs();
+	nonptrs();
+
+	if bad {
+		println("BUG: interface4");
+	}
+}
diff --git a/test/interface/convert.go b/test/interface/convert.go
new file mode 100644
index 0000000..f15f5ef
--- /dev/null
+++ b/test/interface/convert.go
@@ -0,0 +1,140 @@
+// $G $D/$F.go && $L $F.$A && ./$A.out
+
+// 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.
+
+// Check uses of all the different interface
+// conversion runtime functions.
+
+package main
+
+type Stringer interface { String() string }
+type StringLengther interface { String() string; Length() int }
+type Empty interface { }
+
+type T string
+func (t T) String() string {
+	return string(t);
+}
+func (t T) Length() int {
+	return len(t);
+}
+
+type U string
+func (u U) String() string {
+	return string(u);
+}
+
+var t = T("hello")
+var u = U("goodbye")
+var e Empty
+var s Stringer = t
+var sl StringLengther = t
+var i int
+var ok bool
+
+func hello(s string) {
+	if s != "hello" {
+		panic("not hello: ", s);
+	}
+}
+
+func five(i int) {
+	if i != 5 {
+		panic("not 5: ", i);
+	}
+}
+
+func true(ok bool) {
+	if !ok {
+		panic("not true");
+	}
+}
+
+func false(ok bool) {
+	if ok {
+		panic("not false");
+	}
+}
+
+func main() {
+	// T2I
+	s = t;
+	hello(s.String());
+
+	// I2T
+	t = s.(T);
+	hello(t.String());
+
+	// T2E
+	e = t;
+
+	// E2T
+	t = e.(T);
+	hello(t.String());
+
+	// T2I again
+	sl = t;
+	hello(sl.String());
+	five(sl.Length());
+
+	// I2I static
+	s = sl;
+	hello(s.String());
+
+	// I2I dynamic
+	sl = s.(StringLengther);
+	hello(sl.String());
+	five(sl.Length());
+
+	// I2E (and E2T)
+	e = s;
+	hello(e.(T).String());
+
+	// E2I
+	s = e.(Stringer);
+	hello(s.String());
+
+	// I2T2 true
+	t, ok = s.(T);
+	true(ok);
+	hello(t.String());
+
+	// I2T2 false
+	var u1 U;
+	u1, ok = s.(U);
+	false(ok);
+
+	// I2I2 true
+	sl, ok = s.(StringLengther);
+	true(ok);
+	hello(sl.String());
+	five(sl.Length());
+
+	// I2I2 false (and T2I)
+	s = u;
+	sl, ok = s.(StringLengther);
+	false(ok);
+
+	// E2T2 true
+	t, ok = e.(T);
+	true(ok);
+	hello(t.String());
+
+	// E2T2 false
+	i, ok = e.(int);
+	false(ok);
+
+	// E2I2 true
+	sl, ok = e.(StringLengther);
+	true(ok);
+	hello(sl.String());
+	five(sl.Length());
+
+	// E2I2 false (and T2E)
+	e = u;
+	sl, ok = e.(StringLengther);
+	false(ok);
+}
+
diff --git a/test/interface/convert1.go b/test/interface/convert1.go
new file mode 100644
index 0000000..0eff6a9
--- /dev/null
+++ b/test/interface/convert1.go
@@ -0,0 +1,25 @@
+// $G $D/$F.go && $L $F.$A && ./$A.out
+
+// 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.
+
+// Check that static interface conversion of
+// interface value nil succeeds.
+
+package main
+
+type R interface { R(); }
+type RW interface { R(); W(); }
+
+var e interface {}
+var r R;
+var rw RW;
+
+func main() {
+	r = r;
+	r = rw;
+	e = r;
+	e = rw;
+	rw = rw;
+}
diff --git a/test/interface/embed.go b/test/interface/embed.go
new file mode 100644
index 0000000..d216b89
--- /dev/null
+++ b/test/interface/embed.go
@@ -0,0 +1,82 @@
+// $G $D/$F.go && $L $F.$A && ./$A.out
+
+// 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.
+
+// Check methods derived from embedded interface and *interface values.
+
+package main
+
+import "os"
+
+const Value = 1e12
+
+type Inter interface { M() int64 }
+
+type T int64
+func (t T) M() int64 { return int64(t) }
+var t = T(Value)
+var pt = &t
+var ti Inter = t
+var pti = &ti
+
+type S struct { Inter }
+var s = S{ ti }
+var ps = &s
+
+type SP struct { *Inter }
+var sp = SP{ &ti }
+var psp = &sp
+
+var i Inter
+var pi = &i
+
+var ok = true
+
+func check(v int64, s string) {
+	if v != Value {
+		println(s, v);
+		ok = false;
+	}
+}
+
+func main() {
+	check(t.M(), "t.M");
+	check(pt.M(), "pt.M");
+	check(ti.M(), "ti.M");
+	check(pti.M(), "pti.M");
+	check(s.M(), "s.M");
+	check(ps.M(), "ps.M");
+	check(sp.M(), "sp.M");
+	check(psp.M(), "psp.M");
+
+	i = t;
+	check(i.M(), "i.M - i = t");
+	check(pi.M(), "pi.M - i = t");
+
+	i = pt;
+	check(i.M(), "i.M - i = pt");
+	check(pi.M(), "pi.M - i = pt");
+
+	i = s;
+	check(i.M(), "i.M - i = s");
+	check(pi.M(), "pi.M - i = s");
+
+	i = ps;
+	check(i.M(), "i.M - i = ps");
+	check(pi.M(), "pi.M - i = ps");
+
+	i = sp;
+	check(i.M(), "i.M - i = sp");
+	check(pi.M(), "pi.M - i = sp");
+
+	i = psp;
+	check(i.M(), "i.M - i = psp");
+	check(pi.M(), "pi.M - i = psp");
+
+	if !ok {
+		println("BUG: interface10");
+		os.Exit(1)
+	}
+}
diff --git a/test/interface/explicit.go b/test/interface/explicit.go
new file mode 100644
index 0000000..3b5ed01
--- /dev/null
+++ b/test/interface/explicit.go
@@ -0,0 +1,34 @@
+// errchk $G $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.
+
+// Static error messages about interface conversions.
+
+package main
+
+type T struct { a int }
+var t *T
+
+type I interface { M() }
+var i I
+
+type I2 interface { M(); N(); }
+var i2 I2;
+
+var e interface { };
+
+func main() {
+	e = t;	// ok
+	t = e;	// ERROR "need explicit"
+
+	// neither of these can work,
+	// because i has an extra method
+	// that t does not, so i cannot contain a t.
+	i = t;	// ERROR "missing|incompatible|is not"
+	t = i;	// ERROR "missing|incompatible|is not"
+
+	i = i2;	// ok
+	i2 = i;	// ERROR "need explicit"
+}
diff --git a/test/interface/fail.go b/test/interface/fail.go
new file mode 100644
index 0000000..1e37580
--- /dev/null
+++ b/test/interface/fail.go
@@ -0,0 +1,27 @@
+// $G $D/$F.go && $L $F.$A && ! ./$A.out
+
+// 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.
+
+// Check that interface conversion fails when method is missing.
+
+package main
+
+type S struct
+
+type I interface {
+	Foo()
+}
+
+func main() {
+	var s *S;
+	var i I;
+	var e interface {};
+	e = s;
+	i = e.(I);
+}
+
+// hide S down here to avoid static warning
+type S struct {
+}
diff --git a/test/interface/fake.go b/test/interface/fake.go
new file mode 100644
index 0000000..a52d7a5
--- /dev/null
+++ b/test/interface/fake.go
@@ -0,0 +1,97 @@
+// $G $D/$F.go && $L $F.$A && ./$A.out
+
+// 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.
+
+// Interface comparisons using types hidden
+// inside reflected-on structs.
+
+package main
+
+import "reflect"
+
+type T struct {
+	f float32;
+	g float32;
+
+	s string;
+	t string;
+
+	u uint32;
+	v uint32;
+
+	w uint32;
+	x uint32;
+
+	y uint32;
+	z uint32;
+}
+
+func add(s, t string) string {
+	return s + t;
+}
+
+func assert(b bool) {
+	if !b {
+		panic("assert");
+	}
+}
+
+func main() {
+	var x T;
+	x.f = 1.0;
+	x.g = x.f;
+	x.s = add("abc", "def");
+	x.t = add("abc", "def");
+	x.u = 1;
+	x.v = 2;
+	x.w = 1<<28;
+	x.x = 2<<28;
+	x.y = 0x12345678;
+	x.z = x.y;
+
+	// check mem and string
+	v := reflect.NewValue(x);
+	i := v.(reflect.StructValue).Field(0);
+	j := v.(reflect.StructValue).Field(1);
+	assert(i.Interface() == j.Interface());
+
+	s := v.(reflect.StructValue).Field(2);
+	t := v.(reflect.StructValue).Field(3);
+	assert(s.Interface() == t.Interface());
+
+	// make sure different values are different.
+	// make sure whole word is being compared,
+	// not just a single byte.
+	i = v.(reflect.StructValue).Field(4);
+	j = v.(reflect.StructValue).Field(5);
+	assert(i.Interface() != j.Interface());
+
+	i = v.(reflect.StructValue).Field(6);
+	j = v.(reflect.StructValue).Field(7);
+	assert(i.Interface() != j.Interface());
+
+	i = v.(reflect.StructValue).Field(8);
+	j = v.(reflect.StructValue).Field(9);
+	assert(i.Interface() == j.Interface());
+}
+
+/*
+comparing uncomparable type float32
+throw: interface compare
+
+panic PC=0x28ceb8 [1]
+throw+0x41 /Users/rsc/goX/src/runtime/runtime.c:54
+	throw(0x3014a, 0x0)
+ifaceeq+0x15c /Users/rsc/goX/src/runtime/iface.c:501
+	ifaceeq(0x2aa7c0, 0x0, 0x0, 0x0, 0x2aa7c0, ...)
+sys·ifaceeq+0x48 /Users/rsc/goX/src/runtime/iface.c:527
+	sys·ifaceeq(0x2aa7c0, 0x0, 0x0, 0x0, 0x2aa7c0, ...)
+main·main+0x190 /Users/rsc/goX/src/cmd/gc/x.go:10
+	main·main()
+mainstart+0xf /Users/rsc/goX/src/runtime/amd64/asm.s:53
+	mainstart()
+sys·Goexit /Users/rsc/goX/src/runtime/proc.c:124
+	sys·Goexit()
+*/
diff --git a/test/interface/pointer.go b/test/interface/pointer.go
new file mode 100644
index 0000000..202c37d
--- /dev/null
+++ b/test/interface/pointer.go
@@ -0,0 +1,37 @@
+// errchk $G $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.
+
+// Check that interface{M()} = *interface{M()} produces a compiler error.
+
+package main
+
+type Inst interface {
+	Next()	*Inst;
+}
+
+type Regexp struct {
+	code []Inst;
+	start	Inst;
+}
+
+type Start struct {
+	foo	*Inst;
+}
+
+func (start *Start) Next() *Inst { return nil }
+
+
+func AddInst(Inst) *Inst {
+	print("ok in addinst\n");
+	return nil
+}
+
+func main() {
+	re := new(Regexp);
+	print("call addinst\n");
+	var x Inst = AddInst(new(Start));	// ERROR "illegal|incompatible"
+	print("return from  addinst\n");
+}
diff --git a/test/interface/receiver.go b/test/interface/receiver.go
new file mode 100644
index 0000000..438fea0
--- /dev/null
+++ b/test/interface/receiver.go
@@ -0,0 +1,104 @@
+// $G $D/$F.go && $L $F.$A && ./$A.out
+
+// 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.
+
+// Implicit methods for embedded types.
+// Mixed pointer and non-pointer receivers.
+
+package main
+
+type T int
+var nv, np int
+
+func (t T) V() {
+	if t != 42 {
+		panic(t)
+	}
+	nv++
+}
+
+func (t *T) P() {
+	if *t != 42 {
+		panic(t, *t)
+	}
+	np++
+}
+
+type V interface { V() }
+type P interface { P(); V() }
+
+type S struct {
+	T;
+}
+
+type SP struct {
+	*T;
+}
+
+func main() {
+	var t T;
+	var v V;
+	var p P;
+
+	t = 42;
+
+	t.P();
+	t.V();
+
+	v = t;
+	v.V();
+
+	p = &t;
+	p.P();
+	p.V();
+
+	v = &t;
+	v.V();
+
+//	p = t;	// ERROR
+
+//	println("--struct--");
+	var s S;
+	s.T = 42;
+	s.P();
+	s.V();
+
+	v = s;
+	s.V();
+
+	p = &s;
+	p.P();
+	p.V();
+
+	v = &s;
+	v.V();
+
+//	p = s;	// ERROR
+
+//	println("--struct pointer--");
+	var sp SP;
+	sp.T = &t;
+	sp.P();
+	sp.V();
+
+	v = sp;
+	sp.V();
+
+	p = &sp;
+	p.P();
+	p.V();
+
+	v = &sp;
+	v.V();
+
+	p = sp;	// not error
+	p.P();
+	p.V();
+
+	if nv != 13 || np != 7 {
+		panicln("bad count", nv, np)
+	}
+}
+
diff --git a/test/interface/receiver1.go b/test/interface/receiver1.go
new file mode 100644
index 0000000..7f257a3
--- /dev/null
+++ b/test/interface/receiver1.go
@@ -0,0 +1,43 @@
+// errchk $G $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.
+
+// Error messages about missing implicit methods.
+
+package main
+
+type T int
+func (t T) V()
+func (t *T) P()
+
+type V interface { V() }
+type P interface { P(); V() }
+
+type S struct { T; }
+type SP struct { *T; }
+
+func main() {
+	var t T;
+	var v V;
+	var p P;
+	var s S;
+	var sp SP;
+
+	v = t;
+	p = t;	// ERROR "is not|requires a pointer"
+	v = &t;
+	p = &t;
+
+	v = s;
+	p = s;	// ERROR "is not|requires a pointer"
+	v = &s;
+	p = &s;
+
+	v = sp;
+	p = sp;	// no error!
+	v = &sp;
+	p = &sp;
+}
+
diff --git a/test/interface/recursive.go b/test/interface/recursive.go
new file mode 100644
index 0000000..707cfcb
--- /dev/null
+++ b/test/interface/recursive.go
@@ -0,0 +1,24 @@
+// $G $D/$F.go || echo BUG: should 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.
+
+// Check mutually recursive interfaces
+
+package main
+
+type I2 interface
+
+type I1 interface {
+	foo() I2
+}
+
+type I2 interface {
+	bar() I1
+}
+
+type T int
+func (t T) bar() I1;
+func (t T) foo() I2 { return t }
+func (t T) bar() I1 { return t }
diff --git a/test/interface/returntype.go b/test/interface/returntype.go
new file mode 100644
index 0000000..93298bc
--- /dev/null
+++ b/test/interface/returntype.go
@@ -0,0 +1,25 @@
+// $G $D/$F.go && $L $F.$A && (! ./$A.out || echo BUG: should not succeed)
+
+// 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.
+
+// Check methods with different return types.
+
+package main
+
+type S struct { a int }
+type T struct { b string }
+
+func (s *S) Name() int8 { return 1 }
+func (t *T) Name() int64 { return 64 }
+
+type I1 interface { Name() int8 }
+type I2 interface { Name() int64 }
+
+func main() {
+	var i1 I1;
+	var s *S;
+	i1 = s;
+	print(i1.(I2).Name())
+}
diff --git a/test/interface/struct.go b/test/interface/struct.go
new file mode 100644
index 0000000..49926f0
--- /dev/null
+++ b/test/interface/struct.go
@@ -0,0 +1,154 @@
+// $G $D/$F.go && $L $F.$A && ./$A.out || echo BUG interface6
+
+// 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.
+
+// Interface values containing structures.
+
+package main
+
+import "os"
+
+var fail int
+
+func check(b bool, msg string) {
+  if (!b) {
+    println("failure in", msg);
+    fail++;
+  }
+}
+
+type I1 interface { Get() int; Put(int); }
+
+type S1 struct { i int }
+func (p S1) Get() int { return p.i }
+func (p S1) Put(i int) { p.i = i }
+
+func f1() {
+  s := S1{1};
+  var i I1 = s;
+  i.Put(2);
+  check(i.Get() == 1, "f1 i");
+  check(s.i == 1, "f1 s");
+}
+
+func f2() {
+  s := S1{1};
+  var i I1 = &s;
+  i.Put(2);
+  check(i.Get() == 1, "f2 i");
+  check(s.i == 1, "f2 s");
+}
+
+func f3() {
+  s := &S1{1};
+  var i I1 = s;
+  i.Put(2);
+  check(i.Get() == 1, "f3 i");
+  check(s.i == 1, "f3 s");
+}
+
+type S2 struct { i int }
+func (p *S2) Get() int { return p.i }
+func (p *S2) Put(i int) { p.i = i }
+
+// func f4() {
+//   s := S2{1};
+//   var i I1 = s;
+//   i.Put(2);
+//   check(i.Get() == 2, "f4 i");
+//   check(s.i == 1, "f4 s");
+// }
+
+func f5() {
+  s := S2{1};
+  var i I1 = &s;
+  i.Put(2);
+  check(i.Get() == 2, "f5 i");
+  check(s.i == 2, "f5 s");
+}
+
+func f6() {
+  s := &S2{1};
+  var i I1 = s;
+  i.Put(2);
+  check(i.Get() == 2, "f6 i");
+  check(s.i == 2, "f6 s");
+}
+
+type I2 interface { Get() int64; Put(int64); }
+
+type S3 struct { i, j, k, l int64 }
+func (p S3) Get() int64 { return p.l }
+func (p S3) Put(i int64) { p.l = i }
+
+func f7() {
+  s := S3{1, 2, 3, 4};
+  var i I2 = s;
+  i.Put(5);
+  check(i.Get() == 4, "f7 i");
+  check(s.l == 4, "f7 s");
+}
+
+func f8() {
+  s := S3{1, 2, 3, 4};
+  var i I2 = &s;
+  i.Put(5);
+  check(i.Get() == 4, "f8 i");
+  check(s.l == 4, "f8 s");
+}
+
+func f9() {
+  s := &S3{1, 2, 3, 4};
+  var i I2 = s;
+  i.Put(5);
+  check(i.Get() == 4, "f9 i");
+  check(s.l == 4, "f9 s");
+}
+
+type S4 struct { i, j, k, l int64 }
+func (p *S4) Get() int64 { return p.l }
+func (p *S4) Put(i int64) { p.l = i }
+
+// func f10() {
+//   s := S4{1, 2, 3, 4};
+//   var i I2 = s;
+//   i.Put(5);
+//   check(i.Get() == 5, "f10 i");
+//   check(s.l == 4, "f10 s");
+// }
+
+func f11() {
+  s := S4{1, 2, 3, 4};
+  var i I2 = &s;
+  i.Put(5);
+  check(i.Get() == 5, "f11 i");
+  check(s.l == 5, "f11 s");
+}
+
+func f12() {
+  s := &S4{1, 2, 3, 4};
+  var i I2 = s;
+  i.Put(5);
+  check(i.Get() == 5, "f12 i");
+  check(s.l == 5, "f12 s");
+}
+
+func main() {
+  f1();
+  f2();
+  f3();
+//  f4();
+  f5();
+  f6();
+  f7();
+  f8();
+  f9();
+//  f10();
+  f11();
+  f12();
+  if fail > 0 {
+    os.Exit(1)
+  }
+}