diff --git a/importer/pkginfo.go b/importer/pkginfo.go index 0b098785..b0d099f3 100644 --- a/importer/pkginfo.go +++ b/importer/pkginfo.go @@ -9,7 +9,6 @@ package importer import ( "fmt" "go/ast" - "go/token" "code.google.com/p/go.tools/go/exact" "code.google.com/p/go.tools/go/types" @@ -96,119 +95,3 @@ func (info *PackageInfo) TypeCaseVar(cc *ast.CaseClause) *types.Var { } return nil } - -var ( - tEface = new(types.Interface) - tComplex64 = types.Typ[types.Complex64] - tComplex128 = types.Typ[types.Complex128] - tFloat32 = types.Typ[types.Float32] - tFloat64 = types.Typ[types.Float64] -) - -// BuiltinCallSignature returns a new Signature describing the -// effective type of a builtin operator for the particular call e. -// -// This requires ad-hoc typing rules for all variadic (append, print, -// println) and polymorphic (append, copy, delete, close) built-ins. -// This logic could be part of the typechecker, and should arguably -// be moved there and made accessible via an additional types.Context -// callback. -// -func (info *PackageInfo) BuiltinCallSignature(e *ast.CallExpr) *types.Signature { - var params []*types.Var - var isVariadic bool - - switch builtin := unparen(e.Fun).(*ast.Ident).Name; builtin { - case "append": - var t0, t1 types.Type - t0 = info.TypeOf(e) // infer arg[0] type from result type - if e.Ellipsis != 0 { - // append(tslice, tslice...) []T - // append(byteslice, "foo"...) []byte - t1 = info.TypeOf(e.Args[1]) // no conversion - } else { - // append([]T, x, y, z) []T - t1 = t0.Underlying() - isVariadic = true - } - params = append(params, - types.NewVar(token.NoPos, nil, "", t0), - types.NewVar(token.NoPos, nil, "", t1)) - - case "print", "println": // print{,ln}(any, ...) - // Note, args may have any type, not necessarily tEface. - var params []*types.Var - for _, arg := range e.Args { - params = append(params, types.NewVar(token.NoPos, nil, "", info.TypeOf(arg))) - } - - case "close": - params = append(params, types.NewVar(token.NoPos, nil, "", info.TypeOf(e.Args[0]))) - - case "copy": - // copy([]T, []T) int - // Infer arg types from each other. Sleazy. - var st *types.Slice - if t, ok := info.TypeOf(e.Args[0]).Underlying().(*types.Slice); ok { - st = t - } else if t, ok := info.TypeOf(e.Args[1]).Underlying().(*types.Slice); ok { - st = t - } else { - panic("cannot infer types in call to copy()") - } - stvar := types.NewVar(token.NoPos, nil, "", st) - params = append(params, stvar, stvar) - - case "delete": - // delete(map[K]V, K) - tmap := info.TypeOf(e.Args[0]) - tkey := tmap.Underlying().(*types.Map).Key() - params = append(params, - types.NewVar(token.NoPos, nil, "", tmap), - types.NewVar(token.NoPos, nil, "", tkey)) - - case "len", "cap": - params = append(params, types.NewVar(token.NoPos, nil, "", info.TypeOf(e.Args[0]))) - - case "real", "imag": - // Reverse conversion to "complex" case below. - var argType types.Type - switch info.TypeOf(e).(*types.Basic).Kind() { - case types.UntypedFloat: - argType = types.Typ[types.UntypedComplex] - case types.Float64: - argType = tComplex128 - case types.Float32: - argType = tComplex64 - default: - unreachable() - } - params = append(params, types.NewVar(token.NoPos, nil, "", argType)) - - case "complex": - var argType types.Type - switch info.TypeOf(e).(*types.Basic).Kind() { - case types.UntypedComplex: - argType = types.Typ[types.UntypedFloat] - case types.Complex128: - argType = tFloat64 - case types.Complex64: - argType = tFloat32 - default: - unreachable() - } - v := types.NewVar(token.NoPos, nil, "", argType) - params = append(params, v, v) - - case "panic": - params = append(params, types.NewVar(token.NoPos, nil, "", tEface)) - - case "recover": - // no params - - default: - panic("unknown builtin: " + builtin) - } - - return types.NewSignature(nil, nil, types.NewTuple(params...), nil, isVariadic) -} diff --git a/ssa/builder.go b/ssa/builder.go index a23b8777..ff544a68 100644 --- a/ssa/builder.go +++ b/ssa/builder.go @@ -936,7 +936,7 @@ func (b *builder) setCall(fn *Function, e *ast.CallExpr, c *CallCommon) { // Then append the other actual parameters. sig, _ := fn.Pkg.typeOf(e.Fun).Underlying().(*types.Signature) if sig == nil { - sig = fn.Pkg.info.BuiltinCallSignature(e) + panic(fmt.Sprintf("no signature for call of %s", e.Fun)) } c.Args = b.emitCallArgs(fn, sig, e, c.Args) }