Source file
src/go/types/issues_test.go
1
2
3
4
5
6
7 package types_test
8
9 import (
10 "fmt"
11 "go/ast"
12 "go/importer"
13 "go/parser"
14 "go/token"
15 "internal/testenv"
16 "regexp"
17 "sort"
18 "strings"
19 "testing"
20
21 . "go/types"
22 )
23
24 func TestIssue5770(t *testing.T) {
25 _, err := typecheck(`package p; type S struct{T}`, nil, nil)
26 const want = "undefined: T"
27 if err == nil || !strings.Contains(err.Error(), want) {
28 t.Errorf("got: %v; want: %s", err, want)
29 }
30 }
31
32 func TestIssue5849(t *testing.T) {
33 src := `
34 package p
35 var (
36 s uint
37 _ = uint8(8)
38 _ = uint16(16) << s
39 _ = uint32(32 << s)
40 _ = uint64(64 << s + s)
41 _ = (interface{})("foo")
42 _ = (interface{})(nil)
43 )`
44 types := make(map[ast.Expr]TypeAndValue)
45 mustTypecheck(src, nil, &Info{Types: types})
46
47 for x, tv := range types {
48 var want Type
49 switch x := x.(type) {
50 case *ast.BasicLit:
51 switch x.Value {
52 case `8`:
53 want = Typ[Uint8]
54 case `16`:
55 want = Typ[Uint16]
56 case `32`:
57 want = Typ[Uint32]
58 case `64`:
59 want = Typ[Uint]
60 case `"foo"`:
61 want = Typ[String]
62 }
63 case *ast.Ident:
64 if x.Name == "nil" {
65 want = Typ[UntypedNil]
66 }
67 }
68 if want != nil && !Identical(tv.Type, want) {
69 t.Errorf("got %s; want %s", tv.Type, want)
70 }
71 }
72 }
73
74 func TestIssue6413(t *testing.T) {
75 src := `
76 package p
77 func f() int {
78 defer f()
79 go f()
80 return 0
81 }
82 `
83 types := make(map[ast.Expr]TypeAndValue)
84 mustTypecheck(src, nil, &Info{Types: types})
85
86 want := Typ[Int]
87 n := 0
88 for x, tv := range types {
89 if _, ok := x.(*ast.CallExpr); ok {
90 if tv.Type != want {
91 t.Errorf("%s: got %s; want %s", fset.Position(x.Pos()), tv.Type, want)
92 }
93 n++
94 }
95 }
96
97 if n != 2 {
98 t.Errorf("got %d CallExprs; want 2", n)
99 }
100 }
101
102 func TestIssue7245(t *testing.T) {
103 src := `
104 package p
105 func (T) m() (res bool) { return }
106 type T struct{} // receiver type after method declaration
107 `
108 f := mustParse(fset, src)
109
110 var conf Config
111 defs := make(map[*ast.Ident]Object)
112 _, err := conf.Check(f.Name.Name, fset, []*ast.File{f}, &Info{Defs: defs})
113 if err != nil {
114 t.Fatal(err)
115 }
116
117 m := f.Decls[0].(*ast.FuncDecl)
118 res1 := defs[m.Name].(*Func).Type().(*Signature).Results().At(0)
119 res2 := defs[m.Type.Results.List[0].Names[0]].(*Var)
120
121 if res1 != res2 {
122 t.Errorf("got %s (%p) != %s (%p)", res1, res2, res1, res2)
123 }
124 }
125
126
127
128
129 func TestIssue7827(t *testing.T) {
130 const src = `
131 package p
132 func _() {
133 const w = 1 // defs w
134 x, y := 2, 3 // defs x, y
135 w, x, z := 4, 5, 6 // uses w, x, defs z; error: cannot assign to w
136 _, _, _ = x, y, z // uses x, y, z
137 }
138 `
139
140
141 fset := token.NewFileSet()
142 f := mustParse(fset, src)
143
144 const want = `L3 defs func p._()
145 L4 defs const w untyped int
146 L5 defs var x int
147 L5 defs var y int
148 L6 defs var z int
149 L6 uses const w untyped int
150 L6 uses var x int
151 L7 uses var x int
152 L7 uses var y int
153 L7 uses var z int`
154
155
156 conf := Config{Error: func(err error) { t.Log(err) }}
157 defs := make(map[*ast.Ident]Object)
158 uses := make(map[*ast.Ident]Object)
159 _, err := conf.Check(f.Name.Name, fset, []*ast.File{f}, &Info{Defs: defs, Uses: uses})
160 if s := err.Error(); !strings.HasSuffix(s, "cannot assign to w") {
161 t.Errorf("Check: unexpected error: %s", s)
162 }
163
164 var facts []string
165 for id, obj := range defs {
166 if obj != nil {
167 fact := fmt.Sprintf("L%d defs %s", fset.Position(id.Pos()).Line, obj)
168 facts = append(facts, fact)
169 }
170 }
171 for id, obj := range uses {
172 fact := fmt.Sprintf("L%d uses %s", fset.Position(id.Pos()).Line, obj)
173 facts = append(facts, fact)
174 }
175 sort.Strings(facts)
176
177 got := strings.Join(facts, "\n")
178 if got != want {
179 t.Errorf("Unexpected defs/uses\ngot:\n%s\nwant:\n%s", got, want)
180 }
181 }
182
183
184
185
186
187
188
189 func TestIssue13898(t *testing.T) {
190 testenv.MustHaveGoBuild(t)
191
192 const src0 = `
193 package main
194
195 import "go/types"
196
197 func main() {
198 var info types.Info
199 for _, obj := range info.Uses {
200 _ = obj.Pkg()
201 }
202 }
203 `
204
205 const src1 = `
206 package main
207
208 import (
209 "go/types"
210 _ "go/importer"
211 )
212
213 func main() {
214 var info types.Info
215 for _, obj := range info.Uses {
216 _ = obj.Pkg()
217 }
218 }
219 `
220
221
222 const src2 = `
223 package main
224
225 import (
226 _ "go/importer"
227 "go/types"
228 )
229
230 func main() {
231 var info types.Info
232 for _, obj := range info.Uses {
233 _ = obj.Pkg()
234 }
235 }
236 `
237 f := func(test, src string) {
238 info := &Info{Uses: make(map[*ast.Ident]Object)}
239 mustTypecheck(src, nil, info)
240
241 var pkg *Package
242 count := 0
243 for id, obj := range info.Uses {
244 if id.Name == "Pkg" {
245 pkg = obj.Pkg()
246 count++
247 }
248 }
249 if count != 1 {
250 t.Fatalf("%s: got %d entries named Pkg; want 1", test, count)
251 }
252 if pkg.Name() != "types" {
253 t.Fatalf("%s: got %v; want package types", test, pkg)
254 }
255 }
256
257 f("src0", src0)
258 f("src1", src1)
259 f("src2", src2)
260 }
261
262 func TestIssue22525(t *testing.T) {
263 const src = `package p; func f() { var a, b, c, d, e int }`
264
265 got := "\n"
266 conf := Config{Error: func(err error) { got += err.Error() + "\n" }}
267 typecheck(src, &conf, nil)
268 want := `
269 p:1:27: a declared and not used
270 p:1:30: b declared and not used
271 p:1:33: c declared and not used
272 p:1:36: d declared and not used
273 p:1:39: e declared and not used
274 `
275 if got != want {
276 t.Errorf("got: %swant: %s", got, want)
277 }
278 }
279
280 func TestIssue25627(t *testing.T) {
281 const prefix = `package p; import "unsafe"; type P *struct{}; type I interface{}; type T `
282
283
284 for _, src := range []string{
285 `struct { x Missing }`,
286 `struct { Missing }`,
287 `struct { *Missing }`,
288 `struct { unsafe.Pointer }`,
289 `struct { P }`,
290 `struct { *I }`,
291 `struct { a int; b Missing; *Missing }`,
292 } {
293 f := mustParse(fset, prefix+src)
294
295 cfg := Config{Importer: importer.Default(), Error: func(err error) {}}
296 info := &Info{Types: make(map[ast.Expr]TypeAndValue)}
297 _, err := cfg.Check(f.Name.Name, fset, []*ast.File{f}, info)
298 if err != nil {
299 if _, ok := err.(Error); !ok {
300 t.Fatal(err)
301 }
302 }
303
304 ast.Inspect(f, func(n ast.Node) bool {
305 if spec, _ := n.(*ast.TypeSpec); spec != nil {
306 if tv, ok := info.Types[spec.Type]; ok && spec.Name.Name == "T" {
307 want := strings.Count(src, ";") + 1
308 if got := tv.Type.(*Struct).NumFields(); got != want {
309 t.Errorf("%s: got %d fields; want %d", src, got, want)
310 }
311 }
312 }
313 return true
314 })
315 }
316 }
317
318 func TestIssue28005(t *testing.T) {
319
320
321 sources := [...]string{
322 "package p; type A interface{ A() }",
323 "package p; type B interface{ B() }",
324 "package p; type X interface{ A; B }",
325 }
326
327
328 var orig [len(sources)]*ast.File
329 for i, src := range sources {
330 orig[i] = mustParse(fset, src)
331 }
332
333
334 for _, perm := range [][len(sources)]int{
335 {0, 1, 2},
336 {0, 2, 1},
337 {1, 0, 2},
338 {1, 2, 0},
339 {2, 0, 1},
340 {2, 1, 0},
341 } {
342
343 files := make([]*ast.File, len(sources))
344 for i := range perm {
345 files[i] = orig[perm[i]]
346 }
347
348
349 var conf Config
350 info := &Info{Defs: make(map[*ast.Ident]Object)}
351 _, err := conf.Check("", fset, files, info)
352 if err != nil {
353 t.Fatal(err)
354 }
355
356
357 var obj Object
358 for name, def := range info.Defs {
359 if name.Name == "X" {
360 obj = def
361 break
362 }
363 }
364 if obj == nil {
365 t.Fatal("object X not found")
366 }
367 iface := obj.Type().Underlying().(*Interface)
368
369
370
371 for i := 0; i < iface.NumMethods(); i++ {
372 m := iface.Method(i)
373 recvName := m.Type().(*Signature).Recv().Type().(*Named).Obj().Name()
374 if recvName != m.Name() {
375 t.Errorf("perm %v: got recv %s; want %s", perm, recvName, m.Name())
376 }
377 }
378 }
379 }
380
381 func TestIssue28282(t *testing.T) {
382
383 et := Universe.Lookup("error").Type()
384 it := NewInterfaceType(nil, []Type{et})
385 it.Complete()
386
387 want := et.Underlying().(*Interface).Method(0)
388 got := it.Method(0)
389 if got != want {
390 t.Fatalf("%s.Method(0): got %q (%p); want %q (%p)", it, got, got, want, want)
391 }
392
393 obj, _, _ := LookupFieldOrMethod(et, false, nil, "Error")
394 if obj != want {
395 t.Fatalf("%s.Lookup: got %q (%p); want %q (%p)", et, obj, obj, want, want)
396 }
397 obj, _, _ = LookupFieldOrMethod(it, false, nil, "Error")
398 if obj != want {
399 t.Fatalf("%s.Lookup: got %q (%p); want %q (%p)", it, obj, obj, want, want)
400 }
401 }
402
403 func TestIssue29029(t *testing.T) {
404 f1 := mustParse(fset, `package p; type A interface { M() }`)
405 f2 := mustParse(fset, `package p; var B interface { A }`)
406
407
408 printInfo := func(info *Info) string {
409 var buf strings.Builder
410 for _, obj := range info.Defs {
411 if fn, ok := obj.(*Func); ok {
412 fmt.Fprintln(&buf, fn)
413 }
414 }
415 return buf.String()
416 }
417
418
419
420
421
422
423 var conf Config
424 info := &Info{Defs: make(map[*ast.Ident]Object)}
425 check := NewChecker(&conf, fset, NewPackage("", "p"), info)
426 if err := check.Files([]*ast.File{f1, f2}); err != nil {
427 t.Fatal(err)
428 }
429 want := printInfo(info)
430
431
432 info = &Info{Defs: make(map[*ast.Ident]Object)}
433 check = NewChecker(&conf, fset, NewPackage("", "p"), info)
434 if err := check.Files([]*ast.File{f1}); err != nil {
435 t.Fatal(err)
436 }
437 if err := check.Files([]*ast.File{f2}); err != nil {
438 t.Fatal(err)
439 }
440 got := printInfo(info)
441
442 if got != want {
443 t.Errorf("\ngot : %swant: %s", got, want)
444 }
445 }
446
447 func TestIssue34151(t *testing.T) {
448 const asrc = `package a; type I interface{ M() }; type T struct { F interface { I } }`
449 const bsrc = `package b; import "a"; type T struct { F interface { a.I } }; var _ = a.T(T{})`
450
451 a := mustTypecheck(asrc, nil, nil)
452
453 conf := Config{Importer: importHelper{pkg: a}}
454 mustTypecheck(bsrc, &conf, nil)
455 }
456
457 type importHelper struct {
458 pkg *Package
459 fallback Importer
460 }
461
462 func (h importHelper) Import(path string) (*Package, error) {
463 if path == h.pkg.Path() {
464 return h.pkg, nil
465 }
466 if h.fallback == nil {
467 return nil, fmt.Errorf("got package path %q; want %q", path, h.pkg.Path())
468 }
469 return h.fallback.Import(path)
470 }
471
472
473
474
475
476
477
478 func TestIssue34921(t *testing.T) {
479 defer func() {
480 if r := recover(); r != nil {
481 t.Error(r)
482 }
483 }()
484
485 var sources = []string{
486 `package a; type T int`,
487 `package b; import "a"; type T a.T`,
488 }
489
490 var pkg *Package
491 for _, src := range sources {
492 conf := Config{Importer: importHelper{pkg: pkg}}
493 pkg = mustTypecheck(src, &conf, nil)
494 }
495 }
496
497 func TestIssue43088(t *testing.T) {
498
499
500
501
502
503
504
505
506
507 n1 := NewTypeName(nopos, nil, "T1", nil)
508 T1 := NewNamed(n1, nil, nil)
509 n2 := NewTypeName(nopos, nil, "T2", nil)
510 T2 := NewNamed(n2, nil, nil)
511 s1 := NewStruct([]*Var{NewField(nopos, nil, "_", T2, false)}, nil)
512 T1.SetUnderlying(s1)
513 s2 := NewStruct([]*Var{NewField(nopos, nil, "_", T2, false)}, nil)
514 s3 := NewStruct([]*Var{NewField(nopos, nil, "_", s2, false)}, nil)
515 T2.SetUnderlying(s3)
516
517
518 Comparable(T1)
519 Comparable(T2)
520 }
521
522 func TestIssue44515(t *testing.T) {
523 typ := Unsafe.Scope().Lookup("Pointer").Type()
524
525 got := TypeString(typ, nil)
526 want := "unsafe.Pointer"
527 if got != want {
528 t.Errorf("got %q; want %q", got, want)
529 }
530
531 qf := func(pkg *Package) string {
532 if pkg == Unsafe {
533 return "foo"
534 }
535 return ""
536 }
537 got = TypeString(typ, qf)
538 want = "foo.Pointer"
539 if got != want {
540 t.Errorf("got %q; want %q", got, want)
541 }
542 }
543
544 func TestIssue43124(t *testing.T) {
545
546
547 testenv.MustHaveGoBuild(t)
548
549
550
551
552 const (
553 asrc = `package a; import "text/template"; func F(template.Template) {}; func G(int) {}`
554 bsrc = `
555 package b
556
557 import (
558 "a"
559 "html/template"
560 )
561
562 func _() {
563 // Packages should be fully qualified when there is ambiguity within the
564 // error string itself.
565 a.F(template /* ERRORx "cannot use.*html/template.* as .*text/template" */ .Template{})
566 }
567 `
568 csrc = `
569 package c
570
571 import (
572 "a"
573 "fmt"
574 "html/template"
575 )
576
577 // go.dev/issue/46905: make sure template is not the first package qualified.
578 var _ fmt.Stringer = 1 // ERRORx "cannot use 1.*as fmt\\.Stringer"
579
580 // Packages should be fully qualified when there is ambiguity in reachable
581 // packages. In this case both a (and for that matter html/template) import
582 // text/template.
583 func _() { a.G(template /* ERRORx "cannot use .*html/template.*Template" */ .Template{}) }
584 `
585
586 tsrc = `
587 package template
588
589 import "text/template"
590
591 type T int
592
593 // Verify that the current package name also causes disambiguation.
594 var _ T = template /* ERRORx "cannot use.*text/template.* as T value" */.Template{}
595 `
596 )
597
598 a := mustTypecheck(asrc, nil, nil)
599 imp := importHelper{pkg: a, fallback: importer.Default()}
600
601 withImporter := func(cfg *Config) {
602 cfg.Importer = imp
603 }
604
605 testFiles(t, []string{"b.go"}, [][]byte{[]byte(bsrc)}, false, withImporter)
606 testFiles(t, []string{"c.go"}, [][]byte{[]byte(csrc)}, false, withImporter)
607 testFiles(t, []string{"t.go"}, [][]byte{[]byte(tsrc)}, false, withImporter)
608 }
609
610 func TestIssue50646(t *testing.T) {
611 anyType := Universe.Lookup("any").Type()
612 comparableType := Universe.Lookup("comparable").Type()
613
614 if !Comparable(anyType) {
615 t.Error("any is not a comparable type")
616 }
617 if !Comparable(comparableType) {
618 t.Error("comparable is not a comparable type")
619 }
620
621 if Implements(anyType, comparableType.Underlying().(*Interface)) {
622 t.Error("any implements comparable")
623 }
624 if !Implements(comparableType, anyType.(*Interface)) {
625 t.Error("comparable does not implement any")
626 }
627
628 if AssignableTo(anyType, comparableType) {
629 t.Error("any assignable to comparable")
630 }
631 if !AssignableTo(comparableType, anyType) {
632 t.Error("comparable not assignable to any")
633 }
634 }
635
636 func TestIssue55030(t *testing.T) {
637
638 makeSig := func(typ Type) {
639 par := NewVar(nopos, nil, "", typ)
640 params := NewTuple(par)
641 NewSignatureType(nil, nil, nil, params, nil, true)
642 }
643
644
645
646 makeSig(NewSlice(Typ[Int]))
647
648
649 makeSig(Typ[String])
650
651
652 {
653 P := NewTypeName(nopos, nil, "P", nil)
654 makeSig(NewTypeParam(P, NewInterfaceType(nil, []Type{Typ[String]})))
655 }
656
657
658 {
659 P := NewTypeName(nopos, nil, "P", nil)
660 makeSig(NewTypeParam(P, NewInterfaceType(nil, []Type{NewSlice(Typ[Int])})))
661 }
662
663
664 {
665 t1 := NewTerm(true, Typ[String])
666 t2 := NewTerm(false, NewSlice(Typ[Byte]))
667 u := NewUnion([]*Term{t1, t2})
668 P := NewTypeName(nopos, nil, "P", nil)
669 makeSig(NewTypeParam(P, NewInterfaceType(nil, []Type{u})))
670 }
671 }
672
673 func TestIssue51093(t *testing.T) {
674
675
676
677
678 var tests = []struct {
679 typ string
680 val string
681 }{
682 {"bool", "false"},
683 {"int", "-1"},
684 {"uint", "1.0"},
685 {"rune", "'a'"},
686 {"float64", "3.5"},
687 {"complex64", "1.25"},
688 {"string", "\"foo\""},
689
690
691 {"~byte", "1"},
692 {"~int | ~float64 | complex128", "1"},
693 {"~uint64 | ~rune", "'X'"},
694 }
695
696 for _, test := range tests {
697 src := fmt.Sprintf("package p; func _[P %s]() { _ = P(%s) }", test.typ, test.val)
698 types := make(map[ast.Expr]TypeAndValue)
699 mustTypecheck(src, nil, &Info{Types: types})
700
701 var n int
702 for x, tv := range types {
703 if x, _ := x.(*ast.CallExpr); x != nil {
704
705 n++
706 tpar, _ := tv.Type.(*TypeParam)
707 if tpar == nil {
708 t.Fatalf("%s: got type %s, want type parameter", ExprString(x), tv.Type)
709 }
710 if name := tpar.Obj().Name(); name != "P" {
711 t.Fatalf("%s: got type parameter name %s, want P", ExprString(x), name)
712 }
713
714 if tv.Value != nil {
715 t.Errorf("%s: got constant value %s (%s), want no constant", ExprString(x), tv.Value, tv.Value.String())
716 }
717 }
718 }
719
720 if n != 1 {
721 t.Fatalf("%s: got %d CallExpr nodes; want 1", src, 1)
722 }
723 }
724 }
725
726 func TestIssue54258(t *testing.T) {
727
728 tests := []struct{ main, b, want string }{
729 {
730 `package main
731 import "b"
732 type I0 interface {
733 M0(w struct{ f string })
734 }
735 var _ I0 = b.S{}
736 `,
737 `package b
738 type S struct{}
739 func (S) M0(struct{ f string }) {}
740 `,
741 `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[)]
742 .*have M0[(]struct{f string /[*] package b [*]/ }[)]
743 .*want M0[(]struct{f string /[*] package main [*]/ }[)]`},
744
745 {
746 `package main
747 import "b"
748 type I1 interface {
749 M1(struct{ string })
750 }
751 var _ I1 = b.S{}
752 `,
753 `package b
754 type S struct{}
755 func (S) M1(struct{ string }) {}
756 `,
757 `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[)]
758 .*have M1[(]struct{string /[*] package b [*]/ }[)]
759 .*want M1[(]struct{string /[*] package main [*]/ }[)]`},
760
761 {
762 `package main
763 import "b"
764 type I2 interface {
765 M2(y struct{ f struct{ f string } })
766 }
767 var _ I2 = b.S{}
768 `,
769 `package b
770 type S struct{}
771 func (S) M2(struct{ f struct{ f string } }) {}
772 `,
773 `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[)]
774 .*have M2[(]struct{f struct{f string} /[*] package b [*]/ }[)]
775 .*want M2[(]struct{f struct{f string} /[*] package main [*]/ }[)]`},
776
777 {
778 `package main
779 import "b"
780 type I3 interface {
781 M3(z struct{ F struct{ f string } })
782 }
783 var _ I3 = b.S{}
784 `,
785 `package b
786 type S struct{}
787 func (S) M3(struct{ F struct{ f string } }) {}
788 `,
789 `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[)]
790 .*have M3[(]struct{F struct{f string /[*] package b [*]/ }}[)]
791 .*want M3[(]struct{F struct{f string /[*] package main [*]/ }}[)]`},
792
793 {
794 `package main
795 import "b"
796 type I4 interface {
797 M4(_ struct { *string })
798 }
799 var _ I4 = b.S{}
800 `,
801 `package b
802 type S struct{}
803 func (S) M4(struct { *string }) {}
804 `,
805 `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[)]
806 .*have M4[(]struct{[*]string /[*] package b [*]/ }[)]
807 .*want M4[(]struct{[*]string /[*] package main [*]/ }[)]`},
808
809 {
810 `package main
811 import "b"
812 type t struct{ A int }
813 type I5 interface {
814 M5(_ struct {b.S;t})
815 }
816 var _ I5 = b.S{}
817 `,
818 `package b
819 type S struct{}
820 type t struct{ A int }
821 func (S) M5(struct {S;t}) {}
822 `,
823 `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[)]
824 .*have M5[(]struct{b[.]S; b[.]t}[)]
825 .*want M5[(]struct{b[.]S; t}[)]`},
826 }
827
828 fset := token.NewFileSet()
829 test := func(main, b, want string) {
830 re := regexp.MustCompile(want)
831 bpkg := mustTypecheck(b, nil, nil)
832 mast := mustParse(fset, main)
833 conf := Config{Importer: importHelper{pkg: bpkg}}
834 _, err := conf.Check(mast.Name.Name, fset, []*ast.File{mast}, nil)
835 if err == nil {
836 t.Error("Expected failure, but it did not")
837 } else if got := err.Error(); !re.MatchString(got) {
838 t.Errorf("Wanted match for\n\t%s\n but got\n\t%s", want, got)
839 } else if testing.Verbose() {
840 t.Logf("Saw expected\n\t%s", err.Error())
841 }
842 }
843 for _, t := range tests {
844 test(t.main, t.b, t.want)
845 }
846 }
847
848 func TestIssue59944(t *testing.T) {
849 testenv.MustHaveCGO(t)
850
851
852 const src = `
853 package p
854
855 /*
856 struct layout {
857 int field;
858 };
859 */
860 import "C"
861
862 type Layout = C.struct_layout
863
864 func (l *Layout) Binding() {}
865
866 func _() {
867 _ = (*Layout).Binding
868 }
869 `
870
871
872 const cgoTypes = `
873 // Code generated by cmd/cgo; DO NOT EDIT.
874
875 package p
876
877 import "unsafe"
878
879 import "syscall"
880
881 import _cgopackage "runtime/cgo"
882
883 type _ _cgopackage.Incomplete
884 var _ syscall.Errno
885 func _Cgo_ptr(ptr unsafe.Pointer) unsafe.Pointer { return ptr }
886
887 //go:linkname _Cgo_always_false runtime.cgoAlwaysFalse
888 var _Cgo_always_false bool
889 //go:linkname _Cgo_use runtime.cgoUse
890 func _Cgo_use(interface{})
891 type _Ctype_int int32
892
893 type _Ctype_struct_layout struct {
894 field _Ctype_int
895 }
896
897 type _Ctype_void [0]byte
898
899 //go:linkname _cgo_runtime_cgocall runtime.cgocall
900 func _cgo_runtime_cgocall(unsafe.Pointer, uintptr) int32
901
902 //go:linkname _cgoCheckPointer runtime.cgoCheckPointer
903 func _cgoCheckPointer(interface{}, interface{})
904
905 //go:linkname _cgoCheckResult runtime.cgoCheckResult
906 func _cgoCheckResult(interface{})
907 `
908 testFiles(t, []string{"p.go", "_cgo_gotypes.go"}, [][]byte{[]byte(src), []byte(cgoTypes)}, false, func(cfg *Config) {
909 *boolFieldAddr(cfg, "go115UsesCgo") = true
910 })
911 }
912
913 func TestIssue61931(t *testing.T) {
914 const src = `
915 package p
916
917 func A(func(any), ...any) {}
918 func B[T any](T) {}
919
920 func _() {
921 A(B, nil // syntax error: missing ',' before newline in argument list
922 }
923 `
924 fset := token.NewFileSet()
925 f, err := parser.ParseFile(fset, pkgName(src), src, 0)
926 if err == nil {
927 t.Fatal("expected syntax error")
928 }
929
930 var conf Config
931 conf.Check(f.Name.Name, fset, []*ast.File{f}, nil)
932 }
933
934 func TestIssue61938(t *testing.T) {
935 const src = `
936 package p
937
938 func f[T any]() {}
939 func _() { f() }
940 `
941
942 var conf Config
943 typecheck(src, &conf, nil)
944
945
946 conf.Error = func(error) {}
947 typecheck(src, &conf, nil)
948 }
949
950 func TestIssue63260(t *testing.T) {
951 const src = `
952 package p
953
954 func _() {
955 use(f[*string])
956 }
957
958 func use(func()) {}
959
960 func f[I *T, T any]() {
961 var v T
962 _ = v
963 }`
964
965 info := Info{
966 Defs: make(map[*ast.Ident]Object),
967 }
968 pkg := mustTypecheck(src, nil, &info)
969
970
971 T := pkg.Scope().Lookup("f").Type().(*Signature).TypeParams().At(1)
972 if T.Obj().Name() != "T" {
973 t.Fatalf("got type parameter %s, want T", T)
974 }
975
976
977 var v Object
978 for name, obj := range info.Defs {
979 if name.Name == "v" {
980 v = obj
981 break
982 }
983 }
984 if v == nil {
985 t.Fatal("variable v not found")
986 }
987
988
989 if v.Type() != T {
990 t.Fatalf("types of v and T are not pointer-identical: %p != %p", v.Type().(*TypeParam), T)
991 }
992 }
993
994 func TestIssue44410(t *testing.T) {
995 const src = `
996 package p
997
998 type A = []int
999 type S struct{ A }
1000 `
1001
1002 t.Setenv("GODEBUG", "gotypesalias=1")
1003 pkg := mustTypecheck(src, nil, nil)
1004
1005 S := pkg.Scope().Lookup("S")
1006 if S == nil {
1007 t.Fatal("object S not found")
1008 }
1009
1010 got := S.String()
1011 const want = "type p.S struct{p.A}"
1012 if got != want {
1013 t.Fatalf("got %q; want %q", got, want)
1014 }
1015 }
1016
1017 func TestIssue59831(t *testing.T) {
1018
1019
1020 const asrc = `package a; type S struct{}; func (S) m() {}`
1021 apkg := mustTypecheck(asrc, nil, nil)
1022
1023
1024
1025 const bsrc = `package b; type S struct{}; func (S) M() {}`
1026 bpkg := mustTypecheck(bsrc, nil, nil)
1027
1028 tests := []struct {
1029 imported *Package
1030 src, err string
1031 }{
1032
1033 {apkg, `package a1; import "a"; var _ interface { M() } = a.S{}`,
1034 "a.S does not implement interface{M()} (missing method M) have m() want M()"},
1035
1036 {apkg, `package a2; import "a"; var _ interface { m() } = a.S{}`,
1037 "a.S does not implement interface{m()} (unexported method m)"},
1038
1039 {nil, `package a3; type S struct{}; func (S) m(); var _ interface { M() } = S{}`,
1040 "S does not implement interface{M()} (missing method M) have m() want M()"},
1041
1042 {nil, `package a4; type S struct{}; func (S) m(); var _ interface { m() } = S{}`,
1043 ""},
1044
1045 {nil, `package a5; type S struct{}; func (S) m(); var _ interface { n() } = S{}`,
1046 "S does not implement interface{n()} (missing method n)"},
1047
1048
1049 {bpkg, `package b1; import "b"; var _ interface { m() } = b.S{}`,
1050 "b.S does not implement interface{m()} (missing method m) have M() want m()"},
1051
1052 {bpkg, `package b2; import "b"; var _ interface { M() } = b.S{}`,
1053 ""},
1054
1055 {nil, `package b3; type S struct{}; func (S) M(); var _ interface { M() } = S{}`,
1056 ""},
1057
1058 {nil, `package b4; type S struct{}; func (S) M(); var _ interface { m() } = S{}`,
1059 "S does not implement interface{m()} (missing method m) have M() want m()"},
1060
1061 {nil, `package b5; type S struct{}; func (S) M(); var _ interface { n() } = S{}`,
1062 "S does not implement interface{n()} (missing method n)"},
1063 }
1064
1065 for _, test := range tests {
1066
1067 conf := Config{Importer: importHelper{pkg: test.imported}}
1068 pkg, err := typecheck(test.src, &conf, nil)
1069 if err == nil {
1070 if test.err != "" {
1071 t.Errorf("package %s: got no error, want %q", pkg.Name(), test.err)
1072 }
1073 continue
1074 }
1075 if test.err == "" {
1076 t.Errorf("package %s: got %q, want not error", pkg.Name(), err.Error())
1077 }
1078
1079
1080 errmsg := strings.ReplaceAll(err.Error(), "\n", " ")
1081 errmsg = strings.ReplaceAll(errmsg, "\t", "")
1082
1083
1084 if !strings.Contains(errmsg, test.err) {
1085 t.Errorf("package %s: got %q, want %q", pkg.Name(), errmsg, test.err)
1086 }
1087 }
1088 }
1089
1090 func TestIssue64759(t *testing.T) {
1091 const src = `
1092 //go:build go1.18
1093 package p
1094
1095 func f[S ~[]E, E any](S) {}
1096
1097 func _() {
1098 f([]string{})
1099 }
1100 `
1101
1102
1103 conf := Config{GoVersion: "go1.17"}
1104 mustTypecheck(src, &conf, nil)
1105 }
1106
View as plain text