blob: 8bca1931f1ec2d56c052ac6d27151dc4f63ea3eb [file] [log] [blame]
// 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.
// This file implements tests for various issues.
package types_test
import (
"go/ast"
"go/parser"
"strings"
"testing"
_ "code.google.com/p/go.tools/go/gcimporter"
. "code.google.com/p/go.tools/go/types"
)
func TestIssue5770(t *testing.T) {
src := `package p; type S struct{T}`
f, err := parser.ParseFile(fset, "", src, 0)
if err != nil {
t.Fatal(err)
}
_, err = Check(f.Name.Name, fset, []*ast.File{f}) // do not crash
want := "undeclared name: T"
if err == nil || !strings.Contains(err.Error(), want) {
t.Errorf("got: %v; want: %s", err, want)
}
}
func TestIssue5849(t *testing.T) {
src := `
package p
var (
s uint
_ = uint8(8)
_ = uint16(16) << s
_ = uint32(32 << s)
_ = uint64(64 << s + s)
_ = (interface{})("foo")
_ = (interface{})(nil)
)`
f, err := parser.ParseFile(fset, "", src, 0)
if err != nil {
t.Fatal(err)
}
var conf Config
types := make(map[ast.Expr]TypeAndValue)
_, err = conf.Check(f.Name.Name, fset, []*ast.File{f}, &Info{Types: types})
if err != nil {
t.Fatal(err)
}
for x, tv := range types {
var want Type
switch x := x.(type) {
case *ast.BasicLit:
switch x.Value {
case `8`:
want = Typ[Uint8]
case `16`:
want = Typ[Uint16]
case `32`:
want = Typ[Uint32]
case `64`:
want = Typ[Uint] // because of "+ s", s is of type uint
case `"foo"`:
want = Typ[String]
}
case *ast.Ident:
if x.Name == "nil" {
want = Typ[UntypedNil]
}
}
if want != nil && !Identical(tv.Type, want) {
t.Errorf("got %s; want %s", tv.Type, want)
}
}
}
func TestIssue6413(t *testing.T) {
src := `
package p
func f() int {
defer f()
go f()
return 0
}
`
f, err := parser.ParseFile(fset, "", src, 0)
if err != nil {
t.Fatal(err)
}
var conf Config
types := make(map[ast.Expr]TypeAndValue)
_, err = conf.Check(f.Name.Name, fset, []*ast.File{f}, &Info{Types: types})
if err != nil {
t.Fatal(err)
}
want := Typ[Int]
n := 0
for x, tv := range types {
if _, ok := x.(*ast.CallExpr); ok {
if tv.Type != want {
t.Errorf("%s: got %s; want %s", fset.Position(x.Pos()), tv.Type, want)
}
n++
}
}
if n != 2 {
t.Errorf("got %d CallExprs; want 2", n)
}
}
func TestIssue7245(t *testing.T) {
src := `
package p
func (T) m() (res bool) { return }
type T struct{} // receiver type after method declaration
`
f, err := parser.ParseFile(fset, "", src, 0)
if err != nil {
t.Fatal(err)
}
var conf Config
objects := make(map[*ast.Ident]Object)
_, err = conf.Check(f.Name.Name, fset, []*ast.File{f}, &Info{Objects: objects})
if err != nil {
t.Fatal(err)
}
m := f.Decls[0].(*ast.FuncDecl)
res1 := objects[m.Name].(*Func).Type().(*Signature).Results().At(0)
res2 := objects[m.Type.Results.List[0].Names[0]].(*Var)
if res1 != res2 {
t.Errorf("got %s (%p) != %s (%p)", res1, res2, res1, res2)
}
}