blob: 5df3d493f8a4fcb31c09bfd2b5ef73949bded9ae [file] [log] [blame]
Dan Willemsenbc60c3c2021-12-15 01:09:00 -08001// Copyright 2021 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package types_test
6
7import (
8 "bytes"
9 "errors"
10 "fmt"
11 "go/ast"
12 "go/importer"
13 "go/parser"
14 "go/token"
15 "go/types"
16 "strings"
17 "testing"
18)
19
20func checkMono(t *testing.T, body string) error {
21 fset := token.NewFileSet()
22 file, err := parser.ParseFile(fset, "x.go", "package x; import `unsafe`; var _ unsafe.Pointer;\n"+body, 0)
23 if err != nil {
24 t.Fatal(err)
25 }
26 files := []*ast.File{file}
27
28 var buf bytes.Buffer
29 conf := types.Config{
30 Error: func(err error) { fmt.Fprintln(&buf, err) },
31 Importer: importer.Default(),
32 }
33 conf.Check("x", fset, files, nil)
34 if buf.Len() == 0 {
35 return nil
36 }
37 return errors.New(strings.TrimRight(buf.String(), "\n"))
38}
39
40func TestMonoGood(t *testing.T) {
41 for i, good := range goods {
42 if err := checkMono(t, good); err != nil {
43 t.Errorf("%d: unexpected failure: %v", i, err)
44 }
45 }
46}
47
48func TestMonoBad(t *testing.T) {
49 for i, bad := range bads {
50 if err := checkMono(t, bad); err == nil {
51 t.Errorf("%d: unexpected success", i)
52 } else {
53 t.Log(err)
54 }
55 }
56}
57
58var goods = []string{
59 "func F[T any](x T) { F(x) }",
60 "func F[T, U, V any]() { F[U, V, T](); F[V, T, U]() }",
61 "type Ring[A, B, C any] struct { L *Ring[B, C, A]; R *Ring[C, A, B] }",
62 "func F[T any]() { type U[T any] [unsafe.Sizeof(F[*T])]byte }",
63 "func F[T any]() { type U[T any] [unsafe.Sizeof(F[*T])]byte; var _ U[int] }",
64 "type U[T any] [unsafe.Sizeof(F[*T])]byte; func F[T any]() { var _ U[U[int]] }",
65 "func F[T any]() { type A = int; F[A]() }",
66}
67
68// TODO(mdempsky): Validate specific error messages and positioning.
69
70var bads = []string{
71 "func F[T any](x T) { F(&x) }",
72 "func F[T any]() { F[*T]() }",
73 "func F[T any]() { F[[]T]() }",
74 "func F[T any]() { F[[1]T]() }",
75 "func F[T any]() { F[chan T]() }",
76 "func F[T any]() { F[map[*T]int]() }",
77 "func F[T any]() { F[map[error]T]() }",
78 "func F[T any]() { F[func(T)]() }",
79 "func F[T any]() { F[func() T]() }",
80 "func F[T any]() { F[struct{ t T }]() }",
81 "func F[T any]() { F[interface{ t() T }]() }",
82 "type U[_ any] int; func F[T any]() { F[U[T]]() }",
83 "func F[T any]() { type U int; F[U]() }",
84 "func F[T any]() { type U int; F[*U]() }",
85 "type U[T any] int; func (U[T]) m() { var _ U[*T] }",
86 "type U[T any] int; func (*U[T]) m() { var _ U[*T] }",
87 "type U[T1 any] [unsafe.Sizeof(F[*T1])]byte; func F[T2 any]() { var _ U[T2] }",
88 "func F[A, B, C, D, E any]() { F[B, C, D, E, *A]() }",
89 "type U[_ any] int; const X = unsafe.Sizeof(func() { type A[T any] U[A[*T]] })",
90 "func F[T any]() { type A = *T; F[A]() }",
91 "type A[T any] struct { _ A[*T] }",
92}