]> Cypherpunks.ru repositories - gostls13.git/blobdiff - src/cmd/compile/internal/types2/issues_test.go
go/types, types2: introduce _Alias type node
[gostls13.git] / src / cmd / compile / internal / types2 / issues_test.go
index 6005587645b13d0b18e69a0f0c3f6268c8c9dc81..a66e8eab929ea936efbd432dfab571929ca6ef4a 100644 (file)
@@ -11,7 +11,6 @@ import (
        "fmt"
        "internal/testenv"
        "regexp"
-       "runtime"
        "sort"
        "strings"
        "testing"
@@ -498,14 +497,14 @@ func TestIssue43088(t *testing.T) {
        //                 _ 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, "_", T2, false)}, nil)
+       s1 := NewStruct([]*Var{NewField(nopos, nil, "_", T2, false)}, nil)
        T1.SetUnderlying(s1)
-       s2 := NewStruct([]*Var{NewField(syntax.Pos{}, nil, "_", T2, false)}, nil)
-       s3 := NewStruct([]*Var{NewField(syntax.Pos{}, nil, "_", 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).
@@ -536,38 +535,69 @@ func TestIssue44515(t *testing.T) {
 }
 
 func TestIssue43124(t *testing.T) {
-       testenv.MustHaveGoBuild(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 _() { a.F(template.Template{}) }`
-               csrc = `package c; import ("a"; "html/template"); func _() { a.G(template.Template{}) }`
-       )
+               bsrc = `
+package b
 
-       a := mustTypecheck(asrc, nil, nil)
-       conf := Config{Importer: importHelper{pkg: a, fallback: defaultImporter()}}
+import (
+       "a"
+       "html/template"
+)
 
+func _() {
        // Packages should be fully qualified when there is ambiguity within the
        // error string itself.
-       _, err := typecheck(bsrc, &conf, nil)
-       if err == nil {
-               t.Fatal("package b had no errors")
-       }
-       if !strings.Contains(err.Error(), "text/template") || !strings.Contains(err.Error(), "html/template") {
-               t.Errorf("type checking error for b does not disambiguate package template: %q", err)
-       }
+       a.F(template /* ERRORx "cannot use.*html/template.* as .*text/template" */ .Template{})
+}
+`
+               csrc = `
+package c
 
-       // ...and also when there is any ambiguity in reachable packages.
-       _, err = typecheck(csrc, &conf, nil)
-       if err == nil {
-               t.Fatal("package c had no errors")
-       }
-       if !strings.Contains(err.Error(), "html/template") {
-               t.Errorf("type checking error for c does not disambiguate package template: %q", err)
+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) {
@@ -807,11 +837,8 @@ func (S) M5(struct {S;t}) {}
 }
 
 func TestIssue59944(t *testing.T) {
-       if runtime.GOARCH == "wasm" {
-               // While we don't use the cgo tool directly in this test, we must have the
-               // syscall package.
-               t.Skip("cgo generated code does not compile on wasm")
-       }
+       testenv.MustHaveCGO(t)
+
        // The typechecker should resolve methods declared on aliases of cgo types.
        const src = `
 package p
@@ -873,3 +900,107 @@ func _cgoCheckResult(interface{})
                *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 }
+`
+
+       var conf Config
+       *boolFieldAddr(&conf, "_EnableAlias") = true
+       pkg := mustTypecheck(src, &conf, 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)
+       }
+}