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

// type aliases

package decls4

type (
	T0 [10]int
	T1 []byte
	T2 struct {
		x int
	}
	T3 interface{
		m() T2
	}
	T4 func(int, T0) chan T2
)

type (
	Ai = int
	A0 = T0
	A1 = T1
	A2 = T2
	A3 = T3
	A4 = T4

	A10 = [10]int
	A11 = []byte
	A12 = struct {
		x int
	}
	A13 = interface{
		m() A2
	}
	A14 = func(int, A0) chan A2
)

// check assignment compatibility due to equality of types
var (
	xi_ int
	ai Ai = xi_

	x0 T0
	a0 A0 = x0

	x1 T1
	a1 A1 = x1

	x2 T2
	a2 A2 = x2

	x3 T3
	a3 A3 = x3

	x4 T4
	a4 A4 = x4
)

// alias receiver types
func (Ai /* ERROR "cannot define new methods on non-local type int" */) m1() {}
func (T0) m1() {}
func (A0) m1 /* ERROR already declared */ () {}
func (A0) m2 () {}
func (A3 /* ERROR invalid receiver */ ) m1 () {}
func (A10 /* ERROR invalid receiver */ ) m1() {}

// x0 has methods m1, m2 declared via receiver type names T0 and A0
var _ interface{ m1(); m2() } = x0

// alias receiver types (test case for issue #23042)
type T struct{}

var (
	_ = T.m
	_ = T{}.m
	_ interface{m()} = T{}
)

var (
	_ = T.n
	_ = T{}.n
	_ interface{m(); n()} = T{}
)

type U = T
func (U) m() {}

// alias receiver types (long type declaration chains)
type (
	V0 = V1
	V1 = (V2)
	V2 = ((V3))
	V3 = T
)

func (V0) m /* ERROR already declared */ () {}
func (V1) n() {}

// alias receiver types (invalid due to cycles)
type (
	W0 /* ERROR illegal cycle */ = W1
	W1 = (W2)
	W2 = ((W0))
)

func (W0) m() {} // no error expected (due to above cycle error)
func (W1) n() {}

// alias receiver types (invalid due to builtin underlying type)
type (
	B0 = B1
	B1 = B2
	B2 = int
)

func (B0 /* ERROR cannot define new methods on non-local type int */ ) m() {}
func (B1 /* ERROR cannot define new methods on non-local type int */ ) n() {}

// cycles
type (
	C2 /* ERROR illegal cycle */ = C2
	C3 /* ERROR illegal cycle */ = C4
	C4 = C3
	C5 struct {
		f *C6
	}
	C6 = C5
	C7 /* ERROR illegal cycle */  struct {
		f C8
	}
	C8 = C7
)

// embedded fields
var (
	s0 struct { T0 }
	s1 struct { A0 } = s0 /* ERROR cannot use */ // embedded field names are different
)

// embedding and lookup of fields and methods
func _(s struct{A0}) { s.A0 = x0 }

type eX struct{xf int}

func (eX) xm()

type eY = struct{eX} // field/method set of eY includes xf, xm

type eZ = *struct{eX} // field/method set of eZ includes xf, xm

type eA struct {
	eX // eX contributes xf, xm to eA
}

type eA2 struct {
	*eX // *eX contributes xf, xm to eA
}

type eB struct {
	eY // eY contributes xf, xm to eB
}

type eB2 struct {
	*eY // *eY contributes xf, xm to eB
}

type eC struct {
	eZ // eZ contributes xf, xm to eC
}

var (
	_ = eA{}.xf
	_ = eA{}.xm
	_ = eA2{}.xf
	_ = eA2{}.xm
	_ = eB{}.xf
	_ = eB{}.xm
	_ = eB2{}.xf
	_ = eB2{}.xm
	_ = eC{}.xf
	_ = eC{}.xm
)

// ambiguous selectors due to embedding via type aliases
type eD struct {
	eY
	eZ
}

var (
	_ = eD{}.xf /* ERROR ambiguous selector \(eD literal\).xf */
	_ = eD{}.xm /* ERROR ambiguous selector \(eD literal\).xm */
)

var (
	_ interface{ xm() } = eD /* ERROR missing method xm */ {}
)