]> Cypherpunks.ru repositories - gostls13.git/blobdiff - src/cmd/compile/internal/types2/issues_test.go
go/types, types2: implement Alias proposal (export API)
[gostls13.git] / src / cmd / compile / internal / types2 / issues_test.go
index ba7cefb8925a8ae6c20c68e86b7666c0176d581e..95b9f940784da4481680009b31c24c45e42ae7e2 100644 (file)
@@ -1,4 +1,3 @@
-// UNREVIEWED
 // Copyright 2013 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.
@@ -8,10 +7,10 @@
 package types2_test
 
 import (
-       "bytes"
        "cmd/compile/internal/syntax"
        "fmt"
        "internal/testenv"
+       "regexp"
        "sort"
        "strings"
        "testing"
@@ -19,19 +18,9 @@ import (
        . "cmd/compile/internal/types2"
 )
 
-func mustParse(t *testing.T, src string) *syntax.File {
-       f, err := parseSrc("", src)
-       if err != nil {
-               t.Fatal(err)
-       }
-       return f
-}
 func TestIssue5770(t *testing.T) {
-       f := mustParse(t, `package p; type S struct{T}`)
-       var conf Config
-       // conf := Config{Importer: importer.Default()}
-       _, err := conf.Check(f.PkgName.Value, []*syntax.File{f}, nil) // do not crash
-       want := "undeclared name: T"
+       _, err := typecheck(`package p; type S struct{T}`, nil, nil)
+       const want = "undefined: T"
        if err == nil || !strings.Contains(err.Error(), want) {
                t.Errorf("got: %v; want: %s", err, want)
        }
@@ -49,14 +38,8 @@ var (
        _ = (interface{})("foo")
        _ = (interface{})(nil)
 )`
-       f := mustParse(t, src)
-
-       var conf Config
        types := make(map[syntax.Expr]TypeAndValue)
-       _, err := conf.Check(f.PkgName.Value, []*syntax.File{f}, &Info{Types: types})
-       if err != nil {
-               t.Fatal(err)
-       }
+       mustTypecheck(src, nil, &Info{Types: types})
 
        for x, tv := range types {
                var want Type
@@ -76,7 +59,7 @@ var (
                        }
                case *syntax.Name:
                        if x.Value == "nil" {
-                               want = NewInterfaceType(nil, nil) // interface{}
+                               want = NewInterfaceType(nil, nil) // interface{} (for now, go/types types this as "untyped nil")
                        }
                }
                if want != nil && !Identical(tv.Type, want) {
@@ -94,14 +77,8 @@ func f() int {
        return 0
 }
 `
-       f := mustParse(t, src)
-
-       var conf Config
        types := make(map[syntax.Expr]TypeAndValue)
-       _, err := conf.Check(f.PkgName.Value, []*syntax.File{f}, &Info{Types: types})
-       if err != nil {
-               t.Fatal(err)
-       }
+       mustTypecheck(src, nil, &Info{Types: types})
 
        want := Typ[Int]
        n := 0
@@ -125,7 +102,7 @@ package p
 func (T) m() (res bool) { return }
 type T struct{} // receiver type after method declaration
 `
-       f := mustParse(t, src)
+       f := mustParse(src)
 
        var conf Config
        defs := make(map[*syntax.Name]Object)
@@ -156,8 +133,6 @@ func _() {
         _, _, _ = x, y, z  // uses x, y, z
 }
 `
-       f := mustParse(t, src)
-
        const want = `L3 defs func p._()
 L4 defs const w untyped int
 L5 defs var x int
@@ -173,8 +148,8 @@ L7 uses var z int`
        conf := Config{Error: func(err error) { t.Log(err) }}
        defs := make(map[*syntax.Name]Object)
        uses := make(map[*syntax.Name]Object)
-       _, err := conf.Check(f.PkgName.Value, []*syntax.File{f}, &Info{Defs: defs, Uses: uses})
-       if s := fmt.Sprint(err); !strings.HasSuffix(s, "cannot assign to w") {
+       _, err := typecheck(src, &conf, &Info{Defs: defs, Uses: uses})
+       if s := err.Error(); !strings.HasSuffix(s, "cannot assign to w") {
                t.Errorf("Check: unexpected error: %s", s)
        }
 
@@ -197,7 +172,7 @@ L7 uses var z int`
        }
 }
 
-// This tests that the package associated with the types.Object.Pkg method
+// This tests that the package associated with the types2.Object.Pkg method
 // is the type's package independent of the order in which the imports are
 // listed in the sources src1, src2 below.
 // The actual issue is in go/internal/gcimporter which has a corresponding
@@ -252,13 +227,8 @@ func main() {
 }
 `
        f := func(test, src string) {
-               f := mustParse(t, src)
-               conf := Config{Importer: defaultImporter()}
-               info := Info{Uses: make(map[*syntax.Name]Object)}
-               _, err := conf.Check("main", []*syntax.File{f}, &info)
-               if err != nil {
-                       t.Fatal(err)
-               }
+               info := &Info{Uses: make(map[*syntax.Name]Object)}
+               mustTypecheck(src, nil, info)
 
                var pkg *Package
                count := 0
@@ -282,17 +252,17 @@ func main() {
 }
 
 func TestIssue22525(t *testing.T) {
-       f := mustParse(t, `package p; func f() { var a, b, c, d, e int }`)
+       const src = `package p; func f() { var a, b, c, d, e int }`
 
        got := "\n"
        conf := Config{Error: func(err error) { got += err.Error() + "\n" }}
-       conf.Check(f.PkgName.Value, []*syntax.File{f}, nil) // do not crash
+       typecheck(src, &conf, nil) // do not crash
        want := `
-:1:27: a declared but not used
-:1:30: b declared but not used
-:1:33: c declared but not used
-:1:36: d declared but not used
-:1:39: e declared but not used
+p:1:27: a declared and not used
+p:1:30: b declared and not used
+p:1:33: c declared and not used
+p:1:36: d declared and not used
+p:1:39: e declared and not used
 `
        if got != want {
                t.Errorf("got: %swant: %s", got, want)
@@ -312,7 +282,7 @@ func TestIssue25627(t *testing.T) {
                `struct { *I }`,
                `struct { a int; b Missing; *Missing }`,
        } {
-               f := mustParse(t, prefix+src)
+               f := mustParse(prefix + src)
 
                conf := Config{Importer: defaultImporter(), Error: func(err error) {}}
                info := &Info{Types: make(map[syntax.Expr]TypeAndValue)}
@@ -323,7 +293,7 @@ func TestIssue25627(t *testing.T) {
                        }
                }
 
-               syntax.Walk(f, func(n syntax.Node) bool {
+               syntax.Inspect(f, func(n syntax.Node) bool {
                        if decl, _ := n.(*syntax.TypeDecl); decl != nil {
                                if tv, ok := info.Types[decl.Type]; ok && decl.Name.Value == "T" {
                                        want := strings.Count(src, ";") + 1
@@ -332,7 +302,7 @@ func TestIssue25627(t *testing.T) {
                                        }
                                }
                        }
-                       return false
+                       return true
                })
        }
 }
@@ -349,7 +319,7 @@ func TestIssue28005(t *testing.T) {
        // compute original file ASTs
        var orig [len(sources)]*syntax.File
        for i, src := range sources {
-               orig[i] = mustParse(t, src)
+               orig[i] = mustParse(src)
        }
 
        // run the test for all order permutations of the incoming files
@@ -387,9 +357,6 @@ func TestIssue28005(t *testing.T) {
                        t.Fatal("object X not found")
                }
                iface := obj.Type().Underlying().(*Interface) // object X must be an interface
-               if iface == nil {
-                       t.Fatalf("%s is not an interface", obj)
-               }
 
                // Each iface method m is embedded; and m's receiver base type name
                // must match the method's name per the choice in the source file.
@@ -407,8 +374,9 @@ func TestIssue28282(t *testing.T) {
        // create type interface { error }
        et := Universe.Lookup("error").Type()
        it := NewInterfaceType(nil, []Type{et})
-       it.Complete()
        // verify that after completing the interface, the embedded method remains unchanged
+       // (interfaces are "completed" lazily now, so the completion happens implicitly when
+       // accessing Method(0))
        want := et.Underlying().(*Interface).Method(0)
        got := it.Method(0)
        if got != want {
@@ -426,12 +394,12 @@ func TestIssue28282(t *testing.T) {
 }
 
 func TestIssue29029(t *testing.T) {
-       f1 := mustParse(t, `package p; type A interface { M() }`)
-       f2 := mustParse(t, `package p; var B interface { A }`)
+       f1 := mustParse(`package p; type A interface { M() }`)
+       f2 := mustParse(`package p; var B interface { A }`)
 
        // printInfo prints the *Func definitions recorded in info, one *Func per line.
        printInfo := func(info *Info) string {
-               var buf bytes.Buffer
+               var buf strings.Builder
                for _, obj := range info.Defs {
                        if fn, ok := obj.(*Func); ok {
                                fmt.Fprintln(&buf, fn)
@@ -473,28 +441,25 @@ func TestIssue34151(t *testing.T) {
        const asrc = `package a; type I interface{ M() }; type T struct { F interface { I } }`
        const bsrc = `package b; import "a"; type T struct { F interface { a.I } }; var _ = a.T(T{})`
 
-       a, err := pkgFor("a", asrc, nil)
-       if err != nil {
-               t.Fatalf("package %s failed to typecheck: %v", a.Name(), err)
-       }
+       a := mustTypecheck(asrc, nil, nil)
 
-       bast := mustParse(t, bsrc)
-       conf := Config{Importer: importHelper{a}}
-       b, err := conf.Check(bast.PkgName.Value, []*syntax.File{bast}, nil)
-       if err != nil {
-               t.Errorf("package %s failed to typecheck: %v", b.Name(), err)
-       }
+       conf := Config{Importer: importHelper{pkg: a}}
+       mustTypecheck(bsrc, &conf, nil)
 }
 
 type importHelper struct {
-       pkg *Package
+       pkg      *Package
+       fallback Importer
 }
 
 func (h importHelper) Import(path string) (*Package, error) {
-       if path != h.pkg.Path() {
+       if path == h.pkg.Path() {
+               return h.pkg, nil
+       }
+       if h.fallback == nil {
                return nil, fmt.Errorf("got package path %q; want %q", path, h.pkg.Path())
        }
-       return h.pkg, nil
+       return h.fallback.Import(path)
 }
 
 // TestIssue34921 verifies that we don't update an imported type's underlying
@@ -517,37 +482,524 @@ func TestIssue34921(t *testing.T) {
 
        var pkg *Package
        for _, src := range sources {
-               f := mustParse(t, src)
-               conf := Config{Importer: importHelper{pkg}}
-               res, err := conf.Check(f.PkgName.Value, []*syntax.File{f}, nil)
-               if err != nil {
-                       t.Errorf("%q failed to typecheck: %v", src, err)
-               }
-               pkg = res // res is imported by the next package in this test
+               conf := Config{Importer: importHelper{pkg: pkg}}
+               pkg = mustTypecheck(src, &conf, nil) // pkg imported by the next package in this test
        }
 }
 
 func TestIssue43088(t *testing.T) {
        // type T1 struct {
-       //         x T2
+       //         _ T2
        // }
        //
        // type T2 struct {
-       //         x struct {
-       //                 x T2
+       //         _ struct {
+       //                 _ T2
        //         }
        // }
-       n1 := NewTypeName(syntax.Pos{}, nil, "T1", nil)
+       n1 := NewTypeName(nopos, nil, "T1", nil)
        T1 := NewNamed(n1, nil, nil)
-       n2 := NewTypeName(syntax.Pos{}, nil, "T2", nil)
+       n2 := NewTypeName(nopos, nil, "T2", nil)
        T2 := NewNamed(n2, nil, nil)
-       s1 := NewStruct([]*Var{NewField(syntax.Pos{}, nil, "x", T2, false)}, nil)
+       s1 := NewStruct([]*Var{NewField(nopos, nil, "_", T2, false)}, nil)
        T1.SetUnderlying(s1)
-       s2 := NewStruct([]*Var{NewField(syntax.Pos{}, nil, "x", T2, false)}, nil)
-       s3 := NewStruct([]*Var{NewField(syntax.Pos{}, nil, "x", s2, false)}, nil)
+       s2 := NewStruct([]*Var{NewField(nopos, nil, "_", T2, false)}, nil)
+       s3 := NewStruct([]*Var{NewField(nopos, nil, "_", s2, false)}, nil)
        T2.SetUnderlying(s3)
 
        // These calls must terminate (no endless recursion).
        Comparable(T1)
        Comparable(T2)
 }
+
+func TestIssue44515(t *testing.T) {
+       typ := Unsafe.Scope().Lookup("Pointer").Type()
+
+       got := TypeString(typ, nil)
+       want := "unsafe.Pointer"
+       if got != want {
+               t.Errorf("got %q; want %q", got, want)
+       }
+
+       qf := func(pkg *Package) string {
+               if pkg == Unsafe {
+                       return "foo"
+               }
+               return ""
+       }
+       got = TypeString(typ, qf)
+       want = "foo.Pointer"
+       if got != want {
+               t.Errorf("got %q; want %q", got, want)
+       }
+}
+
+func TestIssue43124(t *testing.T) {
+       // TODO(rFindley) move this to testdata by enhancing support for importing.
+
+       testenv.MustHaveGoBuild(t) // The go command is needed for the importer to determine the locations of stdlib .a files.
+
+       // All involved packages have the same name (template). Error messages should
+       // disambiguate between text/template and html/template by printing the full
+       // path.
+       const (
+               asrc = `package a; import "text/template"; func F(template.Template) {}; func G(int) {}`
+               bsrc = `
+package b
+
+import (
+       "a"
+       "html/template"
+)
+
+func _() {
+       // Packages should be fully qualified when there is ambiguity within the
+       // error string itself.
+       a.F(template /* ERRORx "cannot use.*html/template.* as .*text/template" */ .Template{})
+}
+`
+               csrc = `
+package c
+
+import (
+       "a"
+       "fmt"
+       "html/template"
+)
+
+// go.dev/issue/46905: make sure template is not the first package qualified.
+var _ fmt.Stringer = 1 // ERRORx "cannot use 1.*as fmt\\.Stringer"
+
+// Packages should be fully qualified when there is ambiguity in reachable
+// packages. In this case both a (and for that matter html/template) import
+// text/template.
+func _() { a.G(template /* ERRORx "cannot use .*html/template.*Template" */ .Template{}) }
+`
+
+               tsrc = `
+package template
+
+import "text/template"
+
+type T int
+
+// Verify that the current package name also causes disambiguation.
+var _ T = template /* ERRORx "cannot use.*text/template.* as T value" */.Template{}
+`
+       )
+
+       a := mustTypecheck(asrc, nil, nil)
+       imp := importHelper{pkg: a, fallback: defaultImporter()}
+
+       withImporter := func(cfg *Config) {
+               cfg.Importer = imp
+       }
+
+       testFiles(t, []string{"b.go"}, [][]byte{[]byte(bsrc)}, 0, false, withImporter)
+       testFiles(t, []string{"c.go"}, [][]byte{[]byte(csrc)}, 0, false, withImporter)
+       testFiles(t, []string{"t.go"}, [][]byte{[]byte(tsrc)}, 0, false, withImporter)
+}
+
+func TestIssue50646(t *testing.T) {
+       anyType := Universe.Lookup("any").Type()
+       comparableType := Universe.Lookup("comparable").Type()
+
+       if !Comparable(anyType) {
+               t.Error("any is not a comparable type")
+       }
+       if !Comparable(comparableType) {
+               t.Error("comparable is not a comparable type")
+       }
+
+       if Implements(anyType, comparableType.Underlying().(*Interface)) {
+               t.Error("any implements comparable")
+       }
+       if !Implements(comparableType, anyType.(*Interface)) {
+               t.Error("comparable does not implement any")
+       }
+
+       if AssignableTo(anyType, comparableType) {
+               t.Error("any assignable to comparable")
+       }
+       if !AssignableTo(comparableType, anyType) {
+               t.Error("comparable not assignable to any")
+       }
+}
+
+func TestIssue55030(t *testing.T) {
+       // makeSig makes the signature func(typ...)
+       makeSig := func(typ Type) {
+               par := NewVar(nopos, nil, "", typ)
+               params := NewTuple(par)
+               NewSignatureType(nil, nil, nil, params, nil, true)
+       }
+
+       // makeSig must not panic for the following (example) types:
+       // []int
+       makeSig(NewSlice(Typ[Int]))
+
+       // string
+       makeSig(Typ[String])
+
+       // P where P's core type is string
+       {
+               P := NewTypeName(nopos, nil, "P", nil) // [P string]
+               makeSig(NewTypeParam(P, NewInterfaceType(nil, []Type{Typ[String]})))
+       }
+
+       // P where P's core type is an (unnamed) slice
+       {
+               P := NewTypeName(nopos, nil, "P", nil) // [P []int]
+               makeSig(NewTypeParam(P, NewInterfaceType(nil, []Type{NewSlice(Typ[Int])})))
+       }
+
+       // P where P's core type is bytestring (i.e., string or []byte)
+       {
+               t1 := NewTerm(true, Typ[String])          // ~string
+               t2 := NewTerm(false, NewSlice(Typ[Byte])) // []byte
+               u := NewUnion([]*Term{t1, t2})            // ~string | []byte
+               P := NewTypeName(nopos, nil, "P", nil)    // [P ~string | []byte]
+               makeSig(NewTypeParam(P, NewInterfaceType(nil, []Type{u})))
+       }
+}
+
+func TestIssue51093(t *testing.T) {
+       // Each test stands for a conversion of the form P(val)
+       // where P is a type parameter with typ as constraint.
+       // The test ensures that P(val) has the correct type P
+       // and is not a constant.
+       var tests = []struct {
+               typ string
+               val string
+       }{
+               {"bool", "false"},
+               {"int", "-1"},
+               {"uint", "1.0"},
+               {"rune", "'a'"},
+               {"float64", "3.5"},
+               {"complex64", "1.25"},
+               {"string", "\"foo\""},
+
+               // some more complex constraints
+               {"~byte", "1"},
+               {"~int | ~float64 | complex128", "1"},
+               {"~uint64 | ~rune", "'X'"},
+       }
+
+       for _, test := range tests {
+               src := fmt.Sprintf("package p; func _[P %s]() { _ = P(%s) }", test.typ, test.val)
+               types := make(map[syntax.Expr]TypeAndValue)
+               mustTypecheck(src, nil, &Info{Types: types})
+
+               var n int
+               for x, tv := range types {
+                       if x, _ := x.(*syntax.CallExpr); x != nil {
+                               // there must be exactly one CallExpr which is the P(val) conversion
+                               n++
+                               tpar, _ := tv.Type.(*TypeParam)
+                               if tpar == nil {
+                                       t.Fatalf("%s: got type %s, want type parameter", syntax.String(x), tv.Type)
+                               }
+                               if name := tpar.Obj().Name(); name != "P" {
+                                       t.Fatalf("%s: got type parameter name %s, want P", syntax.String(x), name)
+                               }
+                               // P(val) must not be constant
+                               if tv.Value != nil {
+                                       t.Errorf("%s: got constant value %s (%s), want no constant", syntax.String(x), tv.Value, tv.Value.String())
+                               }
+                       }
+               }
+
+               if n != 1 {
+                       t.Fatalf("%s: got %d CallExpr nodes; want 1", src, 1)
+               }
+       }
+}
+
+func TestIssue54258(t *testing.T) {
+       tests := []struct{ main, b, want string }{
+               { //---------------------------------------------------------------
+                       `package main
+import "b"
+type I0 interface {
+       M0(w struct{ f string })
+}
+var _ I0 = b.S{}
+`,
+                       `package b
+type S struct{}
+func (S) M0(struct{ f string }) {}
+`,
+                       `6:12: cannot use b[.]S{} [(]value of type b[.]S[)] as I0 value in variable declaration: b[.]S does not implement I0 [(]wrong type for method M0[)]
+.*have M0[(]struct{f string /[*] package b [*]/ }[)]
+.*want M0[(]struct{f string /[*] package main [*]/ }[)]`},
+
+               { //---------------------------------------------------------------
+                       `package main
+import "b"
+type I1 interface {
+       M1(struct{ string })
+}
+var _ I1 = b.S{}
+`,
+                       `package b
+type S struct{}
+func (S) M1(struct{ string }) {}
+`,
+                       `6:12: cannot use b[.]S{} [(]value of type b[.]S[)] as I1 value in variable declaration: b[.]S does not implement I1 [(]wrong type for method M1[)]
+.*have M1[(]struct{string /[*] package b [*]/ }[)]
+.*want M1[(]struct{string /[*] package main [*]/ }[)]`},
+
+               { //---------------------------------------------------------------
+                       `package main
+import "b"
+type I2 interface {
+       M2(y struct{ f struct{ f string } })
+}
+var _ I2 = b.S{}
+`,
+                       `package b
+type S struct{}
+func (S) M2(struct{ f struct{ f string } }) {}
+`,
+                       `6:12: cannot use b[.]S{} [(]value of type b[.]S[)] as I2 value in variable declaration: b[.]S does not implement I2 [(]wrong type for method M2[)]
+.*have M2[(]struct{f struct{f string} /[*] package b [*]/ }[)]
+.*want M2[(]struct{f struct{f string} /[*] package main [*]/ }[)]`},
+
+               { //---------------------------------------------------------------
+                       `package main
+import "b"
+type I3 interface {
+       M3(z struct{ F struct{ f string } })
+}
+var _ I3 = b.S{}
+`,
+                       `package b
+type S struct{}
+func (S) M3(struct{ F struct{ f string } }) {}
+`,
+                       `6:12: cannot use b[.]S{} [(]value of type b[.]S[)] as I3 value in variable declaration: b[.]S does not implement I3 [(]wrong type for method M3[)]
+.*have M3[(]struct{F struct{f string /[*] package b [*]/ }}[)]
+.*want M3[(]struct{F struct{f string /[*] package main [*]/ }}[)]`},
+
+               { //---------------------------------------------------------------
+                       `package main
+import "b"
+type I4 interface {
+       M4(_ struct { *string })
+}
+var _ I4 = b.S{}
+`,
+                       `package b
+type S struct{}
+func (S) M4(struct { *string }) {}
+`,
+                       `6:12: cannot use b[.]S{} [(]value of type b[.]S[)] as I4 value in variable declaration: b[.]S does not implement I4 [(]wrong type for method M4[)]
+.*have M4[(]struct{[*]string /[*] package b [*]/ }[)]
+.*want M4[(]struct{[*]string /[*] package main [*]/ }[)]`},
+
+               { //---------------------------------------------------------------
+                       `package main
+import "b"
+type t struct{ A int }
+type I5 interface {
+       M5(_ struct {b.S;t})
+}
+var _ I5 = b.S{}
+`,
+                       `package b
+type S struct{}
+type t struct{ A int }
+func (S) M5(struct {S;t}) {}
+`,
+                       `7:12: cannot use b[.]S{} [(]value of type b[.]S[)] as I5 value in variable declaration: b[.]S does not implement I5 [(]wrong type for method M5[)]
+.*have M5[(]struct{b[.]S; b[.]t}[)]
+.*want M5[(]struct{b[.]S; t}[)]`},
+       }
+
+       test := func(main, b, want string) {
+               re := regexp.MustCompile(want)
+               bpkg := mustTypecheck(b, nil, nil)
+               mast := mustParse(main)
+               conf := Config{Importer: importHelper{pkg: bpkg}}
+               _, err := conf.Check(mast.PkgName.Value, []*syntax.File{mast}, nil)
+               if err == nil {
+                       t.Error("Expected failure, but it did not")
+               } else if got := err.Error(); !re.MatchString(got) {
+                       t.Errorf("Wanted match for\n\t%s\n but got\n\t%s", want, got)
+               } else if testing.Verbose() {
+                       t.Logf("Saw expected\n\t%s", err.Error())
+               }
+       }
+       for _, t := range tests {
+               test(t.main, t.b, t.want)
+       }
+}
+
+func TestIssue59944(t *testing.T) {
+       testenv.MustHaveCGO(t)
+
+       // The typechecker should resolve methods declared on aliases of cgo types.
+       const src = `
+package p
+
+/*
+struct layout {
+       int field;
+};
+*/
+import "C"
+
+type Layout = C.struct_layout
+
+func (l *Layout) Binding() {}
+
+func _() {
+       _ = (*Layout).Binding
+}
+`
+
+       // code generated by cmd/cgo for the above source.
+       const cgoTypes = `
+// Code generated by cmd/cgo; DO NOT EDIT.
+
+package p
+
+import "unsafe"
+
+import "syscall"
+
+import _cgopackage "runtime/cgo"
+
+type _ _cgopackage.Incomplete
+var _ syscall.Errno
+func _Cgo_ptr(ptr unsafe.Pointer) unsafe.Pointer { return ptr }
+
+//go:linkname _Cgo_always_false runtime.cgoAlwaysFalse
+var _Cgo_always_false bool
+//go:linkname _Cgo_use runtime.cgoUse
+func _Cgo_use(interface{})
+type _Ctype_int int32
+
+type _Ctype_struct_layout struct {
+       field _Ctype_int
+}
+
+type _Ctype_void [0]byte
+
+//go:linkname _cgo_runtime_cgocall runtime.cgocall
+func _cgo_runtime_cgocall(unsafe.Pointer, uintptr) int32
+
+//go:linkname _cgoCheckPointer runtime.cgoCheckPointer
+func _cgoCheckPointer(interface{}, interface{})
+
+//go:linkname _cgoCheckResult runtime.cgoCheckResult
+func _cgoCheckResult(interface{})
+`
+       testFiles(t, []string{"p.go", "_cgo_gotypes.go"}, [][]byte{[]byte(src), []byte(cgoTypes)}, 0, false, func(cfg *Config) {
+               *boolFieldAddr(cfg, "go115UsesCgo") = true
+       })
+}
+
+func TestIssue61931(t *testing.T) {
+       const src = `
+package p
+
+func A(func(any), ...any) {}
+func B[T any](T)          {}
+
+func _() {
+       A(B, nil // syntax error: missing ',' before newline in argument list
+}
+`
+       f, err := syntax.Parse(syntax.NewFileBase(pkgName(src)), strings.NewReader(src), func(error) {}, nil, 0)
+       if err == nil {
+               t.Fatal("expected syntax error")
+       }
+
+       var conf Config
+       conf.Check(f.PkgName.Value, []*syntax.File{f}, nil) // must not panic
+}
+
+func TestIssue61938(t *testing.T) {
+       const src = `
+package p
+
+func f[T any]() {}
+func _()        { f() }
+`
+       // no error handler provided (this issue)
+       var conf Config
+       typecheck(src, &conf, nil) // must not panic
+
+       // with error handler (sanity check)
+       conf.Error = func(error) {}
+       typecheck(src, &conf, nil) // must not panic
+}
+
+func TestIssue63260(t *testing.T) {
+       const src = `
+package p
+
+func _() {
+        use(f[*string])
+}
+
+func use(func()) {}
+
+func f[I *T, T any]() {
+        var v T
+        _ = v
+}`
+
+       info := Info{
+               Defs: make(map[*syntax.Name]Object),
+       }
+       pkg := mustTypecheck(src, nil, &info)
+
+       // get type parameter T in signature of f
+       T := pkg.Scope().Lookup("f").Type().(*Signature).TypeParams().At(1)
+       if T.Obj().Name() != "T" {
+               t.Fatalf("got type parameter %s, want T", T)
+       }
+
+       // get type of variable v in body of f
+       var v Object
+       for name, obj := range info.Defs {
+               if name.Value == "v" {
+                       v = obj
+                       break
+               }
+       }
+       if v == nil {
+               t.Fatal("variable v not found")
+       }
+
+       // type of v and T must be pointer-identical
+       if v.Type() != T {
+               t.Fatalf("types of v and T are not pointer-identical: %p != %p", v.Type().(*TypeParam), T)
+       }
+}
+
+func TestIssue44410(t *testing.T) {
+       const src = `
+package p
+
+type A = []int
+type S struct{ A }
+`
+
+       t.Setenv("GODEBUG", "gotypesalias=1")
+       pkg := mustTypecheck(src, nil, nil)
+
+       S := pkg.Scope().Lookup("S")
+       if S == nil {
+               t.Fatal("object S not found")
+       }
+
+       got := S.String()
+       const want = "type p.S struct{p.A /* = []int */}"
+       if got != want {
+               t.Fatalf("got %q; want %q", got, want)
+       }
+}