// Copyright 2012 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.

// statements

package stmt0

func _() {
	b, i, f, c, s := false, 1, 1.0, 1i, "foo"
	b = i /* ERROR "cannot assign" */
	i = f /* ERROR "cannot assign" */
	f = c /* ERROR "cannot assign" */
	c = s /* ERROR "cannot assign" */
	s = b /* ERROR "cannot assign" */

	v0 /* ERROR "mismatch" */, v1, v2 := 1, 2, 3, 4

	b = true

	i += 1
	i += "foo" /* ERROR "cannot convert.*int" */

	f -= 1
	f -= "foo" /* ERROR "cannot convert.*float64" */

	c *= 1
	c /= 0 /* ERROR "division by zero" */

	s += "bar"
	s += 1 /* ERROR "cannot convert.*string" */

	var u64 uint64
	u64 += 1<<u64

	undeclared /* ERROR "undeclared" */ = 991
}

func _incdecs() {
	const c = 3.14
	c /* ERROR "cannot assign" */ ++
	s := "foo"
	s /* ERROR "cannot convert" */ --
	3.14 /* ERROR "cannot assign" */ ++
	var (
		x int
		y float32
		z complex128
	)
	x++
	y--
	z++
}

func _sends() {
	var ch chan int
	var rch <-chan int
	var x int
	x /* ERROR "cannot send" */ <- x
	rch /* ERROR "cannot send" */ <- x
	ch /* ERROR "cannot send" */ <- "foo"
	ch <- x
}

func _selects() {
	select {}
	var (
		ch chan int
		sc chan <- bool
		x int
	)
	select {
	case <-ch:
		ch <- x
	case t, ok := <-ch:
		x = t
	case <-sc /* ERROR "cannot receive from send-only channel" */ :
	}
	select {
	default:
	default /* ERROR "multiple defaults" */ :
	}
}

func _gos() {
	go 1 /* ERROR "expected function/method call" */
	go _gos()
	var c chan int
	go close(c)
	go len(c) // TODO(gri) this should not be legal
}

func _defers() {
	defer 1 /* ERROR "expected function/method call" */
	defer _defers()
	var c chan int
	defer close(c)
	defer len(c) // TODO(gri) this should not be legal
}

func _switches() {
	var x int

	switch x {
	default:
	default /* ERROR "multiple defaults" */ :
	}

	switch {
	case 1  /* ERROR "cannot convert" */ :
	}

	switch int32(x) {
	case 1, 2:
	case x /* ERROR "cannot compare" */ :
	}

	switch x {
	case 1 /* ERROR "overflows int" */ << 100:
	}

	switch x {
	case 1:
	case 1 /* ERROR "duplicate case" */ :
	case 2, 3, 4:
	case 1 /* ERROR "duplicate case" */ :
	}

	// TODO(gri) duplicate 64bit values that don't fit into an int64 are not yet detected
	switch uint64(x) {
	case 1<<64-1:
	case 1<<64-1:
	}
}

type I interface {
	m()
}

type I2 interface {
	m(int)
}

type T struct{}
type T1 struct{}
type T2 struct{}

func (T) m() {}
func (T2) m(int) {}

func _typeswitches() {
	var i int
	var x interface{}

	switch x.(type) {}
	switch (x /* ERROR "outside type switch" */ .(type)) {}

	switch x.(type) {
	default:
	default /* ERROR "multiple defaults" */ :
	}

	switch x := x.(type) {}

	switch x := x.(type) {
	case int:
		var y int = x
	}

	switch x := i /* ERROR "not an interface" */ .(type) {}

	switch t := x.(type) {
	case nil:
		var v bool = t /* ERROR "cannot assign" */
	case int:
		var v int = t
	case float32, complex64:
		var v float32 = t /* ERROR "cannot assign" */
	default:
		var v float32 = t /* ERROR "cannot assign" */
	}

	var t I
	switch t.(type) {
	case T:
	case T1 /* ERROR "missing method m" */ :
	case T2 /* ERROR "wrong type for method m" */ :
	case I2 /* ERROR "wrong type for method m" */ :
	}
}

func _rangeloops() {
	var (
		x int
		a [10]float32
		b []string
		p *[10]complex128
		pp **[10]complex128
		s string
		m map[int]bool
		c chan int
		sc chan<- int
		rc <-chan int
	)

	for _ = range x /* ERROR "cannot range over" */ {}
	for i := range x /* ERROR "cannot range over" */ {}

	for i := range a {
		var ii int
		ii = i
	}
	for i, x := range a {
		var ii int
		ii = i
		var xx float64
		xx = x /* ERROR "cannot assign" */
	}
	var ii int
	var xx float32
	for ii, xx := range a {}

	for i := range b {
		var ii int
		ii = i
	}
	for i, x := range b {
		var ii int
		ii = i
		var xx string
		xx = x
	}

	for i := range s {
		var ii int
		ii = i
	}
	for i, x := range s {
		var ii int
		ii = i
		var xx rune
		xx = x
	}

	for _, x := range p {
		var xx complex128
		xx = x
	}

	for _, x := range pp /* ERROR "cannot range over" */ {}

	for k := range m {
		var kk int32
		kk = k /* ERROR "cannot assign" */
	}
	for k, v := range m {
		var kk int
		kk = k
		if v {}
	}

	for _, _ /* ERROR "only one iteration variable" */ = range c {}
	for e := range c {
		var ee int
		ee = e
	}
	for _ = range sc /* ERROR "cannot range over send-only channel" */ {}
	for _ = range rc {}

	// constant strings
	const cs = "foo"
	for i, x := range cs {}
	for i, x := range "" {
		var ii int
		ii = i
		var xx rune
		xx = x
	}
}
