// 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 to type parameter type (below: *T)
// we don't have any methods, like for interfaces.
type C[T any] interface {
    m()
}

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

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

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{~uint}] struct{}

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

// This is the original (simplified) program causing the same issue.
type Unsigned interface {
	~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 constraints */ ] {
    return T2[U /* ERROR U has no 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 /* ERROR illegal cycle */ [T any] struct{ _ inf1[T] }
type inf2 /* ERROR illegal cycle */ [T any] struct{ inf2[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{~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{~int | ~string}](x, y T) T {
	return x + y
}

// Simplified, from https://go2goplay.golang.org/p/efS6x6s-9NI:
func Sum[T interface{~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{~*T}] (x T) PT {
    return &x
}

// Indexing of generic types containing type parameters in their type list:
func at[T interface{ ~[]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{~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 { ~[10]int }](x T) {
	_ = x[9] // ok
	_ = x[20 /* ERROR out of bounds */ ]
}

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

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

// Calling of a generic variable.
func _[T interface{ ~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{ ~[]E }

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

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 { panic(0) }

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