// 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 assignments0() (int, int) {
	var a, b, c int
	var ch chan int
	f0 := func() {}
	f1 := func() int { return 1 }
	f2 := func() (int, int) { return 1, 2 }
	f3 := func() (int, int, int) { return 1, 2, 3 }

	a, b, c = 1, 2, 3
	a, b, c = 1 /* ERROR "assignment count mismatch" */ , 2
	a, b, c = 1 /* ERROR "assignment count mismatch" */ , 2, 3, 4
	_, _, _ = a, b, c

	a = f0 /* ERROR "used as value" */ ()
	a = f1()
	a = f2 /* ERROR "assignment count mismatch" */ ()
	a, b = f2()
	a, b, c = f2 /* ERROR "assignment count mismatch" */ ()
	a, b, c = f3()
	a, b = f3 /* ERROR "assignment count mismatch" */ ()

	a, b, c = <- /* ERROR "assignment count mismatch" */ ch

	return /* ERROR "wrong number of return values" */
	return /* ERROR "wrong number of return values" */ 1
	return 1, 2
	return /* ERROR "wrong number of return values" */ 1, 2, 3
}

func assignments1() {
	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, v1, v2 := 1 /* ERROR "mismatch" */ , 2, 3, 4
	_, _, _ = v0, v1, v2

	b = true

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

	f -= 1
	f /= 0
	f = float32(0)/0 /* ERROR "division by zero" */
	f -= "foo" /* ERROR "cannot convert.*float64" */

	c *= 1
	c /= 0

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

	var u64 uint64
	u64 += 1<<u64

	undeclared /* ERROR "undeclared" */ = 991

	// test cases for issue 5800
	var (
		_ int = nil /* ERROR "untyped nil value" */
		_ [10]int = nil /* ERROR "untyped nil value" */
		_ []byte = nil
		_ struct{} = nil /* ERROR "untyped nil value" */
		_ func() = nil
		_ map[int]string = nil
		_ chan int = nil
	)

	// test cases for issue 5500
	_ = func() (int, bool) {
		var m map[int]int
		return /* ERROR "wrong number of return values" */ m[0]
	}

	g := func(int, bool){}
	var m map[int]int
	g(m[0]) /* ERROR "too few arguments" */

	// assignments to _
	_ = nil /* ERROR "use of untyped nil" */
	_ = 1 /* ERROR overflow */ <<1000
	(_) = 0
}

func assignments2() {
	type mybool bool
	var m map[string][]bool
	var s []bool
	var b bool
	var d mybool
	_ = s
	_ = b
	_ = d

	// assignments to map index expressions are ok
	s, b = m["foo"]
	_, d = m["bar"]
	m["foo"] = nil
	m["foo"] = nil /* ERROR assignment count mismatch */ , false
	_ = append(m["foo"])
	_ = append(m["foo"], true)

	var c chan int
	_, b = <-c
	_, d = <-c
	<- /* ERROR cannot assign */ c = 0
	<-c = 0 /* ERROR assignment count mismatch */ , false

	var x interface{}
	_, b = x.(int)
	x /* ERROR cannot assign */ .(int) = 0
	x.(int) = 0 /* ERROR assignment count mismatch */ , false

	assignments2 /* ERROR used as value */ () = nil
	int /* ERROR not an expression */ = 0
}

func issue6487() {
	type S struct{x int}
	_ = &S /* ERROR "cannot take address" */ {}.x
	_ = &( /* ERROR "cannot take address" */ S{}.x)
	_ = (&S{}).x
	S /* ERROR "cannot assign" */ {}.x = 0
	(&S{}).x = 0

	type M map[string]S
	var m M
	m /* ERROR "cannot assign" */ ["foo"].x = 0
	_ = &( /* ERROR "cannot take address" */ m["foo"].x)
	_ = &m /* ERROR "cannot take address" */ ["foo"].x
}

func issue6766a() {
	a, a /* ERROR redeclared */ := 1, 2
	_ = a
	a, b, b /* ERROR redeclared */ := 1, 2, 3
	_ = b
	c, c /* ERROR redeclared */, b := 1, 2, 3
	_ = c
	a, b := /* ERROR no new variables */ 1, 2
}

