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

package p

import "unsafe"

// test case from issue #18395

type (
	A interface { B }
	B interface { C }
	C interface { D; F() A }
	D interface { G() B }
)

var _ = A(nil).G // G must be found


// test case from issue #21804

type sourceBridge interface {
	listVersions() ([]Version, error)
}

type Constraint interface {
	copyTo(*ConstraintMsg)
}

type ConstraintMsg struct{}

func (m *ConstraintMsg) asUnpairedVersion() UnpairedVersion {
	return nil
}

type Version interface {
	Constraint
}

type UnpairedVersion interface {
	Version
}

var _ Constraint = UnpairedVersion(nil)


// derived test case from issue #21804

type (
	_ interface{ m(B1) }
	A1 interface{ a(D1) }
	B1 interface{ A1 }
	C1 interface{ B1 }
	D1 interface{ C1 }
)

var _ A1 = C1(nil)


// derived test case from issue #22701

func F(x I4) interface{} {
	return x.Method()
}

type Unused interface {
	RefersToI1(a I1)
}

type I1 interface {
	I2
	I3
}

type I2 interface {
	RefersToI4() I4
}

type I3 interface {
	Method() interface{}
}

type I4 interface {
	I1
}


// check embedding of error interface

type Error interface{ error }

var err Error
var _ = err.Error()


// more esoteric cases

type (
	T1 interface { T2 }
	T2 /* ERROR invalid recursive type */ T2
)

type (
	T3 interface { T4 }
	T4 /* ERROR invalid recursive type */ T5
	T5 = T6
	T6 = T7
	T7 = T4
)


// arbitrary code may appear inside an interface

const n = unsafe.Sizeof(func(){})

type I interface {
	m([unsafe.Sizeof(func() { I.m(nil, [n]byte{}) })]byte)
}


// test cases for varias alias cycles

type T10 /* ERROR invalid recursive type */ = *T10                 // issue #25141
type T11 /* ERROR invalid recursive type */ = interface{ f(T11) }  // issue #23139

// issue #18640
type (
	aa = bb
	bb struct {
		*aa
	}
)

type (
	a struct{ *b }
	b = c
	c struct{ *b /* ERROR invalid use of type alias */ }
)

// issue #24939
type (
	_ interface {
		M(P)
	}

	M interface {
		F() P // ERROR invalid use of type alias
	}

	P = interface {
		I() M
	}
)

// issue #8699
type T12 /* ERROR invalid recursive type */ [len(a12)]int
var a12 = makeArray()
func makeArray() (res T12) { return }

// issue #20770
var r /* ERROR invalid cycle in declaration of r */ = newReader()
func newReader() r

// variations of the theme of #8699 and #20770
var arr /* ERROR cycle */ = f()
func f() [len(arr)]int

// issue #25790
func ff(ff /* ERROR not a type */ )
func gg((gg /* ERROR not a type */ ))

type T13 /* ERROR invalid recursive type T13 */ [len(b13)]int
var b13 T13

func g1() [unsafe.Sizeof(g1)]int
func g2() [unsafe.Sizeof(x2)]int
var x2 = g2

// verify that we get the correct sizes for the functions above
// (note: assert is statically evaluated in go/types test mode)
func init() {
	assert(unsafe.Sizeof(g1) == 8)
	assert(unsafe.Sizeof(x2) == 8)
}

func h() [h /* ERROR no value */ ()[0]]int { panic(0) }

var c14 /* ERROR cycle */ T14
type T14 [uintptr(unsafe.Sizeof(&c14))]byte

// issue #34333
type T15 /* ERROR invalid recursive type T15 */ struct {
	f func() T16
	b T16
}

type T16 struct {
	T15
}