// 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 cycle */ = 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 */ [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 */ struct {
	f func() T16
	b T16
}

type T16 struct {
	T15
}