func shortVarDecls1() {
	const c = 0
	type d int
	a, b, c /* ERROR "cannot assign" */ , d /* ERROR "cannot assign" */  := 1, "zwei", 3.0, 4
	var _ int = a // a is of type int
	var _ string = b // b is of type string
}

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 <- "foo" /* ERROR "cannot convert" */
	ch <- x
}

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

	// test for issue 9570: ch2 in second case falsely resolved to
	// ch2 declared in body of first case
	ch1 := make(chan int)
	ch2 := make(chan int)
	select {
	case <-ch1:
		var ch2 /* ERROR ch2 declared but not used */ chan bool
	case i := <-ch2:
		print(i + 1)
	}
}

func gos() {
	go 1 /* ERROR HERE "function must be invoked" */
	go int /* ERROR "go requires function call, not conversion" */ (0)
	go gos()
	var c chan int
	go close(c)
	go len /* ERROR "go discards result" */ (c)
}

func defers() {
	defer 1 /* ERROR HERE "function must be invoked" */
	defer int /* ERROR "defer requires function call, not conversion" */ (0)
	defer defers()
	var c chan int
	defer close(c)
	defer len /* ERROR "defer discards result" */ (c)
}

func breaks() {
	var x, y int

	break /* ERROR "break" */
	{
		break /* ERROR "break" */
	}
	if x < y {
		break /* ERROR "break" */
	}

	switch x {
	case 0:
		break
	case 1:
		if x == y {
			break
		}
	default:
		break
		break
	}

	var z interface{}
	switch z.(type) {
	case int:
		break
	}

	for {
		break
	}

	var a []int
	for _ = range a {
		break
	}

	for {
		if x == y {
			break
		}
	}

	var ch chan int
	select {
	case <-ch:
		break
	}

	select {
	case <-ch:
		if x == y {
			break
		}
	default:
		break
	}
}

func continues() {
	var x, y int

	continue /* ERROR "continue" */
	{
		continue /* ERROR "continue" */
	}

	if x < y {
		continue /* ERROR "continue" */
	}

	switch x {
	case 0:
		continue /* ERROR "continue" */
	}

	var z interface{}
	switch z.(type) {
	case int:
		continue /* ERROR "continue" */
	}

	var ch chan int
	select {
	case <-ch:
		continue /* ERROR "continue" */
	}

	for i := 0; i < 10; i++ {
		continue
		if x < y {
			continue
			break
		}
		switch x {
		case y:
			continue
		default:
			break
		}
		select {
		case <-ch:
			continue
		}
	}

	var a []int
	for _ = range a {
		continue
		if x < y {
			continue
			break
		}
		switch x {
		case y:
			continue
		default:
			break
		}
		select {
		case <-ch:
			continue
		}
	}
}

func returns0() {
	return
	return 0 /* ERROR no result values expected */
}

func returns1(x float64) (int, *float64) {
	return 0, &x
	return /* ERROR wrong number of return values */
	return "foo" /* ERROR "cannot convert" */, x /* ERROR "cannot return" */
	return /* ERROR wrong number of return values */ 0, &x, 1
}

func returns2() (a, b int) {
	return
	return 1, "foo" /* ERROR cannot convert */
	return /* ERROR wrong number of return values */ 1, 2, 3
	{
		type a int
		return 1, 2
		return /* ERROR a not in scope at return */
	}
}

func returns3() (_ int) {
	return
	{
		var _ int // blank (_) identifiers never shadow since they are in no scope
		return
	}
}

func switches0() {
	var x int

	switch x {
	}

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

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

	true := "false"
	_ = true
	// A tagless switch is equivalent to the bool 
        // constant true, not the identifier 'true'.
	switch {
	case "false" /* ERROR "cannot convert" */:
	}

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

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

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

	switch uint64(x) {
	case 1 /* DISABLED duplicate case */ <<64-1:
	case 1 /* DISABLED duplicate case */ <<64-1:
	}
}

