|
5 | 5 | "go/types" |
6 | 6 | "regexp" |
7 | 7 | "sort" |
| 8 | + "strings" |
8 | 9 | "testing" |
9 | 10 | "time" |
10 | 11 |
|
@@ -749,6 +750,62 @@ func TestArchiveSelectionAfterSerialization(t *testing.T) { |
749 | 750 | } |
750 | 751 | } |
751 | 752 |
|
| 753 | +func TestNestedTypesDuplicateDecls(t *testing.T) { |
| 754 | + // This is a subset of the type param nested test. |
| 755 | + // See https://github.com/golang/go/blob/go1.19.13/test/typeparam/nested.go |
| 756 | + // The test is failing because nested types aren't being typed differently. |
| 757 | + // For example the type of `T[int]` below is different based on `F[X]` |
| 758 | + // instance for different `X` type parameters, hence Go prints the type as |
| 759 | + // `T[X;int]` instead of `T[int]`. |
| 760 | + |
| 761 | + src := ` |
| 762 | + package main |
| 763 | +
|
| 764 | + type intish interface { ~int } |
| 765 | +
|
| 766 | + func F[A intish]() { |
| 767 | + type T[B intish] struct{} |
| 768 | + print(T[int]{}) |
| 769 | + } |
| 770 | +
|
| 771 | + func main() { |
| 772 | + type Int int |
| 773 | +
|
| 774 | + F[int]() |
| 775 | + F[Int]() |
| 776 | + }` |
| 777 | + |
| 778 | + srcFiles := []srctesting.Source{{Name: `main.go`, Contents: []byte(src)}} |
| 779 | + root := srctesting.ParseSources(t, srcFiles, nil) |
| 780 | + archives := compileProject(t, root, false) |
| 781 | + mainPkg := archives[root.PkgPath] |
| 782 | + |
| 783 | + // Regex to match strings like `Foo[42 /* bar */] =` and capture |
| 784 | + // the name (`Foo`), the index (`42`), and the instance type (`bar`). |
| 785 | + rex := regexp.MustCompile(`^\s*(\w+)\s*\[\s*(\d+)\s*\/\*(.+)\*\/\s*\]\s*\=`) |
| 786 | + |
| 787 | + // Collect all instances of generics (i.e. `Foo[bar]`) written to the decl code. |
| 788 | + insts := []string{} |
| 789 | + for _, decl := range mainPkg.Declarations { |
| 790 | + if match := rex.FindAllStringSubmatch(string(decl.DeclCode), 1); len(match) > 0 { |
| 791 | + instance := match[0][1] + `[` + strings.TrimSpace(match[0][3]) + `]` |
| 792 | + instance = strings.ReplaceAll(instance, `command-line-arguments.`, ``) |
| 793 | + insts = append(insts, instance) |
| 794 | + } |
| 795 | + } |
| 796 | + sort.Strings(insts) |
| 797 | + |
| 798 | + exp := []string{ |
| 799 | + `F[Int]`, |
| 800 | + `F[int]`, |
| 801 | + `T[Int;int]`, |
| 802 | + `T[int;int]`, |
| 803 | + } |
| 804 | + if diff := cmp.Diff(exp, insts); len(diff) > 0 { |
| 805 | + t.Errorf("the instances of generics are different:\n%s", diff) |
| 806 | + } |
| 807 | +} |
| 808 | + |
752 | 809 | func compareOrder(t *testing.T, sourceFiles []srctesting.Source, minify bool) { |
753 | 810 | t.Helper() |
754 | 811 | outputNormal := compile(t, sourceFiles, minify) |
|
0 commit comments