// run -gcflags=-G=3

// Copyright 2021 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 test case stress tests a number of subtle cases involving
// nested type-parameterized declarations. At a high-level, it
// declares a generic function that contains a generic type
// declaration:
//
//	func F[A intish]() {
//		type T[B intish] struct{}
//
//		// store reflect.Type tuple (A, B, F[A].T[B]) in tests
//	}
//
// It then instantiates this function with a variety of type arguments
// for A and B. Particularly tricky things like shadowed types.
//
// From this data it tests two things:
//
// 1. Given tuples (A, B, F[A].T[B]) and (A', B', F[A'].T[B']),
//    F[A].T[B] should be identical to F[A'].T[B'] iff (A, B) is
//    identical to (A', B').
//
// 2. A few of the instantiations are constructed to be identical, and
//    it tests that exactly these pairs are duplicated (by golden
//    output comparison to nested.out).
//
// In both cases, we're effectively using the compiler's existing
// runtime.Type handling (which is well tested) of type identity of A
// and B as a way to help bootstrap testing and validate its new
// runtime.Type handling of F[A].T[B].
//
// This isn't perfect, but it smoked out a handful of issues in
// gotypes2 and unified IR.

package main

import (
	"fmt"
	"reflect"
)

type test struct {
	TArgs    [2]reflect.Type
	Instance reflect.Type
}

var tests []test

type intish interface{ ~int }

type Int int
type GlobalInt = Int // allow access to global Int, even when shadowed

func F[A intish]() {
	add := func(B, T interface{}) {
		tests = append(tests, test{
			TArgs: [2]reflect.Type{
				reflect.TypeOf(A(0)),
				reflect.TypeOf(B),
			},
			Instance: reflect.TypeOf(T),
		})
	}

	type Int int

	type T[B intish] struct{}

	add(int(0), T[int]{})
	add(Int(0), T[Int]{})
	add(GlobalInt(0), T[GlobalInt]{})
	add(A(0), T[A]{}) // NOTE: intentionally dups with int and GlobalInt

	type U[_ any] int
	type V U[int]
	type W V

	add(U[int](0), T[U[int]]{})
	add(U[Int](0), T[U[Int]]{})
	add(U[GlobalInt](0), T[U[GlobalInt]]{})
	add(U[A](0), T[U[A]]{}) // NOTE: intentionally dups with U[int] and U[GlobalInt]
	add(V(0), T[V]{})
	add(W(0), T[W]{})
}

func main() {
	type Int int

	F[int]()
	F[Int]()
	F[GlobalInt]()

	type U[_ any] int
	type V U[int]
	type W V

	F[U[int]]()
	F[U[Int]]()
	F[U[GlobalInt]]()
	F[V]()
	F[W]()

	type X[A any] U[X[A]]

	F[X[int]]()
	F[X[Int]]()
	F[X[GlobalInt]]()

	for j, tj := range tests {
		for i, ti := range tests[:j+1] {
			if (ti.TArgs == tj.TArgs) != (ti.Instance == tj.Instance) {
				fmt.Printf("FAIL: %d,%d: %s, but %s\n", i, j, eq(ti.TArgs, tj.TArgs), eq(ti.Instance, tj.Instance))
			}

			// The test is constructed so we should see a few identical types.
			// See "NOTE" comments above.
			if i != j && ti.Instance == tj.Instance {
				fmt.Printf("%d,%d: %v\n", i, j, ti.Instance)
			}
		}
	}
}

func eq(a, b interface{}) string {
	op := "=="
	if a != b {
		op = "!="
	}
	return fmt.Sprintf("%v %s %v", a, op, b)
}
