codekingpro/portable-devtools
114k
1// run2 3// Copyright 2021 The Go Authors. All rights reserved.4// Use of this source code is governed by a BSD-style5// license that can be found in the LICENSE file.6 7// This test case stress tests a number of subtle cases involving8// nested type-parameterized declarations. At a high-level, it9// declares a generic function that contains a generic type10// declaration:11//12// func F[A intish]() {13// type T[B intish] struct{}14//15// // store reflect.Type tuple (A, B, F[A].T[B]) in tests16// }17//18// It then instantiates this function with a variety of type arguments19// for A and B. Particularly tricky things like shadowed types.20//21// From this data it tests two things:22//23// 1. Given tuples (A, B, F[A].T[B]) and (A', B', F[A'].T[B']),24// F[A].T[B] should be identical to F[A'].T[B'] iff (A, B) is25// identical to (A', B').26//27// 2. A few of the instantiations are constructed to be identical, and28// it tests that exactly these pairs are duplicated (by golden29// output comparison to nested.out).30//31// In both cases, we're effectively using the compiler's existing32// runtime.Type handling (which is well tested) of type identity of A33// and B as a way to help bootstrap testing and validate its new34// runtime.Type handling of F[A].T[B].35//36// This isn't perfect, but it smoked out a handful of issues in37// gotypes2 and unified IR.38 39package main40 41import (42 "fmt"43 "reflect"44)45 46type test struct {47 TArgs [2]reflect.Type48 Instance reflect.Type49}50 51var tests []test52 53type intish interface{ ~int }54 55type Int int56type GlobalInt = Int // allow access to global Int, even when shadowed57 58func F[A intish]() {59 add := func(B, T interface{}) {60 tests = append(tests, test{61 TArgs: [2]reflect.Type{62 reflect.TypeOf(A(0)),63 reflect.TypeOf(B),64 },65 Instance: reflect.TypeOf(T),66 })67 }68 69 type Int int70 71 type T[B intish] struct{}72 73 add(int(0), T[int]{})74 add(Int(0), T[Int]{})75 add(GlobalInt(0), T[GlobalInt]{})76 add(A(0), T[A]{}) // NOTE: intentionally dups with int and GlobalInt77 78 type U[_ any] int79 type V U[int]80 type W V81 82 add(U[int](0), T[U[int]]{})83 add(U[Int](0), T[U[Int]]{})84 add(U[GlobalInt](0), T[U[GlobalInt]]{})85 add(U[A](0), T[U[A]]{}) // NOTE: intentionally dups with U[int] and U[GlobalInt]86 add(V(0), T[V]{})87 add(W(0), T[W]{})88}89 90func main() {91 type Int int92 93 F[int]()94 F[Int]()95 F[GlobalInt]()96 97 type U[_ any] int98 type V U[int]99 type W V100 101 F[U[int]]()102 F[U[Int]]()103 F[U[GlobalInt]]()104 F[V]()105 F[W]()106 107 type X[A any] U[X[A]]108 109 F[X[int]]()110 F[X[Int]]()111 F[X[GlobalInt]]()112 113 for j, tj := range tests {114 for i, ti := range tests[:j+1] {115 if (ti.TArgs == tj.TArgs) != (ti.Instance == tj.Instance) {116 fmt.Printf("FAIL: %d,%d: %s, but %s\n", i, j, eq(ti.TArgs, tj.TArgs), eq(ti.Instance, tj.Instance))117 }118 119 // The test is constructed so we should see a few identical types.120 // See "NOTE" comments above.121 if i != j && ti.Instance == tj.Instance {122 fmt.Printf("%d,%d: %v\n", i, j, ti.Instance)123 }124 }125 }126}127 128func eq(a, b interface{}) string {129 op := "=="130 if a != b {131 op = "!="132 }133 return fmt.Sprintf("%v %s %v", a, op, b)134}135 