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

// This file contains regression tests for bugs found.

package p

import "io"
import "context"

// Interfaces are always comparable (though the comparison may panic at runtime).
func eql[T comparable](x, y T) bool {
	return x == y
}

func _() {
	var x interface{}
	var y interface{ m() }
	eql(x, y /* ERROR does not match */ ) // interfaces of different types
	eql(x, x)
	eql(y, y)
	eql(y, nil)
	eql[io.Reader](nil, nil)
}

// If we have a receiver of pointer type (below: *T) we must ignore
// the pointer in the implementation of the method lookup because
// the type bound of T is an interface and pointer to interface types
// have no methods and then the lookup would fail.
type C[T any] interface {
    m()
}

// using type bound C
func _[T C[T]](x *T) {
	x.m()
}

// using an interface literal as bound
func _[T interface{ m() }](x *T) {
	x.m()
}

func f2[_ interface{ m1(); m2() }]()

type T struct{}
func (T) m1()
func (*T) m2()

func _() {
	f2[T /* ERROR wrong method signature */ ]()
	f2[*T]()
}

// When a type parameter is used as an argument to instantiate a parameterized
// type with a type list constraint, all of the type argument's types in its
// bound, but at least one (!), must be in the type list of the bound of the
// corresponding parameterized type's type parameter.
type T1[P interface{type uint}] struct{}

func _[P any]() {
    _ = T1[P /* ERROR P has no type constraints */ ]{}
}

// This is the original (simplified) program causing the same issue.
type Unsigned interface {
	type uint
}

type T2[U Unsigned] struct {
    s U
}

func (u T2[U]) Add1() U {
    return u.s + 1
}

func NewT2[U any]() T2[U /* ERROR U has no type constraints */ ] {
    return T2[U /* ERROR U has no type constraints */ ]{}
}

func _() {
    u := NewT2[string]()
    _ = u.Add1()
}

// When we encounter an instantiated type such as Elem[T] we must
// not "expand" the instantiation when the type to be instantiated
// (Elem in this case) is not yet fully set up.
type Elem[T any] struct {
	next *Elem[T]
	list *List[T]
}

type List[T any] struct {
	root Elem[T]
}

func (l *List[T]) Init() {
	l.root.next = &l.root
}

// This is the original program causing the same issue.
type Element2[TElem any] struct {
	next, prev *Element2[TElem]
	list *List2[TElem]
	Value TElem
}

type List2[TElem any] struct {
	root Element2[TElem]
	len  int
}

func (l *List2[TElem]) Init() *List2[TElem] {
	l.root.next = &l.root
	l.root.prev = &l.root
	l.len = 0
	return l
}

// Self-recursive instantiations must work correctly.
type A[P any] struct { _ *A[P] }

type AB[P any] struct { _ *BA[P] }
type BA[P any] struct { _ *AB[P] }

// And a variation that also caused a problem with an
// unresolved underlying type.
type Element3[TElem any] struct {
	next, prev *Element3[TElem]
	list *List3[TElem]
	Value TElem
}

func (e *Element3[TElem]) Next() *Element3[TElem] {
	if p := e.next; e.list != nil && p != &e.list.root {
		return p
	}
	return nil
}

type List3[TElem any] struct {
	root Element3[TElem]
	len  int
}

// Infinite generic type declarations must lead to an error.
type inf1[T any] struct{ _ inf1 /* ERROR illegal cycle */ [T] }
type inf2[T any] struct{ inf2 /* ERROR illegal cycle */ [T] }

// The implementation of conversions T(x) between integers and floating-point
// numbers checks that both T and x have either integer or floating-point
// type. When the type of T or x is a type parameter, the respective simple
// predicate disjunction in the implementation was wrong because if a type list
// contains both an integer and a floating-point type, the type parameter is
// neither an integer or a floating-point number.
func convert[T1, T2 interface{type int, uint, float32}](v T1) T2 {
	return T2(v)
}

func _() {
	convert[int, uint](5)
}

// When testing binary operators, for +, the operand types must either be
// both numeric, or both strings. The implementation had the same problem
// with this check as the conversion issue above (issue #39623).

func issue39623[T interface{type int, string}](x, y T) T {
	return x + y
}

// Simplified, from https://go2goplay.golang.org/p/efS6x6s-9NI:
func Sum[T interface{type int, string}](s []T) (sum T) {
	for _, v := range s {
		sum += v
	}
	return
}

// Assignability of an unnamed pointer type to a type parameter that
// has a matching underlying type.
func _[T interface{}, PT interface{type *T}] (x T) PT {
    return &x
}

// Indexing of generic types containing type parameters in their type list:
func at[T interface{ type []E }, E interface{}](x T, i int) E {
        return x[i]
}

// A generic type inside a function acts like a named type. Its underlying
// type is itself, its "operational type" is defined by the type list in
// the tybe bound, if any.
func _[T interface{type int}](x T) {
	type myint int
	var _ int = int(x)
	var _ T = 42
	var _ T = T(myint(42))
}

// Indexing a generic type with an array type bound checks length.
// (Example by mdempsky@.)
func _[T interface { type [10]int }](x T) {
	_ = x[9] // ok
	_ = x[20 /* ERROR out of bounds */ ]
}

// Pointer indirection of a generic type.
func _[T interface{ type *int }](p T) int {
	return *p
}

// Channel sends and receives on generic types.
func _[T interface{ type chan int }](ch T) int {
	ch <- 0
	return <- ch
}

// Calling of a generic variable.
func _[T interface{ type func() }](f T) {
	f()
	go f()
}

// We must compare against the underlying type of type list entries
// when checking if a constraint is satisfied by a type. The under-
// lying type of each type list entry must be computed after the
// interface has been instantiated as its typelist may contain a
// type parameter that was substituted with a defined type.
// Test case from an (originally) failing example.

type sliceOf[E any] interface{ type []E }

func append[T interface{}, S sliceOf[T], T2 interface{ type T }](s S, t ...T2) S

var f           func()
var cancelSlice []context.CancelFunc
var _ = append[context.CancelFunc, []context.CancelFunc, context.CancelFunc](cancelSlice, f)

// A generic function must be instantiated with a type, not a value.

func g[T any](T) T

var _ = g[int]
var _ = g[nil /* ERROR is not a type */ ]
var _ = g(0)