func switches1() {
	fallthrough /* ERROR "fallthrough statement out of place" */

	var x int
	switch x {
	case 0:
		fallthrough /* ERROR "fallthrough statement out of place" */
		break
	case 1:
		fallthrough
	case 2:
	default:
		fallthrough
	case 3:
		fallthrough /* ERROR "fallthrough statement out of place" */
	}

	var y interface{}
	switch y.(type) {
	case int:
		fallthrough /* ERROR "fallthrough statement out of place" */
	default:
	}

	switch x {
	case 0:
		if x == 0 {
			fallthrough /* ERROR "fallthrough statement out of place" */
		}
	}

	switch x {
	case 0:
		goto L1
		L1: fallthrough
	case 1:
		goto L2
		goto L3
		goto L4
		L2: L3: L4: fallthrough
	default:
	}

	switch x {
	case 0:
		goto L5
		L5: fallthrough
	default:
		goto L6
		goto L7
		goto L8
		L6: L7: L8: fallthrough /* ERROR "fallthrough statement out of place" */
	}

	switch x {
	case 0:
		{
			fallthrough /* ERROR "fallthrough statement out of place" */
		}
	default:
	}
}

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 /* ERROR "declared but not used" */ := x.(type) {}
	switch _ /* ERROR "no new variable on left side of :=" */ := x.(type) {}

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

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

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

	var t I
	switch t.(type) {
	case T:
	case T1 /* ERROR "missing method m" */ :
	case T2 /* ERROR "wrong type for method m" */ :
	case I2 /* STRICT "wrong type for method m" */ : // only an error in strict mode (issue 8561)
	}
}

// Test that each case clause uses the correct type of the variable
// declared by the type switch (issue 5504).
func typeswitch0() {
	switch y := interface{}(nil).(type) {
	case int:
		func() int { return y + 0 }()
	case float32:
		func() float32 { return y }()
	}
}

// Test correct scope setup.
// (no redeclaration errors expected in the type switch)
func typeswitch1() {
	var t I
	switch t := t; t := t.(type) {
	case nil:
		var _ I = t
	case T:
		var _ T = t
	default:
		var _ I = t
	}
}

// Test correct typeswitch against interface types.
type A interface { a() }
type B interface { b() }
type C interface { a(int) }

func typeswitch2() {
	switch A(nil).(type) {
	case A:
	case B:
	case C /* STRICT "cannot have dynamic type" */: // only an error in strict mode (issue 8561)
	}
}

func typeswitch3(x interface{}) {
	switch x.(type) {
	case int:
	case float64:
	case int /* ERROR duplicate case */ :
	}

	switch x.(type) {
	case nil:
	case int:
	case nil /* ERROR duplicate case */ , nil /* ERROR duplicate case */ :
	}

	type F func(int)
	switch x.(type) {
	case nil:
	case int, func(int):
	case float32, func /* ERROR duplicate case */ (x int):
	case F:
	}
}

func fors1() {
	for {}
	var i string
	_ = i
	for i := 0; i < 10; i++ {}
	for i := 0; i < 10; j /* ERROR cannot declare */ := 0 {}
}

func rangeloops1() {
	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 _ = range x /* ERROR "cannot range over" */ {}
	for i := range x /* ERROR "cannot range over" */ {}

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

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

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

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

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

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

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

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

func rangeloops2() {
	type I int
	type R rune

	var a [10]int
	var i I
	_ = i
	for i /* ERROR cannot assign */ = range a {}
	for i /* ERROR cannot assign */ = range &a {}
	for i /* ERROR cannot assign */ = range a[:] {}

	var s string
	var r R
	_ = r
	for i /* ERROR cannot assign */ = range s {}
	for i /* ERROR cannot assign */ = range "foo" {}
	for _, r /* ERROR cannot assign */ = range s {}
	for _, r /* ERROR cannot assign */ = range "foo" {}
}

func issue6766b() {
	for _ := /* ERROR no new variables */ range "" {}
	for a, a /* ERROR redeclared */ := range "" { _ = a }
	var a int
	_ = a
	for a, a /* ERROR redeclared */ := range []int{1, 2, 3} { _ = a }
}

// Test that despite errors in the range clause,
// the loop body is still type-checked (and thus
// errors reported).
func issue10148() {
	for y /* ERROR declared but not used */ := range "" {
		_ = "" /* ERROR cannot convert */ + 1
	}
	for range 1 /* ERROR cannot range over 1 */ {
		_ = "" /* ERROR cannot convert */ + 1
	}
	for y := range 1 /* ERROR cannot range over 1 */ {
		_ = "" /* ERROR cannot convert */ + 1
	}
}

func labels0() {
	goto L0
	goto L1
	L0:
	L1:
	L1 /* ERROR "already declared" */ :
	if true {
		goto L2		
		L2:
		L0 /* ERROR "already declared" */ :
	}
	_ = func() {
		goto L0
		goto L1
		goto L2
		L0:
		L1:
		L2:
	}
}

func expression_statements(ch chan int) {
	expression_statements(ch)
	<-ch
	println()

	0 /* ERROR "not used" */
	1 /* ERROR "not used" */ +2
	cap /* ERROR "not used" */ (ch)
	println /* ERROR "must be called" */
}
