diff --git a/src/pkg/exp/datafmt/datafmt.go b/src/pkg/exp/datafmt/datafmt.go index 7472a97a937..e77f445b5a2 100644 --- a/src/pkg/exp/datafmt/datafmt.go +++ b/src/pkg/exp/datafmt/datafmt.go @@ -661,7 +661,7 @@ func (s *State) eval(fexpr expr, value reflect.Value, index int) bool { // in which is available in custom formatters through // the state parameter. // -func (f Format) Eval(env Environment, args ...) ([]byte, os.Error) { +func (f Format) Eval(env Environment, args ...interface{}) ([]byte, os.Error) { if f == nil { return nil, os.NewError("format is nil") } @@ -670,9 +670,12 @@ func (f Format) Eval(env Environment, args ...) ([]byte, os.Error) { s := newState(f, env, errors) go func() { - value := reflect.NewValue(args).(*reflect.StructValue) - for i := 0; i < value.NumField(); i++ { - fld := value.Field(i) + for _, v := range args { + fld := reflect.NewValue(v) + if fld == nil { + errors <- os.NewError("nil argument") + return + } mark := s.save() if !s.eval(s.getFormat(typename(fld.Type())), fld, 0) { // TODO is 0 index correct? s.restore(mark) @@ -693,7 +696,7 @@ func (f Format) Eval(env Environment, args ...) ([]byte, os.Error) { // and writes to w. The result is the total number of bytes // written and an os.Error, if any. // -func (f Format) Fprint(w io.Writer, env Environment, args ...) (int, os.Error) { +func (f Format) Fprint(w io.Writer, env Environment, args ...interface{}) (int, os.Error) { data, err := f.Eval(env, args) if err != nil { // TODO should we print partial result in case of error? @@ -707,7 +710,7 @@ func (f Format) Fprint(w io.Writer, env Environment, args ...) (int, os.Error) { // and writes to standard output. The result is the total // number of bytes written and an os.Error, if any. // -func (f Format) Print(args ...) (int, os.Error) { +func (f Format) Print(args ...interface{}) (int, os.Error) { return f.Fprint(os.Stdout, nil, args) } @@ -717,7 +720,7 @@ func (f Format) Print(args ...) (int, os.Error) { // during formatting, the result string contains the // partially formatted result followed by an error message. // -func (f Format) Sprint(args ...) string { +func (f Format) Sprint(args ...interface{}) string { var buf bytes.Buffer _, err := f.Fprint(&buf, nil, args) if err != nil { diff --git a/src/pkg/exp/datafmt/datafmt_test.go b/src/pkg/exp/datafmt/datafmt_test.go index b109bca6e0e..9088947178b 100644 --- a/src/pkg/exp/datafmt/datafmt_test.go +++ b/src/pkg/exp/datafmt/datafmt_test.go @@ -20,7 +20,7 @@ func parse(t *testing.T, form string, fmap FormatterMap) Format { } -func verify(t *testing.T, f Format, expected string, args ...) { +func verify(t *testing.T, f Format, expected string, args ...interface{}) { if f == nil { return // allow other tests to run } @@ -92,7 +92,7 @@ func TestCustomFormatters(t *testing.T) { // ---------------------------------------------------------------------------- // Formatting of basic and simple composite types -func check(t *testing.T, form, expected string, args ...) { +func check(t *testing.T, form, expected string, args ...interface{}) { f := parse(t, form, nil) if f == nil { return // allow other tests to run @@ -177,16 +177,6 @@ func TestFuncTypes(t *testing.T) { } -func TestInterfaceTypes(t *testing.T) { - var i0 interface{} - check(t, `interface="interface"`, `interface`, i0) - - i0 = "foo" - check(t, `interface="interface"`, `interface`, i0) - check(t, `interface=*; string="%s"`, `foo`, i0) -} - - func TestMapTypes(t *testing.T) { var m0 map[string]int check(t, `map="map"`, `map`, m0) diff --git a/src/pkg/reflect/all_test.go b/src/pkg/reflect/all_test.go index 552b09d89a6..6b1fd32060e 100644 --- a/src/pkg/reflect/all_test.go +++ b/src/pkg/reflect/all_test.go @@ -6,6 +6,7 @@ package reflect_test import ( "container/vector" + "fmt" "io" "os" . "reflect" @@ -139,10 +140,10 @@ var typeTests = []pair{ }, pair{struct { x struct { - f func(args ...) + f func(args ...int) } }{}, - "struct { f func(...) }", + "struct { f func(...int) }", }, pair{struct { x (interface { @@ -1221,3 +1222,26 @@ func TestImportPath(t *testing.T) { t.Errorf("Typeof(vector.Vector{}).PkgPath() = %q, want \"container/vector\"", path) } } + +func TestDotDotDot(t *testing.T) { + // Test example from FuncType.DotDotDot documentation. + var f func(x int, y ...float) + typ := Typeof(f).(*FuncType) + if typ.NumIn() == 2 && typ.In(0) == Typeof(int(0)) { + sl, ok := typ.In(1).(*SliceType) + if ok { + if sl.Elem() == Typeof(float(0)) { + // ok + return + } + } + } + + // Failed + t.Errorf("want NumIn() = 2, In(0) = int, In(1) = []float") + s := fmt.Sprintf("have NumIn() = %d", typ.NumIn()) + for i := 0; i < typ.NumIn(); i++ { + s += fmt.Sprintf(", In(%d) = %s", i, typ.In(i)) + } + t.Error(s) +} diff --git a/src/pkg/reflect/type.go b/src/pkg/reflect/type.go index 19290647c51..6016b0dc0fa 100644 --- a/src/pkg/reflect/type.go +++ b/src/pkg/reflect/type.go @@ -388,8 +388,8 @@ func (t *FuncType) In(i int) Type { } // DotDotDot returns true if the final function input parameter -// is a "..." parameter. If so, the parameter's underlying static -// type - either interface{} or []T - is returned by t.In(t.NumIn() - 1). +// is a "..." parameter. If so, t.In(t.NumIn() - 1) returns the +// parameter's underlying static type []T. // // For concreteness, if t is func(x int, y ... float), then // diff --git a/src/pkg/testing/script/script.go b/src/pkg/testing/script/script.go index 3dbfbd5ff6d..11f5a74251a 100644 --- a/src/pkg/testing/script/script.go +++ b/src/pkg/testing/script/script.go @@ -129,8 +129,12 @@ func (s Send) getSend() sendAction { return s } func (s Send) getChannel() interface{} { return s.Channel } -func newEmptyInterface(args ...) reflect.Value { - return reflect.NewValue(args).(*reflect.StructValue).Field(0) +type empty struct { + x interface{} +} + +func newEmptyInterface(e empty) reflect.Value { + return reflect.NewValue(e).(*reflect.StructValue).Field(0) } func (s Send) send() { @@ -140,7 +144,7 @@ func (s Send) send() { c := reflect.NewValue(s.Channel).(*reflect.ChanValue) var v reflect.Value if iface, ok := c.Type().(*reflect.ChanType).Elem().(*reflect.InterfaceType); ok && iface.NumMethod() == 0 { - v = newEmptyInterface(s.Value) + v = newEmptyInterface(empty{s.Value}) } else { v = reflect.NewValue(s.Value) } diff --git a/test/fixedbugs/bug153.go b/test/fixedbugs/bug153.go deleted file mode 100644 index 609397fed86..00000000000 --- a/test/fixedbugs/bug153.go +++ /dev/null @@ -1,14 +0,0 @@ -// errchk $G $D/$F.go - -// Copyright 2009 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. - -package main - -func f(args ...) { -} - -func main() { - f(nil); // ERROR "nil" -} diff --git a/test/fixedbugs/bug228.go b/test/fixedbugs/bug228.go index 243d20ee7c3..81bc908569e 100644 --- a/test/fixedbugs/bug228.go +++ b/test/fixedbugs/bug228.go @@ -6,14 +6,14 @@ package main -func f(x int, y ...) // ok +func f(x int, y ...int) // ok func g(x int, y float) (...) // ERROR "[.][.][.]" -func h(x, y ...) // ERROR "[.][.][.]" +func h(x, y ...int) // ERROR "[.][.][.]" -func i(x int, y ..., z float) // ERROR "[.][.][.]" +func i(x int, y ...int, z float) // ERROR "[.][.][.]" -var x ...; // ERROR "[.][.][.]|syntax|type" +var x ...int; // ERROR "[.][.][.]|syntax|type" -type T ...; // ERROR "[.][.][.]|syntax|type" +type T ...int; // ERROR "[.][.][.]|syntax|type" diff --git a/test/fixedbugs/bug232.go b/test/fixedbugs/bug232.go index c0b8eb69ada..99bd02ff699 100644 --- a/test/fixedbugs/bug232.go +++ b/test/fixedbugs/bug232.go @@ -5,4 +5,4 @@ // license that can be found in the LICENSE file. package main -type I interface { X(...) } +type I interface { X(...int) } diff --git a/test/fixedbugs/bug252.go b/test/fixedbugs/bug252.go index 7ed8b87cbe0..bd11b86ebf6 100644 --- a/test/fixedbugs/bug252.go +++ b/test/fixedbugs/bug252.go @@ -6,7 +6,7 @@ package main -func f(args ...) { +func f(args ...int) { g(args) // ERROR "[.][.][.] mismatch" }