// 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 _() {
	// TODO(rFindley) this error should be positioned on the 'T'.
	f2 /* ERROR wrong method signature */ [T]()
	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)
