// run
// 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.
// Test 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" {
		println("not hello: ", s)
		panic("fail")
	}
}
func five(i int) {
	if i != 5 {
		println("not 5: ", i)
		panic("fail")
	}
}
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
	_, 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)
}